Browse Source

Merge branch 'xj' of http://192.168.0.115:3000/bill/public-fuse into xj

tangning 1 year ago
parent
commit
c5aa5af80e

+ 1 - 1
src/app/fire/view/dispatch/list.vue

@@ -89,7 +89,7 @@
         {{ fireStatusDesc[row.status as FireStatus] }}
       </el-table-column>
       <slot name="appendColumn" />
-      <el-table-column label="操作" v-slot:default="{ row }" :width="220">
+      <el-table-column label="操作" v-slot:default="{ row }" :width="220" fixed="right">
         <slot name="rowCtrl" :row="row" />
       </el-table-column>
     </el-table>

+ 1 - 0
src/constant/scene.ts

@@ -51,6 +51,7 @@ export const ModelSceneStatusDesc: { [key in ModelSceneStatus]: string } = {
   [ModelSceneStatus.CANCEL]: "已取消",
   [ModelSceneStatus.ERR]: "上传失败",
   [ModelSceneStatus.RUN]: "上传中",
+  [ModelSceneStatus.REV]: "转换中",
   [ModelSceneStatus.SUCCESS]: "成功",
 };
 

+ 12 - 1
src/core/Scene.js

@@ -2,6 +2,7 @@ import * as THREE from "three";
 import Stats from "three/examples/jsm/libs/stats.module.js";
 import Player from "./player/Player.js";
 import BoxManager from "./box/BoxManager.js";
+import mitt from "mitt";
 
 const stats = new Stats();
 
