浏览代码

模型添加枢轴控制器

WQQ 1 月之前
父节点
当前提交
02db9d0358
共有 44 个文件被更改,包括 394 次插入676 次删除
  1. 1 1
      RuoYi-Vue3/package.json
  2. 二进制
      RuoYi-Vue3/public/img/skyboxs/cloudy/Back.png
  3. 二进制
      RuoYi-Vue3/public/img/skyboxs/cloudy/Down.png
  4. 二进制
      RuoYi-Vue3/public/img/skyboxs/cloudy/Front.png
  5. 二进制
      RuoYi-Vue3/public/img/skyboxs/cloudy/Left.png
  6. 二进制
      RuoYi-Vue3/public/img/skyboxs/cloudy/Right.png
  7. 二进制
      RuoYi-Vue3/public/img/skyboxs/cloudy/Up.png
  8. 二进制
      RuoYi-Vue3/public/img/skyboxs/sunset/Back.png
  9. 二进制
      RuoYi-Vue3/public/img/skyboxs/sunset/Down.png
  10. 二进制
      RuoYi-Vue3/public/img/skyboxs/sunset/Front.png
  11. 二进制
      RuoYi-Vue3/public/img/skyboxs/sunset/Left.png
  12. 二进制
      RuoYi-Vue3/public/img/skyboxs/sunset/Right.png
  13. 二进制
      RuoYi-Vue3/public/img/skyboxs/sunset/Up.png
  14. 324 670
      RuoYi-Vue3/src/supermap-cesium-module/components/draw/draw-solid-figure/ModelEditor.js
  15. 19 3
      RuoYi-Vue3/src/supermap-cesium-module/components/scene/scene-attribute/scene-attribute.js
  16. 41 0
      RuoYi-Vue3/src/supermap-cesium-module/components/viewer/viewer.js
  17. 8 1
      RuoYi-Vue3/src/views/front/content/ShuiliGongcheng.vue
  18. 1 1
      RuoYi-Vue3/vite.config.js
  19. 二进制
      ruoyi-admin/target/ruoyi-admin.jar
  20. 二进制
      ruoyi-admin/target/ruoyi-admin.jar.original
  21. 二进制
      ruoyi-admin/uploads/models/2026/04/09/平望场景_20260409165637A001.glb
  22. 二进制
      ruoyi-admin/uploads/models/2026/04/16/莒口水闸_20260416145511A001.glb
  23. 二进制
      ruoyi-common/target/ruoyi-common-3.9.1.jar
  24. 二进制
      ruoyi-framework/target/ruoyi-framework-3.9.1.jar
  25. 二进制
      ruoyi-generator/target/classes/com/ruoyi/generator/domain/GenTable.class
  26. 二进制
      ruoyi-generator/target/classes/com/ruoyi/generator/service/GenTableServiceImpl.class
  27. 二进制
      ruoyi-generator/target/classes/com/ruoyi/generator/util/GenUtils.class
  28. 二进制
      ruoyi-generator/target/classes/com/ruoyi/generator/util/VelocityInitializer.class
  29. 二进制
      ruoyi-generator/target/ruoyi-generator-3.9.1.jar
  30. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/controller/SysJobController.class
  31. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/controller/SysJobLogController.class
  32. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/domain/SysJob.class
  33. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/domain/SysJobLog.class
  34. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.class
  35. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/service/impl/SysJobServiceImpl.class
  36. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/task/RyTask.class
  37. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/util/AbstractQuartzJob.class
  38. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/util/CronUtils.class
  39. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/util/JobInvokeUtil.class
  40. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.class
  41. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/util/QuartzJobExecution.class
  42. 二进制
      ruoyi-quartz/target/classes/com/ruoyi/quartz/util/ScheduleUtils.class
  43. 二进制
      ruoyi-quartz/target/ruoyi-quartz-3.9.1.jar
  44. 二进制
      ruoyi-system/target/ruoyi-system-3.9.1.jar

+ 1 - 1
RuoYi-Vue3/package.json

@@ -23,7 +23,7 @@
     "@vueuse/core": "13.3.0",
     "autofit.js": "^3.2.8",
     "axios": "1.9.0",
-    "cesium": "^1.137.0",
+    "cesium": "^1.140.0",
     "cesium-transform-gizmo": "^0.1.1",
     "clipboard": "2.0.11",
     "echarts": "5.6.0",

二进制
RuoYi-Vue3/public/img/skyboxs/cloudy/Back.png


二进制
RuoYi-Vue3/public/img/skyboxs/cloudy/Down.png


二进制
RuoYi-Vue3/public/img/skyboxs/cloudy/Front.png


二进制
RuoYi-Vue3/public/img/skyboxs/cloudy/Left.png


二进制
RuoYi-Vue3/public/img/skyboxs/cloudy/Right.png


二进制
RuoYi-Vue3/public/img/skyboxs/cloudy/Up.png


二进制
RuoYi-Vue3/public/img/skyboxs/sunset/Back.png


二进制
RuoYi-Vue3/public/img/skyboxs/sunset/Down.png


二进制
RuoYi-Vue3/public/img/skyboxs/sunset/Front.png


二进制
RuoYi-Vue3/public/img/skyboxs/sunset/Left.png


二进制
RuoYi-Vue3/public/img/skyboxs/sunset/Right.png


二进制
RuoYi-Vue3/public/img/skyboxs/sunset/Up.png


+ 324 - 670
RuoYi-Vue3/src/supermap-cesium-module/components/draw/draw-solid-figure/ModelEditor.js

