瀏覽代碼

Merge branch 'dev' of http://192.168.0.115:3000/bill/traffic-laser into dev

bill 1 年之前
父節點
當前提交
9e46ce7e83

+ 26 - 0
src/components/base/editor/input-canvas/index.vue

@@ -0,0 +1,26 @@
+<!--  -->
+<template>
+  <div>
+    <!-- <input type="text" /> -->
+    <div class="content">{{ value }}</div>
+  </div>
+</template>
+
+<script setup>
+import { reactive, ref, toRefs, onBeforeMount, onMounted, defineProps } from "vue";
+const props = defineProps(["value", "downMode"]);
+</script>
+<style lang="scss" scoped>
+input {
+  width: 100%;
+  height: 100%;
+  text-align: center;
+}
+.content {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+</style>

+ 131 - 312
src/graphic/Controls/MoveRoad.js

@@ -44,21 +44,13 @@ export default class MoveRoad {
     // }
     this.adsorbPointRoads = {};
     this.splitRoadId = null;
-    let flag = this.canMoveForPoint(
-      pointId,
-      position,
-      linkedRoadPointId,
-      linkedRoadId
-    );
+    let flag = this.canMoveForPoint(pointId, position, linkedRoadPointId, linkedRoadId);
 
     if (!flag) {
       return false;
     }
 
-    if (
-      this.splitRoadId == null &&
-      Object.keys(this.adsorbPointRoads).length > 0
-    ) {
+    if (this.splitRoadId == null && Object.keys(this.adsorbPointRoads).length > 0) {
       //要吸附一下
       const adsorbPointId = Object.keys(this.adsorbPointRoads)[0];
       const road = dataService.getRoad(this.adsorbPointRoads[adsorbPointId]);
@@ -74,14 +66,8 @@ export default class MoveRoad {
       point.setPosition(position);
     }
     // 与别的墙角重合
-    else if (
-      modifyPoint.hasOwnProperty("linkedRoadPointId") &&
-      modifyPoint.linkedRoadPointId != null
-    ) {
-      const roadId = roadService.getRoadId(
-        pointId,
-        modifyPoint.linkedRoadPointId
-      );
+    else if (modifyPoint.hasOwnProperty("linkedRoadPointId") && modifyPoint.linkedRoadPointId != null) {
+      const roadId = roadService.getRoadId(pointId, modifyPoint.linkedRoadPointId);
       // pointId与linkedPointId属于同一堵墙,不允许,所以不移动
       if (roadId != null) {
         return false;
@@ -97,24 +83,15 @@ export default class MoveRoad {
       const endPoint = dataService.getRoadPoint(road.endId);
 
       // 与其余墙角的距离过短,不允许拖动
-      if (
-        mathUtil.getDistance(startPoint, position) < Constant.minRealDis ||
-        mathUtil.getDistance(endPoint, position) < Constant.minRealDis
-      ) {
+      if (mathUtil.getDistance(startPoint, position) < Constant.minRealDis || mathUtil.getDistance(endPoint, position) < Constant.minRealDis) {
         return false;
       }
       point.setPosition(modifyPoint);
     } else if (modifyPoint.hasOwnProperty("linkedCurveRoadPointId")) {
       point.setPosition(position);
-    } else if (
-      modifyPoint.hasOwnProperty("linkedRoadPointIdX") &&
-      modifyPoint.linkedRoadPointIdX
-    ) {
+    } else if (modifyPoint.hasOwnProperty("linkedRoadPointIdX") && modifyPoint.linkedRoadPointIdX) {
       point.setPosition(position);
-    } else if (
-      modifyPoint.hasOwnProperty("linkedRoadPointIdY") &&
-      modifyPoint.linkedRoadPointIdY
-    ) {
+    } else if (modifyPoint.hasOwnProperty("linkedRoadPointIdY") && modifyPoint.linkedRoadPointIdY) {
       point.setPosition(position);
     } else {
       return false;
@@ -134,38 +111,52 @@ export default class MoveRoad {
     //     point.setPosition(position);
     //   }
     // }
-    roadService.initRoadWidthTipsPos(road);
+    // roadService.initRoadWidthTipsPos(road);
     edgeService.updateEdgeForMovePoint(pointId);
-    if (leftEdge.roadSide) {
-      leftEdge.initRoadSide();
-    }
-    if (rightEdge.roadSide) {
-      rightEdge.initRoadSide();
-    }
+    // console.error(point);
+    // if (Object.keys(point.parent).length == 1) {
+    let centerPointId = null;
+    Object.keys(point.parent).forEach((item) => {
+      const road = dataService.getRoad(item);
+      if (pointId == road.startId) {
+        centerPointId = road.endId;
+      }
+      if (pointId == road.endId) {
+        centerPointId = road.startId;
+      }
+
+      let centerPoint = dataService.getRoadPoint(centerPointId);
+      Object.keys(centerPoint.parent).forEach((item) => {
+        const newRoad = dataService.getRoad(item);
+        roadService.initRoadWidthTipsPos(newRoad);
+        let newLeftEdge = dataService.getRoadEdge(newRoad.leftEdgeId);
+        let newRightEdge = dataService.getRoadEdge(newRoad.rightEdgeId);
+
+        if (newLeftEdge.roadSide) {
+          newLeftEdge.initRoadSide();
+        }
+        if (newRightEdge.roadSide) {
+          newRightEdge.initRoadSide();
+        }
+      });
+    });
+    // }
+    // if (leftEdge.roadSide) {
+    //   leftEdge.initRoadSide();
+    // }
+    // if (rightEdge.roadSide) {
+    //   rightEdge.initRoadSide();
+    // }
     return true;
   }
 
   finishByMoveRoadPoint(point) {
-    if (
-      listenLayer.modifyPoint &&
-      listenLayer.modifyPoint.hasOwnProperty("linkedRoadPointId")
-    ) {
+    if (listenLayer.modifyPoint && listenLayer.modifyPoint.hasOwnProperty("linkedRoadPointId")) {
       this.moveTo(point.vectorId, listenLayer.modifyPoint.linkedRoadPointId);
-    } else if (
-      listenLayer.modifyPoint &&
-      (listenLayer.modifyPoint.linkedRoadPointIdX ||
-        listenLayer.modifyPoint.linkedRoadPointIdY)
-    ) {
+    } else if (listenLayer.modifyPoint && (listenLayer.modifyPoint.linkedRoadPointIdX || listenLayer.modifyPoint.linkedRoadPointIdY)) {
       mathUtil.clonePoint(point, listenLayer.modifyPoint);
-    } else if (
-      listenLayer.modifyPoint &&
-      listenLayer.modifyPoint.hasOwnProperty("linkedRoadId")
-    ) {
-      roadService.splitRoad(
-        listenLayer.modifyPoint.linkedRoadId,
-        point.vectorId,
-        "start"
-      );
+    } else if (listenLayer.modifyPoint && listenLayer.modifyPoint.hasOwnProperty("linkedRoadId")) {
+      roadService.splitRoad(listenLayer.modifyPoint.linkedRoadId, point.vectorId, "start");
       edgeService.updateEdgeForMovePoint(point.vectorId);
     }
     // else if (this.splitRoadId != null) {
@@ -215,10 +206,7 @@ export default class MoveRoad {
     const startPoint = dataService.getRoadPoint(road.startId);
 
     function sortNumber(a, b) {
-      return (
-        mathUtil.getDistance(startPoint, a.join) -
-        mathUtil.getDistance(startPoint, b.join)
-      );
+      return mathUtil.getDistance(startPoint, a.join) - mathUtil.getDistance(startPoint, b.join);
     }
 
     joins = joins.sort(sortNumber.bind(this));
@@ -236,10 +224,7 @@ export default class MoveRoad {
       let splitRoad = dataService.getRoad(this.splitRoadId);
       let splitRoadStartPoint = dataService.getRoadPoint(splitRoad.startId);
       let splitRoadEndPoint = dataService.getRoadPoint(splitRoad.endId);
-      let splitLine = mathUtil.createLine1(
-        splitRoadStartPoint,
-        splitRoadEndPoint
-      );
+      let splitLine = mathUtil.createLine1(splitRoadStartPoint, splitRoadEndPoint);
       let parent = point.getParent();
       for (let key in parent) {
         let road = dataService.getRoad(key);
@@ -247,17 +232,10 @@ export default class MoveRoad {
         let endPoint = dataService.getRoadPoint(road.endId);
         let line = mathUtil.createLine1(startPoint, endPoint);
         let join = mathUtil.getIntersectionPoint(splitLine, line);
-        if (
-          mathUtil.isContainForSegment(join, startPoint, endPoint) &&
-          mathUtil.getDistance(join, splitRoadStartPoint) <
-            Constant.minAdsorbPix
-        ) {
+        if (mathUtil.isContainForSegment(join, startPoint, endPoint) && mathUtil.getDistance(join, splitRoadStartPoint) < Constant.minAdsorbPix) {
           roadService.splitRoad(key, splitRoadStartPoint.vectorId, "start");
           return splitRoadStartPoint.vectorId;
-        } else if (
-          mathUtil.isContainForSegment(join, startPoint, endPoint) &&
-          mathUtil.getDistance(join, splitRoadEndPoint) < Constant.minAdsorbPix
-        ) {
+        } else if (mathUtil.isContainForSegment(join, startPoint, endPoint) && mathUtil.getDistance(join, splitRoadEndPoint) < Constant.minAdsorbPix) {
           roadService.splitRoad(key, splitRoadEndPoint.vectorId, "end");
           return splitRoadEndPoint.vectorId;
         }
@@ -326,16 +304,8 @@ export default class MoveRoad {
       const startPoint2 = dataService.getRoadPoint(road2.startId);
       const endPoint2 = dataService.getRoadPoint(road2.endId);
 
-      const join1 = mathUtil.getIntersectionPoint4(
-        startPoint1,
-        endPoint1,
-        newLine
-      );
-      const join2 = mathUtil.getIntersectionPoint4(
-        startPoint2,
-        endPoint2,
-        newLine
-      );
+      const join1 = mathUtil.getIntersectionPoint4(startPoint1, endPoint1, newLine);
+      const join2 = mathUtil.getIntersectionPoint4(startPoint2, endPoint2, newLine);
 
       // 取角度大的
       if (join1 == null && join2 == null) {
@@ -374,10 +344,7 @@ export default class MoveRoad {
       let join = mathUtil.getIntersectionPoint(startLimitLine, newLine);
       const tempStartPoint = dataService.getRoadPoint(tempRoad.startId);
       const tempEndPoint = dataService.getRoadPoint(tempRoad.endId);
-      if (
-        angle > Constant.maxAngle ||
-        !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint)
-      ) {
+      if (angle > Constant.maxAngle || !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint)) {
         startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint);
         limitInfos.startRoadId = null;
         limitInfos.newStartRoadId = true;
@@ -413,16 +380,8 @@ export default class MoveRoad {
       const startPoint2 = dataService.getRoadPoint(road2.startId);
       const endPoint2 = dataService.getRoadPoint(road2.endId);
 
-      const join1 = mathUtil.getIntersectionPoint4(
-        startPoint1,
-        endPoint1,
-        newLine
-      );
-      const join2 = mathUtil.getIntersectionPoint4(
-        startPoint2,
-        endPoint2,
-        newLine
-      );
+      const join1 = mathUtil.getIntersectionPoint4(startPoint1, endPoint1, newLine);
+      const join2 = mathUtil.getIntersectionPoint4(startPoint2, endPoint2, newLine);
 
       // 取角度大的
       if (join1 == null && join2 == null) {
@@ -461,10 +420,7 @@ export default class MoveRoad {
       const tempStartPoint = dataService.getRoadPoint(tempRoad.start);
       const tempEndPoint = dataService.getRoadPoint(tempRoad.end);
 
-      if (
-        angle > Constant.maxAngle ||
-        !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint)
-      ) {
+      if (angle > Constant.maxAngle || !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint)) {
         endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint);
         limitInfos.endRoadId = null;
         limitInfos.newEndRoadId = true;
@@ -484,13 +440,7 @@ export default class MoveRoad {
     // 开始考虑第一点
     if (flag) {
       // 不仅仅角度,还有相交
-      flag = this.isOKForCross(
-        pointId,
-        position,
-        point.parent,
-        linkedRoadPointId,
-        linkedRoadId
-      );
+      flag = this.isOKForCross(pointId, position, point.parent, linkedRoadPointId, linkedRoadId);
     }
     return flag;
   }
@@ -646,14 +596,7 @@ export default class MoveRoad {
         const otherPointId = _road.getOtherPointId(pointId);
         const otherPoint = dataService.getRoadPoint(otherPointId);
 
-        const flag = this.isOKForCrossTwoRoad(
-          position,
-          otherPoint,
-          key,
-          linkedRoadPointId,
-          linkedRoadId,
-          _road.vectorId
-        );
+        const flag = this.isOKForCrossTwoRoad(position, otherPoint, key, linkedRoadPointId, linkedRoadId, _road.vectorId);
         // 交叉
         if (!flag) {
           this.adsorbPointRoads = {};
@@ -674,28 +617,12 @@ export default class MoveRoad {
   // position1表示拖拽的点的坐标(修复过了的)
   // position2对应墙的另一头坐标
   // roadId表示其余的墙(与position1无关的墙)
-  isOKForCrossTwoRoad(
-    position1,
-    position2,
-    roadId,
-    linkedRoadPointId,
-    linkedRoadId,
-    dragRoadId
-  ) {
+  isOKForCrossTwoRoad(position1, position2, roadId, linkedRoadPointId, linkedRoadId, dragRoadId) {
     const road = dataService.getRoad(roadId);
     const startPoint = dataService.getRoadPoint(road.startId);
     const endPoint = dataService.getRoadPoint(road.endId);
-    const join = mathUtil.getIntersectionPoint3(
-      position1,
-      position2,
-      startPoint,
-      endPoint
-    );
-    if (
-      join &&
-      road.startId != linkedRoadPointId &&
-      road.endId != linkedRoadPointId
-    ) {
+    const join = mathUtil.getIntersectionPoint3(position1, position2, startPoint, endPoint);
+    if (join && road.startId != linkedRoadPointId && road.endId != linkedRoadPointId) {
       // 交叉了
       this.splitRoadId = roadId;
       return true;
@@ -707,20 +634,14 @@ export default class MoveRoad {
       let join1 = mathUtil.getJoinLinePoint(startPoint, line);
       let join2 = mathUtil.getJoinLinePoint(endPoint, line);
 
-      if (
-        mathUtil.getDistance(join1, startPoint) < Constant.minRealDis &&
-        mathUtil.PointInSegment(join1, position1, position2)
-      ) {
+      if (mathUtil.getDistance(join1, startPoint) < Constant.minRealDis && mathUtil.PointInSegment(join1, position1, position2)) {
         if (road.startId != linkedRoadPointId) {
           // 交叉了
           this.adsorbPointRoads[startPoint.vectorId] = dragRoadId;
           //为了找到全部的吸附点,暂时返回true,在外面一层再做判断
           return true;
         }
-      } else if (
-        mathUtil.getDistance(join2, endPoint) < Constant.minRealDis &&
-        mathUtil.PointInSegment(join2, position1, position2)
-      ) {
+      } else if (mathUtil.getDistance(join2, endPoint) < Constant.minRealDis && mathUtil.PointInSegment(join2, position1, position2)) {
         if (road.endId != linkedRoadPointId) {
           // 交叉了
           this.adsorbPointRoads[endPoint.vectorId] = dragRoadId;
@@ -732,28 +653,14 @@ export default class MoveRoad {
       line = mathUtil.createLine1(startPoint, endPoint);
       join1 = mathUtil.getJoinLinePoint(position1, line);
       join2 = mathUtil.getJoinLinePoint(position2, line);
-      if (
-        mathUtil.getDistance(join1, position1) < Constant.minRealDis &&
-        mathUtil.PointInSegment(join1, startPoint, endPoint)
-      ) {
-        if (
-          road.startId != linkedRoadPointId &&
-          road.endId != linkedRoadPointId &&
-          roadId != linkedRoadId
-        ) {
+      if (mathUtil.getDistance(join1, position1) < Constant.minRealDis && mathUtil.PointInSegment(join1, startPoint, endPoint)) {
+        if (road.startId != linkedRoadPointId && road.endId != linkedRoadPointId && roadId != linkedRoadId) {
           // 交叉了
           //return false
           return true;
         }
-      } else if (
-        mathUtil.getDistance(join2, position2) < Constant.minRealDis &&
-        mathUtil.PointInSegment(join2, startPoint, endPoint)
-      ) {
-        if (
-          road.startId != linkedRoadPointId &&
-          road.endId != linkedRoadPointId &&
-          roadId != linkedRoadId
-        ) {
+      } else if (mathUtil.getDistance(join2, position2) < Constant.minRealDis && mathUtil.PointInSegment(join2, startPoint, endPoint)) {
+        if (road.startId != linkedRoadPointId && road.endId != linkedRoadPointId && roadId != linkedRoadId) {
           // 交叉了
           //return false
           return true;
@@ -768,13 +675,7 @@ export default class MoveRoad {
     const road = dataService.getRoad(roadId);
     const startPoint = dataService.getRoadPoint(road.startId);
     const endPoint = dataService.getRoadPoint(road.endId);
-    let flag = mathUtil.crossTwoLines(
-      position1,
-      position2,
-      startPoint,
-      endPoint,
-      0.01
-    );
+    let flag = mathUtil.crossTwoLines(position1, position2, startPoint, endPoint, 0.01);
     if (flag) {
       // 交叉了
       return false;
@@ -795,13 +696,7 @@ export default class MoveRoad {
     const road = dataService.getRoad(roadId);
     const startPoint = dataService.getRoadPoint(road.startId);
     const endPoint = dataService.getRoadPoint(road.endId);
-    const flag = mathUtil.crossTwoLines(
-      position1,
-      position2,
-      startPoint,
-      endPoint,
-      0.01
-    );
+    const flag = mathUtil.crossTwoLines(position1, position2, startPoint, endPoint, 0.01);
     if (flag) {
       // 交叉了
       return false;
@@ -813,26 +708,17 @@ export default class MoveRoad {
       let join1 = mathUtil.getJoinLinePoint(startPoint, line);
       const join2 = mathUtil.getJoinLinePoint(endPoint, line);
 
-      if (
-        mathUtil.getDistance(join1, startPoint) < Constant.minRealDis &&
-        mathUtil.isPointOnSegment(join1, position1, position2)
-      ) {
+      if (mathUtil.getDistance(join1, startPoint) < Constant.minRealDis && mathUtil.isPointOnSegment(join1, position1, position2)) {
         // 交叉了
         return false;
-      } else if (
-        mathUtil.getDistance(join2, endPoint) < Constant.minRealDis &&
-        mathUtil.isPointOnSegment(join2, position1, position2)
-      ) {
+      } else if (mathUtil.getDistance(join2, endPoint) < Constant.minRealDis && mathUtil.isPointOnSegment(join2, position1, position2)) {
         // 交叉了
         return false;
       }
 
       line = mathUtil.createLine1(startPoint, endPoint);
       join1 = mathUtil.getJoinLinePoint(position1, line);
-      if (
-        mathUtil.getDistance(join1, position1) < Constant.minRealDis &&
-        roadService.isContain(road, join1)
-      ) {
+      if (mathUtil.getDistance(join1, position1) < Constant.minRealDis && roadService.isContain(road, join1)) {
         // 交叉了
         return false;
       }
@@ -848,16 +734,10 @@ export default class MoveRoad {
     let line = mathUtil.createLine1(position1, position2);
     let join1 = mathUtil.getJoinLinePoint(startPoint, line);
     let join2 = mathUtil.getJoinLinePoint(endPoint, line);
-    if (
-      mathUtil.getDistance(join1, startPoint) < Constant.minRealDis &&
-      mathUtil.PointInSegment(join1, position1, position2)
-    ) {
+    if (mathUtil.getDistance(join1, startPoint) < Constant.minRealDis && mathUtil.PointInSegment(join1, position1, position2)) {
       // 交叉了
       return false;
-    } else if (
-      mathUtil.getDistance(join2, endPoint) < Constant.minRealDis &&
-      mathUtil.PointInSegment(join2, position1, position2)
-    ) {
+    } else if (mathUtil.getDistance(join2, endPoint) < Constant.minRealDis && mathUtil.PointInSegment(join2, position1, position2)) {
       // 交叉了
       return false;
     }
@@ -866,16 +746,10 @@ export default class MoveRoad {
     join1 = mathUtil.getJoinLinePoint(position1, line);
     join2 = mathUtil.getJoinLinePoint(position2, line);
 
-    if (
-      mathUtil.getDistance(join1, position1) < Constant.minRealDis &&
-      roadService.isContain(road, join1)
-    ) {
+    if (mathUtil.getDistance(join1, position1) < Constant.minRealDis && roadService.isContain(road, join1)) {
       // 交叉了
       return false;
-    } else if (
-      mathUtil.getDistance(join2, position2) < Constant.minRealDis &&
-      roadService.isContain(road, join2)
-    ) {
+    } else if (mathUtil.getDistance(join2, position2) < Constant.minRealDis && roadService.isContain(road, join2)) {
       // 交叉了
       return false;
     }
@@ -895,11 +769,8 @@ export default class MoveRoad {
         otherPoint = dataService.getRoadPoint(otherPointId);
         // 会吸附另一头
         if (
-          mathUtil.getDistance(virtualPosition, otherPoint) <
-            Constant.minRealDis ||
-          (!roadService.isContain(limitRoad, virtualPosition) &&
-            mathUtil.getDistance(virtualPosition, otherPoint) <
-              mathUtil.getDistance(virtualPosition, point))
+          mathUtil.getDistance(virtualPosition, otherPoint) < Constant.minRealDis ||
+          (!roadService.isContain(limitRoad, virtualPosition) && mathUtil.getDistance(virtualPosition, otherPoint) < mathUtil.getDistance(virtualPosition, point))
         ) {
           mathUtil.clonePoint(virtualPosition, otherPoint);
           adsorb = true;
@@ -994,15 +865,7 @@ export default class MoveRoad {
   // position5和position6表示road的end一边的线段(endPoint——virtualEndPoint)
   // adsorbPointId1对应start那一头的吸附点
   // adsorbPointId2对应end那一头的吸附点
-  isOKForCrossForMoveRoad(
-    position1,
-    position2,
-    roadId,
-    startPointId,
-    endPointId,
-    adsorbPointId1,
-    adsorbPointId2
-  ) {
+  isOKForCrossForMoveRoad(position1, position2, roadId, startPointId, endPointId, adsorbPointId1, adsorbPointId2) {
     const startPoint = dataService.getRoadPoint(startPointId);
     const endPoint = dataService.getRoadPoint(endPointId);
     let flag = true;
@@ -1016,16 +879,10 @@ export default class MoveRoad {
       let flag2 = true;
 
       const _road = dataService.getRoad(key);
-      if (
-        adsorbPointId1 &&
-        (adsorbPointId1 == _road.startId || adsorbPointId1 == _road.endId)
-      ) {
+      if (adsorbPointId1 && (adsorbPointId1 == _road.startId || adsorbPointId1 == _road.endId)) {
         flag1 = false;
       }
-      if (
-        adsorbPointId2 &&
-        (adsorbPointId2 == _road.startId || adsorbPointId2 == _road.endId)
-      ) {
+      if (adsorbPointId2 && (adsorbPointId2 == _road.startId || adsorbPointId2 == _road.endId)) {
         flag2 = false;
       }
 
@@ -1045,11 +902,7 @@ export default class MoveRoad {
       if (!flag) {
         return false;
       }
-      if (
-        flag1 &&
-        _road.startId != startPointId &&
-        _road.endId != startPointId
-      ) {
+      if (flag1 && _road.startId != startPointId && _road.endId != startPointId) {
         flag = this.isOKForCrossTwoRoad3(position1, startPoint, key);
       }
 
@@ -1075,10 +928,7 @@ export default class MoveRoad {
     const road = dataService.getRoad(roadId);
     const startPoint = dataService.getRoadPoint(road.startId);
     const endPoint = dataService.getRoadPoint(road.endId);
-    if (
-      Object.keys(startPoint.getParent()).length == 1 &&
-      Object.keys(endPoint.getParent()).length == 1
-    ) {
+    if (Object.keys(startPoint.getParent()).length == 1 && Object.keys(endPoint.getParent()).length == 1) {
       const p1 = { x: startPoint.x + dx, y: startPoint.y + dy };
       const p2 = { x: endPoint.x + dx, y: endPoint.y + dy };
 
@@ -1231,9 +1081,7 @@ export default class MoveRoad {
         road1.endId = pointId2;
         point2.setPointParent(roadId1, "end");
       } else {
-        console.error(
-          "roadService.moveTo****************************************************"
-        );
+        console.error("roadService.moveTo****************************************************");
       }
     }
 
@@ -1301,38 +1149,54 @@ export default class MoveRoad {
     const line2 = mathUtil.createLine1(rightEdge.start, rightEdge.end);
     let rightJoin = mathUtil.getJoinLinePoint(position, line2);
 
-    if (
-      dir == "left" &&
-      (mathUtil.isContainForSegment(position, join, rightJoin) ||
-        mathUtil.isContainForSegment(rightJoin, join, position))
-    ) {
+    if (dir == "left" && (mathUtil.isContainForSegment(position, join, rightJoin) || mathUtil.isContainForSegment(rightJoin, join, position))) {
       return;
     }
 
-    if (
-      dir == "right" &&
-      (mathUtil.isContainForSegment(position, join, leftJoin) ||
-        mathUtil.isContainForSegment(leftJoin, join, position))
-    ) {
+    if (dir == "right" && (mathUtil.isContainForSegment(position, join, leftJoin) || mathUtil.isContainForSegment(leftJoin, join, position))) {
       return;
     }
 
     const newWidth = mathUtil.getDisForPoinLine(position, line);
-    if (
-      newWidth > Constant.minRoadSideWidth &&
-      newWidth < Constant.maxRoadSideWidth
-    ) {
+    if (newWidth > Constant.minRoadSideWidth && newWidth < Constant.maxRoadSideWidth) {
       roadService.updateForWidth(parent, newWidth, dir);
     }
-    roadService.initRoadWidthTipsPos(road);
-    // if (edge.roadSide) {
-    //   edge.initRoadSide();
-    // }
-    if(leftEdge.roadSide){
-      leftEdge.initRoadSide();
+    // roadService.initRoadWidthTipsPos(road);
+
+    let centerPointId = null;
+    let startPoint = dataService.getRoadPoint(road.startId);
+    let endPoint = dataService.getRoadPoint(road.endId);
+
+    if (Object.keys(startPoint.parent).length > 1) {
+      centerPointId = road.startId;
     }
-    if(rightEdge.roadSide){
-      rightEdge.initRoadSide();
+    if (Object.keys(endPoint.parent).length > 1) {
+      centerPointId = road.endId;
+    }
+
+    if (centerPointId) {
+      let centerPoint = dataService.getRoadPoint(centerPointId);
+      Object.keys(centerPoint.parent).forEach((item) => {
+        const newRoad = dataService.getRoad(item);
+
+        let newLeftEdge = dataService.getRoadEdge(newRoad.leftEdgeId);
+        let newRightEdge = dataService.getRoadEdge(newRoad.rightEdgeId);
+        roadService.initRoadWidthTipsPos(newRoad);
+        if (newLeftEdge.roadSide) {
+          newLeftEdge.initRoadSide();
+        }
+        if (newRightEdge.roadSide) {
+          newRightEdge.initRoadSide();
+        }
+      });
+    } else {
+      roadService.initRoadWidthTipsPos(road);
+      if (leftEdge.roadSide) {
+        leftEdge.initRoadSide();
+      }
+      if (rightEdge.roadSide) {
+        rightEdge.initRoadSide();
+      }
     }
   }
 
@@ -1362,70 +1226,25 @@ export default class MoveRoad {
 
     const leftCurveEdge = dataService.getCurveRoadEdge(curveRoad.leftEdgeId);
     const rightCurveEdge = dataService.getCurveRoadEdge(curveRoad.rightEdgeId);
-    let joinInfo = mathUtil.getHitInfoForCurve(
-      position,
-      curveRoad.curves[index],
-      Math.max(curveRoad.leftWidth, curveRoad.rightWidth)
-    );
-
-    let leftJoinInfo = mathUtil.getHitInfoForCurve(
-      position,
-      leftCurveEdge.curves[index],
-      curveRoad.leftWidth
-    );
-    let leftLine = mathUtil.createLine1(
-      leftJoinInfo.position,
-      joinInfo.position
-    );
+    let joinInfo = mathUtil.getHitInfoForCurve(position, curveRoad.curves[index], Math.max(curveRoad.leftWidth, curveRoad.rightWidth));
+
+    let leftJoinInfo = mathUtil.getHitInfoForCurve(position, leftCurveEdge.curves[index], curveRoad.leftWidth);
+    let leftLine = mathUtil.createLine1(leftJoinInfo.position, joinInfo.position);
     let leftJoin = mathUtil.getJoinLinePoint(position, leftLine);
 
-    let rightJoinInfo = mathUtil.getHitInfoForCurve(
-      position,
-      rightCurveEdge.curves[index],
-      curveRoad.rightWidth
-    );
-    let rightLine = mathUtil.createLine1(
-      rightJoinInfo.position,
-      joinInfo.position
-    );
+    let rightJoinInfo = mathUtil.getHitInfoForCurve(position, rightCurveEdge.curves[index], curveRoad.rightWidth);
+    let rightLine = mathUtil.createLine1(rightJoinInfo.position, joinInfo.position);
     let rightJoin = mathUtil.getJoinLinePoint(position, rightLine);
-    if (
-      dir == "left" &&
-      (mathUtil.isContainForSegment(
-        rightJoin,
-        rightJoinInfo.position,
-        joinInfo.position
-      ) ||
-        mathUtil.isContainForSegment(
-          rightJoinInfo.position,
-          rightJoin,
-          joinInfo.position
-        ))
-    ) {
+    if (dir == "left" && (mathUtil.isContainForSegment(rightJoin, rightJoinInfo.position, joinInfo.position) || mathUtil.isContainForSegment(rightJoinInfo.position, rightJoin, joinInfo.position))) {
       return;
     }
 
-    if (
-      dir == "right" &&
-      (mathUtil.isContainForSegment(
-        leftJoin,
-        leftJoinInfo.position,
-        joinInfo.position
-      ) ||
-        mathUtil.isContainForSegment(
-          leftJoinInfo.position,
-          leftJoin,
-          joinInfo.position
-        ))
-    ) {
+    if (dir == "right" && (mathUtil.isContainForSegment(leftJoin, leftJoinInfo.position, joinInfo.position) || mathUtil.isContainForSegment(leftJoinInfo.position, leftJoin, joinInfo.position))) {
       return;
     }
 
     const newWidth = mathUtil.getDistance(joinInfo.position, position);
-    if (
-      newWidth > Constant.minRoadSideWidth &&
-      newWidth < Constant.maxRoadSideWidth
-    ) {
+    if (newWidth > Constant.minRoadSideWidth && newWidth < Constant.maxRoadSideWidth) {
       curveRoadService.updateForWidth(parent, newWidth, dir);
     }
     if (curveEdge.roadSide) {

+ 11 - 11
src/graphic/ListenLayer.js

@@ -685,15 +685,15 @@ export default class ListenLayer {
       }
 
       //检查edge
-      // ||
-      // (mathUtil.isContainForSegment(join, startPoint, endPoint) &&
-      //  leftSideJoin &&
-      //  mathUtil.isContainForSegment(position, leftSideJoin, leftJoin)
-      // )
+    
       distance = this.getDistance(position, leftJoin);
       if (
         mathUtil.isContainForSegment(leftJoin, leftEdge.start, leftEdge.end) &&
-        distance < Constant.minAdsorbPix / 2
+        distance < Constant.minAdsorbPix / 2   ||
+        (mathUtil.isContainForSegment(join, startPoint, endPoint) &&
+         leftSideJoin &&
+         mathUtil.isContainForSegment(position, leftSideJoin, leftJoin)
+        )
       ) {
         if (!edgeInfo.edgeId || distance < edgeInfo.distance) {
           edgeInfo = {
@@ -706,17 +706,17 @@ export default class ListenLayer {
       }
 
       distance = this.getDistance(position, rightJoin);
-      // ||
-      //   (mathUtil.isContainForSegment(join, startPoint, endPoint) &&
-      //    rightSideJoin &&
-      //    mathUtil.isContainForSegment(position,rightSideJoin,rightJoin))
+
       if (
         mathUtil.isContainForSegment(
           rightJoin,
           rightEdge.start,
           rightEdge.end
         ) &&
-        distance < Constant.minAdsorbPix / 2
+        distance < Constant.minAdsorbPix / 2  ||
+        (mathUtil.isContainForSegment(join, startPoint, endPoint) &&
+         rightSideJoin &&
+         mathUtil.isContainForSegment(position,rightSideJoin,rightJoin))
       ) {
         if (!edgeInfo.edgeId || distance < edgeInfo.distance) {
           edgeInfo = {

+ 2 - 2
src/graphic/Renderer/Draw.js

@@ -197,7 +197,7 @@ export const help = {
     const fontSize = (style.fontSize || 10) * coordinate.ratio;
     const vline = mathUtil.getVerticalLineByDistance(start, end, fontSize);
     const center = mathUtil.lineCenter(vline[0], vline[1]);
-    console.log(center, start, end);
+    // console.log(center, start, end);
     ctx.save();
     ctx.translate(center.x, center.y);
     ctx.rotate((angle * Math.PI) / 180);
@@ -587,7 +587,7 @@ export default class Draw {
     } else {
       width = vector.singleRoadWidth / vector.singleRoadDrivewayCount;
     }
-    console.log(width);
+    // console.log(width);
     width = width.toFixed(0);
 
     vector.roadWidthTipsPos.forEach((line) => {

+ 10 - 30
src/store/sync.ts

@@ -14,6 +14,7 @@ import { baseURL } from "@/dbo/main";
 import { defaultUses, uses } from "@/store/SVGLabel";
 import { imageRotate } from "@/utils/image-rotate";
 import { sceneSeting } from "./sceneSeting";
+import { tables } from "./tables";
 
 const global = window as any;
 
@@ -62,9 +63,7 @@ export const api = !global.android
         url = url.trim();
         const paths = url.split("/");
         const notBase64BaseTypes = [".png", ".jpg"];
-        const notBase64 = notBase64BaseTypes.some((type) =>
-          paths[paths.length - 1].includes(type)
-        );
+        const notBase64 = notBase64BaseTypes.some((type) => paths[paths.length - 1].includes(type));
         if (notBase64) {
           // await new Promise((resolve) => setTimeout(resolve, 2000));
           return baseURL + url;
@@ -109,11 +108,7 @@ export const api = !global.android
           global.setSceneStoreCallback = (data) => {
             resolve(data);
           };
-          global.android.setSceneStore(
-            params.m + "/store.json",
-            JSON.stringify(data),
-            "setSceneStoreCallback"
-          );
+          global.android.setSceneStore(params.m + "/store.json", JSON.stringify(data), "setSceneStoreCallback");
         });
       },
       getStore() {
@@ -138,9 +133,7 @@ export const api = !global.android
           // ".png", ".jpg"
           // , ".bin"
         ];
-        const notBase64 = notBase64BaseTypes.some((type) =>
-          paths[paths.length - 1].includes(type)
-        );
+        const notBase64 = notBase64BaseTypes.some((type) => paths[paths.length - 1].includes(type));
 
         if (!notBase64) {
           return await new Promise<string>((resolve) => {
@@ -164,11 +157,7 @@ export const api = !global.android
             delete global[apiName];
           };
           const data = await blobToBase64(file);
-          global.android.uploadImage(
-            params.m + "/attach/upload/" + file.name,
-            data,
-            apiName
-          );
+          global.android.uploadImage(params.m + "/attach/upload/" + file.name, data, apiName);
         });
       },
       downloadImage(file: File) {
@@ -187,11 +176,7 @@ export const api = !global.android
         return new Promise<string>((resolve) => {
           const apiName = `photograph${count++}`;
           global[apiName] = (data) => {
-            data
-              ? rotate
-                ? normalImage(data).then(resolve)
-                : resolve(data)
-              : resolve(null);
+            data ? (rotate ? normalImage(data).then(resolve) : resolve(data)) : resolve(null);
             delete global[apiName];
           };
           global.android.cameraPhotograph(params.m, apiName);
@@ -201,11 +186,7 @@ export const api = !global.android
         return new Promise<string>((resolve) => {
           const apiName = `selectPhotoAlbum${count++}`;
           global[apiName] = (data) => {
-            data
-              ? rotate
-                ? normalImage(data).then(resolve)
-                : resolve(data)
-              : resolve(null);
+            data ? (rotate ? normalImage(data).then(resolve) : resolve(data)) : resolve(null);
             delete global[apiName];
           };
           global.android.selectPhotoAlbum(params.m, apiName);
@@ -234,6 +215,7 @@ const loadStore = async () => {
   accidentPhotos.value = data?.accidentPhotos || [];
   roadPhotos.value = data?.roadPhotos || [];
   uses.value = data?.uses || defaultUses;
+  tables.value = data?.tables || {};
 
   syncSceneStore();
 };
@@ -245,10 +227,7 @@ export const uploadImage = (blob: Blob, name = `${getId()}.jpg`) => {
 };
 
 export const downloadImage = async (data: Blob | string, name = `${getId()}.jpg`) => {
-  const blob: Blob =
-    typeof data === "string"
-      ? (await axios.get(data, { responseType: "blob" })).data
-      : data;
+  const blob: Blob = typeof data === "string" ? (await axios.get(data, { responseType: "blob" })).data : data;
   const file = new File([blob], name, { type: "image/jpeg" });
 
   return await api.downloadImage(file);
@@ -266,6 +245,7 @@ const syncSceneStore = () => {
       uses: uses.value,
       accidentPhotos: accidentPhotos.value,
       roadPhotos: roadPhotos.value,
+      tables: tables.value,
     }),
     (data) => {
       updateSceneStore(data);

+ 3 - 0
src/store/tables.ts

@@ -0,0 +1,3 @@
+import { ref } from "vue";
+
+export const tables = ref({});

+ 20 - 5
src/views/scene/index.vue

@@ -31,19 +31,19 @@
         <div class="info-top-right" :class="{ full: viewStatus }">
           <div class="input-item">
             <p>事故时间:</p>
-            <input type="text" />
+            <input type="text" v-model="sceneInfo.accidentTime" @input="inputHandler" />
           </div>
           <div class="input-item">
             <p>天气:</p>
-            <input type="text" />
+            <input type="text" v-model="sceneInfo.weather" @input="inputHandler" />
           </div>
           <div class="input-item">
             <p>地点:</p>
-            <input type="text" />
+            <input type="text" v-model="sceneInfo.address" @input="inputHandler" />
           </div>
           <div class="text-item">
             <p>事故描述:</p>
-            <textarea class="info-textarea"></textarea>
+            <textarea class="info-textarea" v-model="sceneInfo.accidentDesc" @input="inputHandler"></textarea>
           </div>
           <div class="info-btn">
             <div class="right-btn" @click="router.push('/roads?back=1')">现场绘图({{ sceneSortPhotos.length }})</div>
@@ -82,7 +82,8 @@ import { currentView } from "./currentScene";
 import { router } from "@/router";
 import { roadPhotos } from "@/store/roadPhotos";
 import { types, accidentPhotos } from "@/store/accidentPhotos";
-
+import { debounce } from "@/utils";
+import { tables } from "@/store/tables";
 const layoutRef = ref(null);
 const activeMenuKeys = ref<string[]>([]);
 const accodentSortPhotos = computed(() => {
@@ -107,6 +108,16 @@ const stopReg = watchEffect(() => {
     disabledMap.measure = false;
   }
 });
+const sceneInfo = ref({
+  accidentTime: "",
+  weather: "",
+  address: "",
+  accidentDesc: "",
+});
+const inputHandler = debounce(() => {
+  console.error(1);
+  tables.value["sceneInfo"] = sceneInfo.value;
+}, 300);
 const viewStatus = ref(false);
 const onScale = () => {
   viewStatus.value = !viewStatus.value;
@@ -166,6 +177,10 @@ onMounted(() => {
   var screenHeight = document.body.clientHeight;
   layoutRef.value.style.height = screenHeight + "px";
   document.body.style.height = screenHeight + "px";
+
+  if (tables.value && tables.value["sceneInfo"]) {
+    sceneInfo.value = tables.value["sceneInfo"];
+  }
 });
 onActivated(async () => {
   await nextTick();

+ 183 - 36
src/views/tables/ask.vue

@@ -2,7 +2,7 @@
 <template>
   <!-- <iframe style="width:100%;height: 100%;" src="./static/html/FG.html" frameborder="0"></iframe> -->
 
-  <div class="ask-content">
+  <div class="ask-content" :class="{ downMode }" v-if="data">
     <!-- <Write v-if="isWrite" :text="text" :textIndex="textIndex" @onTextConfirm="onTextConfirm"> </Write> -->
     <div v-show="!isWrite" class="num-box">
       <span>第</span>
@@ -13,7 +13,10 @@
     </div>
     <div v-show="!isWrite" class="num-box" style="padding-right: 114px">
       <span>第</span>
-      <div class="input-box" contenteditable></div>
+      <div class="input-box">
+        <input style="text-align: center; width: 100%" type="text" v-model="data.times" />
+        <div class="content-box">{{ data.times }}</div>
+      </div>
       <span>次</span>
     </div>
 
@@ -22,62 +25,120 @@
     <div class="container" v-show="!isWrite">
       <div class="line">
         <span>时间</span>
-        <div class="write-line" contenteditable></div>
+        <div class="write-line">
+          <input type="text" v-model="data.startTime" />
+          <div class="content-box">{{ data.startTime }}</div>
+        </div>
         <span>至</span>
-        <div class="write-line" contenteditable></div>
+        <div class="write-line">
+          <input type="text" v-model="data.endTime" />
+          <div class="content-box">{{ data.endTime }}</div>
+        </div>
       </div>
       <div class="line">
         <span>地点</span>
-        <div class="write-line left" contenteditable></div>
+        <div class="write-line left">
+          <input type="text" v-model="data.address" />
+          <div class="content-box">{{ data.address }}</div>
+        </div>
       </div>
       <div class="line">
         <span v-if="type == '1'">询问/<span class="through">讯问</span>人</span>
         <span v-else><span class="through">询问</span>/讯问人</span>
-        <div class="write-line" contenteditable></div>
+        <div class="write-line">
+          <input type="text" v-model="data.asker" />
+          <div class="content-box">{{ data.asker }}</div>
+        </div>
         <span>工作单位</span>
-        <div class="write-line" contenteditable></div>
+        <div class="write-line">
+          <input type="text" v-model="data.askCompany" />
+          <div class="content-box">{{ data.askCompany }}</div>
+        </div>
       </div>
       <div class="line">
         <span>记录人</span>
-        <div class="write-line" contenteditable></div>
+        <div class="write-line">
+          <input type="text" v-model="data.reporter" />
+          <div class="content-box">{{ data.reporter }}</div>
+        </div>
         <span>工作单位</span>
-        <div class="write-line" contenteditable></div>
+        <div class="write-line">
+          <input type="text" v-model="data.reporterCompany" />
+          <div class="content-box">{{ data.reporterCompany }}</div>
+        </div>
       </div>
       <div class="line">
         <span v-if="type == '1'">被询问/<span class="through">讯问</span>人</span>
         <span v-else>被<span class="through">询问</span>/讯问人</span>
-        <div style="flex: 0.5" class="write-line" contenteditable></div>
+        <div style="flex: 0.5" class="write-line">
+          <input type="text" v-model="data.askerBy" />
+          <div class="content-box">{{ data.askerBy }}</div>
+        </div>
         <span>性别</span>
-        <div style="flex: 0.3" class="write-line" contenteditable></div>
+        <div style="flex: 0.3" class="write-line">
+          <input type="text" v-model="data.sex" />
+          <div class="content-box">{{ data.sex }}</div>
+        </div>
         <span>年龄</span>
-        <div style="flex: 0.3" class="write-line" contenteditable></div>
+        <div style="flex: 0.3" class="write-line">
+          <input type="text" v-model="data.age" />
+          <div class="content-box">{{ data.age }}</div>
+        </div>
         <span>出生日期</span>
-        <div class="write-line" contenteditable></div>
+        <div class="write-line">
+          <input type="text" v-model="data.birth" />
+          <div class="content-box">{{ data.birth }}</div>
+        </div>
       </div>
       <div class="line">
         <span>身份证件种类及号码</span>
-        <div class="write-line" contenteditable></div>
-        <span>是否人大代表</span>
+        <div class="write-line">
+          <input type="text" v-model="data.id" />
+          <div class="content-box">{{ data.id }}</div>
+        </div>
+        <div v-for="(i, index) in isnotList.options" @click="checkOptions(isnotList, index)">
+          <ui-icon :type="data.NPC.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
+          <span>{{ i.title }}</span>
+        </div>
+        <span>人大代表</span>
       </div>
       <div class="line">
         <span>现住址</span>
-        <div class="write-line" contenteditable></div>
+        <div class="write-line">
+          <input type="text" v-model="data.adressNow" />
+          <div class="content-box">{{ data.adressNow }}</div>
+        </div>
         <span>联系方式</span>
-        <div style="flex: 0.3" class="write-line" contenteditable></div>
+        <div style="flex: 0.3" class="write-line">
+          <input type="text" v-model="data.phoneNumber" />
+          <div class="content-box">{{ data.phoneNumber }}</div>
+        </div>
       </div>
       <div class="line">
         <span>户籍所在地</span>
-        <div class="write-line left" contenteditable></div>
+        <div class="write-line left">
+          <input type="text" v-model="data.residence" />
+          <div class="content-box">{{ data.residence }}</div>
+        </div>
       </div>
       <div class="line worap">
         <span v-if="type == '1'" style="line-height: 40px"> (口头传唤/被扭送/自动投案的被询问/<span class="through">讯问</span>人于</span>
         <span v-else style="line-height: 40px"> (口头传唤/被扭送/自动投案的被<span class="through">询问</span>/讯问人于</span>
-        <div class="write-line" style="width: 40%" contenteditable></div>
+        <div class="write-line" style="width: 40%">
+          <input type="text" v-model="data.reachTime" />
+          <div class="content-box">{{ data.reachTime }}</div>
+        </div>
         <span style="line-height: 40px"> 到达,</span>
-        <div class="write-line" style="" contenteditable></div>
+        <div class="write-line" style="">
+          <input type="text" v-model="data.leaveTime" />
+          <div class="content-box">{{ data.leaveTime }}</div>
+        </div>
         <span style="line-height: 40px"> 离开,</span>
         <span style="line-height: 40px"> 本人签名:</span>
-        <div class="write-line" style="" contenteditable></div>
+        <div class="write-line" style="">
+          <input type="text" v-model="data.sign" />
+          <div class="content-box">{{ data.sign }}</div>
+        </div>
         <span> )。</span>
       </div>
       <div class="more-line" @click="goWrite" id="line-box">
@@ -93,60 +154,130 @@
     <div class="bottom-name" v-show="!isWrite">
       <span v-if="type == '1'">被询问人:</span>
       <span v-else>被讯问人:</span>
-      <div style="flex: 1" contenteditable></div>
+      <div style="flex: 1">
+        <input type="text" v-model="data.askerBys" />
+        <div class="content-box">{{ data.askerBys }}</div>
+      </div>
     </div>
   </div>
 </template>
 
 <script setup>
-import { reactive, ref, toRefs, onBeforeMount, onMounted, defineProps, defineEmits } from 'vue';
-import { router } from '@/router';
-import Write from './write/index.vue';
-import { bus } from '@/hook/useGraphic';
+import { reactive, ref, toRefs, onBeforeMount, onMounted, defineProps, defineEmits } from "vue";
+import { router } from "@/router";
+import Write from "./write/index.vue";
+import { bus } from "@/hook/useGraphic";
+import { tables } from "@/store/tables";
+import { tablesInfo, setData } from "./data";
+
+const data = ref(null);
 const props = defineProps({
   downMode: {
     type: Boolean,
     default: false,
   },
+  isDownloadShow: { type: Boolean, default: false },
   text: {
     type: String,
-    default: '',
+    default: "",
   },
   page: {
     type: Number,
     default: 1,
   },
 });
-const emits = defineEmits(['onTextConfirm', 'goWrite']);
+
+const isnotList = ref({
+  check: 0,
+  type: "NPC",
+  options: [
+    {
+      id: 1,
+      title: "是",
+    },
+    {
+      id: 2,
+      title: "否",
+    },
+  ],
+});
+const checkOptions = (item, index) => {
+  item.check = item.options[index].id;
+  data.value[item.type].check = item.check;
+};
+const emits = defineEmits(["onTextConfirm", "goWrite"]);
 const isWrite = ref(false);
 // const text = ref('');
 const type = ref(router.currentRoute.value.query.type);
 // const page = ref(1);
 const textIndex = ref(0);
-const onTextConfirm = (data) => {
-  text.value = data.text;
-  // page.value = data.page;
-  isWrite.value = false;
-  emits('onTextConfirm', data);
-};
+// const onTextConfirm = (data) => {
+//   console.error(data);
+//   text.value = data.text;
+//   // page.value = data.page;
+//   isWrite.value = false;
+//   emits("onTextConfirm", data);
+// };
 
 const goWrite = () => {
   let text = window.getSelection();
   textIndex.value = text.anchorOffset;
 
   // isWrite.value = true;
-  emits('goWrite', { textIndex: textIndex.value });
+  emits("goWrite", { textIndex: textIndex.value });
 };
 // const handlerBus = (data) => {
 //   console.error(data);
 //   textIndex.value = data.textIndex;
 //   isWrite.value = true;
 // };
+const saveHandler = () => {
+  const origin = tables.value;
+  data.value.text = props.text;
+  data.value.page = props.page;
+
+  let json = {};
+
+  if (type.value == "1") {
+    json = { type: "askOne", data: data.value };
+  } else {
+    json = { type: "askTwo", data: data.value };
+  }
+  return json;
+};
+defineExpose({ saveHandler });
 onMounted(() => {
-  // bus.on('goWrite', handlerBus);
+  if (props.isDownloadShow) {
+  } else {
+    if (type.value == "1") {
+      setData("askOne");
+    } else {
+      setData("askTwo");
+    }
+  }
+  if (type.value == "1") {
+    if (tablesInfo.askOne) {
+      data.value = tablesInfo.askOne;
+    }
+  } else {
+    if (tablesInfo.askTwo) {
+      data.value = tablesInfo.askTwo;
+    }
+    console.error(tablesInfo);
+  }
 });
 </script>
 <style lang="scss" scoped>
+.content-box {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  &.left {
+    justify-content: flex-start;
+  }
+}
 div[contenteditable] {
   outline: none;
 }
@@ -163,6 +294,18 @@ div[contenteditable] {
   overflow: auto;
   font-family: SimSun-Regular, SimSun;
   box-sizing: border-box;
+  overflow-x: hidden;
+  .content-box {
+    display: none;
+  }
+  &.downMode {
+    input {
+      display: none;
+    }
+    .content-box {
+      display: flex;
+    }
+  }
   .num-box {
     display: flex;
     align-items: center;
@@ -215,6 +358,10 @@ div[contenteditable] {
         padding: 0 10px;
         outline: none;
         flex: 1;
+        input {
+          width: 100%;
+          text-align: center;
+        }
         &.left {
           text-align: left;
         }

+ 124 - 62
src/views/tables/author/author-one.vue

@@ -1,80 +1,88 @@
 <!--  -->
 <template>
-  <div class="author">
+  <div class="author" :class="{ downMode }" v-if="data">
     <h2 class="title">授权委托书</h2>
     <div class="content">
-      <div class="item">
-        <span>委托人:</span>
-        <div class="input-box" style="width: 100px"><input /></div>
-        <span>性别:</span>
-        <div class="input-box" style="width: 60px"><input /></div>
-        <span>年龄:</span>
-        <div class="input-box" style="width: 60px"><input /></div>
-        <span>身份证号:</span>
-        <div class="input-box" style="flex: 1"><input /></div>
-      </div>
-      <div class="item">
-        <span>住址:</span>
-        <div style="flex: 1" class="input-box"><input /></div>
-        <span>联系方式:</span>
-        <div class="input-box"><input /></div>
-      </div>
-      <div class="item">
-        <span>委托人:</span>
-        <div class="input-box" style="width: 100px"><input /></div>
-        <span>性别:</span>
-        <div class="input-box" style="width: 60px"><input /></div>
-        <span>年龄:</span>
-        <div class="input-box" style="width: 60px"><input /></div>
-        <span>身份证号:</span>
-        <div class="input-box" style="flex: 1"><input /></div>
-      </div>
-      <div class="item">
-        <span>住址:</span>
-        <div style="flex: 1" class="input-box"><input /></div>
-        <span>联系方式:</span>
-        <div class="input-box"><input /></div>
-      </div>
-      <div class="item">
-        <span>委托人:</span>
-        <div class="input-box" style="width: 100px"><input /></div>
-        <span>性别:</span>
-        <div class="input-box" style="width: 60px"><input /></div>
-        <span>年龄:</span>
-        <div class="input-box" style="width: 60px"><input /></div>
-        <span>身份证号:</span>
-        <div class="input-box" style="flex: 1"><input /></div>
-      </div>
-      <div class="item">
-        <span>住址:</span>
-        <div style="flex: 1" class="input-box"><input /></div>
-        <span>联系方式:</span>
-        <div class="input-box"><input /></div>
-      </div>
-      <!--  -->
+      <template v-for="(i, index) in data.authorList">
+        <div class="item">
+          <span>委托人:</span>
+          <div class="input-box" style="min-width: 100px">
+            <input style="width: 100px" v-model="i.name" />
+            <div class="content-box">{{ i.name }}</div>
+          </div>
+          <span>性别:</span>
+          <div class="input-box" style="min-width: 60px">
+            <input style="width: 60px" v-model="i.sex" />
+            <div class="content-box">{{ i.sex }}</div>
+          </div>
+          <span>年龄:</span>
+          <div class="input-box" style="min-width: 60px">
+            <input style="width: 60px" v-model="i.age" />
+            <div class="content-box">{{ i.age }}</div>
+          </div>
+          <span>身份证号:</span>
+          <div class="input-box" style="flex: 1">
+            <input style="width: 100%" v-model="i.id" />
+            <div class="content-box">{{ i.id }}</div>
+          </div>
+        </div>
+        <div class="item">
+          <span>住址:</span>
+          <div style="flex: 1" class="input-box">
+            <input style="width: 100%" v-model="i.address" />
+            <div class="content-box">{{ i.address }}</div>
+          </div>
+          <span>联系方式:</span>
+          <div class="input-box">
+            <input style="width: 100%" v-model="i.phoneNum" />
+            <div class="content-box">{{ i.phoneNum }}</div>
+          </div>
+        </div>
+      </template>
 
       <div class="item" style="margin-top: 100px">
         <span>受委托人姓名:</span>
-        <div style="flex: 1" class="input-box"><input /></div>
+        <div style="flex: 1" class="input-box">
+          <input style="width: 100%" v-model="data.authorBy.name" />
+          <div class="content-box">{{ data.authorBy.name }}</div>
+        </div>
         <span>性别:</span>
-        <div class="input-box" style="width: 60px"><input /></div>
+        <div class="input-box" style="min-width: 60px">
+          <input style="width: 60px" v-model="data.authorBy.sex" />
+          <div class="content-box">{{ data.authorBy.sex }}</div>
+        </div>
         <span>年龄:</span>
-        <div class="input-box" style="width: 60px"><input /></div>
+        <div class="input-box" style="min-width: 60px">
+          <input style="width: 60px" v-model="data.authorBy.age" />
+          <div class="content-box">{{ data.authorBy.age }}</div>
+        </div>
         <span>身份证号:</span>
       </div>
       <div class="item">
-        <div style="flex: 1" class="input-box"><input /></div>
+        <div style="flex: 1" class="input-box">
+          <input style="width: 100%" v-model="data.authorBy.id" />
+          <div class="content-box">{{ data.authorBy.id }}</div>
+        </div>
         <span>工作单位:</span>
-        <div class="input-box" style="width: 330px"><input /></div>
+        <div class="input-box" style="min-width: 330px">
+          <input style="width: 330px" v-model="data.authorBy.company" />
+          <div class="content-box">{{ data.authorBy.company }}</div>
+        </div>
         <span>住址及联系方式:</span>
       </div>
       <div class="item">
-        <div style="flex: 1" class="input-box"><input /></div>
+        <div style="flex: 1" class="input-box">
+          <input style="width: 100%" v-model="data.authorBy.addressPhoneNum" />
+          <div class="content-box">{{ data.authorBy.addressPhoneNum }}</div>
+        </div>
       </div>
 
       <div class="item" style="margin-top: 120px">
         <div style="text-indent: 2em">现委托上述受委托人参与:</div>
-        <div style="flex: 1" class="input-box"><input /></div>
+        <div style="flex: 1" class="input-box">
+          <input style="width: 100%" v-model="data.message" />
+          <div class="content-box">{{ data.message }}</div>
+        </div>
         <span>一案</span>
       </div>
       <div class="item">
@@ -82,13 +90,16 @@
       </div>
       <div class="item" style="margin-top: 100px">
         <span>受托人:</span>
-        <div class="input-box"><input /></div>
+        <div class="input-box">
+          <input style="width: 100%" v-model="data.authorBy.name" />
+          <div class="content-box">{{ data.authorBy.name }}</div>
+        </div>
         <span>代理权限为:</span>
       </div>
 
       <div class="check-item" @click="checkOptions(checkData, index)" v-for="(i, index) in checkData.options">
         <div style="display: inline-block">
-          <ui-icon :type="checkData.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
+          <ui-icon :type="data.options.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
           <span>{{ i.title }}</span>
         </div>
       </div>
@@ -97,25 +108,64 @@
 </template>
 
 <script setup>
-import { reactive, ref, toRefs, onBeforeMount, onMounted } from 'vue';
+import { reactive, ref, toRefs, onBeforeMount, onMounted } from "vue";
+import { tables } from "@/store/tables";
+import { tablesInfo, setData } from "../data";
+const props = defineProps({
+  downMode: { type: Boolean, default: false },
+  isDownloadShow: { type: Boolean, default: false },
+});
+const data = ref(null);
 const checkOptions = (item, index) => {
   item.check = item.options[index].id;
+  data.value[item.type].check = item.check;
 };
 const checkData = ref({
   check: 0,
+  type: "options",
   options: [
     {
       id: 1,
-      title: '一般代理。即代理为参与诉讼、调解,提供法律帮助。',
+      title: "一般代理。即代理为参与诉讼、调解,提供法律帮助。",
     },
     {
       id: 2,
-      title: '特别授权,代为起诉,陈述事实,参加辩论和调解,代为提出、承认、放弃或变更赔偿请求, 提起反诉或上诉,签收法律文书。',
+      title: "特别授权,代为起诉,陈述事实,参加辩论和调解,代为提出、承认、放弃或变更赔偿请求, 提起反诉或上诉,签收法律文书。",
     },
   ],
 });
+
+const saveHandler = () => {
+  return { type: "author", data: data.value };
+};
+
+defineExpose({ saveHandler, data });
+onMounted(() => {
+  if (props.isDownloadShow) {
+  } else {
+    setData("author");
+  }
+
+  if (tablesInfo.author) {
+    data.value = tablesInfo.author;
+  }
+});
 </script>
 <style lang="scss" scoped>
+.content-box {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+
+  border-bottom: 1px solid #000;
+  padding: 0 10px;
+  box-sizing: border-box;
+  &.left {
+    justify-content: flex-start;
+  }
+}
 .input-box {
   input {
     width: 100%;
@@ -123,6 +173,7 @@ const checkData = ref({
     border-bottom: 1px solid #000;
     padding: 0 10px;
     box-sizing: border-box;
+    text-align: center;
   }
 }
 .author {
@@ -133,6 +184,17 @@ const checkData = ref({
   font-family: SimHei-Regular, SimHei;
   font-size: 24px;
   font-weight: 400;
+  .content-box {
+    display: none;
+  }
+  &.downMode {
+    input {
+      display: none;
+    }
+    .content-box {
+      display: flex;
+    }
+  }
   .title {
     text-align: center;
     margin-bottom: 70px;

+ 62 - 9
src/views/tables/author/author-two.vue

@@ -1,6 +1,6 @@
 <!--  -->
 <template>
-  <div class="author">
+  <div class="author" :class="{ downMode }" v-if="data">
     <div class="content">
       <!-- <div class="check-item" @click="checkOptions(checkData1, index)" v-for="(i, index) in checkData1.options">
         <div class="item">
@@ -23,27 +23,39 @@
 
       <div class="item" style="margin-top: 200px">
         <span style="padding-left: 20px">委托人(签名):</span>
-        <div style="flex: 1" contenteditable></div>
+        <div style="flex: 1">
+          <input type="text" v-model="data.authorSign" />
+        </div>
       </div>
       <div class="item" style="margin-top: 100px">
         <span>受委托人(签名):</span>
-        <div style="flex: 1" contenteditable></div>
+        <div style="flex: 1">
+          <input type="text" v-model="data.authorBySign" />
+        </div>
       </div>
     </div>
   </div>
 </template>
 
 <script setup>
-import { reactive, ref, toRefs, onBeforeMount, onMounted } from 'vue';
+import { reactive, ref, toRefs, onBeforeMount, onMounted } from "vue";
+import { tables } from "@/store/tables";
+import { tablesInfo, setData } from "../data";
+const props = defineProps({
+  downMode: { type: Boolean, default: false },
+  isDownloadShow: { type: Boolean, default: false },
+});
+const data = ref(null);
 const checkOptions = (item, index) => {
   item.check = item.options[index].id;
+  data.value[item.type].check = item.check;
 };
 const checkData1 = ref({
   check: 0,
   options: [
     {
       id: 1,
-      title: '...',
+      title: "...",
     },
   ],
 });
@@ -52,24 +64,54 @@ const checkData = ref({
   options: [
     {
       id: 1,
-      title: '...',
+      title: "...",
     },
     {
       id: 2,
-      title: '一般代理。即代理为参与诉讼、调解,提供法律帮助。',
+      title: "一般代理。即代理为参与诉讼、调解,提供法律帮助。",
     },
     {
       id: 3,
-      title: '特别授权,代为起诉,陈述事实,参加辩论和调解,代为提出、承认、放弃或变更赔偿请求, 提起反诉或上诉,签收法律文书。',
+      title: "特别授权,代为起诉,陈述事实,参加辩论和调解,代为提出、承认、放弃或变更赔偿请求, 提起反诉或上诉,签收法律文书。",
     },
     {
       id: 4,
-      title: '...',
+      title: "...",
     },
   ],
 });
+
+const saveHandler = () => {
+  return { type: "author", data: data.value };
+};
+
+defineExpose({ saveHandler, data });
+onMounted(() => {
+  if (props.isDownloadShow) {
+  } else {
+    setData("author");
+  }
+
+  if (tablesInfo.author) {
+    data.value = tablesInfo.author;
+  }
+});
 </script>
 <style lang="scss" scoped>
+.content-box {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+
+  border-bottom: 1px solid #000;
+  padding: 0 10px;
+  box-sizing: border-box;
+  &.left {
+    justify-content: flex-start;
+  }
+}
 div[contenteditable] {
   outline: none;
 }
@@ -90,6 +132,17 @@ div[contenteditable] {
   font-family: SimHei-Regular, SimHei;
   font-size: 24px;
   font-weight: 400;
+  .content-box {
+    display: none;
+  }
+  &.downMode {
+    input {
+      display: none;
+    }
+    .content-box {
+      display: flex;
+    }
+  }
   .title {
     text-align: center;
     margin-bottom: 70px;

+ 221 - 0
src/views/tables/data/index.ts

@@ -0,0 +1,221 @@
+import { tables } from "@/store/tables";
+
+let data = {
+  explorateOne: {
+    explorateType: null,
+    explorateCompany: "",
+    explorateTime: "",
+    accidentTime: "",
+    technicalLevel: "",
+    administrativeLevel: { check: "", value: "" },
+    cityRoad: "",
+    roadSide: "",
+    roadPart: "",
+    roadName: "",
+    roadNum: "",
+    longitude: "",
+    latitude: "",
+    addressDesc: "",
+    weather: { check: "", value: "" },
+    environments: [
+      { check: "", value: "" },
+      { check: "", value: "" },
+      { check: "", value: "" },
+      { check: "", value: "" },
+      { check: "", value: "" },
+      { check: "", value: "" },
+      { check: "", value: "" },
+      { check: "", value: "" },
+      { check: "", value: "" },
+      { check: "", value: "" },
+    ],
+    explorateSign: "",
+    reportSign: "",
+    clientSign: "",
+    witnessSign: "",
+  },
+  explorateTwo: {
+    cameraInfo: { check: "", value: "" },
+    dieNum: "",
+    doctorSign: "",
+    hurtNum: "",
+    hurtDieGo: "",
+    desc: "",
+    dangerousInfo: { check: "", value: "" },
+    reachs: { check: "" },
+    list: [
+      ["", "", "", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", "", "", ""],
+    ],
+    explorateSign: "",
+    reportSign: "",
+    clientSign: "",
+    witnessSign: "",
+  },
+  explorateThree: {
+    groundTrace: "",
+    carTrace: "",
+    bodyTrace: "",
+    meterialEvidence: "",
+    other: "",
+    explorateSign: "",
+    reportSign: "",
+    clientSign: "",
+    witnessSign: "",
+  },
+  explorateFour: {
+    driversInfoList: [
+      ["", "", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", "", ""],
+    ],
+    carsInfoList: [
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+    ],
+    measureDesc: "",
+    otherDesc: "",
+  },
+  askOne: {
+    times: "",
+    startTime: "",
+    endTime: "",
+    adress: "",
+    asker: "",
+    askCompany: "",
+    reporter: "",
+    reporterCompany: "",
+    askerBy: "",
+    sex: "",
+    age: "",
+    birth: "",
+    id: "",
+    NPC: { check: "", value: "" },
+    adressNow: "",
+    phoneNumber: "",
+    residence: "",
+    reachTime: "",
+    leaveTime: "",
+    sign: "",
+    text: "",
+    askerBys: "",
+    page: 1,
+  },
+  askTwo: {
+    times: "",
+    startTime: "",
+    endTime: "",
+    adress: "",
+    asker: "",
+    askCompany: "",
+    reporter: "",
+    reporterCompany: "",
+    askerBy: "",
+    sex: "",
+    age: "",
+    birth: "",
+    id: "",
+    NPC: { check: "", value: "" },
+    adressNow: "",
+    phoneNumber: "",
+    residence: "",
+    reachTime: "",
+    leaveTime: "",
+    sign: "",
+    text: "",
+    askerBys: "",
+    page: 1,
+  },
+  identification: {
+    id: "",
+    time: "",
+    weather: "",
+    address: "",
+    list: [
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+    ],
+    optionsOne: { check: "", client: "", police: "", seal: "" },
+    optionsTwo: { client: "", police: "", seal: "" },
+  },
+  extract: {
+    name: "",
+    sex: "",
+    id: "",
+    time: "",
+    adress: "",
+    extractTime: "",
+    extractAdress: "",
+    aNumber: "",
+    aVolume: "",
+    bNumber: "",
+    bVolume: "",
+    disinfect: "",
+    sealing: "",
+    extractUnit: "",
+    extractMumber: "",
+    notice: "",
+    extractBySign: "",
+    witnessSign: "",
+    policeSign: "",
+    company: "",
+  },
+  legacy: {
+    accidentTime: "",
+    accidentAddress: "",
+    partySign: "",
+    policeSign: "",
+    list: [
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+      ["", "", "", "", "", "", ""],
+    ],
+  },
+  author: {
+    authorList: [
+      { name: "", sex: "", age: "", id: "", address: "", phoneNum: "" },
+      { name: "", sex: "", age: "", id: "", address: "", phoneNum: "" },
+      { name: "", sex: "", age: "", id: "", address: "", phoneNum: "" },
+    ],
+    authorBy: {
+      sex: "",
+      age: "",
+      id: "",
+      company: "",
+      addressPhoneNum: "",
+    },
+    message: "",
+    options: { check: "", value: "" },
+    authorSign: "",
+    authorBySign: "",
+  },
+};
+
+export let tablesInfo = JSON.parse(JSON.stringify(data));
+export const resetData = () => {
+  tablesInfo = JSON.parse(JSON.stringify(data));
+};
+export const setData = (type) => {
+  if (tables && tables.value[type]) {
+    tablesInfo[type] = JSON.parse(JSON.stringify(tables.value[type]));
+  }
+  // return tablesInfo;
+};

+ 89 - 29
src/views/tables/explorate-four.vue

@@ -1,6 +1,6 @@
 <!--  -->
 <template>
-  <div class="explorate">
+  <div class="explorate" v-if="data">
     <div>
       <h2 class="title">道路交通事故现场勘查笔录(续页)</h2>
 
@@ -19,17 +19,19 @@
               <td>备注</td>
             </tr>
 
-            <tr>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
+            <tr v-for="(i, index) in data.driversInfoList">
+              <td v-for="(j, j_index) in i">
+                <div><input type="text" /></div>
+              </td>
+              <!-- <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
+              <td><div contenteditable></div></td> -->
             </tr>
-            <tr>
+            <!-- <tr>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
@@ -68,7 +70,7 @@
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
-            </tr>
+            </tr> -->
           </table>
         </div>
         <div class="table-excel">
@@ -83,17 +85,18 @@
               <td>驾乘人员情况</td>
               <td>其他信息</td>
             </tr>
-
-            <tr>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
+            <tr v-for="(i, index) in data.carsInfoList">
+              <td v-for="(j, j_index) in i">
+                <div><input type="text" /></div>
+              </td>
+              <!-- <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
+              <td><div contenteditable></div></td> -->
             </tr>
-            <tr>
+            <!-- <tr>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
@@ -110,40 +113,51 @@
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
               <td><div contenteditable></div></td>
-            </tr>
+            </tr> -->
           </table>
         </div>
         <div class="table-body">
           <div class="item column">
             <span>八、现场采取强制措施情况</span>
-            <div contenteditable></div>
+            <div>
+              <textarea v-model="data.measureDesc" name="" id="" cols="30" rows="10"></textarea>
+            </div>
           </div>
         </div>
         <div class="table-body no-border">
           <div class="item column">
             <span>九、勘查现场的交通警察认为应当记录的其他情况</span>
-            <div contenteditable></div>
+            <div>
+              <textarea v-model="data.otherDesc" name="" id="" cols="30" rows="10"></textarea>
+            </div>
           </div>
         </div>
-
         <div class="sign-box">
           <div>
             <span>现场勘查人员签名:</span>
-            <div contenteditable></div>
+            <div>
+              <input type="text" v-model="data.explorateSign" />
+            </div>
           </div>
           <div>
             <span>记录人签名:</span>
-            <div contenteditable></div>
+            <div>
+              <input type="text" v-model="data.reportSign" />
+            </div>
           </div>
         </div>
         <div class="sign-box">
           <div>
             <span>当事人签名:</span>
-            <div contenteditable></div>
+            <div>
+              <input type="text" v-model="data.clientSign" />
+            </div>
           </div>
           <div>
             <span>见证人签名:</span>
-            <div contenteditable></div>
+            <div>
+              <input type="text" v-model="data.witnessSign" />
+            </div>
           </div>
         </div>
       </div>
@@ -157,7 +171,33 @@
 </template>
 
 <script setup lang="ts">
-import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from 'vue';
+import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from "vue";
+import { tables } from "@/store/tables";
+import { tablesInfo, setData } from "./data";
+
+const props = defineProps({
+  downMode: { type: Boolean, default: false },
+  isDownloadShow: { type: Boolean, default: false },
+});
+const data = ref(null);
+const saveHandler = () => {
+  return { type: "explorateFour", data: data.value };
+};
+const saveStore = () => {
+  // return new Promise((res, rej) => {
+  // origin["legacy"] = JSON.parse(JSON.stringify(data.value));
+  // });
+};
+defineExpose({ saveHandler, data });
+onMounted(() => {
+  if (props.isDownloadShow) {
+  } else {
+    setData("explorateFour");
+  }
+  if (tablesInfo.explorateFour) {
+    data.value = tablesInfo.explorateFour;
+  }
+});
 </script>
 <style lang="scss" scoped>
 .explorate {
@@ -182,6 +222,11 @@ import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from 'vue';
         border: 1px solid #000;
         tr {
           // border-bottom: 1px solid #000;
+          &:first-of-type {
+            td {
+              padding: 10px 14px;
+            }
+          }
           &:last-of-type {
             td {
               border-bottom: none;
@@ -189,7 +234,7 @@ import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from 'vue';
           }
         }
         td {
-          padding: 10px 14px;
+          padding: 0 5px;
           box-sizing: border-box;
           text-align: center;
           max-width: 11%;
@@ -201,6 +246,11 @@ import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from 'vue';
           }
           > div {
             outline: none;
+            input {
+              width: 100%;
+              height: 100%;
+              text-align: center;
+            }
           }
         }
       }
@@ -237,16 +287,26 @@ import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from 'vue';
         border-bottom: none;
       }
       .item {
-        display: flex;
+        // display: flex;
         margin-bottom: 10px;
-        &.column {
-          flex-direction: column;
-          height: 130px;
-          > div {
-            outline: none;
+        > span {
+          display: block;
+        }
+        > div {
+          height: 110px;
+          textarea {
+            width: 100%;
             height: 100%;
           }
         }
+        &.column {
+          // flex-direction: column;
+          height: 130px;
+          // > div {
+          //   outline: none;
+          //   height: 100%;
+          // }
+        }
       }
     }
   }

+ 92 - 18
src/views/tables/explorate-one.vue

@@ -7,7 +7,7 @@
       </Header>
     </template> -->
 
-  <div class="explorate" :class="{ downMode }">
+  <div class="explorate" :class="{ downMode }" v-if="data">
     <div ref="layoutRef">
       <h2 class="title">道路交通事故现场勘查笔录</h2>
 
@@ -15,21 +15,28 @@
         <div class="wrapper">
           <div class="header">
             <div class="item" v-for="(i, index) in sceneTypes.options" @click="checkLevel(sceneTypes, index)">
-              <ui-icon :type="sceneTypes.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
+              <ui-icon :type="data.explorateType == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
               <span>{{ i.title }}</span>
             </div>
           </div>
           <div class="info">
             <div>勘查单位</div>
-            <div class="input-box" contenteditable></div>
+            <!-- <div class="input-box" contenteditable v-html="data.explorateCompany"></div> -->
+            <div class="input-box">
+              <input type="text" v-model="data.explorateCompany" />
+            </div>
           </div>
           <div class="info">
             <div>勘查时间</div>
-            <div class="input-box" contenteditable></div>
+            <div class="input-box">
+              <input type="text" v-model="data.explorateTime" />
+            </div>
           </div>
           <div class="info">
             <div>事故时间</div>
-            <div class="input-box" contenteditable></div>
+            <div class="input-box">
+              <input type="text" v-model="data.accidentTime" />
+            </div>
           </div>
           <div class="time">
             <div class="name">事故地点</div>
@@ -56,7 +63,7 @@
                             <ui-icon :type="administrativeLevel.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
                             <span>{{ i.title }}</span>
                             <div class="input-box" style="flex: 1" v-if="i.id == 5">
-                              <input type="text" />
+                              <input type="text" v-model="data.administrativeLevel.value" />
                             </div>
                           </div>
                         </div>
@@ -104,9 +111,13 @@
               <div class="road-info">
                 <div class="road-name">路名</div>
                 <div class="road-msg">
-                  <div class="road-name-text" contenteditable></div>
+                  <div class="road-name-text input-box">
+                    <input type="text" v-model="data.roadName" />
+                  </div>
                   <div class="road-num">路号(公路)</div>
-                  <div class="road-num-text" contenteditable></div>
+                  <div class="road-num-text input-box">
+                    <input type="text" v-model="data.roadNum" />
+                  </div>
                 </div>
               </div>
               <div class="road-pos">
@@ -117,17 +128,23 @@
                     <div class="pos-msg" style="height: 30px">
                       <div class="longitude">
                         <span>经度:</span>
-                        <div contenteditable></div>
+                        <div class="input-box">
+                          <input type="text" v-model="data.longitude" />
+                        </div>
                       </div>
                       <div class="latitude">
                         <span>纬度:</span>
-                        <div contenteditable></div>
+                        <div>
+                          <input type="text" v-model="data.latitude" />
+                        </div>
                       </div>
                     </div>
                   </div>
                   <div class="pos-item">
                     <div class="pos-item-name" style="height: 54px">地点描述</div>
-                    <div class="pos-msg desc" style="height: 54px" contenteditable></div>
+                    <div class="pos-msg desc input-box" style="height: 54px">
+                      <input type="text" v-model="data.addressDesc" />
+                    </div>
                   </div>
                 </div>
               </div>
@@ -141,7 +158,7 @@
                 <ui-icon :type="weatherList.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
                 <span>{{ i.title }}</span>
                 <div class="input-box" v-if="i.id == 10">
-                  <input type="text" />
+                  <input type="text" v-model="data.weather.value" />
                 </div>
               </div>
             </div>
@@ -157,11 +174,11 @@
                       <ui-icon :type="i.check == j.id ? 'rb_y' : 'rb_n'"></ui-icon>
                       <span>{{ j.name }}</span>
                       <div class="input-box" v-if="j_index == i.options.length - 1">
-                        <input type="text" />
+                        <input type="text" v-model="data.environments[index].value" />
                       </div>
                     </div>
                     <div class="input-box" v-if="!i.options.length">
-                      <input type="text" />
+                      <input type="text" v-model="data.environments[index].value" />
                     </div>
                   </div>
                   <!-- <div class="input-box" v-if="index == environments.length - 1">
@@ -174,21 +191,29 @@
           <div class="sign-box">
             <div>
               <span>现场勘查人员签名:</span>
-              <div contenteditable></div>
+              <div>
+                <input type="text" v-model="data.explorateSign" />
+              </div>
             </div>
             <div>
               <span>记录人签名:</span>
-              <div contenteditable></div>
+              <div>
+                <input type="text" v-model="data.reportSign" />
+              </div>
             </div>
           </div>
           <div class="sign-box">
             <div>
               <span>当事人签名:</span>
-              <div contenteditable></div>
+              <div>
+                <input type="text" v-model="data.clientSign" />
+              </div>
             </div>
             <div>
               <span>见证人签名:</span>
-              <div contenteditable></div>
+              <div>
+                <input type="text" v-model="data.witnessSign" />
+              </div>
             </div>
           </div>
         </div>
@@ -209,6 +234,17 @@ import { downloadImage, uploadImage } from "@/store/sync";
 import Message from "@/components/base/components/message/message.vue";
 import Header from "@/components/photos/header.vue";
 import MainPanel from "@/components/main-panel/index.vue";
+import UiInput from "@/components/base/components/input/index.vue";
+import { genUseLoading } from "@/hook";
+import { tables } from "@/store/tables";
+import { tablesInfo, setData } from "./data";
+
+const props = defineProps({
+  downMode: { type: Boolean, default: false },
+  isDownloadShow: { type: Boolean, default: false },
+});
+const data = ref(null);
+
 const layoutRef = ref<HTMLDivElement>();
 const downMode = ref(false);
 const getLayoutImage = async () => {
@@ -224,6 +260,7 @@ const getLayoutImage = async () => {
 };
 const sceneTypes = ref({
   check: 0,
+  type: "explorateType",
   options: [
     { id: 1, title: "现场勘查" },
     { id: 2, title: "补充勘查" },
@@ -231,6 +268,7 @@ const sceneTypes = ref({
 });
 const roadPartList = ref({
   check: 0,
+  type: "roadPart",
   options: [
     { id: 1, title: "普通路段" },
     { id: 2, title: "高架路段" },
@@ -244,6 +282,7 @@ const roadPartList = ref({
   ],
 });
 const roadSideList = ref({
+  type: "roadSide",
   check: 0,
   options: [
     { id: 1, title: "三枝分叉口" },
@@ -255,6 +294,7 @@ const roadSideList = ref({
 });
 const cityRoadList = ref({
   check: 0,
+  type: "cityRoad",
   options: [
     { id: 1, title: "城市快速路" },
     { id: 2, title: "一般城市道路" },
@@ -267,6 +307,7 @@ const cityRoadList = ref({
 
 const administrativeLevel = ref({
   check: 0,
+  type: "administrativeLevel",
   options: [
     { id: 1, title: "国道" },
     { id: 2, title: "省道" },
@@ -286,9 +327,16 @@ const administrativeLevel = ref({
 });
 const checkLevel = (item, index) => {
   item.check = item.options[index].id;
+  if (item.type == "administrativeLevel" || item.type == "weather") {
+    data.value[item.type].check = item.check;
+  } else {
+    data.value[item.type] = item.check;
+  }
+  console.log(data.value);
 };
 const technicalLevel = ref({
   check: 0,
+  type: "technicalLevel",
   options: [
     { id: 1, title: "高速" },
     { id: 2, title: "一级" },
@@ -312,6 +360,7 @@ const technicalLevel = ref({
 });
 const weatherList = ref({
   check: 0,
+  type: "weather",
   options: [
     { id: 1, title: "晴" },
     { id: 2, title: "阴" },
@@ -352,6 +401,7 @@ const weatherList = ref({
 
 const checkEnvironItem = (item, index, j_index) => {
   environments.value[index].check = item.id;
+  data.value.environments[index].check = item.id;
 };
 const environments = ref([
   {
@@ -465,8 +515,32 @@ const environments = ref([
     options: [],
   },
 ]);
+
+const saveHandler = () => {
+  const origin = tables.value;
+  return { type: "explorateOne", data: data.value };
+};
+const saveStore = () => {
+  // return new Promise((res, rej) => {
+  // origin["legacy"] = JSON.parse(JSON.stringify(data.value));
+  // });
+};
+defineExpose({ saveHandler, data });
+onMounted(() => {
+  if (props.isDownloadShow) {
+  } else {
+    setData("explorateOne");
+  }
+
+  if (tablesInfo.explorateOne) {
+    data.value = tablesInfo.explorateOne;
+  }
+});
 </script>
 <style lang="scss" scoped>
+input {
+  width: 100%;
+}
 div {
   box-sizing: border-box;
 }

+ 65 - 19
src/views/tables/explorate-three.vue

@@ -1,6 +1,6 @@
 <!--  -->
 <template>
-  <div class="explorate">
+  <div class="explorate" v-if="data">
     <div>
       <h2 class="title">道路交通事故现场勘查笔录(续页)</h2>
 
@@ -10,44 +10,52 @@
 
           <div class="item column">
             <span>(一)地面痕迹:</span>
-            <div contenteditable></div>
+            <div><textarea v-model="data.groundTrace" name="" id="" cols="30" rows="10"></textarea></div>
           </div>
           <div class="item column">
             <span>(二)车体痕迹:</span>
-            <div contenteditable></div>
+            <div><textarea v-model="data.carTrace" name="" id="" cols="30" rows="10"></textarea></div>
           </div>
           <div class="item column">
             <span>(三)人体痕迹:</span>
-            <div contenteditable></div>
+            <div><textarea v-model="data.bodyTrace" name="" id="" cols="30" rows="10"></textarea></div>
           </div>
           <div class="item column">
             <span>(四)物证:</span>
-            <div contenteditable></div>
+            <div><textarea v-model="data.meterialEvidence" name="" id="" cols="30" rows="10"></textarea></div>
           </div>
           <div class="item column">
             <span>(五)其他:</span>
-            <div contenteditable></div>
+            <div><textarea v-model="data.other" name="" id="" cols="30" rows="10"></textarea></div>
           </div>
         </div>
 
         <div class="sign-box">
           <div>
             <span>现场勘查人员签名:</span>
-            <div contenteditable></div>
+            <div>
+              <input type="text" v-model="data.explorateSign" />
+            </div>
           </div>
           <div>
             <span>记录人签名:</span>
-            <div contenteditable></div>
+            <div>
+              <input type="text" v-model="data.reportSign" />
+            </div>
           </div>
         </div>
         <div class="sign-box">
           <div>
             <span>当事人签名:</span>
-            <div contenteditable></div>
+            <div>
+              <input type="text" v-model="data.clientSign" />
+            </div>
           </div>
           <div>
             <span>见证人签名:</span>
-            <div contenteditable></div>
+            <div>
+              <input type="text" v-model="data.witnessSign" />
+            </div>
           </div>
         </div>
       </div>
@@ -60,7 +68,33 @@
 </template>
 
 <script setup lang="ts">
-import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from 'vue';
+import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from "vue";
+import { tables } from "@/store/tables";
+import { tablesInfo, setData } from "./data";
+
+const props = defineProps({
+  downMode: { type: Boolean, default: false },
+  isDownloadShow: { type: Boolean, default: false },
+});
+const data = ref(null);
+const saveHandler = () => {
+  return { type: "explorateThree", data: data.value };
+};
+const saveStore = () => {
+  // return new Promise((res, rej) => {
+  // origin["legacy"] = JSON.parse(JSON.stringify(data.value));
+  // });
+};
+defineExpose({ saveHandler, data });
+onMounted(() => {
+  if (props.isDownloadShow) {
+  } else {
+    setData("explorateThree");
+  }
+  if (tablesInfo.explorateThree) {
+    data.value = tablesInfo.explorateThree;
+  }
+});
 </script>
 <style lang="scss" scoped>
 .explorate {
@@ -111,18 +145,30 @@ import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from 'vue';
       margin-top: 10px;
       padding: 0 10px 10px;
       .item {
-        display: flex;
+        // display: flex;
         margin-bottom: 10px;
-
+        span {
+          display: block;
+        }
+        > div {
+          outline: none;
+          height: 180px;
+          padding: 10px;
+          textarea {
+            height: 100%;
+            width: 100%;
+            resize: none;
+          }
+        }
         &.column {
-          flex-direction: column;
-          height: 200px;
+          // flex-direction: column;
+          // height: 200px;
           width: 100%;
 
-          > div {
-            outline: none;
-            height: 100%;
-          }
+          // > div {
+          //   outline: none;
+          //   height: 100%;
+          // }
         }
       }
     }

+ 101 - 85
src/views/tables/explorate-two.vue

@@ -1,6 +1,6 @@
 <!--  -->
 <template>
-  <div class="explorate">
+  <div class="explorate" :class="{ downMode }" v-if="data">
     <div>
       <h2 class="title">道路交通事故现场勘查笔录(续页)</h2>
 
@@ -9,9 +9,12 @@
           <p style="margin-bottom: 5px">二、现场监控设备情况</p>
           <div class="table-header-info">
             <div class="item" v-for="(i, index) in headerList.options" @click="checkOptions(headerList, index)">
-              <ui-icon :type="headerList.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
+              <ui-icon :type="data.cameraInfo.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
               <span>{{ i.title }}</span>
-              <div v-if="i.id == 2" style="flex: 1"><input type="text" /></div>
+              <div v-if="i.id == 2" style="flex: 1">
+                <input type="text" v-model="data.cameraInfo.value" />
+                <div class="content-box left" style="border-bottom: 1px solid #000">{{ data.cameraInfo.value }}</div>
+              </div>
             </div>
           </div>
         </div>
@@ -20,15 +23,22 @@
           <p style="margin-bottom: 10px">(一)伤亡人员基本情况;</p>
           <div class="item">
             <span>当场死亡:(</span>
-            <div contenteditable style="min-width: 10px"></div>
+            <div style="min-width: 10px">
+              <input style="width: 30px" type="text" v-model="data.dieNum" />
+              <div class="content-box">{{ data.dieNum }}</div>
+            </div>
             <span>)人;急救、医疗人员签名确认:</span>
             <div style="flex: 1">
-              <input type="text" />
+              <input class="under-line" type="text" v-model="data.doctorSign" />
+              <div class="content-box left" style="border-bottom: 1px solid #000">{{ data.doctorSign }}</div>
             </div>
           </div>
           <div class="item">
             <span>受伤:(</span>
-            <div contenteditable style="min-width: 10px"></div>
+            <div style="min-width: 10px">
+              <input style="width: 30px" type="text" />
+              <div class="content-box"></div>
+            </div>
             <span>)人。</span>
           </div>
           <div class="item column">
@@ -44,7 +54,7 @@
           <div class="item" style="margin-top: 10px">
             <span> 是否涉及危险物品:</span>
             <div style="margin-right: 40px" v-for="(i, index) in isnotList.options" @click="checkOptions(isnotList, index)">
-              <ui-icon :type="isnotList.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
+              <ui-icon :type="data.dangerousInfo.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
               <span>{{ i.title }}</span>
             </div>
             <!-- <div style="margin-right: 40px">
@@ -53,7 +63,8 @@
             </div> -->
             <div>名称:</div>
             <div style="flex: 1">
-              <input type="text" />
+              <input class="under-line" type="text" v-model="data.dangerousInfo.value" />
+              <div class="content-box left" style="border-bottom: 1px solid #000">{{ data.dangerousInfo.value }}</div>
             </div>
           </div>
           <p style="margin-bottom: 5px">相关部门和人员到达情况:</p>
@@ -66,10 +77,6 @@
                 </div>
               </div>
             </template>
-
-            <!-- <div>
-              <div style="display: inline-block"><ui-icon type="rb_n"></ui-icon> <span>消防</span></div>
-            </div> -->
           </div>
           <div class="item half">
             <template v-for="(i, index) in reachList.options">
@@ -80,9 +87,6 @@
                 </div>
               </div>
             </template>
-            <!-- <div>
-              <div style="display: inline-block"><ui-icon type="rb_n"></ui-icon> <span>其他</span></div>
-            </div> -->
           </div>
         </div>
         <div class="table-excel">
@@ -102,81 +106,32 @@
               <td>车载事件数据记录仪</td>
               <td>卫星定位装置</td>
             </tr>
-            <tr>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-            </tr>
-            <tr>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-            </tr>
-            <tr>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-            </tr>
-            <tr>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-            </tr>
-            <tr>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
-              <td><div contenteditable></div></td>
+            <tr v-for="(i, index) in data.list">
+              <td v-for="(j, j_index) in i">
+                <div class="content-box">{{ data.list[index][j_index] }}</div>
+                <input type="text" v-model="data.list[index][j_index]" />
+              </td>
             </tr>
           </table>
         </div>
         <div class="sign-box">
           <div>
             <span>现场勘查人员签名:</span>
-            <div contenteditable></div>
+            <div><input type="text" v-model="data.explorateSign" /></div>
           </div>
           <div>
             <span>记录人签名:</span>
-            <div contenteditable></div>
+            <div><input type="text" v-model="data.reportSign" /></div>
           </div>
         </div>
         <div class="sign-box">
           <div>
             <span>当事人签名:</span>
-            <div contenteditable></div>
+            <div><input type="text" v-model="data.clientSign" /></div>
           </div>
           <div>
             <span>见证人签名:</span>
-            <div contenteditable></div>
+            <div><input type="text" v-model="data.witnessSign" /></div>
           </div>
         </div>
       </div>
@@ -189,62 +144,104 @@
 </template>
 
 <script setup lang="ts">
-import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from 'vue';
+import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick, defineProps } from "vue";
+
+import { tables } from "@/store/tables";
+import { tablesInfo, setData } from "./data";
+const props = defineProps({
+  downMode: { type: Boolean, default: false },
+  isDownloadShow: { type: Boolean, default: false },
+});
+const data = ref(null);
+
 const checkOptions = (item, index) => {
   item.check = item.options[index].id;
+  data.value[item.type].check = item.check;
 };
 const headerList = ref({
   check: 0,
+  type: "cameraInfo",
   options: [
     {
       id: 1,
-      title: '未发现',
+      title: "未发现",
     },
     {
       id: 2,
-      title: '发现',
+      title: "发现",
     },
   ],
 });
 const isnotList = ref({
   check: 0,
+  type: "dangerousInfo",
   options: [
     {
       id: 1,
-      title: '否',
+      title: "否",
     },
     {
       id: 2,
-      title: '是',
+      title: "是",
     },
   ],
 });
 const reachList = ref({
   check: 0,
+  type: "reachs",
   options: [
     {
       id: 1,
-      title: '医疗',
+      title: "医疗",
     },
     {
       id: 2,
-      title: '消防',
+      title: "消防",
     },
     {
       id: 3,
-      title: '清障',
+      title: "清障",
     },
     {
       id: 4,
-      title: '其他',
+      title: "其他",
     },
   ],
 });
+const saveHandler = () => {
+  return { type: "explorateTwo", data: data.value };
+};
+const saveStore = () => {
+  // return new Promise((res, rej) => {
+  // origin["legacy"] = JSON.parse(JSON.stringify(data.value));
+  // });
+};
+defineExpose({ saveHandler, data });
+
+onMounted(() => {
+  if (props.isDownloadShow) {
+  } else {
+    setData("explorateTwo");
+  }
+  if (tablesInfo.explorateTwo) {
+    data.value = tablesInfo.explorateTwo;
+  }
+});
 </script>
 <style lang="scss" scoped>
 div[contenteditable] {
   outline: none;
 }
+.content-box {
+  width: 100%;
+  height: 100%;
+  display: none;
+  align-items: center;
+  justify-content: center;
+  &.left {
+    justify-content: flex-start;
+  }
+}
 .explorate {
   color: #000;
   width: 100%;
@@ -257,6 +254,15 @@ div[contenteditable] {
   > div {
     // padding: 20px 50px 30px;
   }
+
+  &.downMode {
+    input {
+      display: none;
+    }
+    .content-box {
+      display: flex;
+    }
+  }
   .title {
     text-align: center;
     margin-bottom: 10px;
@@ -267,6 +273,7 @@ div[contenteditable] {
     .table-excel {
       padding: 10px;
       table {
+        width: 100%;
         border-collapse: collapse;
         border: 1px solid #000;
         tr {
@@ -278,7 +285,7 @@ div[contenteditable] {
           }
         }
         td {
-          padding: 0 14px;
+          padding: 0 2px;
           box-sizing: border-box;
           text-align: center;
           max-width: 11%;
@@ -288,6 +295,11 @@ div[contenteditable] {
           &:last-of-type {
             border-right: none;
           }
+          input {
+            width: 100%;
+            height: 100%;
+            text-align: center;
+          }
           > div {
             outline: none;
           }
@@ -344,8 +356,12 @@ div[contenteditable] {
         }
         > div {
           input {
-            width: 100%;
-            border-bottom: 1px solid #000;
+            &.under-line {
+              width: 100%;
+
+              border-bottom: 1px solid #000;
+            }
+            // border-bottom: 1px solid #000;
           }
         }
       }

+ 164 - 39
src/views/tables/extract.vue

@@ -1,83 +1,179 @@
 <!--  -->
 <template>
-  <div class="explorate" ref="layoutRef">
+  <div class="extract" ref="layoutRef" :class="{ downMode }" v-if="data">
     <h2 class="title">当事人血样(尿样)提取登记表</h2>
 
     <div class="container">
       <table>
         <tr>
           <td width="12%" colspan="2">姓名</td>
-          <td width="20%"><div contenteditable></div></td>
+          <td width="20%">
+            <div>
+              <input v-model="data.name" />
+              <div class="content-box">{{ data.name }}</div>
+            </div>
+          </td>
           <td width="10%">性别</td>
-          <td width="8%"><div contenteditable></div></td>
+          <td width="8%">
+            <div>
+              <input v-model="data.sex" />
+              <div class="content-box">{{ data.sex }}</div>
+            </div>
+          </td>
           <td width="20%">身份证号码</td>
-          <td width="30%" colspan="2"><div contenteditable></div></td>
+          <td width="30%" colspan="2">
+            <div>
+              <input v-model="data.id" />
+              <div class="content-box">{{ data.id }}</div>
+            </div>
+          </td>
         </tr>
         <tr>
           <td width="15%" colspan="2">事故时间</td>
-          <td width="35%" colspan="3"><div contenteditable></div></td>
+          <td width="35%" colspan="3">
+            <div>
+              <input v-model="data.time" />
+              <div class="content-box">{{ data.time }}</div>
+            </div>
+          </td>
           <td width="20%">地点</td>
-          <td width="30%" colspan="2"><div contenteditable></div></td>
+          <td width="30%" colspan="2">
+            <div>
+              <input v-model="data.address" />
+              <div class="content-box">{{ data.address }}</div>
+            </div>
+          </td>
         </tr>
         <tr>
           <td colspan="2">血样(尿样)提取时间</td>
-          <td colspan="6"><div contenteditable></div></td>
+          <td colspan="6">
+            <div>
+              <input v-model="data.extractTime" />
+              <div class="content-box">{{ data.extractTime }}</div>
+            </div>
+          </td>
         </tr>
         <tr>
           <td colspan="2">血样(尿样)提取地点</td>
-          <td colspan="6"><div contenteditable></div></td>
+          <td colspan="6">
+            <div>
+              <input v-model="data.extractAdress" />
+              <div class="content-box">{{ data.extractAdress }}</div>
+            </div>
+          </td>
         </tr>
         <tr>
           <td width="10%" rowspan="4" colspan="1">血样(尿样)提取人员填写</td>
           <td width="5%" rowspan="3">提取登记</td>
           <td colspan="3">A样本盛装容器编号</td>
-          <td><div contenteditable></div></td>
+          <td>
+            <div>
+              <input v-model="data.aNumber" />
+              <div class="content-box">{{ data.aNumber }}</div>
+            </div>
+          </td>
           <td width="10%">提取量</td>
           <td>
             <div>
-              <div contenteditable></div>
+              <div>
+                <input v-model="data.aVolume" />
+                <div class="content-box">{{ data.aVolume }}</div>
+              </div>
               ml
             </div>
           </td>
         </tr>
         <tr>
           <td colspan="3">B样本盛装容器编号</td>
-          <td><div contenteditable></div></td>
+          <td>
+            <div>
+              <input v-model="data.bNumber" />
+              <div class="content-box">{{ data.bNumber }}</div>
+            </div>
+          </td>
           <td>提取量</td>
           <td>
             <div>
-              <div contenteditable></div>
+              <div>
+                <input v-model="data.bVolume" />
+                <div class="content-box">{{ data.bVolume }}</div>
+              </div>
               ml
             </div>
           </td>
         </tr>
         <tr>
           <td colspan="1">消毒名称</td>
-          <td colspan="2"><div contenteditable></div></td>
+          <td colspan="2">
+            <div>
+              <input v-model="data.disinfect" />
+              <div class="content-box">{{ data.disinfect }}</div>
+            </div>
+          </td>
           <td>密封方式</td>
-          <td colspan="2"><div contenteditable></div></td>
+          <td colspan="2">
+            <div>
+              <input v-model="data.sealing" />
+              <div class="content-box">{{ data.sealing }}</div>
+            </div>
+          </td>
         </tr>
         <tr>
           <td width="10%" colspan="2">提取人员单位</td>
-          <td colspan="2"><div contenteditable></div></td>
+          <td colspan="2">
+            <div>
+              <input v-model="data.extractUnit" />
+              <div class="content-box">{{ data.extractUnit }}</div>
+            </div>
+          </td>
           <td>提取人员(签名)</td>
-          <td colspan="2"><div contenteditable></div></td>
+          <td colspan="2">
+            <div>
+              <input v-model="data.extractMumber" />
+              <div class="content-box">{{ data.extractMumber }}</div>
+            </div>
+          </td>
         </tr>
         <tr>
           <td>通知家属情况</td>
-          <td colspan="7"><div contenteditable></div></td>
+          <td colspan="7">
+            <div>
+              <input v-model="data.notice" />
+              <div class="content-box">{{ data.notice }}</div>
+            </div>
+          </td>
         </tr>
         <tr>
           <td>被提取人(签名)</td>
-          <td colspan="2"><div contenteditable></div></td>
+          <td colspan="2">
+            <div>
+              <input v-model="data.extractBySign" />
+              <div class="content-box">{{ data.extractBySign }}</div>
+            </div>
+          </td>
           <td>见证人(签名)</td>
-          <td colspan="2"><div contenteditable></div></td>
+          <td colspan="2">
+            <div>
+              <input v-model="data.witnessSign" />
+              <div class="content-box">{{ data.witnessSign }}</div>
+            </div>
+          </td>
           <td>交通警察(签名)</td>
-          <td colspan="2"><div contenteditable></div></td>
+          <td colspan="2">
+            <div>
+              <input v-model="data.policeSign" />
+              <div class="content-box">{{ data.policeSign }}</div>
+            </div>
+          </td>
         </tr>
         <tr>
           <td>办案单位</td>
-          <td colspan="7"><div contenteditable></div></td>
+          <td colspan="7">
+            <div>
+              <input v-model="data.company" />
+              <div class="content-box">{{ data.company }}</div>
+            </div>
+          </td>
         </tr>
       </table>
     </div>
@@ -85,9 +181,42 @@
 </template>
 
 <script setup lang="ts">
-import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from 'vue';
+import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick } from "vue";
+
+import { tables } from "@/store/tables";
+import { tablesInfo, setData } from "./data";
+const props = defineProps({
+  downMode: { type: Boolean, default: false },
+  isDownloadShow: { type: Boolean, default: false },
+});
+const data = ref(null);
+const saveHandler = () => {
+  return { type: "extract", data: data.value };
+};
+
+defineExpose({ saveHandler, data });
+onMounted(() => {
+  if (props.isDownloadShow) {
+  } else {
+    setData("extract");
+  }
+
+  if (tablesInfo.extract) {
+    data.value = tablesInfo.extract;
+  }
+});
 </script>
 <style lang="scss" scoped>
+.content-box {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  &.left {
+    justify-content: flex-start;
+  }
+}
 div[contenteditable] {
   outline: none;
   display: flex;
@@ -96,7 +225,7 @@ div[contenteditable] {
   // height: 100%;
   width: 100%;
 }
-.explorate {
+.extract {
   color: #000;
   font-size: 20px;
   // padding: 10px 30px;
@@ -106,6 +235,17 @@ div[contenteditable] {
   overflow: auto;
   font-family: sr, st;
   box-sizing: border-box;
+  .content-box {
+    display: none;
+  }
+  &.downMode {
+    input {
+      display: none;
+    }
+    .content-box {
+      display: flex;
+    }
+  }
 
   .title {
     text-align: center;
@@ -143,7 +283,7 @@ div[contenteditable] {
             white-space: nowrap;
             line-height: 110px;
             width: 100%;
-              height: 100%;
+            height: 100%;
             input {
               width: 100%;
               height: 100%;
@@ -160,20 +300,5 @@ div[contenteditable] {
       }
     }
   }
-  &.downMode {
-    // table {
-    //   border: 1px solid #000;
-    //   tr {
-    //     td {
-    //       border: none;
-    //       border-bottom: 1px solid #000;
-    //       border-right: 1px solid #000;
-    //       &:last-of-type {
-    //         border-right: none;
-    //       }
-    //     }
-    //   }
-    // }
-  }
 }
 </style>

+ 112 - 61
src/views/tables/identification.vue

@@ -1,21 +1,33 @@
 <template>
-  <div class="identification">
+  <div class="identification" :class="{ downMode }" v-if="data">
     <h2 class="title">道路交通事故认定书(简易程序)</h2>
     <div class="num">
-      <div contenteditable></div>
+      <div>
+        <input v-model="data.id" />
+        <div class="content-box">{{ data.id }}</div>
+      </div>
     </div>
     <div class="table-layout">
       <div class="msg-box">
         <div class="name">事故时间</div>
-        <div class="input-box" style="flex: 1" contenteditable></div>
+        <div class="input-box" style="flex: 1">
+          <input v-model="data.time" />
+          <div class="content-box">{{ data.time }}</div>
+        </div>
         <div class="weather">天气</div>
-        <div class="input-box" style="width: 128px" contenteditable></div>
+        <div class="input-box" style="width: 128px">
+          <input v-model="data.weather" />
+          <div class="content-box">{{ data.weather }}</div>
+        </div>
       </div>
       <div class="msg-box">
         <div class="name">事故地点</div>
-        <div style="flex: 1" class="input-box" contenteditable></div>
+        <div style="flex: 1" class="input-box">
+          <input v-model="data.address" />
+          <div class="content-box">{{ data.address }}</div>
+        </div>
       </div>
 
       <table>
@@ -28,63 +40,29 @@
           <td>保险公司</td>
           <td>交强险凭证号</td>
         </tr>
-        <tr>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-        </tr>
-        <tr>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-        </tr>
-        <tr>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-        </tr>
-        <tr>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-        </tr>
-        <tr>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
-          <td><div contenteditable></div></td>
+        <tr v-for="(i, index) in data.list">
+          <td v-for="(j, j_index) in i">
+            <div>
+              <input v-model="data.list[index][j_index]" />
+              <div class="content-box">{{ data.list[index][j_index] }}</div>
+            </div>
+          </td>
         </tr>
       </table>
       <div class="respons">
         <div class="name" style="width: 50px">交通事故事实及责任</div>
         <div class="info">
           <div style="margin-bottom: 10px" v-for="(i, index) in topList.options" @click="checkOptions(topList, index)">
-            <ui-icon :type="topList.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
+            <ui-icon :type="data.optionsOne.check == i.id ? 'rb_y' : 'rb_n'"></ui-icon>
             <span>{{ i.title }}</span>
           </div>
           <div class="sign-box" style="margin-bottom: 40px">
             <div style="flex: 1">
               <span>当事人:</span>
-              <div style="flex: 1" contenteditable></div>
+              <div style="flex: 1">
+                <input v-model="data.optionsOne.client" />
+                <div class="content-box">{{ data.optionsOne.client }}</div>
+              </div>
             </div>
             <div>
               <span>(道路交通事故处理专用章)</span>
@@ -92,7 +70,10 @@
           </div>
           <div class="sign-box">
             <span>交通警察:</span>
-            <div style="flex: 1" contenteditable></div>
+            <div style="flex: 1">
+              <input v-model="data.optionsOne.police" />
+              <div class="content-box">{{ data.optionsOne.police }}</div>
+            </div>
           </div>
         </div>
       </div>
@@ -102,7 +83,10 @@
           <div class="sign-box" style="margin-bottom: 40px">
             <div style="flex: 1">
               <span>当事人:</span>
-              <div style="flex: 1" contenteditable></div>
+              <div style="flex: 1">
+                <input v-model="data.optionsOne.client" />
+                <div class="content-box">{{ data.optionsOne.client }}</div>
+              </div>
             </div>
             <div>
               <span>(道路交通事故处理专用章)</span>
@@ -110,7 +94,10 @@
           </div>
           <div class="sign-box">
             <span>交通警察:</span>
-            <div style="flex: 1" contenteditable></div>
+            <div style="flex: 1">
+              <input v-model="data.optionsOne.police" />
+              <div class="content-box">{{ data.optionsOne.police }}</div>
+            </div>
           </div>
         </div>
       </div>
@@ -125,29 +112,64 @@
 </template>
 
 <script setup>
-import { reactive, ref, toRefs, onBeforeMount, onMounted, defineEmits } from 'vue';
-import { router } from '@/router';
+import { reactive, ref, toRefs, onBeforeMount, onMounted, defineEmits } from "vue";
+import { router } from "@/router";
+
+import { tables } from "@/store/tables";
+import { tablesInfo, setData } from "./data";
+const props = defineProps({
+  downMode: { type: Boolean, default: false },
+  isDownloadShow: { type: Boolean, default: false },
+});
+const data = ref(null);
+
 const checkOptions = (item, index) => {
   item.check = item.options[index].id;
+  data.value[item.type].check = item.check;
 };
 const topList = ref({
   check: 0,
+  type: "optionsOne",
   options: [
     {
       id: 1,
-      title: '财产损失事故',
+      title: "财产损失事故",
     },
     {
       id: 2,
-      title: '受伤当事人伤势轻微,各方当事人一致同意适用简易程序处理',
+      title: "受伤当事人伤势轻微,各方当事人一致同意适用简易程序处理",
     },
   ],
 });
+
+
+const saveHandler = () => {
+  return { type: "identification", data: data.value };
+};
+
+defineExpose({ saveHandler, data });
 onMounted(() => {
+  if (props.isDownloadShow) {
+  } else {
+    setData("identification");
+  }
 
+  if (tablesInfo.identification) {
+    data.value = tablesInfo.identification;
+  }
 });
 </script>
 <style lang="scss" scoped>
+.content-box {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  &.left {
+    justify-content: flex-start;
+  }
+}
 div[contenteditable] {
   outline: none;
 }
@@ -158,6 +180,17 @@ div[contenteditable] {
   height: 100%;
   font-family: sr, st;
   overflow: auto;
+  .content-box {
+    display: none;
+  }
+  &.downMode {
+    input {
+      display: none;
+    }
+    .content-box {
+      display: flex;
+    }
+  }
   .title {
     text-align: center;
     margin-bottom: 10px;
@@ -167,13 +200,26 @@ div[contenteditable] {
     align-items: center;
     justify-content: center;
     > div {
-      padding: 0 30px;
+      // padding: 0 30px;
+      min-width: 60px;
+      input {
+        width: 60px;
+        height: 100%;
+        text-align: center;
+      }
+      .content-box {
+      }
     }
   }
   .table-layout {
     border: 1px solid #000;
     .input-box {
       padding: 0 10px;
+      height: 100%;
+      input {
+        width: 100%;
+        height: 100%;
+      }
     }
     .msg-box {
       border-bottom: 1px solid #000;
@@ -218,8 +264,13 @@ div[contenteditable] {
           border-right: none;
         }
         > div {
-          outline: none;
-          word-break: break-all;
+          // outline: none;
+          // word-break: break-all;
+          input {
+            width: 100%;
+            height: 100%;
+            text-align: center;
+          }
         }
       }
     }

+ 68 - 8
src/views/tables/index.vue

@@ -3,7 +3,8 @@
   <MainPanel>
     <template v-slot:header>
       <Header :title="headerTitle" :on-back="onBack" type="return">
-        <ui-button v-if="tableType != 'law'" type="primary" width="96px" @click="saveHandler"> {{ isWrite ? "确定" : "完成" }} </ui-button>
+        <ui-button v-if="!isWrite" style="margin-right: 16px" class="download-btn" type="null" width="96px" @click="downloadHandler"> 下载 </ui-button>
+        <ui-button v-if="tableType != 'law'" type="primary" width="96px" @click="saveHandler"> {{ isWrite ? "确定" : "保存" }} </ui-button>
       </Header>
     </template>
 
@@ -11,11 +12,21 @@
       <div class="swiper-wrapper">
         <div class="swiper-slide tables-item" :class="{ show: downMode }" v-for="(i, index) in eleList">
           <div class="warpper" :class="{ downMode, 'no-padding': tableType == 'law' }" :id="`layoutRef${index}`">
-            <component :page="askPage" :pageIndex="index" :text="text" @onTextChange="onTextChange" @onTextConfirm="onTextConfirm" @goWrite="goWrite" :downMode="downMode" :is="i"></component>
+            <component
+              ref="content"
+              :page="askPage"
+              :pageIndex="index"
+              :text="text"
+              @onTextChange="onTextChange"
+              @onTextConfirm="onTextConfirm"
+              @goWrite="goWrite"
+              :downMode="downMode"
+              :is="i"
+            ></component>
           </div>
 
           <div class="warpper" v-if="downMode" :class="{ show: downMode, 'no-padding': tableType == 'law' }">
-            <component :page="askPage" :pageIndex="index" :text="text" @onTextChange="onTextChange" @onTextConfirm="onTextConfirm" @goWrite="goWrite" :is="i"></component>
+            <component :isDownloadShow="true" :page="askPage" :pageIndex="index" :text="text" @onTextChange="onTextChange" @onTextConfirm="onTextConfirm" @goWrite="goWrite" :is="i"></component>
           </div>
         </div>
       </div>
@@ -25,12 +36,15 @@
 </template>
 
 <script setup lang="ts">
-import { reactive, ref, watch, onMounted, nextTick, onActivated, onDeactivated } from "vue";
+import { reactive, ref, watch, onMounted, nextTick, onActivated, onDeactivated, provide } from "vue";
 import { router } from "@/router";
 import Swiper from "swiper";
 import html2canvas from "html2canvas";
 import { downloadImage, uploadImage } from "@/store/sync";
 import { genUseLoading } from "@/hook";
+import { tables } from "@/store/tables";
+import { resetData } from "./data";
+
 import Write from "./write/index.vue";
 import Message from "@/components/base/components/message/message.vue";
 import Header from "@/components/photos/header.vue";
@@ -39,7 +53,6 @@ import one from "./explorate-one.vue";
 import two from "./explorate-two.vue";
 import three from "./explorate-three.vue";
 import four from "./explorate-four.vue";
-
 import identification from "./identification.vue";
 
 //授权委托书
@@ -60,6 +73,7 @@ import law from "./law.vue";
 // const eleList = ref([one, two, three, four]);
 // const eleList = ref([authorOne, authorTwo]);
 const com = ref(null); // 通过 模板ref 绑定子组件
+const content = ref(null); // 通过 模板ref 绑定子组件
 const eleList = ref([]);
 const headerTitle = ref("");
 const tableType = ref<string | string[]>();
@@ -94,15 +108,42 @@ const onTextConfirm = (data) => {
 const onTextChange = (data) => {
   text.value = data.text;
 };
-
+const downloadHandler = genUseLoading(async () => {
+  // if (isWrite.value) {
+  //   com.value.onConfirm();
+  //   return;
+  // }
+  await getLayoutImage();
+});
 const saveHandler = genUseLoading(async () => {
   if (isWrite.value) {
     com.value.onConfirm();
     return;
   }
-  await getLayoutImage();
 
+  saveStore();
+  router.replace("/scene");
 });
+
+const saveStore = () => {
+  let reportData = initData();
+  console.error(reportData);
+  const origin = tables.value;
+  let newData = Object.assign(origin, reportData);
+};
+const initData = () => {
+  let dataList = content.value;
+
+  let obj = {};
+  dataList.forEach((item) => {
+    if (item.saveHandler) {
+      let data = item.saveHandler();
+
+      obj[data.type] = data.data;
+    }
+  });
+  return obj;
+};
 let slideIndex = 0;
 const slideFunc = () => {
   let eles = document.querySelectorAll(".tables-item");
@@ -144,7 +185,7 @@ const getLayoutImage = async () => {
 
       if (num == eleList.value.length) {
         downMode.value = false;
-        router.replace('/scene');
+        // router.replace("/scene");
         res(true);
       }
     });
@@ -163,10 +204,21 @@ const initTables = () => {
       eleList.value = [ask];
       if (router.currentRoute.value.query.type == "1") {
         headerTitle.value = "询问笔录";
+        if (tables.value.askOne) {
+          text.value = tables.value.askOne.text;
+          askPage.value = tables.value.askOne.page;
+        }
       } else {
         headerTitle.value = "讯问笔录";
+        if (tables.value.askTwo) {
+          text.value = tables.value.askTwo.text;
+          askPage.value = tables.value.askTwo.page;
+        }
       }
 
+      isWrite.value = false;
+      setAskPage();
+
       break;
     case "author":
       eleList.value = [authorOne, authorTwo];
@@ -239,9 +291,17 @@ onDeactivated(() => {
   isWrite.value = false;
   text.value = "";
   loaded.value = false;
+
+  resetData();
 });
 </script>
+<style></style>
 <style lang="scss" scoped>
+.download-btn {
+  border-color: #3a3d3d;
+  background-color: #3a3d3d !important;
+  color: #fff;
+}
 .mySwiper {
   height: 100%;
   width: 100%;

+ 107 - 113
src/views/tables/legacy.vue

@@ -1,6 +1,6 @@
 <!--  -->
 <template>
-  <div class="legacy">
+  <div class="legacy" :class="{ downMode }" v-if="data">
     <h2 class="title">道路交通事故现场遗留物品清单</h2>
     <table>
       <tr>
@@ -8,7 +8,8 @@
           <div style="display: flex; align-items: center; justify-content: flex-start; height: 100%">
             <span style="height: 100%; line-height: 60px">事故时间:</span>
             <div style="height: 100%; flex: 1" class="input-box">
-              <input type="text" style="width: 100%; height: 100%" />
+              <div class="content-box">{{ data.accidentTime }}</div>
+              <input type="text" style="width: 100%; height: 100%" v-model="data.accidentTime" />
             </div>
           </div>
         </td>
@@ -19,7 +20,8 @@
           <div style="display: flex; align-items: center; justify-content: flex-start; height: 100%">
             <span style="height: 100%; line-height: 60px">事故地点:</span>
             <div style="height: 100%; flex: 1" class="input-box">
-              <input type="text" style="width: 100%; height: 100%" />
+              <div class="content-box">{{ data.accidentAddress }}</div>
+              <input type="text" style="width: 100%; height: 100%" v-model="data.accidentAddress" />
             </div>
           </div>
         </td>
@@ -33,132 +35,104 @@
         <td>领取时间</td>
         <td>备注</td>
       </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-      </tr>
-      <tr>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
-        <td><div contenteditable></div></td>
+      <tr v-for="(i, index) in data.list">
+        <td v-for="(j, j_index) in i">
+          <div>
+            <div class="content-box">{{ data.list[index][j_index] }}</div>
+            <input type="text" v-model="data.list[index][j_index]" />
+          </div>
+          <!-- <div v-else contenteditable v-html="j"></div> -->
+          <!-- <div contenteditable v-html="j" @input="handlerInput($event, index, j_index)"></div> -->
+        </td>
       </tr>
     </table>
     <div class="sign-box">
       <div>
         <span>当事人签名:</span>
-        <div contenteditable></div>
+        <div>
+          <input type="text" v-model="data.partySign" />
+          <div class="content-box left">{{ data.partySign }}</div>
+        </div>
       </div>
       <div>
         <span>交通警察(签名):</span>
-        <div contenteditable></div>
+        <div>
+          <input type="text" v-model="data.policeSign" />
+          <div class="content-box left">{{ data.policeSign }}</div>
+        </div>
       </div>
     </div>
   </div>
 </template>
 
 <script setup>
-import { reactive, ref, toRefs, onBeforeMount, onMounted } from 'vue';
+import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick, defineProps } from "vue";
+import { genUseLoading } from "@/hook";
+import UiInput from "@/components/base/components/input/index.vue";
+import { tables } from "@/store/tables";
+import { tablesInfo, setData } from "./data";
+const props = defineProps({
+  downMode: { type: Boolean, default: false },
+  isDownloadShow: { type: Boolean, default: false },
+});
+const data = ref(null);
+// const data = ref({
+//   accidentTime: "",
+//   accidentAddress: "",
+//   partySign: "",
+//   policeSign: "",
+//   list: [
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//     ["", "", "", "", "", "", ""],
+//   ],
+// });
+const handlerInput = (e, index, j_index) => {
+  data.value.list[index][j_index] = e.target.innerText;
+};
+
+const saveHandler = async () => {
+  await saveStore();
+};
+const saveStore = genUseLoading(async () => {
+  // return new Promise((res, rej) => {
+  const origin = tables.value;
+  console.log(data.value);
+  origin["legacy"] = JSON.parse(JSON.stringify(data.value));
+  // });
+});
+defineExpose({ saveHandler, data });
+onMounted(() => {
+  if (props.isDownloadShow) {
+  } else {
+    setData("legacy");
+  }
+
+  if (tablesInfo.legacy) {
+    data.value = tablesInfo.legacy;
+  }
+});
 </script>
 <style lang="scss" scoped>
+.content-box {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  &.left {
+    justify-content: flex-start;
+  }
+}
 div[contenteditable] {
   outline: none;
 }
@@ -168,6 +142,17 @@ div[contenteditable] {
   width: 100%;
   height: 100%;
   font-family: sr, st;
+  .content-box {
+    display: none;
+  }
+  &.downMode {
+    input {
+      display: none;
+    }
+    .content-box {
+      display: flex;
+    }
+  }
   .title {
     text-align: center;
     margin-bottom: 10px;
@@ -203,6 +188,15 @@ div[contenteditable] {
         &:last-of-type {
           border-right: none;
         }
+        div {
+          width: 100%;
+          height: 100%;
+          input {
+            width: 100%;
+            height: 100%;
+            text-align: center;
+          }
+        }
         > div[contenteditable] {
           width: 100%;
           height: 100%;

+ 21 - 20
src/views/tables/write/index.vue

@@ -15,24 +15,24 @@
 </template>
 
 <script setup>
-import { reactive, ref, toRefs, onBeforeMount, computed, onMounted, nextTick, defineEmits, defineProps } from 'vue';
+import { reactive, ref, toRefs, onBeforeMount, computed, onMounted, nextTick, defineEmits, defineProps } from "vue";
 
 const props = defineProps({
   text: {
     type: String,
-    default: '',
+    default: "",
   },
   textIndex: {
     type: Number,
     default: 0,
   },
 });
-const emits = defineEmits(['onTextConfirm', 'onTextChange']);
-const inputText = ref('');
+const emits = defineEmits(["onTextConfirm", "onTextChange"]);
+const inputText = ref("");
 const lineCount = ref(1);
 const inputHeight = ref(0);
 const getLineCount = () => {
-  let containerH = document.getElementById('container').clientHeight;
+  let containerH = document.getElementById("container").clientHeight;
   let count = Math.floor(containerH / 40);
   lineCount.value = count;
   inputHeight.value = count * 40;
@@ -46,15 +46,16 @@ const onConfirm = () => {
   } else {
     page = page + Math.ceil((msgHeight.value - 400) / 1080);
   }
-  emits('onTextConfirm', { text: inputText.value, msgHeight: msgHeight.value, page });
+  emits("onTextConfirm", { text: inputText.value, msgHeight: msgHeight.value, page });
 };
-defineExpose({ onConfirm });
 const msgHeight = ref(40);
+defineExpose({ onConfirm });
+
 const hanlderWrite = (e) => {
-  let msgH = document.getElementById('msg').clientHeight;
+  let msgH = document.getElementById("msg").clientHeight;
   msgHeight.value = msgH;
   let msgCount = Math.floor(msgH / 40);
-  let containerH = document.getElementById('container').clientHeight;
+  let containerH = document.getElementById("container").clientHeight;
   let containerCount = Math.floor(containerH / 40);
   // text.value = e.target.innerHTML;
   if (msgCount > containerCount) {
@@ -67,7 +68,7 @@ const hanlderWrite = (e) => {
     lineCount.value = containerCount;
   }
 
-  emits('onTextChange', { text: inputText.value });
+  emits("onTextChange", { text: inputText.value });
 
   // textAreaHeight.value = msgH;
 };
@@ -75,12 +76,12 @@ const onPaste = (e) => {
   setTimeout(() => {
     // let msgH = document.getElementById('msg').clientHeight;
     hanlderWrite(e);
-    let content = document.getElementById('content');
+    let content = document.getElementById("content");
     content.scrollTo(0, 9999999);
   }, 100);
 };
 const setFocusAt = (focusIndex) => {
-  let txtarea = document.getElementById('write-info');
+  let txtarea = document.getElementById("write-info");
   setCaretPosition(txtarea, focusIndex);
 };
 
@@ -92,8 +93,8 @@ const setCaretPosition = (ctrl, pos) => {
   } else if (ctrl.createTextRange) {
     var range = ctrl.createTextRange();
     range.collapse(true);
-    range.moveEnd('character', pos);
-    range.moveStart('character', pos);
+    range.moveEnd("character", pos);
+    range.moveStart("character", pos);
     range.select();
   }
 
@@ -105,7 +106,7 @@ const setCaretPosition = (ctrl, pos) => {
 // 获取 textarea 元素
 
 const getSelectionDistance = () => {
-  var textarea = document.getElementById('write-info'); 
+  var textarea = document.getElementById("write-info");
   // // 获取 textarea 的样式属性
   var textareaStyle = getComputedStyle(textarea);
   // // 计算光标位置距离顶部的距离
@@ -115,7 +116,7 @@ const getSelectionDistance = () => {
   // 获取 textarea 内容
   var textareaValue = textarea.value;
   // 将内容分割成行
-  var lines = textareaValue.split('\n');
+  var lines = textareaValue.split("\n");
   // 计算光标所在的行数1
   var cursorLine = 1; // 初始化行数为1
   for (var i = 0; i < lines.length; i++) {
@@ -125,11 +126,11 @@ const getSelectionDistance = () => {
     cursorPosition -= lines[i].length + 1; // 加1是为了包括换行符
     cursorLine++;
   }
-  let scrollBox = document.getElementById('content');
+  let scrollBox = document.getElementById("content");
   let scrollHeight = cursorLine * lineHeight;
   let scrollBoxHeight = scrollBox.offsetHeight;
   if (scrollHeight > scrollBoxHeight) {
-    console.log('光标所在的行数:', cursorLine);
+    console.log("光标所在的行数:", cursorLine);
     scrollBox.scrollTo(0, scrollHeight - scrollBoxHeight);
   }
 };
@@ -147,8 +148,8 @@ onMounted(async () => {
     }
   }, 0);
   nextTick(() => {
-    let scrollBox = document.getElementById('content');
-    scrollBox.addEventListener('scroll', (data) => {
+    let scrollBox = document.getElementById("content");
+    scrollBox.addEventListener("scroll", (data) => {
       // console.error(data);
     });
   });