@@ -12,13 +13,14 @@ export default class Scene {
     this.renderer = null;
     this.orthCamera = null;
     this.player = null;
-
+    this.mitt = null;
     this.width = 0;
     this.height = 0;
     this.inited = false;
 
     this.init = () => {
       this.scene = new THREE.Scene();
+      this.mitt = new mitt();
       this.scene.background = new THREE.Color(0xf0f2f5);
       this.renderer = new THREE.WebGLRenderer({
         canvas: this.domElement,
@@ -47,6 +49,7 @@ export default class Scene {
       this.orthCamera.lookAt(0, 0, 0);
       // this.orthCamera.setViewOffset(this.width, this.height, 0, 0);
       this.orthCamera.updateProjectionMatrix();
+  
       //player
       this.player = new Player(this);
 
@@ -93,6 +96,14 @@ export default class Scene {
 
   toVertical = () => {};
 
+  lockView(open) {
+    if (open) {
+      this.player.floorplanControls.enablePan = true;
+    } else {
+      this.player.floorplanControls.enablePan = false;
+    }
+  }
+
   onResize = (width, height) => {
     this.width = width !== undefined ? width : this.domElement.clientWidth;
     this.height = height !== undefined ? height : this.domElement.clientHeight;

+ 7 - 3
src/core/box/BoxManager.js

@@ -1,6 +1,8 @@
 import * as THREE from "three";
-import HorizontalBox from "./horizontalBox";
+import HorizontalBox from "./HorizontalBox";
 import VerticalBox from "./VerticalBox";
+import SimpleLabel from "./object/SimpleLabel";
+
 export default class BoxManager {
   constructor(scene) {
     this.scene = scene;
@@ -17,19 +19,21 @@ export default class BoxManager {
 
   load = (list, type) => {
     console.log("this.model.name", this.model.name);
+    const total = list.length;
     list.forEach((item, index) => {
       if (type === 1) {
         //横排
         console.log("横排");
-        const box = new HorizontalBox(this, item, index);
+        const box = new HorizontalBox(this, item, index, total);
         this.model.add(box);
       }
       if (type === 2) {
         //竖排
-        const box = new VerticalBox(this, item, index);
+        const box = new VerticalBox(this, item, index, total);
         // console.log("竖排");
         this.model.add(box);
       }
+
     });
 
     this.scene.scene.add(this.model);

+ 29 - 4
src/core/box/HorizontalBox.js

@@ -1,14 +1,15 @@
 import * as THREE from "three";
 import TextLabel from "./object/TextLabel";
+import SimpleLabel from "./object/SimpleLabel";
 import ImgLabel from "./object/ImgLabel";
 import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
 
 export default class HorizontalBox extends THREE.Group {
-  constructor(manager, data, index) {
+  constructor(manager, data, index, total) {
     super();
     this.manager = manager;
     this.name = "horizontal_box";
-
+    this.total = total;
     this.getStyle();
     this.load(data, index);
   }
@@ -17,7 +18,15 @@ export default class HorizontalBox extends THREE.Group {
     this.height = (2 * 710) / 500;
     this.color = 0xffffff;
   }
+  cover(texture, aspect) {
+    var imageAspect = texture.image.width / texture.image.height;
 
+    if (aspect < imageAspect) {
+      texture.matrix.setUvTransform(0, 0, aspect / imageAspect, 1, 0, 0.5, 0.5);
+    } else {
+      texture.matrix.setUvTransform(0, 0, 1, imageAspect / aspect, 0, 0.5, 0.5);
+    }
+  }
   load(data, index) {
     //box
 
@@ -48,16 +57,25 @@ export default class HorizontalBox extends THREE.Group {
     data.forEach((i, j) => {
       //img
       let img;
-
       this.manager.loader.load(i.imgUrl, (texture) => {
+        let imgRatio = texture.image.width / texture.image.height;
+
+        let planeRatio = 1.5 /  0.85;
+        let ratio = planeRatio / imgRatio;
+
+        texture.repeat.x = ratio;
+        texture.offset.x = 0.5 * (1 - ratio);
+        
+        // console.log("texture", texture);
         texture.colorSpace = THREE.SRGBColorSpace;
         img = new ImgLabel(texture, matLine);
+
         img.userData = i.id;
         img.position.y += 1;
         if (j === 0) {
           img.position.z -= 0.8;
         } else {
-          img.position.z += 0.5;
+          img.position.z += 0.43;
         }
         this.add(img);
         this.manager.imgList.push(img);
@@ -67,5 +85,12 @@ export default class HorizontalBox extends THREE.Group {
         textlabel.position.z += textlabel.scale.z * 0.5 + 0.1;
       });
     });
+    //页脚
+    const f_txt_label = ` 第 ${index + 1} 页  共 ${this.total} 页`;
+    const footlabel = new SimpleLabel(f_txt_label, true);
+    footlabel.renderOrder = 100;
+    footlabel.position.z += 1.26;
+
+    this.add(footlabel);
   }
 }

+ 22 - 9
src/core/box/VerticalBox.js

@@ -1,13 +1,15 @@
 import * as THREE from "three";
 import TextLabel from "./object/TextLabel";
 import ImgLabel from "./object/ImgLabel";
+import SimpleLabel from "./object/SimpleLabel";
 import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
 
 export default class VerticalBox extends THREE.Group {
-  constructor(manager, data, index) {
+  constructor(manager, data, index, total) {
     super();
     this.manager = manager;
-    this.name = "horizontal_box";
+    this.total = total;
+    this.name = "vertical_box";
     this.getStyle();
     this.load(data, index);
   }
@@ -47,21 +49,32 @@ export default class VerticalBox extends THREE.Group {
       //img
       let img;
       this.manager.loader.load(i.imgUrl, (texture) => {
+        let imgRatio = texture.image.width / texture.image.height;
+        let planeRatio = 1.5 / 2;
+        let ratio = planeRatio / imgRatio;
+
+        texture.repeat.x = ratio;
+        texture.offset.x = 0.5 * (1 - ratio);
+
         texture.colorSpace = THREE.SRGBColorSpace;
-        img = new ImgLabel(texture, matLine);
+        img = new ImgLabel(texture, matLine, false);
         img.position.y += 1;
-        if (j === 0) {
-          img.position.z -= 0.8;
-        } else {
-          img.position.z += 0.5;
-        }
+        img.position.z -= 0.2;
         this.add(img);
         this.manager.imgList.push(img);
         const textlabel = new TextLabel(i.imgInfo, true);
         this.add(textlabel);
         textlabel.position.copy(img.position);
-        textlabel.position.z += textlabel.scale.z * 0.5 + 0.1;
+        textlabel.position.z += textlabel.scale.z * 0.5 + 0.7;
       });
     });
+
+    //页脚
+    const f_txt_label = ` 第 ${index + 1} 页  共 ${this.total} 页`;
+    const footlabel = new SimpleLabel(f_txt_label, true);
+    footlabel.renderOrder = 100;
+    footlabel.position.z += 1.26;
+
+    this.add(footlabel);
   }
 }

+ 27 - 11
src/core/box/object/ImgLabel.js

@@ -1,11 +1,30 @@
 import * as THREE from "three";
 import TouchEdge from "./TouchEdge";
 
-export default class ImgLabel extends THREE.Mesh {
-  constructor(texture, matLine) {
-    const width = 1.5;
-    const height = 0.85;
 
+
+export default class ImgLabel extends THREE.Mesh {
+  constructor(texture, matLine, isHorizontal = true) {
+    let width, height, p;
+    if (isHorizontal) {
+      width = 1.5;
+      height = 0.85;
+      p = [
+        [-0.75, 0, -0.425, 0.75, 0, -0.425],
+        [-0.75, 0, -0.425, -0.75, 0, 0.425],
+        [-0.75, 0, 0.425, 0.75, 0, 0.425],
+        [0.75, 0, 0.425, 0.75, 0, -0.425],
+      ];
+    } else {
+      width = 1.5;
+      height = 2;
+      p = [
+        [-0.75, 0, -1, 0.75, 0, -1],
+        [-0.75, 0, -1, -0.75, 0, 1],
+        [-0.75, 0, 1, 0.75, 0, 1],
+        [0.75, 0, 1, 0.75, 0, -1],
+      ];
+    }
     const g = new THREE.PlaneGeometry(width, height);
     g.rotateX(-Math.PI / 2);
 
@@ -13,17 +32,14 @@ export default class ImgLabel extends THREE.Mesh {
       map: texture,
     });
     super(g, m);
-    // console.log(g);
-    const p = [
-      [-0.75, 0, -0.425, 0.75, 0, -0.425],
-      [-0.75, 0, -0.425, -0.75, 0, 0.425],
-      [-0.75, 0, 0.425, 0.75, 0, 0.425],
-      [0.75, 0, 0.425, 0.75, 0, -0.425],
-    ];
+
+    this.width = width;
+    this.height = height;
     this.touchLines = new TouchEdge(p, matLine);
 
     this.touchLines.position.y += 0.5;
     this.add(this.touchLines);
+    // this.touchLines.children.forEach((child) => (child.visible = true));
 
     this.name = "imglabel";
   }

+ 47 - 0
src/core/box/object/SimpleLabel.js

@@ -0,0 +1,47 @@
+import * as THREE from "three";
+
+export default class SimpleLabel extends THREE.Mesh {
+  constructor(text, outline) {
+    let res = 5;
+    const width = 150 * res;
+    const height = 15 * res;
+    var canvas = document.createElement("canvas");
+    canvas.width = width;
+    canvas.height = height;
+    let fontFamily = "Arial";
+    let fontSize = 5.2 * res;
+    let offsetX = 75 * res;
+    let offsetY = 10 * res;
+    var context = canvas.getContext("2d");
+
+    context.fillStyle = "#ffffff";
+    context.rect(0, 0, width, height);
+    context.fill();
+    context.font = "normal " + fontSize + "px " + fontFamily;
+    context.fillStyle = "#000000";
+    context.textAlign = "center";
+    context.fillText(text, offsetX, offsetY);
+    const canvas_map = new THREE.Texture(canvas);
+    canvas_map.colorSpace = THREE.SRGBColorSpace;
+    canvas_map.needsUpdate = true;
+    canvas_map.anisotropy = 4;
+
+    const g = new THREE.PlaneGeometry(1.5, 0.15);
+    g.rotateX(-Math.PI / 2);
+
+    const m = new THREE.MeshBasicMaterial({
+      map: canvas_map,
+    });
+    super(g, m);
+
+    // const edges = new THREE.EdgesGeometry(g);
+    // const line = new THREE.LineSegments(
+    //   edges,
+    //   new THREE.LineBasicMaterial({ color: 0xcccccc })
+    // );
+    // line.position.y += 0.5;
+    // this.add(line);
+
+    this.name = "SimpleLabel_" + text;
+  }
+}

+ 28 - 0
src/core/box/object/marker.js

@@ -0,0 +1,28 @@
+import * as THREE from "three";
+import gotoPic from "@/assets/image/goto.png";
+const m = new THREE.MeshBasicMaterial({
+  map: new THREE.TextureLoader().load(gotoPic),
+  color: 0x26559b,
+  transparent: true,
+});
+
+export default class Marker extends THREE.Mesh {
+  constructor(startPoint) {
+    const g = new THREE.PlaneGeometry(0.3, 0.3);
+    g.rotateX(-Math.PI / 2);
+    super(g, m);
+    const a = startPoint.clone();
+    this.position.copy(a);
+
+    this.rotation.y = Math.PI / 2;
+    this.position.y = 5;
+    this.position.z -= 0.02;
+
+    this.visible = true;
+    this.scale.set(1, 1, 1);
+    this.position.y += 0.5;
+    this.name = "marker_";
+    this.renderOrder = 1000;
+    console.log(this, this.position);
+  }
+}

+ 1 - 1
src/core/controls/FloorplanControls.js

@@ -285,7 +285,7 @@ export default class FloorplanControls {
     }
   };
   onMouseWheel = (event) => {
-    console.log("this", this);
+    // console.log("this", this);
     if (this.locked) return;
     if (this.enableZoom === false) return;
     event.preventDefault();

+ 130 - 38
src/core/player/Player.js

@@ -2,8 +2,10 @@ import * as THREE from "three";
 
 import FloorplanControls from "../controls/FloorplanControls.js";
 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
+import { TrackballControls } from "three/examples/jsm/controls/TrackballControls.js";
 import Line from "../box/object/Line";
 import LinePoints from "../box/object/LinePoints.js";
+import Marker from "../box/object/marker.js";
 import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
 
 const convertScreenToNDC = function (event, domElement) {
@@ -24,25 +26,45 @@ export default class Player {
     this.pointerdown = new THREE.Vector2();
     this.pointerup = new THREE.Vector2();
     this.pointer = new THREE.Vector2();
+    this.markPosition = new THREE.Vector3();
 
     this.touchImg = null;
     this.activeEdge = null;
     this.drawLine = null;
     this.startObj = null;
+    this.marker = null;
     this.allowDrawing = false;
 
     this.drawing = false;
     this.inited = false;
     this.renderLines = [];
     this.activeEdges = [];
+    this.markers = [];
     this.matLine = null;
     this.lineColor = 0xe44d54;
+    // 1是画线,2是标方向
+    this.mode = 2;
     this.init();
   }
 
+  setMode(mode) {
+    this.mode = mode;
+  }
+
+  removeMarker() {
+    if (this.marker) {
+      this.scene.scene.remove(this.marker);
+      this.marker = null;
+    }
+  }
+
   init = () => {
     // //floorplanControls
-    // this.floorplanControls = new FloorplanControls(this.orthCamera, this.scene.domElement, this);
+    // this.floorplanControls = new FloorplanControls(
+    //   this.orthCamera,
+    //   this.scene.domElement,
+    //   this
+    // );
     this.floorplanControls = new OrbitControls(
       this.orthCamera,
       this.scene.domElement
@@ -52,17 +74,24 @@ export default class Player {
     // this.floorplanControls.target.set(0, 1, 0);
     // this.floorplanControls.rotateSpeed = 0.5;
     // this.floorplanControls.panSpeed = 0.75
-    // this.floorplanControls.maxDistance = 100
-    // this.floorplanControls.minDistance = 3.5
+
+    this.floorplanControls.maxDistance = 100;
+    this.floorplanControls.minDistance = 3.5;
     this.floorplanControls.maxZoom = 500;
     this.floorplanControls.minZoom = 100;
 
+    // this.floorplanControls.mouseButtons = {
+    //   LEFT: THREE.MOUSE.PAN,
+    //   MIDDLE: THREE.MOUSE.DOLLY,
+    //   RIGHT: THREE.MOUSE.PAN
+    // }
+
     this.floorplanControls.enableRotate = false;
     this.raycaster = new THREE.Raycaster();
     this.onBindEvent();
     this.inited = true;
 
-    console.log("this.floorplanControls", this.floorplanControls);
+    console.log("this.floorplanControls", this.scene.mitt);
 
     this.matLine = new LineMaterial({
       color: this.lineColor,
@@ -78,52 +107,89 @@ export default class Player {
 
   onPointerMove = (e) => {
     if (!this.drawing) return;
+
     this.pointermove = convertScreenToNDC(e, this.scene.domElement);
-    this.raycaster.setFromCamera(this.pointermove, this.orthCamera);
-    let intersectArr = this.scene.boxManager.imgList;
-    // if(this.startObj) {
-    //   let i = intersectArr.indexOf(this.startObj)
-    //   intersectArr.splice(i, 1)
-    // }
-    const intersects = this.raycaster.intersectObjects(intersectArr, false);
-    if (intersects[0] && intersects[0].object !== this.startObj) {
-      this.touchImg = intersects[0];
-      this.setActiveLine(this.touchImg);
+    if (this.mode === 1) {
+      this.raycaster.setFromCamera(this.pointermove, this.orthCamera);
+      let intersectArr = this.scene.boxManager.imgList;
+      // if(this.startObj) {
+      //   let i = intersectArr.indexOf(this.startObj)
+      //   intersectArr.splice(i, 1)
+      // }
+
+      const intersects = this.raycaster.intersectObjects(intersectArr, false);
+      if (intersects[0] && intersects[0].object !== this.startObj) {
+        this.touchImg = intersects[0];
+        this.setActiveLine(this.touchImg);
+      }
+    }
+    if (this.mode === 2) {
+      let pos = new THREE.Vector3(this.pointermove.x, this.pointermove.y, -1);
+      pos.unproject(this.orthCamera);
+      pos.y = 5;
+      console.log("pos", pos);
+      this.marker.position.copy(pos);
+      // console.log(this.pointermove);
     }
   };
 
   onPointerDown = (e) => {
     console.log("start draw");
     this.pointerdown = convertScreenToNDC(e, this.scene.domElement);
-    this.raycaster.setFromCamera(this.pointerdown, this.orthCamera);
-    let intersectArr = this.scene.boxManager.imgList;
-    const intersects = this.raycaster.intersectObjects(intersectArr, false);
-    console.log("intersects", intersects);
-    if (intersects[0]) {
-      this.startObj = intersects[0].object;
-      this.drawing = true;
-    } else {
-      this.startObj = null;
-      this.drawing = false;
+    if (this.mode === 1) {
+      this.raycaster.setFromCamera(this.pointerdown, this.orthCamera);
+      let intersectArr = this.scene.boxManager.imgList;
+      const intersects = this.raycaster.intersectObjects(intersectArr, false);
+      console.log("intersects", intersects);
+      if (intersects[0]) {
+        this.startObj = intersects[0].object;
+        this.drawing = true;
+      } else {
+        this.startObj = null;
+        this.drawing = false;
+      }
     }
 
+    if (this.mode === 2) {
+      if (!this.marker) {
+        let pos = new THREE.Vector3(this.pointerdown.x, this.pointerdown.y, -1);
+        pos.unproject(this.orthCamera);
+        pos.y = 5;
+        this.marker = new Marker(pos);
+        this.scene.scene.add(this.marker);
+        this.drawing = true;
+      } else {
+        this.drawing = false;
+      }
+    }
     // this.floorplanControls.enabled = false;
   };
   onPointerUp = (e) => {
-    // console.log("last Line-wPos", points);
     this.pointerup = convertScreenToNDC(e, this.scene.domElement);
-    this.drawing = false;
-    this.floorplanControls.enabled = true;
-    this.startObj = null;
+    console.log("onPointerUp", this.pointerup);
 
-    if (this.drawLine) {
-      const points = this.drawLine.userData.points;
-      const dir = this.drawLine.userData.dir;
-      const finishLine = new LinePoints(points, 0, this.matLine);
-      this.renderLines.push(points);
-      this.scene.scene.add(finishLine);
-      const imageId = this.touchImg.object.userData;
-      console.log("this.touchImg", dir, imageId, points);
+    if (this.mode === 1) {
+      this.drawing = false;
+      this.floorplanControls.enabled = true;
+      this.startObj = null;
+      if (this.drawLine) {
+        const points = this.drawLine.userData.points;
+        const dir = this.drawLine.userData.dir;
+        const finishLine = new LinePoints(points, 0, this.matLine);
+        this.renderLines.push(points);
+        this.scene.scene.add(finishLine);
+        const imageId = this.touchImg.object.userData;
+        const activeLineItem = {
+          id: imageId,
+          dir: [dir],
+        };
+        console.log("this.touchImg", activeLineItem, points);
+        this.insertActiveEdge(activeLineItem);
+        this.drawLine = null;
+      }
+    }
+    if (this.mode === 2) {
+      // this.drawing = false;
     }
   };
 
@@ -167,7 +233,6 @@ export default class Player {
     if (this.drawLine) {
       this.drawLine.removeFromParent();
     }
-    // console.log("this.drawLine", this.drawLine);
     let s = new THREE.Vector3(this.pointerdown.x, this.pointerdown.y, -1);
     let e = new THREE.Vector3(this.pointermove.x, this.pointermove.y, -1);
     s.unproject(this.orthCamera);
@@ -191,7 +256,6 @@ export default class Player {
       x -= 0.5;
       y -= 0.5;
       // console.log(x, y);
-
       if (x >= 0 && y >= 0) {
         if (x > y) {
           return 3;
@@ -229,10 +293,38 @@ export default class Player {
     this.activeEdge.visible = true;
     this.buildLine();
   };
+  insertActiveEdge(item) {
+    const exist = this.activeEdges.find((s) => item.id === s.id);
+    if (exist) {
+      exist.dir = [...new Set([...exist.dir, ...item.dir])];
+    } else {
+      this.activeEdges.push(item);
+    }
+  }
+
+  showAllActiveEdges() {
+    if (this.inited) {
+      let imgList = this.scene.boxManager.imgList;
+      this.activeEdges.forEach((edge) => {
+        const exist = imgList.find((item) => item.userData === edge.id);
+        // console.log("exist", exist);
+        if (exist) {
+          edge.dir.forEach((dir) => {
+            exist.touchLines.children[dir].visible = true;
+          });
+        }
+      });
+    }
+  }
+
+  reset() {
+    this.activeEdges = [];
+  }
 
   update = () => {
     if (this.floorplanControls.enabled) {
       this.floorplanControls && this.floorplanControls.update();
+      this.scene.boxManager && this.showAllActiveEdges();
     }
   };
 }

+ 5 - 0
src/core/save.json

@@ -0,0 +1,5 @@
+{
+    hor_lines:[],
+    activeEdges:[],
+    vir_lines:[],
+}

+ 3 - 0
src/request/urls.ts

@@ -193,6 +193,9 @@ export const caseExtractDetail = "/fusion-xj/caseExtractDetail/info";
 export const caseExtractDetailOpt = "/fusion-xj/caseExtractDetail/saveOrUpdate";
 export const caseExtractDetailExport = "/fusion-xj/caseExtractDetail/downDocx";
 
+//标注
+export const saveCaseImgTag = "/fusion-xj/caseImgTag/saveOrUpdate";
+
 // 火调链接地址设置密码
 export const setCasePsw = "/fusion-xj/web/fireProject/updateRandomCode";
 export const getCasePsw = "/fusion-xj/web/fireProject/getRandCode";

+ 6 - 0
src/store/case.ts

@@ -18,6 +18,7 @@ import {
   caseExtractDetailOpt,
   caseExtractDetailExport,
   copyExample,
+  saveCaseImgTag
 } from "@/request";
 import { ModelScene, QuoteScene, Scene, SceneType } from "./scene";
 import { CaseFile } from "./caseFile";
@@ -126,3 +127,8 @@ export const exportCaseDetailInfo = (caseId: number) =>
     params: { caseId, ingoreRes: true },
     responseType: "blob",
   });
+
+// 
+
+export const saveCaseImgTagData = (caseId: number, data) =>
+  axios.post(saveCaseImgTag, { caseId, ...data });

+ 4 - 1
src/store/scene.ts

@@ -91,6 +91,7 @@ export enum SceneType {
 export enum ModelSceneStatus {
   ERR = -1,
   RUN = 0,
+  REV = 2,
   SUCCESS = 1,
   CANCEL = -2,
 }
@@ -176,7 +177,7 @@ type ScenePaggingParams = PaggingReq<
   }
 >;
 export const getScenePagging = async (params: ScenePaggingParams) => {
-  return (
+  const data = (
     await axios.get(
       params.type === SceneType.SWMX ? getModelSceneList : getSceneList,
       {
@@ -184,6 +185,8 @@ export const getScenePagging = async (params: ScenePaggingParams) => {
       }
     )
   ).data as PaggingRes<Scene>;
+
+  return data;
 };
 
 export const delQuoteScene = (scene: QuoteScene) =>

+ 71 - 41
src/view/case/photos/index.vue

@@ -2,20 +2,33 @@
   <div class="photo">
     <div class="left">
       <div class="upload">
-        <el-button type="primary" @click="addCaseFileHandler"> 上传照片 </el-button>
-        <el-button type="primary" @click="sortType = !sortType" :icon="sortType ? FullScreen : Menu">{{ sortType ? "横排"
-          : "竖排" }}</el-button>
+        <el-button type="primary" @click="addCaseFileHandler">
+          上传照片
+        </el-button>
+        <el-button
+          type="primary"
+          @click="sortType = !sortType"
+          :icon="sortType ? FullScreen : Menu"
+          >{{ sortType ? "横排" : "竖排" }}</el-button
+        >
       </div>
-      <draggable ref="childRef" :caseId="caseId" :sortType="sortType" @changeList="changeList"
-        @handleItem="handleItem" />
+      <draggable
+        ref="childRef"
+        :caseId="caseId"
+        :sortType="sortType"
+        @changeList="changeList"
+        @handleItem="handleItem"
+      />
     </div>
     <div class="right">
       <div class="tools">
-        <el-button>开始标注</el-button>
-        <el-button>退出标注</el-button>
+        <el-button @click="handleMark">标注方向</el-button>
+        <el-button @click="handleLine">标注连线</el-button>
+        <el-button @click="handleSave">保存</el-button>
       </div>
-      <!-- <swiper
+      <swiper
         class="swiper"
+        v-if="false"
         slides-per-view="auto"
         :space-between="24"
         :centeredSlides="true"
@@ -23,7 +36,11 @@
         style="height: 100%"
         @slideChange="onSlideChange"
       >
-        <swiper-slide class="swiperItem" v-for="(item, index) in newlist" :key="index">
+        <swiper-slide
+          class="swiperItem"
+          v-for="(item, index) in newlist"
+          :key="index"
+        >
           <div class="swiperList">
             <div
               class="itemper"
@@ -31,11 +48,7 @@
               v-for="eleItem in item"
               :key="eleItem"
             >
-              <img
-                class="itemImg"
-                :src="eleItem.imgUrl"
-                alt=""
-              />
+              <img class="itemImg" :src="eleItem.imgUrl" alt="" />
               <div class="text">{{ eleItem.imgInfo }}</div>
             </div>
             <div class="page">
@@ -44,8 +57,8 @@
             </div>
           </div>
         </swiper-slide>
-      </swiper> -->
-      <canvas id="canvas"></canvas>
+      </swiper>
+      <canvas id="canvas" v-show="true"></canvas>
     </div>
   </div>
 </template>
@@ -57,8 +70,9 @@ import { Swiper, SwiperSlide } from "swiper/vue";
 import "swiper/css";
 // import { addCaseFile } from "@/store/caseFile";
 import { addCaseImgFile } from "../quisk";
-import Scene from '@/core/Scene.js'
-import draggable from './draggable.vue';
+import { saveCaseImgTagData } from "@/store/case";
+import Scene from "@/core/Scene.js";
+import draggable from "./draggable.vue";
 const props = defineProps({ caseId: Number });
 const newlist = ref([]);
 const swiperRef = ref(null);
@@ -67,22 +81,22 @@ const caseId = ref(props.caseId);
 const sortType = ref(false);
 let scene = null;
 
-
 const addCaseFileHandler = async () => {
   await addCaseImgFile({
-    caseId: caseId.value, data: {
-      imgUrl: '',
-      imgInfo: '',
-      id: '',
-      sort: '',
-    }
+    caseId: caseId.value,
+    data: {
+      imgUrl: "",
+      imgInfo: "",
+      id: "",
+      sort: "",
+    },
   });
   refresh();
 };
 function refresh() {
   console.log("changeList", childRef.value);
   if (childRef.value) {
-    childRef.value.getList()
+    childRef.value.getList();
   }
 }
 const changeList = (list) => {
@@ -98,24 +112,23 @@ const changeList = (list) => {
     }
   });
   newlist.value = newList;
-  const arr = []
-  newList.map(i => arr.push(JSON.parse(JSON.stringify(i))))
-  const type = sortType.value ? 2 : 1
+  const arr = [];
+  newList.map((i) => arr.push(JSON.parse(JSON.stringify(i))));
+  const type = sortType.value ? 2 : 1;
   if (scene) {
-    scene.load(arr, type)
+    scene.load(arr, type);
     console.log("changeList", arr, type);
   }
-
 };
 const renderCanvas = () => {
-  const canvas = document.getElementById('canvas')
+  const canvas = document.getElementById("canvas");
   // console.log(canvas)
-  scene = new Scene(canvas)
-  scene.init()
-  window.scene = scene
-}
+  scene = new Scene(canvas);
+  scene.init();
+  window.scene = scene;
+};
 const onSwiper = (swiper) => {
-  console.log('onSwiper')
+  console.log("onSwiper");
   swiperRef.value = swiper;
 };
 const onSlideChange = (swiper) => {
@@ -127,15 +140,31 @@ const handleItem = (item) => {
   console.log("handleItem", item, active);
 };
 const handleDetele = async (item) => {
-  if (await confirm("删除该场景,将同时从案件和融合模型中移除,确定要删除吗?")) {
+  if (
+    await confirm("删除该场景,将同时从案件和融合模型中移除,确定要删除吗?")
+  ) {
     const scenes = getCaseScenes(list.value.filter((item) => item !== scene));
     await replaceCaseScenes(props.caseId, scenes);
     refresh();
   }
 };
+const handleMark = () => {
+  if (window.scene) {
+    window.scene.player.setMode(2);
+  }
+};
+const handleLine = () => {
+  if (window.scene) {
+    window.scene.player.setMode(1);
+  }
+};
+const handleSave = () => {
+  if (window.scene) {
+  }
+};
 onMounted(() => {
   renderCanvas();
-})
+});
 </script>
 <style lang="scss" scoped>
 #canvas {
@@ -166,7 +195,7 @@ onMounted(() => {
 
     .tools {
       position: absolute;
-      top: 30px;
+      top: 15px;
       left: 30px;
     }
 
@@ -215,7 +244,8 @@ onMounted(() => {
         .oneItemper {
           height: calc(100% - 120px);
 
-          .itemImg {}
+          .itemImg {
+          }
         }
       }
     }

+ 297 - 147
src/view/case/records/index.vue

@@ -3,102 +3,226 @@
   <div class="records">
     <div class="header">
       <el-button type="primary" @click="handleSave">保存</el-button>
-      <el-button @click="handleExport">导出</el-button>
+      <el-button :disabled="isDisableExport" @click="handleExport"
+        >导出</el-button
+      >
     </div>
     <h3 class="title">基本信息</h3>
     <div class="content">
-
       <div class="line">
         <span>勘验次数:</span>
         <span>第</span>
-        <el-input class="input" v-model="data.count" placeholder="" style="width: 80px;" />
+        <el-input
+          class="input"
+          v-model="data.count"
+          placeholder=""
+          style="width: 80px"
+        />
         <span>次勘验</span>
       </div>
 
       <div class="line">
         <span>勘验时间:</span>
         <div>
-          <el-input class="input" :maxlength="4" type="text" v-model="data.startTime.year" placeholder=""
-            style="width: 80px;" />
+          <el-input
+            class="input"
+            :maxlength="4"
+            type="text"
+            v-model="data.startTime.year"
+            placeholder=""
+            style="width: 80px"
+          />
           <span>年</span>
-          <el-input class="input" :maxlength="2" type="text" v-model="data.startTime.month" placeholder=""
-            style="width: 80px;" />
+          <el-input
+            class="input"
+            :maxlength="2"
+            type="text"
+            v-model="data.startTime.month"
+            placeholder=""
+            style="width: 80px"
+          />
           <span>月</span>
-          <el-input class="input" :maxlength="2" type="text" v-model="data.startTime.day" placeholder=""
-            style="width: 80px;" />
+          <el-input
+            class="input"
+            :maxlength="2"
+            type="text"
+            v-model="data.startTime.day"
+            placeholder=""
+            style="width: 80px"
+          />
           <span>日</span>
-          <el-input class="input" :maxlength="2" type="text" v-model="data.startTime.hour" placeholder=""
-            style="width: 80px;" />
+          <el-input
+            class="input"
+            :maxlength="2"
+            type="text"
+            v-model="data.startTime.hour"
+            placeholder=""
+            style="width: 80px"
+          />
           <span>时</span>
-          <el-input class="input" :maxlength="2" type="text" v-model="data.startTime.min" placeholder=""
-            style="width: 80px;" />
+          <el-input
+            class="input"
+            :maxlength="2"
+            type="text"
+            v-model="data.startTime.min"
+            placeholder=""
+            style="width: 80px"
+          />
           <span>分</span>
         </div>
-        <span style="width: 60px;text-align: center">至</span>
+        <span style="width: 60px; text-align: center">至</span>
         <div>
-          <el-input class="input" :maxlength="4" v-model="data.endTime.year" placeholder="" style="width: 80px;" />
+          <el-input
+            class="input"
+            :maxlength="4"
+            v-model="data.endTime.year"
+            placeholder=""
+            style="width: 80px"
+          />
           <span>年</span>
-          <el-input class="input" :maxlength="2" v-model="data.endTime.month" placeholder="" style="width: 80px;" />
+          <el-input
+            class="input"
+            :maxlength="2"
+            v-model="data.endTime.month"
+            placeholder=""
+            style="width: 80px"
+          />
           <span>月</span>
-          <el-input class="input" :maxlength="2" v-model="data.endTime.day" placeholder="" style="width: 80px;" />
+          <el-input
+            class="input"
+            :maxlength="2"
+            v-model="data.endTime.day"
+            placeholder=""
+            style="width: 80px"
+          />
           <span>日</span>
-          <el-input class="input" :maxlength="2" type="text" v-model="data.endTime.hour" placeholder=""
-            style="width: 80px;" />
+          <el-input
+            class="input"
+            :maxlength="2"
+            type="text"
+            v-model="data.endTime.hour"
+            placeholder=""
+            style="width: 80px"
+          />
           <span>时</span>
-          <el-input class="input" :maxlength="2" type="text" v-model="data.endTime.min" placeholder=""
-            style="width: 80px;" />
+          <el-input
+            class="input"
+            :maxlength="2"
+            type="text"
+            v-model="data.endTime.min"
+            placeholder=""
+            style="width: 80px"
+          />
           <span>分</span>
         </div>
       </div>
 
       <div class="line">
         <span>勘验地点:</span>
-        <el-input class="input" type="tel" v-model="data.address" placeholder="" style="width: 100%;" />
+        <el-input
+          class="input"
+          type="tel"
+          v-model="data.address"
+          placeholder=""
+          style="width: 100%"
+        />
       </div>
       <div class="line">
         <span>勘验人员姓名、单位、职务(含技术职务):</span>
-        <el-input class="input" type="tel" v-model="data.userInfo" placeholder="" style="width: 100%;" />
-
+        <el-input
+          class="input"
+          type="tel"
+          v-model="data.userInfo"
+          placeholder=""
+          style="width: 100%"
+        />
       </div>
 
       <div class="line">
         <span>勘验气象条件(天气、风力、温度):</span>
-        <el-input class="input" type="tel" v-model="data.weather" placeholder="" style="width: 100%;" />
+        <el-input
+          class="input"
+          type="tel"
+          v-model="data.weather"
+          placeholder=""
+          style="width: 100%"
+        />
       </div>
 
       <div class="textarea">
         <span>勘验情况:</span>
-        <el-input type="textarea" :rows="4" v-model="data.situation" placeholder="" style="width: 100%;" />
-
+        <el-input
+          type="textarea"
+          :rows="4"
+          v-model="data.situation"
+          placeholder=""
+          style="width: 100%"
+        />
       </div>
       <div class="textarea">
         <span>一、环境勘验</span>
-        <el-input type="textarea" :rows="4" v-model="data.environment" placeholder="" style="width: 100%;" />
+        <el-input
+          type="textarea"
+          :rows="4"
+          v-model="data.environment"
+          placeholder=""
+          style="width: 100%"
+        />
       </div>
 
       <div class="textarea">
         <span>二、初步勘验</span>
-        <el-input type="textarea" :rows="4" v-model="data.firstInquest" placeholder="" style="width: 100%;" />
+        <el-input
+          type="textarea"
+          :rows="4"
+          v-model="data.firstInquest"
+          placeholder=""
+          style="width: 100%"
+        />
       </div>
 
       <div class="textarea">
         <span>三、细项勘验</span>
-        <el-input type="textarea" :rows="4" v-model="data.carefulInquest" placeholder="" style="width: 100%;" />
+        <el-input
+          type="textarea"
+          :rows="4"
+          v-model="data.carefulInquest"
+          placeholder=""
+          style="width: 100%"
+        />
       </div>
 
       <div class="textarea">
         <span>四、专项勘验</span>
-        <el-input type="textarea" :rows="6" v-model="data.specialInquest" placeholder="" style="width: 100%;" />
+        <el-input
+          type="textarea"
+          :rows="6"
+          v-model="data.specialInquest"
+          placeholder=""
+          style="width: 100%"
+        />
       </div>
 
       <div class="textarea">
         <span>提取物品描述:</span>
-        <el-input type="textarea" :rows="6" v-model="data.itemDescription" placeholder="" style="width: 100%;" />
+        <el-input
+          type="textarea"
+          :rows="6"
+          v-model="data.itemDescription"
+          placeholder=""
+          style="width: 100%"
+        />
       </div>
 
       <div class="textarea">
         <span>现场拍照制图描述:</span>
-        <el-input type="textarea" :rows="6" v-model="data.imgDescription" placeholder="" style="width: 100%;" />
+        <el-input
+          type="textarea"
+          :rows="6"
+          v-model="data.imgDescription"
+          placeholder=""
+          style="width: 100%"
+        />
       </div>
 
       <div class="info">
@@ -128,51 +252,78 @@
           <span class="sub-tit">证人信息:</span>
           <div class="line">
             <span>证人或当事人:</span>
-            <el-input class="input" v-model="item.name" placeholder="" style="width: 180px;" />
+            <el-input
+              class="input"
+              v-model="item.name"
+              placeholder=""
+              style="width: 180px"
+            />
             <div>
-              <el-input class="input" v-model="item.year" placeholder="" style="width: 80px;" />
+              <el-input
+                class="input"
+                v-model="item.year"
+                placeholder=""
+                style="width: 80px"
+              />
               <span>年</span>
-              <el-input class="input" v-model="item.month" placeholder="" style="width: 80px;" />
+              <el-input
+                class="input"
+                v-model="item.month"
+                placeholder=""
+                style="width: 80px"
+              />
               <span>月</span>
-              <el-input class="input" v-model="item.day" placeholder="" style="width: 80px;" />
+              <el-input
+                class="input"
+                v-model="item.day"
+                placeholder=""
+                style="width: 80px"
+              />
               <span>日</span>
             </div>
 
-            <span style="margin-left:50px">身份证件号码:</span>
-            <el-input class="input" v-model="item.id" placeholder="" style="width: 280px;" />
+            <span style="margin-left: 50px">身份证件号码:</span>
+            <el-input
+              class="input"
+              v-model="item.id"
+              placeholder=""
+              style="width: 280px"
+            />
           </div>
           <div class="line">
             <span>单位或住址:</span>
-            <el-input class="input" v-model="item.address" placeholder="" style="width: 100%;" />
+            <el-input
+              class="input"
+              v-model="item.address"
+              placeholder=""
+              style="width: 100%"
+            />
           </div>
         </div>
-
       </template>
 
       <div class="btn-container">
         <el-button class="btn" @click="addwitnessInfo">+新增</el-button>
       </div>
 
-      <div>
-      </div>
+      <div></div>
     </div>
   </div>
-
 </template>
 <script setup>
-import { onMounted, ref, watch } from 'vue';
-import { reactive } from 'vue'
+import { onMounted, ref, watch } from "vue";
+import { reactive } from "vue";
 import {
   getCaseInquestInfo,
   saveCaseInquestInfo,
-  exportCaseInquestInfo
+  exportCaseInquestInfo,
 } from "@/store/case";
-import { ElMessage } from 'element-plus'
+import { ElMessage } from "element-plus";
 import saveAs from "@/util/file-serve";
-const props = defineProps({ caseId: Number })
-
-console.log(props)
+const props = defineProps({ caseId: Number });
 
+console.log(props);
+const isDisableExport = ref(false);
 const data = reactive({
   count: "",
   startTime: {
@@ -180,96 +331,102 @@ const data = reactive({
     month: "",
     day: "",
     hour: "",
-    min: ""
+    min: "",
   },
   endTime: {
     year: "",
     month: "",
     day: "",
     hour: "",
-    min: ""
+    min: "",
   },
-  address: '',
-  userInfo: '',
-  weather: '',
-  situation: '',
-  environment: '',  //环境勘验
-  firstInquest: '', //初步勘验
-  carefulInquest: '', //细项勘验
-  specialInquest: '', //专项勘验
-  itemDescription: '',
-  imgDescription: '',
-  leader: '',
-  recorder: '',
-  inspector: '',
-  witnessInfo: [{
-    name: "",
-    year: "",
-    month: "",
-    day: "",
-    id: "",
-    address: ""
-  }, {
-    name: "",
-    year: "",
-    month: "",
-    day: "",
-    id: "",
-    address: ""
-  }]
-})
-
-watch(data, newValue => {
-  // data.userName = newValue.userName.replace(/[^0-9]/g, '');
-  const sMonth = newValue.startTime.month.replace(/[^0-9]/g, '');
-  const sDay = newValue.startTime.day.replace(/[^0-9]/g, '');
-  const sHour = newValue.startTime.hour.replace(/[^0-9]/g, '');
-  const sMin = newValue.startTime.min.replace(/[^0-9]/g, '');
-
-  const eMonth = newValue.endTime.month.replace(/[^0-9]/g, '');
-  const eDay = newValue.endTime.day.replace(/[^0-9]/g, '');
-  const eHour = newValue.endTime.hour.replace(/[^0-9]/g, '');
-  const eMin = newValue.endTime.min.replace(/[^0-9]/g, '');
-
-
-  data.startTime.year = newValue.startTime.year.replace(/[^0-9]/g, '');
-  data.startTime.month = Number(sMonth) > 12 ? '12' : sMonth;
-  data.startTime.day = Number(sDay) > 31 ? '31' : sDay;
-  data.startTime.hour = Number(sDay) > 24 ? '24' : sHour;
-  data.startTime.min = Number(sMin) > 60 ? '0' : sMin;
-
-  data.endTime.year = newValue.endTime.year.replace(/[^0-9]/g, '');
-  data.endTime.month = Number(eMonth) > 12 ? '12' : eMonth;
-  data.endTime.day = Number(eDay) > 31 ? '31' : eDay;
-  data.endTime.hour = Number(eHour) > 24 ? '24' : eHour;
-  data.endTime.min = Number(eMin) > 60 ? '0' : eMin;
-
-
-  newValue.witnessInfo.forEach((item, key) => {
-    const year = newValue.witnessInfo[key].year.replace(/[^0-9]/g, '');
-    const month = newValue.witnessInfo[key].month.replace(/[^0-9]/g, '');
-    const day = newValue.witnessInfo[key].day.replace(/[^0-9]/g, '');
-    data.witnessInfo[key].year = year;
-    data.witnessInfo[key].month = Number(month) > 12 ? '12' : month;
-    data.witnessInfo[key].day = Number(day) > 31 ? '31' : day;
-  })
-
-}, {
-  immediate: true,
-  deep: true
-})
+  address: "",
+  userInfo: "",
+  weather: "",
+  situation: "",
+  environment: "", //环境勘验
+  firstInquest: "", //初步勘验
+  carefulInquest: "", //细项勘验
+  specialInquest: "", //专项勘验
+  itemDescription: "",
+  imgDescription: "",
+  leader: "",
+  recorder: "",
+  inspector: "",
+  witnessInfo: [
+    {
+      name: "",
+      year: "",
+      month: "",
+      day: "",
+      id: "",
+      address: "",
+    },
+    {
+      name: "",
+      year: "",
+      month: "",
+      day: "",
+      id: "",
+      address: "",
+    },
+  ],
+});
+
+watch(
+  data,
+  (newValue) => {
+    // data.userName = newValue.userName.replace(/[^0-9]/g, '');
+    const sMonth = newValue.startTime.month.replace(/[^0-9]/g, "");
+    const sDay = newValue.startTime.day.replace(/[^0-9]/g, "");
+    const sHour = newValue.startTime.hour.replace(/[^0-9]/g, "");
+    const sMin = newValue.startTime.min.replace(/[^0-9]/g, "");
+
+    const eMonth = newValue.endTime.month.replace(/[^0-9]/g, "");
+    const eDay = newValue.endTime.day.replace(/[^0-9]/g, "");
+    const eHour = newValue.endTime.hour.replace(/[^0-9]/g, "");
+    const eMin = newValue.endTime.min.replace(/[^0-9]/g, "");
+
+    data.startTime.year = newValue.startTime.year.replace(/[^0-9]/g, "");
+    data.startTime.month = Number(sMonth) > 12 ? "12" : sMonth;
+    data.startTime.day = Number(sDay) > 31 ? "31" : sDay;
+    data.startTime.hour = Number(sDay) > 24 ? "24" : sHour;
+    data.startTime.min = Number(sMin) > 60 ? "0" : sMin;
+
+    data.endTime.year = newValue.endTime.year.replace(/[^0-9]/g, "");
+    data.endTime.month = Number(eMonth) > 12 ? "12" : eMonth;
+    data.endTime.day = Number(eDay) > 31 ? "31" : eDay;
+    data.endTime.hour = Number(eHour) > 24 ? "24" : eHour;
+    data.endTime.min = Number(eMin) > 60 ? "0" : eMin;
+
+    newValue.witnessInfo.forEach((item, key) => {
+      const year = newValue.witnessInfo[key].year.replace(/[^0-9]/g, "");
+      const month = newValue.witnessInfo[key].month.replace(/[^0-9]/g, "");
+      const day = newValue.witnessInfo[key].day.replace(/[^0-9]/g, "");
+      data.witnessInfo[key].year = year;
+      data.witnessInfo[key].month = Number(month) > 12 ? "12" : month;
+      data.witnessInfo[key].day = Number(day) > 31 ? "31" : day;
+    });
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
 
 onMounted(async () => {
   const res = await getCaseInquestInfo(props.caseId);
-  console.log('res', res)
+  console.log("res", res);
+  if (!res.data) {
+    isDisableExport.value = true;
+  }
   for (var k in data) {
     if (res.data && res.data.hasOwnProperty(k)) {
-      console.log("Key is " + k)
-      data[k] = res.data[k]
+      console.log("Key is " + k);
+      data[k] = res.data[k];
     }
   }
-
-})
+});
 
 const addwitnessInfo = () => {
   // witnessInfoes.value += 1
@@ -278,23 +435,22 @@ const addwitnessInfo = () => {
     year: "",
     month: "",
     day: "",
-    id: ""
-  })
-}
+    id: "",
+  });
+};
 
 const handleSave = async () => {
-  console.log('data', data)
+  console.log("data", data);
   const res = await saveCaseInquestInfo(props.caseId, data);
   if (res.code === 0) {
-    ElMessage.success('保存成功!')
+    ElMessage.success("保存成功!");
   }
-}
+};
 const handleExport = async () => {
   const res = await exportCaseInquestInfo(props.caseId);
-  console.log('res', res)
-  saveAs(res, `勘验笔录-${props.caseId}.docx`)
-}
-
+  console.log("res", res);
+  saveAs(res, `勘验笔录-${props.caseId}.docx`);
+};
 </script>
 
 <style lang="scss">
@@ -352,8 +508,6 @@ const handleExport = async () => {
 .info {
   display: block;
 
-
-
   .inner {
     display: flex;
     flex-direction: row;
@@ -369,15 +523,11 @@ const handleExport = async () => {
       align-items: center;
       justify-content: center;
     }
-
-
   }
-
-
 }
 
 .witnessInfo {
-  background: #F5F5F5;
+  background: #f5f5f5;
   padding: 15px;
   margin-top: 20px;
   margin-right: 8px;
@@ -391,13 +541,13 @@ const handleExport = async () => {
   padding: 20px 0;
 
   .btn {
-    color: #26559B;
+    color: #26559b;
     width: 100%;
 
     &:hover {
-      background: #F5F5F5;
+      background: #f5f5f5;
       border-color: #dcdfe6;
     }
   }
 }
-</style>
+</style>

+ 1 - 1
src/view/organization/index.vue

@@ -173,7 +173,7 @@ onMounted(refresh);
         font-size: 14px;
         padding-right: 8px;
         .butList {
-          width: 140px;
+          width: 200px;
           a {
             margin: 0 8px;
           }

+ 21 - 33
src/view/vrmodel/modelContent.vue

@@ -44,44 +44,32 @@
     </el-table-column>
     <el-table-column label="所属架构" prop="deptName"></el-table-column>
     <el-table-column label="操作" v-slot:default="{ row }" width="350px">
+      <template v-if="row.createStatus === ModelSceneStatus.SUCCESS">
+        <span class="oper-span" @click="downOrigin(row)" v-if="row.fileNewName">
+          下载原始资源
+        </span>
+        <span class="oper-span" @click="downHash(row)"> Hash </span>
+        <span class="oper-span" @click="copyHanlder(row)"> 复制 </span>
+        <span class="oper-span" v-pdpath="['edit']" @click="editHanlder(row)">
+          修改
+        </span>
+        <span
+          class="oper-span"
+          v-pdpath="['view']"
+          @click="openSceneUrl(row, OpenType.query)"
+        >
+          查看
+        </span>
+      </template>
       <span
+        v-else-if="row.createStatus === ModelSceneStatus.REV"
         class="oper-span"
-        @click="downOrigin(row)"
-        v-if="row.createStatus === ModelSceneStatus.SUCCESS && row.fileNewName"
+        v-pdpath="['viewaaa']"
       >
-        下载原始资源
-      </span>
-      <span
-        class="oper-span"
-        @click="downHash(row)"
-        v-if="row.createStatus === ModelSceneStatus.SUCCESS"
-      >
-        Hash
-      </span>
-      <span
-        class="oper-span"
-        @click="copyHanlder(row)"
-        v-if="row.createStatus === ModelSceneStatus.SUCCESS"
-      >
-        复制
-      </span>
-      <span
-        class="oper-span"
-        v-pdpath="['edit']"
-        @click="editHanlder(row)"
-        v-if="row.createStatus === ModelSceneStatus.SUCCESS"
-      >
-        修改
-      </span>
-      <span
-        class="oper-span"
-        v-pdpath="['view']"
-        @click="openSceneUrl(row, OpenType.query)"
-        v-if="row.createStatus === ModelSceneStatus.SUCCESS"
-      >
-        查看
+        模型转换中…
       </span>
       <span
+        v-else
         class="oper-span delBtn"
         v-pdscene="row"
         @click="delOrCancel(row)"

+ 1 - 0
vite.config.ts

@@ -20,6 +20,7 @@ export default defineConfig({
       input: {
         index: resolve(__dirname, "index.html"),
         map: resolve(__dirname, "map.html"),
+        mirror: resolve(__dirname, "mirror.html"),
         // 在这里继续添加更多页面
       },
     },