@@ -1,718 +1,372 @@
-// 模型编辑控制器
 class ModelEditor {
   constructor(viewer, entity) {
     this.viewer = viewer;
     this.entity = entity;
+
     this.handler = null;
-    this.activePrimitive = null;
-    this.activeAxis = null;
-    this.startMousePosition = null;
-    this.startMouseCartesian = null;
-    this.dragMode = null;
-    
-    this.translateEnabled = true;
-    this.rotateEnabled = true;
-    this.scaleEnabled = true;
-    
-    this.primitives = [];
-    this.originPoint = null;
-    this.moveAxes = [];
-    this.axisPlanes = [];
-    this.rotateAxes = [];
-    this.scalePoints = [];
-    
-    // 获取 primitives 的辅助方法
-    this.primitivesCollection = this.viewer.primitives || (this.viewer.scene && this.viewer.scene.primitives);
-    
-    this.center = this.getCenter();
-    this.radius = this.getRadius();
-    
-    if (this.entity.model) {
-      if (this.entity.model.readyPromise) {
-        this.entity.model.readyPromise.then(() => {
-          console.log('模型加载完成(通过 readyPromise)');
-          this.center = this.getCenter();
-          this.radius = this.getRadius();
-          this.init();
-        }).catch(() => {
-          console.log('模型加载失败,使用当前位置初始化枢轴');
-          this.center = this.getCenter();
-          this.radius = this.getRadius();
-          this.init();
-        });
-      } else if (this.entity.model.boundingSphere) {
-        this.init();
-      } else {
-        console.log('模型没有 readyPromise,等待 boundingSphere');
-        this.entity.model.definitionChanged.addEventListener(() => {
-          if (this.entity.model.boundingSphere) {
-            console.log('模型加载完成(通过 definitionChanged)');
-            this.center = this.getCenter();
-            this.radius = this.getRadius();
-            this.init();
-          }
-        });
-        
-        setTimeout(() => {
-          if (!this.entity.model.boundingSphere) {
-            console.log('模型加载超时,使用当前位置初始化枢轴');
-            this.center = this.getCenter();
-            this.radius = this.getRadius();
-            this.init();
-          }
-        }, 3000);
-      }
-    } else {
-      this.init();
-    }
-  }
-  
-  async waitForModelLoad() {
-    if (this.initPromise) {
-      await this.initPromise;
-    }
-  }
-  
-  getCenter() {
-    // 首先尝试从 entity.position 获取中心点
-    if (this.entity.position) {
-      const position = this.entity.position.getValue(this.viewer.clock.currentTime);
-      if (position) {
-        return position;
-      }
-    }
-    
-    // 尝试多种方式获取模型中心点
-    if (this.entity.model) {
-      // 尝试直接访问 boundingSphere
-      if (this.entity.model.boundingSphere) {
-        return this.entity.model.boundingSphere.center;
-      }
-      // 尝试通过 _boundingSphere 访问
-      if (this.entity.model._boundingSphere) {
-        return this.entity.model._boundingSphere.center;
-      }
-      // 尝试通过 _primitive 访问
-      if (this.entity.model._primitive && this.entity.model._primitive.boundingSphere) {
-        return this.entity.model._primitive.boundingSphere.center;
-      }
-    }
-    
-    // 如果实体有 position 属性但没有获取到值,尝试获取实体的默认位置
-    if (this.entity.position) {
-      return this.entity.position.getValue(this.viewer.clock.currentTime) || this.viewer.camera.position;
-    }
-    
-    // 返回相机位置作为默认值
-    return this.viewer.camera.position;
-  }
-  
-  getRadius() {
-    // 首先尝试从模型获取半径
-    if (this.entity.model) {
-      // 尝试直接访问 boundingSphere
-      if (this.entity.model.boundingSphere) {
-        return this.entity.model.boundingSphere.radius;
-      }
-      // 尝试通过 _boundingSphere 访问
-      if (this.entity.model._boundingSphere) {
-        return this.entity.model._boundingSphere.radius;
-      }
-      // 尝试通过 _primitive 访问
-      if (this.entity.model._primitive && this.entity.model._primitive.boundingSphere) {
-        return this.entity.model._primitive.boundingSphere.radius;
-      }
-    }
-    
-    // 使用较小的默认半径
-    return 2;
+    this.billboardCollection = null;
+    this.polylineCollection = null;
+
+    this.hoverBillboard = null;
+    this.isDragging = false;
+    this.dragType = null;
+    this.dragAxis = null;
+
+    this.startMousePos = null;
+    this.startScreenPos = null;
+    this.startWorldPos = null;
+    this.dragWorldAxis = null;
+    this.startModelMatrix = null;
+    this.startCenter = null;
+
+    this.center = null;
+    this.radius = 2;
+
+    this.init();
   }
-  
+
   init() {
-    // 先清理旧的 primitives
-    this.clearPrimitives();
-    
-    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas);
-    this.createPrimitives();
-    this.addEventListener();
-  }
-  
-  createPrimitives(isModel = true) {
-    this.createOriginPoint();
-    
-    if (this.translateEnabled) {
-      this.createMoveAxis();
-      this.createAxisPlane();
-    }
-    
-    if (isModel && this.rotateEnabled) {
-      this.createRotateAxis();
-    }
-    
-    if (isModel && this.scaleEnabled) {
-      this.createScaleAxis();
-    }
+    this.cleanup();
+    const scene = this.viewer.scene;
+    const canvas = scene.canvas;
+
+    this.handler = new Cesium.ScreenSpaceEventHandler(canvas);
+    this.billboardCollection = scene.primitives.add(new Cesium.BillboardCollection());
+    this.polylineCollection = scene.primitives.add(new Cesium.PolylineCollection());
+
+    this.center = this.entity.position.getValue(this.viewer.clock.currentTime);
+    this.createAllControls();
+    this.setupEvents();
   }
-  
-  clearPrimitives() {
-    this.primitives.forEach(p => {
-      if (this.primitivesCollection) {
-        this.primitivesCollection.remove(p);
+
+  createAllControls() {
+    const axisLength = this.radius * 0.8;
+    const rotateRadius = this.radius;
+    const axes = [
+      { key: 'X', color: Cesium.Color.RED, dir: new Cesium.Cartesian3(1, 0, 0) },
+      { key: 'Y', color: Cesium.Color.GREEN, dir: new Cesium.Cartesian3(0, 1, 0) },
+      { key: 'Z', color: Cesium.Color.BLUE, dir: new Cesium.Cartesian3(0, 0, 1) },
+    ];
+
+    // 平移轴
+    axes.forEach(({ key, color, dir }) => {
+      const end = this.localToWorld(new Cesium.Cartesian3(dir.x * axisLength, dir.y * axisLength, dir.z * axisLength));
+      this.billboardCollection.add({
+        position: end,
+        image: this.makeArrow(color),
+        disableDepthTestDistance: Number.POSITIVE_INFINITY,
+        id: { type: 'translate', axis: key }
+      });
+      this.polylineCollection.add({
+        positions: [this.center, end],
+        width: 3,
+        material: Cesium.Material.fromType('Color', { color })
+      });
+    });
+
+    // 旋转圆环
+    axes.forEach(({ key, color }) => {
+      const points = [];
+      for (let i = 0; i <= 64; i++) {
+        const ang = i / 64 * Math.PI * 2;
+        let p;
+        if (key === 'X') p = new Cesium.Cartesian3(0, Math.cos(ang) * rotateRadius, Math.sin(ang) * rotateRadius);
+        else if (key === 'Y') p = new Cesium.Cartesian3(Math.cos(ang) * rotateRadius, 0, Math.sin(ang) * rotateRadius);
+        else p = new Cesium.Cartesian3(Math.cos(ang) * rotateRadius, Math.sin(ang) * rotateRadius, 0);
+        points.push(this.localToWorld(p));
       }
+      this.polylineCollection.add({
+        positions: points,
+        width: 2,
+        material: Cesium.Material.fromType('Color', { color })
+      });
+
+      let rotPos;
+      if (key === 'X') rotPos = this.localToWorld(new Cesium.Cartesian3(0, rotateRadius, 0));
+      else if (key === 'Y') rotPos = this.localToWorld(new Cesium.Cartesian3(rotateRadius, 0, 0));
+      else rotPos = this.localToWorld(new Cesium.Cartesian3(rotateRadius, 0, 0));
+
+      this.billboardCollection.add({
+        position: rotPos,
+        image: this.makeRing(color),
+        disableDepthTestDistance: Number.POSITIVE_INFINITY,
+        id: { type: 'rotate', axis: key }
+      });
+    });
+
+    // 缩放方块
+    axes.forEach(({ key, color, dir }) => {
+      const end = this.localToWorld(new Cesium.Cartesian3(dir.x * axisLength, dir.y * axisLength, dir.z * axisLength));
+      this.billboardCollection.add({
+        position: end,
+        image: this.makeBox(color),
+        disableDepthTestDistance: Number.POSITIVE_INFINITY,
+        id: { type: 'scale', axis: key }
+      });
     });
-    this.primitives = [];
-    this.moveAxes = [];
-    this.axisPlanes = [];
-    this.rotateAxes = [];
-    this.scalePoints = [];
-  }
-  
-  createOriginPoint() {
-    if (!this.center) return;
-    
-    const primitives = this.primitivesCollection;
-    if (!primitives) return;
-    
-    const size = Math.max(this.radius * 0.05, 0.1);
-    
-    const primitive = primitives.add(new Cesium.Primitive({
-      geometryInstances: new Cesium.GeometryInstance({
-        geometry: new Cesium.BoxGeometry({
-          vertexFormat: Cesium.VertexFormat.POSITION_AND_COLOR,
-          maximum: new Cesium.Cartesian3(
-            this.center.x + size,
-            this.center.y + size,
-            this.center.z + size
-          ),
-          minimum: new Cesium.Cartesian3(
-            this.center.x - size,
-            this.center.y - size,
-            this.center.z - size
-          )
-        }),
-        attributes: {
-          color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.WHITE.withAlpha(0.8))
-        }
-      }),
-      appearance: new Cesium.PerInstanceColorAppearance({
-        flat: true
-      })
-    }));
-    
-    this.primitives.push(primitive);
-    this.originPoint = primitive;
   }
-  
-  getModelRotationMatrix() {
-    try {
-      console.log('开始获取模型旋转矩阵');
-      const entity = this.entity;
-      
-      if (entity.model) {
-        const model = entity.model;
-        console.log('model 属性:', Object.keys(model));
-        console.log('model._nodeTransformations:', model._nodeTransformations);
-        
-        if (model._nodeTransformations) {
-          console.log('遍历 nodeTransformations:');
-          for (const key in model._nodeTransformations) {
-            const node = model._nodeTransformations[key];
-            console.log('  节点:', key, node);
-            if (node.rotation) {
-              console.log('    rotation:', node.rotation);
-              const rot = Cesium.Matrix3.fromQuaternion(node.rotation, new Cesium.Matrix3());
-              console.log('从 nodeTransformations.rotation 获取旋转矩阵成功');
-              return rot;
-            }
-            if (node.matrix) {
-              console.log('    matrix:', node.matrix);
-              const mat = new Cesium.Matrix4(
-                node.matrix[0], node.matrix[1], node.matrix[2], node.matrix[3],
-                node.matrix[4], node.matrix[5], node.matrix[6], node.matrix[7],
-                node.matrix[8], node.matrix[9], node.matrix[10], node.matrix[11],
-                node.matrix[12], node.matrix[13], node.matrix[14], node.matrix[15]
-              );
-              const rot = Cesium.Matrix4.getMatrix3(mat, new Cesium.Matrix3());
-              console.log('从 nodeTransformations.matrix 获取旋转矩阵成功');
-              return rot;
-            }
-          }
-        }
-        
-        if (model._root) {
-          console.log('model._root 存在');
-          const root = model._root;
-          console.log('root 属性:', Object.keys(root));
-          
-          if (root.transform) {
-            console.log('root.transform:', root.transform);
-            const rot = Cesium.Matrix4.getMatrix3(root.transform, new Cesium.Matrix3());
-            console.log('从 root.transform 获取旋转矩阵成功');
-            return rot;
-          }
-          
-          if (root._transform) {
-            console.log('root._transform:', root._transform);
-            const rot = Cesium.Matrix4.getMatrix3(root._transform, new Cesium.Matrix3());
-            console.log('从 root._transform 获取旋转矩阵成功');
-            return rot;
-          }
+
+  setupEvents() {
+    // 鼠标移动 - 悬停
+    this.handler.setInputAction((e) => {
+      if (this.isDragging) return;
+      const picked = this.pick(e.endPosition);
+
+      if (picked !== this.hoverBillboard) {
+        if (this.hoverBillboard) {
+          this.hoverBillboard.scale = 1.0;
+          this.hoverBillboard.color = Cesium.Color.WHITE;
         }
-      }
-      
-      console.log('无法获取旋转矩阵,使用单位矩阵');
-    } catch (e) {
-      console.log('获取旋转矩阵失败:', e);
-    }
-    
-    return Cesium.Matrix3.IDENTITY.clone();
-  }
-  
-  createMoveAxis() {
-    if (!this.center) return;
-    
-    const length = this.radius * 0.8;
-    const rotationMatrix = this.getModelRotationMatrix();
-    
-    const createAxis = (axis, color) => {
-      let localOffset;
-      if (axis === 'X') {
-        localOffset = new Cesium.Cartesian3(length, 0, 0);
-      } else if (axis === 'Y') {
-        localOffset = new Cesium.Cartesian3(0, length, 0);
-      } else {
-        localOffset = new Cesium.Cartesian3(0, 0, length);
-      }
-      
-      const worldOffset = Cesium.Matrix3.multiplyByVector(rotationMatrix, localOffset, new Cesium.Cartesian3());
-      
-      const points = [
-        new Cesium.Cartesian3(this.center.x, this.center.y, this.center.z),
-        new Cesium.Cartesian3(
-          this.center.x + worldOffset.x,
-          this.center.y + worldOffset.y,
-          this.center.z + worldOffset.z
-        )
-      ];
-      
-      const primitive = this.primitivesCollection.add(new Cesium.Primitive({
-        geometryInstances: new Cesium.GeometryInstance({
-          geometry: new Cesium.PolylineGeometry({
-            positions: points,
-            vertexFormat: Cesium.VertexFormat.POSITION_AND_COLOR
-          }),
-          attributes: {
-            color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
-          }
-        }),
-        appearance: new Cesium.PolylineColorAppearance()
-      }));
-      
-      this.primitives.push(primitive);
-      this.moveAxes.push({ primitive, axis, color });
-      return primitive;
-    };
-    
-    createAxis('X', Cesium.Color.RED);
-    createAxis('Y', Cesium.Color.GREEN);
-    createAxis('Z', Cesium.Color.BLUE);
-  }
-  
-  createAxisPlane() {
-    if (!this.center) return;
-    
-    const size = this.radius * 0.8;
-    const halfSize = size / 2;
-    
-    const createPlane = (axis1, axis2, color) => {
-      let points = [];
-      
-      if (axis1 === 'X' && axis2 === 'Y') {
-        points = [
-          new Cesium.Cartesian3(-halfSize, -halfSize, 0),
-          new Cesium.Cartesian3(halfSize, -halfSize, 0),
-          new Cesium.Cartesian3(halfSize, halfSize, 0),
-          new Cesium.Cartesian3(-halfSize, halfSize, 0)
-        ];
-      } else if (axis1 === 'X' && axis2 === 'Z') {
-        points = [
-          new Cesium.Cartesian3(-halfSize, 0, -halfSize),
-          new Cesium.Cartesian3(halfSize, 0, -halfSize),
-          new Cesium.Cartesian3(halfSize, 0, halfSize),
-          new Cesium.Cartesian3(-halfSize, 0, halfSize)
-        ];
-      } else if (axis1 === 'Y' && axis2 === 'Z') {
-        points = [
-          new Cesium.Cartesian3(0, -halfSize, -halfSize),
-          new Cesium.Cartesian3(0, halfSize, -halfSize),
-          new Cesium.Cartesian3(0, halfSize, halfSize),
-          new Cesium.Cartesian3(0, -halfSize, halfSize)
-        ];
-      }
-      
-      points = points.map(p => new Cesium.Cartesian3(
-        this.center.x + p.x,
-        this.center.y + p.y,
-        this.center.z + p.z
-      ));
-      
-      const primitive = this.primitivesCollection.add(new Cesium.Primitive({
-        geometryInstances: new Cesium.GeometryInstance({
-          geometry: new Cesium.PolygonGeometry({
-            polygonHierarchy: new Cesium.PolygonHierarchy(points),
-            extrudedHeight: 0.1
-          }),
-          attributes: {
-            color: Cesium.ColorGeometryInstanceAttribute.fromColor(color.withAlpha(0.3))
-          }
-        }),
-        appearance: new Cesium.PerInstanceColorAppearance({
-          flat: true
-        })
-      }));
-      
-      this.primitives.push(primitive);
-      this.axisPlanes.push({ primitive, axis1, axis2, color });
-    };
-    
-    createPlane('X', 'Y', Cesium.Color.fromCssColorString('#ffff00'));
-    createPlane('X', 'Z', Cesium.Color.fromCssColorString('#ff00ff'));
-    createPlane('Y', 'Z', Cesium.Color.fromCssColorString('#00ffff'));
-  }
-  
-  createRotateAxis() {
-    if (!this.center) return;
-    
-    const ringRadius = this.radius * 1.0;
-    const rotationMatrix = this.getModelRotationMatrix();
-    
-    const createRotateAxis = (axis, color) => {
-      const points = [];
-      const segments = 64;
-      
-      for (let i = 0; i <= segments; i++) {
-        const angle = (i / segments) * Math.PI * 2;
-        let localX, localY, localZ;
-        
-        if (axis === 'X') {
-          localX = 0;
-          localY = Math.cos(angle) * ringRadius;
-          localZ = Math.sin(angle) * ringRadius;
-        } else if (axis === 'Y') {
-          localX = Math.cos(angle) * ringRadius;
-          localY = 0;
-          localZ = Math.sin(angle) * ringRadius;
-        } else {
-          localX = Math.cos(angle) * ringRadius;
-          localY = Math.sin(angle) * ringRadius;
-          localZ = 0;
+        this.hoverBillboard = picked;
+        if (this.hoverBillboard) {
+          this.hoverBillboard.scale = 1.5;
+          this.hoverBillboard.color = Cesium.Color.YELLOW;
         }
-        
-        const worldOffset = Cesium.Matrix3.multiplyByVector(
-          rotationMatrix,
-          new Cesium.Cartesian3(localX, localY, localZ),
-          new Cesium.Cartesian3()
-        );
-        
-        points.push(new Cesium.Cartesian3(
-          this.center.x + worldOffset.x,
-          this.center.y + worldOffset.y,
-          this.center.z + worldOffset.z
-        ));
       }
+      this.viewer.canvas.style.cursor = picked ? 'pointer' : 'default';
+    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+    // 左键按下
+    this.handler.setInputAction((e) => {
+      const bb = this.pick(e.position);
+      if (!bb) return;
+
+      this.isDragging = true;
+      this.dragType = bb.id.type;
+      this.dragAxis = bb.id.axis;
+      this.startMousePos = { x: e.position.x, y: e.position.y };
+      this.startScreenPos = { x: e.position.x, y: e.position.y };
       
-      const primitive = this.primitivesCollection.add(new Cesium.Primitive({
-        geometryInstances: new Cesium.GeometryInstance({
-          geometry: new Cesium.PolylineGeometry({
-            positions: points,
-            vertexFormat: Cesium.VertexFormat.POSITION_AND_COLOR
-          }),
-          attributes: {
-            color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
-          }
-        }),
-        appearance: new Cesium.PolylineColorAppearance()
-      }));
+      const localAxis = this.getAxis(this.dragAxis);
+      this.dragWorldAxis = this.localToWorld(localAxis);
+      Cesium.Cartesian3.normalize(this.dragWorldAxis, this.dragWorldAxis);
       
-      this.primitives.push(primitive);
-      this.rotateAxes.push({ primitive, axis, color });
-      return primitive;
-    };
-    
-    createRotateAxis('X', Cesium.Color.RED);
-    createRotateAxis('Y', Cesium.Color.GREEN);
-    createRotateAxis('Z', Cesium.Color.BLUE);
-  }
-  
-  createScaleAxis() {
-    if (!this.center) return;
-    
-    const length = this.radius * 0.8;
-    const rotationMatrix = this.getModelRotationMatrix();
-    
-    const createScalePoint = (axis, color) => {
-      let localOffset;
-      if (axis === 'X') {
-        localOffset = new Cesium.Cartesian3(length, 0, 0);
-      } else if (axis === 'Y') {
-        localOffset = new Cesium.Cartesian3(0, length, 0);
+      this.startCenter = this.entity.position.getValue ? this.entity.position.getValue(this.viewer.clock.currentTime) : this.entity.position;
+      this.center = Cesium.Cartesian3.clone(this.startCenter);
+
+      if (this.entity.model) {
+        this.startModelMatrix = Cesium.Matrix4.clone(this.entity.model.modelMatrix);
       } else {
-        localOffset = new Cesium.Cartesian3(0, 0, length);
-      }
-      
-      const worldOffset = Cesium.Matrix3.multiplyByVector(rotationMatrix, localOffset, new Cesium.Cartesian3());
-      const size = Math.max(this.radius * 0.08, 0.15);
-      
-      const primitive = this.primitivesCollection.add(new Cesium.Primitive({
-        geometryInstances: new Cesium.GeometryInstance({
-          geometry: new Cesium.BoxGeometry({
-            vertexFormat: Cesium.VertexFormat.POSITION_AND_COLOR,
-            maximum: new Cesium.Cartesian3(
-              this.center.x + worldOffset.x + size,
-              this.center.y + worldOffset.y + size,
-              this.center.z + worldOffset.z + size
-            ),
-            minimum: new Cesium.Cartesian3(
-              this.center.x + worldOffset.x - size,
-              this.center.y + worldOffset.y - size,
-              this.center.z + worldOffset.z - size
-            )
-          }),
-          attributes: {
-            color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
-          }
-        }),
-        appearance: new Cesium.PerInstanceColorAppearance({
-          flat: true
-        })
-      }));
-      
-      this.primitives.push(primitive);
-      this.scalePoints.push({ primitive, axis, color });
-      return primitive;
-    };
-    
-    createScalePoint('X', Cesium.Color.RED);
-    createScalePoint('Y', Cesium.Color.GREEN);
-    createScalePoint('Z', Cesium.Color.BLUE);
-  }
-  
-  addEventListener() {
-    const handler = this.handler;
-    
-    handler.setInputAction((event) => {
-      const picked = this.viewer.scene.pick(event.position);
-      
-      if (Cesium.defined(picked) && Cesium.defined(picked.primitive)) {
-        this.activePrimitive = picked.primitive;
-        this.startMousePosition = event.position;
-        
-        if (this.originPoint === picked.primitive) {
-          this.dragMode = 'translate';
-          this.activeAxis = 'XYZ';
-        } else if (this.moveAxes.some(a => a.primitive === picked.primitive)) {
-          const axisInfo = this.moveAxes.find(a => a.primitive === picked.primitive);
-          this.dragMode = 'translate';
-          this.activeAxis = axisInfo.axis;
-        } else if (this.axisPlanes.some(p => p.primitive === picked.primitive)) {
-          const planeInfo = this.axisPlanes.find(p => p.primitive === picked.primitive);
-          this.dragMode = 'translate';
-          this.activeAxis = planeInfo.axis1 + planeInfo.axis2;
-        } else if (this.rotateAxes.some(r => r.primitive === picked.primitive)) {
-          const axisInfo = this.rotateAxes.find(r => r.primitive === picked.primitive);
-          this.dragMode = 'rotate';
-          this.activeAxis = axisInfo.axis;
-        } else if (this.scalePoints.some(s => s.primitive === picked.primitive)) {
-          const axisInfo = this.scalePoints.find(s => s.primitive === picked.primitive);
-          this.dragMode = 'scale';
-          this.activeAxis = axisInfo.axis;
-        }
-        
-        if (this.dragMode) {
-          this.startMouseCartesian = this.pickCartesianFromMouse(event.position);
-        }
+        this.startModelMatrix = Cesium.Matrix4.IDENTITY.clone();
       }
+
+      this.viewer.scene.screenSpaceCameraController.enableInputs = false;
     }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
-    
-    handler.setInputAction((event) => {
-      if (!this.dragMode || !this.activePrimitive) return;
-      
-      const currentMouseCartesian = this.pickCartesianFromMouse(event.position);
+
+    // 拖拽
+    this.handler.setInputAction((e) => {
+      if (!this.isDragging || !this.startScreenPos) return;
       
-      if (!this.startMouseCartesian || !currentMouseCartesian) return;
+      const dx = e.endPosition.x - this.startScreenPos.x;
+      const dy = e.endPosition.y - this.startScreenPos.y;
       
-      if (this.dragMode === 'translate') {
-        this.translate(currentMouseCartesian);
-      } else if (this.dragMode === 'rotate') {
-        this.rotate(event.position);
-      } else if (this.dragMode === 'scale') {
-        this.scale(currentMouseCartesian);
+      if (this.dragType === 'rotate') {
+        const rotateDx = e.endPosition.x - this.startMousePos.x;
+        this.doRotate(rotateDx);
+        this.startMousePos = { x: e.endPosition.x, y: e.endPosition.y };
+      } else {
+        this.startScreenPos = { x: e.endPosition.x, y: e.endPosition.y };
+        if (this.dragType === 'translate') this.doTranslate(dx, dy);
+        if (this.dragType === 'scale') this.doScale(dx, dy);
       }
-      
-      this.startMouseCartesian = currentMouseCartesian;
     }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
-    
-    handler.setInputAction(() => {
-      this.activePrimitive = null;
-      this.dragMode = null;
-      this.startMousePosition = null;
-      this.startMouseCartesian = null;
+
+    // 左键抬起
+    this.handler.setInputAction(() => {
+      this.isDragging = false;
+      this.dragType = null;
+      this.startScreenPos = null;
+      this.dragWorldAxis = null;
+      this.viewer.scene.screenSpaceCameraController.enableInputs = true;
     }, Cesium.ScreenSpaceEventType.LEFT_UP);
   }
-  
-  pickCartesianFromMouse(mousePosition) {
-    const ray = this.viewer.camera.getRay(mousePosition);
-    const cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
-    
-    if (!cartesian) {
-      // 如果没有与地面相交,则使用相机前方一定距离的点
-      const position = this.viewer.camera.position;
-      const direction = this.viewer.camera.direction;
-      const distance = 100;
-      cartesian = new Cesium.Cartesian3(
-        position.x + direction.x * distance,
-        position.y + direction.y * distance,
-        position.z + direction.z * distance
-      );
+
+  // 平移
+  doTranslate(dx, dy) {
+    const camera = this.viewer.camera;
+    const center = this.entity.position.getValue ? this.entity.position.getValue(this.viewer.clock.currentTime) : this.entity.position;
+    const dist = Cesium.Cartesian3.distance(camera.position, center);
+    const sensitivity = dist * 0.002;
+    
+    const right = camera.right;
+    const up = camera.up;
+    
+    const mat = Cesium.Transforms.eastNorthUpToFixedFrame(center);
+    const xAxis = Cesium.Matrix4.multiplyByPoint(mat, new Cesium.Cartesian3(1, 0, 0), new Cesium.Cartesian3());
+    const yAxis = Cesium.Matrix4.multiplyByPoint(mat, new Cesium.Cartesian3(0, 1, 0), new Cesium.Cartesian3());
+    const zAxis = Cesium.Matrix4.multiplyByPoint(mat, new Cesium.Cartesian3(0, 0, 1), new Cesium.Cartesian3());
+    Cesium.Cartesian3.subtract(xAxis, center, xAxis);
+    Cesium.Cartesian3.subtract(yAxis, center, yAxis);
+    Cesium.Cartesian3.subtract(zAxis, center, zAxis);
+    
+    let moveDir;
+    if (this.dragAxis === 'X') {
+      moveDir = xAxis;
+    } else if (this.dragAxis === 'Y') {
+      moveDir = yAxis;
+    } else {
+      moveDir = zAxis;
     }
+    Cesium.Cartesian3.normalize(moveDir, moveDir);
     
-    return cartesian;
-  }
-  
-  translate(currentMouseCartesian) {
-    if (!this.startMouseCartesian || !currentMouseCartesian) return;
-    
-    const offset = new Cesium.Cartesian3(
-      currentMouseCartesian.x - this.startMouseCartesian.x,
-      currentMouseCartesian.y - this.startMouseCartesian.y,
-      currentMouseCartesian.z - this.startMouseCartesian.z
-    );
-    
-    // 根据选中轴过滤偏移量
-    if (this.activeAxis.indexOf('X') === -1) offset.x = 0;
-    if (this.activeAxis.indexOf('Y') === -1) offset.y = 0;
-    if (this.activeAxis.indexOf('Z') === -1) offset.z = 0;
+    const screenDirX = right.x * dx + up.x * (-dy);
+    const screenDirY = right.y * dx + up.y * (-dy);
+    const screenDirZ = right.z * dx + up.z * (-dy);
+    const screenMove = new Cesium.Cartesian3(screenDirX, screenDirY, screenDirZ);
+    const dot = Cesium.Cartesian3.dot(screenMove, moveDir);
     
-    // 更新实体位置
-    if (this.entity.position) {
-      const currentPosition = this.entity.position.getValue(this.viewer.clock.currentTime);
-      if (currentPosition) {
-        const newPosition = new Cesium.Cartesian3(
-          currentPosition.x + offset.x,
-          currentPosition.y + offset.y,
-          currentPosition.z + offset.z
-        );
-        this.entity.position = newPosition;
-      }
-    }
+    const moveAmount = dot * sensitivity;
+    const offset = Cesium.Cartesian3.multiplyByScalar(moveDir, moveAmount, new Cesium.Cartesian3());
     
-    // 更新中心点
-    this.center = this.getCenter();
+    this.center = Cesium.Cartesian3.add(this.startCenter, offset, new Cesium.Cartesian3());
+    this.entity.position = Cesium.Cartesian3.clone(this.center);
+    this.startCenter = Cesium.Cartesian3.clone(this.center);
     
-    // 重新创建枢轴
-    this.init();
+    this.updateControls();
+    this.viewer.scene.requestRender();
   }
   
-  rotate(mousePosition) {
-    if (!this.startMousePosition || !mousePosition) return;
-    
-    const deltaX = mousePosition.x - this.startMousePosition.x;
-    const angle = deltaX * 0.01;
-    
-    let axis = new Cesium.Cartesian3(0, 0, 1);
-    if (this.activeAxis === 'X') {
-      axis = new Cesium.Cartesian3(1, 0, 0);
-    } else if (this.activeAxis === 'Y') {
-      axis = new Cesium.Cartesian3(0, 1, 0);
-    } else if (this.activeAxis === 'Z') {
-      axis = new Cesium.Cartesian3(0, 0, 1);
+  updateControls() {
+    if (this.billboardCollection) {
+      this.viewer.scene.primitives.remove(this.billboardCollection);
+      this.viewer.scene.primitives.remove(this.polylineCollection);
+      this.billboardCollection = this.viewer.scene.primitives.add(new Cesium.BillboardCollection());
+      this.polylineCollection = this.viewer.scene.primitives.add(new Cesium.PolylineCollection());
+      this.createAllControls();
     }
+  }
+
+  // 缩放
+  doScale(dx, dy) {
+    const scaleDelta = (dx + dy) * 0.01;
+    const scale = Math.max(0.1, 1 + scaleDelta);
+    
+    const modelMatrix = this.entity.model.modelMatrix;
+    const scaleVec = new Cesium.Cartesian3(1, 1, 1);
+    if (this.dragAxis === 'X') scaleVec.x = scale;
+    if (this.dragAxis === 'Y') scaleVec.y = scale;
+    if (this.dragAxis === 'Z') scaleVec.z = scale;
+    
+    const currentScale = Cesium.Matrix4.getScale(modelMatrix, new Cesium.Cartesian3());
+    const newScale = new Cesium.Cartesian3(
+      currentScale.x * scaleVec.x,
+      currentScale.y * scaleVec.y,
+      currentScale.z * scaleVec.z
+    );
     
-    // 创建旋转矩阵
-    const quaternion = Cesium.Quaternion.fromAxisAngle(axis, angle);
-    const rotationMatrix = Cesium.Matrix3.fromQuaternion(quaternion);
+    const translation = Cesium.Matrix4.getTranslation(modelMatrix, new Cesium.Cartesian3());
+    const rotation = Cesium.Matrix4.getRotation(modelMatrix, new Cesium.Matrix3());
     
-    // 获取当前位置
-    if (this.entity.position) {
-      const currentPosition = this.entity.position.getValue(this.viewer.clock.currentTime);
-      if (currentPosition) {
-        // 计算新位置(绕中心点旋转)
-        const translation = Cesium.Matrix4.fromTranslation(currentPosition);
-        const rotation = Cesium.Matrix4.fromTranslationRotationScale(
-          Cesium.Vector3.ZERO,
-          quaternion,
-          new Cesium.Cartesian3(1, 1, 1)
-        );
-        
-        Cesium.Matrix4.multiply(translation, rotation, translation);
-        
-        const newPosition = Cesium.Matrix4.getTranslation(translation, new Cesium.Cartesian3());
-        this.entity.position = newPosition;
-      }
+    const newModelMatrix = Cesium.Matrix4.fromTranslationRotationScale(translation, rotation, newScale);
+    this.entity.model.modelMatrix = newModelMatrix;
+    this.viewer.scene.requestRender();
+  }
+
+  // 旋转
+  doRotate(dx) {
+    if (!this.entity.model) return;
+    
+    const center = this.entity.position.getValue ? this.entity.position.getValue(this.viewer.clock.currentTime) : this.entity.position;
+    const angleSensitivity = 0.005;
+    const angle = dx * angleSensitivity;
+    
+    let rotateAxis;
+    if (this.dragAxis === 'X') {
+      rotateAxis = new Cesium.Cartesian3(1, 0, 0);
+    } else if (this.dragAxis === 'Y') {
+      rotateAxis = new Cesium.Cartesian3(0, 1, 0);
+    } else {
+      rotateAxis = new Cesium.Cartesian3(0, 0, 1);
     }
     
-    // 更新中心点
-    this.center = this.getCenter();
-    
-    // 重新创建枢轴
-    this.init();
+    const mat = Cesium.Transforms.eastNorthUpToFixedFrame(center);
+    const worldAxis = Cesium.Matrix4.multiplyByPoint(mat, rotateAxis, new Cesium.Cartesian3());
+    Cesium.Cartesian3.subtract(worldAxis, center, worldAxis);
+    Cesium.Cartesian3.normalize(worldAxis, worldAxis);
     
-    this.startMousePosition = mousePosition;
-  }
-  
-  scale(currentMouseCartesian) {
-    if (!this.startMouseCartesian || !currentMouseCartesian) return;
+    const quat = Cesium.Quaternion.fromAxisAngle(worldAxis, angle);
+    const rotationMatrix = Cesium.Matrix3.fromQuaternion(quat);
     
-    const offset = new Cesium.Cartesian3(
-      currentMouseCartesian.x - this.startMouseCartesian.x,
-      currentMouseCartesian.y - this.startMouseCartesian.y,
-      currentMouseCartesian.z - this.startMouseCartesian.z
-    );
+    const modelMatrix = this.entity.model.modelMatrix;
+    const translation = Cesium.Matrix4.getTranslation(modelMatrix, new Cesium.Cartesian3());
+    const scale = Cesium.Matrix4.getScale(modelMatrix, new Cesium.Cartesian3());
     
-    // 根据选中轴计算缩放比例
-    let scaleFactor = 1.0;
-    if (this.activeAxis === 'X' && offset.x !== 0) {
-      scaleFactor = 1 + offset.x * 0.01;
-    } else if (this.activeAxis === 'Y' && offset.y !== 0) {
-      scaleFactor = 1 + offset.y * 0.01;
-    } else if (this.activeAxis === 'Z' && offset.z !== 0) {
-      scaleFactor = 1 + offset.z * 0.01;
-    }
+    const currentRotMatrix = Cesium.Matrix4.getRotation(modelMatrix, new Cesium.Matrix3());
+    const newRotMatrix = Cesium.Matrix3.multiply(currentRotMatrix, rotationMatrix, new Cesium.Matrix3());
     
-    // 更新模型缩放
-    if (this.entity.model) {
-      const currentScale = this.entity.model.scale || 1.0;
-      this.entity.model.scale = currentScale * scaleFactor;
-    }
+    const newModelMatrix = Cesium.Matrix4.fromTranslationRotationScale(translation, newRotMatrix, scale);
     
-    this.startMouseCartesian = currentMouseCartesian;
+    this.entity.model.modelMatrix = newModelMatrix;
+    this.viewer.scene.requestRender();
   }
-  
-  destroy() {
-    // 清理事件监听器
-    if (this.handler) {
-      this.handler.destroy();
-      this.handler = null;
+
+  // 拾取
+  pick(windowPos) {
+    const bbs = this.billboardCollection._billboards || [];
+    for (const bb of bbs) {
+      if (!bb?.position || !bb.id) continue;
+      const screenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, bb.position);
+      if (!screenPos) continue;
+      const dist = Math.hypot(screenPos.x - windowPos.x, screenPos.y - windowPos.y);
+      if (dist < 50) return bb;
     }
-    
-    // 清理 primitives
-    if (this.entity.model && this.entity.model.definitionChanged) {
-      this.entity.model.definitionChanged.removeEventListener(() => {
-        if (this.entity.model.boundingSphere) {
-          this.center = this.getCenter();
-          this.radius = this.getRadius();
-          this.init();
-        }
-      });
+    return null;
+  }
+
+  getAxis(axis) {
+    switch (axis) {
+      case 'X': return new Cesium.Cartesian3(1, 0, 0);
+      case 'Y': return new Cesium.Cartesian3(0, 1, 0);
+      case 'Z': return new Cesium.Cartesian3(0, 0, 1);
+      default: return new Cesium.Cartesian3();
     }
-    
-    this.clearPrimitives();
-    
-    this.activePrimitive = null;
-    this.activeAxis = null;
-    this.dragMode = null;
-    this.startMouseCartesian = null;
   }
+
+  localToWorld(v) {
+    const mat = Cesium.Transforms.eastNorthUpToFixedFrame(this.center);
+    return Cesium.Matrix4.multiplyByPoint(mat, v, new Cesium.Cartesian3());
+  }
+
+  makeArrow(color) {
+    const c = document.createElement('canvas');
+    c.width = 32; c.height = 32;
+    const ctx = c.getContext('2d');
+    ctx.fillStyle = `rgb(${color.red * 255},${color.green * 255},${color.blue * 255})`;
+    ctx.beginPath();
+    ctx.moveTo(4, 16); ctx.lineTo(24, 16); ctx.lineTo(24, 6); ctx.lineTo(30, 16); ctx.lineTo(24, 26); ctx.closePath();
+    ctx.fill();
+    return c.toDataURL();
+  }
+
+  makeBox(color) {
+    const c = document.createElement('canvas');
+    c.width = 24; c.height = 24;
+    const ctx = c.getContext('2d');
+    ctx.fillStyle = `rgb(${color.red * 255},${color.green * 255},${color.blue * 255})`;
+    ctx.fillRect(6, 6, 12, 12);
+    return c.toDataURL();
+  }
+
+  makeRing(color) {
+    const c = document.createElement('canvas');
+    c.width = 24; c.height = 24;
+    const ctx = c.getContext('2d');
+    ctx.strokeStyle = `rgb(${color.red * 255},${color.green * 255},${color.blue * 255})`;
+    ctx.lineWidth = 3;
+    ctx.beginPath();
+    ctx.arc(12, 12, 8, 0, Math.PI * 2);
+    ctx.stroke();
+    return c.toDataURL();
+  }
+
+  cleanup() {
+    if (this.handler) this.handler.destroy();
+    if (this.billboardCollection) this.viewer.scene.primitives.remove(this.billboardCollection);
+    if (this.polylineCollection) this.viewer.scene.primitives.remove(this.polylineCollection);
+    this.viewer.scene.screenSpaceCameraController.enableInputs = true;
+  }
+
+  destroy() { this.cleanup(); }
 }
 
-export default ModelEditor;
+export default ModelEditor;

+ 19 - 3
RuoYi-Vue3/src/supermap-cesium-module/components/scene/scene-attribute/scene-attribute.js

@@ -15,11 +15,11 @@ function s3mlayerAttribute(props) {
         earthShow: true,
         shadows: false,
         cloud: false,
-        skyBox: false,
+        skyBox: true,
         sunShow: false,
         timeline: false,
         depthAgainst: true,
-        atomsphereRender: true,
+        atomsphereRender: false,
         fogEffect: true,
         underground: true,
         frameRate: false,
@@ -28,7 +28,7 @@ function s3mlayerAttribute(props) {
         surfaceTransparency: 1,
         cloudsUrl: 'public/img/skyboxs/clouds/clouds1.png',
         skyboxSources: null,
-        skyboxType: 'bluesky',
+        skyboxType: 'cloudy',
         uspeed: 0,
         vspeed: 0,
         wspeed: 0.5,
@@ -60,6 +60,22 @@ function s3mlayerAttribute(props) {
             negativeY: 'public/img/skyboxs/sunsetglow/Back.jpg',
             positiveZ: 'public/img/skyboxs/sunsetglow/Up.jpg',
             negativeZ: 'public/img/skyboxs/sunsetglow/Down.jpg'
+        },
+        sunset: {
+            positiveX: 'public/img/skyboxs/sunset/Right.png',
+            negativeX: 'public/img/skyboxs/sunset/Left.png',
+            positiveY: 'public/img/skyboxs/sunset/Front.png',
+            negativeY: 'public/img/skyboxs/sunset/Back.png',
+            positiveZ: 'public/img/skyboxs/sunset/Up.png',
+            negativeZ: 'public/img/skyboxs/sunset/Down.png'
+        },
+        cloudy: {
+            positiveX: 'public/img/skyboxs/cloudy/Right.png',
+            negativeX: 'public/img/skyboxs/cloudy/Left.png',
+            positiveY: 'public/img/skyboxs/cloudy/Front.png',
+            negativeY: 'public/img/skyboxs/cloudy/Back.png',
+            positiveZ: 'public/img/skyboxs/cloudy/Up.png',
+            negativeZ: 'public/img/skyboxs/cloudy/Down.png'
         }
     };
 

+ 41 - 0
RuoYi-Vue3/src/supermap-cesium-module/components/viewer/viewer.js

@@ -74,6 +74,47 @@ function initViewer(props, callback) {
   viewer.scene.debugShowFramesPerSecond = true; //帧率
   viewer.scene.globe.baseColor = Cesium.Color.BLACK; // 没有影像图层时地球的底色
   // viewer.scene.globe.depthTestAgainstTerrain = false; //地形深度
+  
+  // 完全禁用大气效果
+  if (viewer.scene.skyAtmosphere) {
+    viewer.scene.skyAtmosphere.show = false;
+  }
+  
+  // 禁用太阳和月亮
+  if (viewer.scene.sun) {
+    viewer.scene.sun.show = false;
+  }
+  if (viewer.scene.moon) {
+    viewer.scene.moon.show = false;
+  }
+  
+  // 禁用光照效果,避免影响天空盒
+  viewer.scene.globe.enableLighting = false;
+  
+  // 使用与场景属性设置相同的方式创建天空盒
+  const skyboxSources = {
+    cloudy: {
+      positiveX: 'public/img/skyboxs/cloudy/Right.png',
+      negativeX: 'public/img/skyboxs/cloudy/Left.png',
+      positiveY: 'public/img/skyboxs/cloudy/Front.png',
+      negativeY: 'public/img/skyboxs/cloudy/Back.png',
+      positiveZ: 'public/img/skyboxs/cloudy/Up.png',
+      negativeZ: 'public/img/skyboxs/cloudy/Down.png'
+    }
+  };
+  
+  // 创建天空盒实例
+  let skybox = new Cesium.SkyBox({ sources: skyboxSources.cloudy });
+  skybox.USpeed = 0;
+  skybox.VSpeed = 0;
+  skybox.WSpeed = 0.5;
+  
+  // 设置天空盒
+  viewer.scene.skyBox = skybox;
+  
+  // 启用天空盒
+  viewer.scene.skyBox.show = true;
+  
   window.viewer = viewer;
   window.scene = viewer.scene;
   scene.moon.show = false;

+ 8 - 1
RuoYi-Vue3/src/views/front/content/ShuiliGongcheng.vue

@@ -1278,8 +1278,15 @@ const deleteModel = async (row) => {
 const handleFileChange = (file, fileList) => {
   console.log('选择的文件:', file)
   console.log('文件列表:', fileList)
+  
+  const maxSize = 1024 * 1024 * 1024 // 1GB
+  if (file.size > maxSize) {
+    ElMessage.error('上传文件大小不能超过 1GB!')
+    formData.value.file = null
+    return
+  }
+  
   formData.value.file = file.raw
-  // 自动填充格式
   const fileName = file.name
   const fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1).toUpperCase()
   formData.value.format = fileExtension

+ 1 - 1
RuoYi-Vue3/vite.config.js

@@ -26,7 +26,7 @@ export default defineConfig(({ mode, command }) => {
         // 设置别名
         '@': path.resolve(__dirname, './src'),
         // Cesium别名
-        'cesium': path.resolve(__dirname, './node_modules/cesium/Build/Cesium/Cesium.js')
+        'cesium': path.resolve(__dirname, './node_modules/cesium/Build/CesiumUnminified/Cesium.js')
       },
       // https://cn.vitejs.dev/config/#resolve-extensions
       extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']

二进制
ruoyi-admin/target/ruoyi-admin.jar


二进制
ruoyi-admin/target/ruoyi-admin.jar.original


二进制
ruoyi-admin/uploads/models/2026/04/09/平望场景_20260409165637A001.glb


二进制
ruoyi-admin/uploads/models/2026/04/16/莒口水闸_20260416145511A001.glb


二进制
ruoyi-common/target/ruoyi-common-3.9.1.jar


二进制
ruoyi-framework/target/ruoyi-framework-3.9.1.jar


二进制
ruoyi-generator/target/classes/com/ruoyi/generator/domain/GenTable.class


二进制
ruoyi-generator/target/classes/com/ruoyi/generator/service/GenTableServiceImpl.class


二进制
ruoyi-generator/target/classes/com/ruoyi/generator/util/GenUtils.class


二进制
ruoyi-generator/target/classes/com/ruoyi/generator/util/VelocityInitializer.class


二进制
ruoyi-generator/target/ruoyi-generator-3.9.1.jar


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/controller/SysJobController.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/controller/SysJobLogController.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/domain/SysJob.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/domain/SysJobLog.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/service/impl/SysJobServiceImpl.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/task/RyTask.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/util/AbstractQuartzJob.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/util/CronUtils.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/util/JobInvokeUtil.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/util/QuartzJobExecution.class


二进制
ruoyi-quartz/target/classes/com/ruoyi/quartz/util/ScheduleUtils.class


二进制
ruoyi-quartz/target/ruoyi-quartz-3.9.1.jar


二进制
ruoyi-system/target/ruoyi-system-3.9.1.jar