Переглянути джерело

隔离点布局按照单元格位置布局

pm 1 рік тому
батько
коміт
ee694b243a
2 змінених файлів з 330 додано та 171 видалено
  1. 293 130
      src/views/mes/sop/sopm/IsolationLeft.vue
  2. 37 41
      src/views/mes/sop/sopm/NewSop.vue

+ 293 - 130
src/views/mes/sop/sopm/IsolationLeft.vue

@@ -3,29 +3,187 @@
 </template>
 
 <script>
-import Konva from "konva";
+import Konva from 'konva'
 
 export default {
-  name: "KonvaExample",
+  name: 'KonvaExample',
   data() {
     return {
       stage: null,
       layer: null,
-      isSelected: true, //判断是否选中隔离点
-      selectedStates: {}, // 存储每个图片的选中状态
-    };
+      selectedStates: [], // 用于存储每个元素的选中状态
+      selectedText: [] // 用于存储未选中的元素文本
+    }
   },
   mounted() {
-    this.initKonva();
+    this.initKonva()
   },
   methods: {
+    // initKonva() {
+    //   // 创建舞台
+    //   this.stage = new Konva.Stage({
+    //     container: this.$refs.container, // 容器元素
+    //     width: 1250,
+    //     height: 830,
+    //     fill: 'black'
+    //   })
+    //
+    //   // 创建图层
+    //   this.layer = new Konva.Layer()
+    //
+    //   // 创建底图
+    //   const bgImage = new Image()
+    //   bgImage.src = require('@/assets/images/table.png')
+    //   bgImage.onload = () => {
+    //     const KnovaImage = new Konva.Image({
+    //       x: 350,
+    //       y: 10,
+    //       image: bgImage,
+    //       width: 500,
+    //       height: 790,
+    //       draggable: false
+    //     })
+    //     this.layer.add(KnovaImage)
+    //
+    //     this.layer.draw()
+    //   }
+    //   // 调用函数
+    //   const imageSrc = require('@/assets/images/localSetIcon.jpg'); // 图片路径
+    //
+    //   this.renderGrid(imageSrc, 6, 3, 450, 100, 120, 100, 50, 50, 60, 25);
+    //   // 将图层添加到舞台
+    //   this.stage.add(this.layer)
+    //   this.layer.draw()
+    //
+    //   // 添加鼠标滚轮缩放功能
+    //   this.stage.on('wheel', (e) => {
+    //     e.evt.preventDefault()
+    //
+    //     const scaleBy = 1.05 // 缩放因子
+    //     const oldScale = this.stage.scaleX() // 获取当前缩放比例
+    //     const pointer = this.stage.getPointerPosition() // 获取鼠标位置
+    //
+    //     const mousePointTo = {
+    //       x: (pointer.x - this.stage.x()) / oldScale,
+    //       y: (pointer.y - this.stage.y()) / oldScale
+    //     }
+    //
+    //     // 根据滚轮滚动的方向决定缩放
+    //     const newScale = e.evt.deltaY > 0 ? oldScale / scaleBy : oldScale * scaleBy
+    //
+    //     this.stage.scale({ x: newScale, y: newScale })
+    //
+    //     const newPos = {
+    //       x: pointer.x - mousePointTo.x * newScale,
+    //       y: pointer.y - mousePointTo.y * newScale
+    //     }
+    //     this.stage.position(newPos)
+    //     this.stage.batchDraw()
+    //   })
+    //
+    //   this.stage.on('mousedown', function() {
+    //     this.stage.container().style.cursor = 'move'
+    //   }.bind(this))
+    //
+    //   this.stage.on('mouseup', function() {
+    //     this.stage.container().style.cursor = 'default'
+    //   }.bind(this))
+    //   this.stage.draggable(true)
+    // },
+    // renderGrid(imageSrc, rows, cols, startX, startY, xOffset, yOffset, imageWidth, imageHeight, rectWidth, rectHeight) {
+    //   // 初始化状态数组
+    //   this.selectedStates = new Array(rows * cols).fill(false);
+    //
+    //   for (let row = 0; row < rows; row++) {
+    //     for (let col = 0; col < cols; col++) {
+    //       const x = startX + col * xOffset;
+    //       const y = startY + row * yOffset;
+    //       const index = row * cols + col;
+    //
+    //       const point = new Image();
+    //       point.src = imageSrc;
+    //       point.onload = () => {
+    //         const knovaImage = new Konva.Image({
+    //           x: x,
+    //           y: y,
+    //           image: point,
+    //           width: imageWidth,
+    //           height: imageHeight,
+    //           draggable: false,
+    //         });
+    //
+    //         knovaImage.on('click', () => {
+    //           // 切换选中状态
+    //           this.selectedStates[index] = !this.selectedStates[index];
+    //
+    //           // 更新 selectedText 数组
+    //           if (this.selectedStates[index]) {
+    //             // 元素被选中,替换成选中的图片
+    //             point.src = require('@/assets/images/localSetSelect.jpg');
+    //
+    //             // 检查是否已经在 selectedText 数组中
+    //             if (!this.selectedText.some(item => item.value === index + 1)) {
+    //               // 元素被选中,添加到 selectedText 数组
+    //               this.selectedText.push({
+    //                 label: `E-${index + 1}`,
+    //                 value: index + 1
+    //               });
+    //             }
+    //           } else {
+    //             // 元素未选中,恢复原图片
+    //             point.src = imageSrc;
+    //
+    //             // 元素未选中,从 selectedText 数组中移除
+    //             const textIndex = this.selectedText.findIndex(item => item.value === index + 1);
+    //             if (textIndex !== -1) {
+    //               this.selectedText.splice(textIndex, 1); // 如果元素在 selectedText 中,移除它
+    //             }
+    //           }
+    //
+    //           knovaImage.image(point); // 更新图片
+    //           this.layer.draw(); // 重绘图层
+    //
+    //           // console.log(this.selectedText, '子组件选中的隔离点');
+    //
+    //           // 传递选中的元素文本到父组件
+    //           this.$emit('selection-changed', this.selectedText);
+    //         });
+    //
+    //         this.layer.add(knovaImage);
+    //
+    //         const rect = new Konva.Rect({
+    //           x: x - 3,
+    //           y: y + imageHeight + 10,
+    //           width: rectWidth,
+    //           height: rectHeight,
+    //           cornerRadius: 10,
+    //           stroke: 'red',
+    //           strokeWidth: 2,
+    //           fill: 'white',
+    //         });
+    //         this.layer.add(rect);
+    //
+    //         const text = new Konva.Text({
+    //           x: x + 12,
+    //           y: y + imageHeight + 15,
+    //           fontSize: 20,
+    //           text: `E-${index + 1}`,
+    //           fontFamily: 'Calibri',
+    //           fill: 'red',
+    //         });
+    //         this.layer.add(text);
+    //
+    //         this.layer.draw();
+    //       };
+    //     }
+    //   }
+    // }
     initKonva() {
       // 创建舞台
       this.stage = new Konva.Stage({
         container: this.$refs.container, // 容器元素
-        width: 1250,
-        height:800,
-        fill: "black",
+        width: 1270,
+        height: 830,
       });
 
       // 创建图层
@@ -33,156 +191,161 @@ export default {
 
       // 创建底图
       const bgImage = new Image();
-      bgImage.src = require("@/assets/images/table.png");
+      bgImage.src = require('@/assets/images/table.png');
       bgImage.onload = () => {
-        const KnovaImage = new Konva.Image({
-          x: 350,
+        const knovaImage = new Konva.Image({
+          x: 330,
           y: 10,
           image: bgImage,
           width: 500,
-          height: 800,
+          height: 790,
           draggable: false,
         });
-        this.layer.add(KnovaImage);
-
+        this.layer.add(knovaImage);
         this.layer.draw();
       };
-      // 调用函数
-      const imageSrc = require("@/assets/images/localSetIcon.jpg"); // 图片路径
 
+      // 绘制无限网格
+      this.drawGrid(50, 50, '#e0e0e0'); // 每个单元格50x50,浅灰色网格
+
+      // 渲染数据
+      const imageSrc = require('@/assets/images/localSetIcon.jpg'); // 图片路径
       this.renderGrid(imageSrc, 6, 3, 450, 100, 120, 100, 50, 50, 60, 25);
+
       // 将图层添加到舞台
       this.stage.add(this.layer);
       this.layer.draw();
 
-      // 添加鼠标滚轮缩放功能
-      this.stage.on("wheel", (e) => {
-        e.evt.preventDefault();
+      // 禁止舞台拖拽
+      this.stage.draggable(false);
+    },
+
+// 绘制无限网格
+    drawGrid(cellWidth, cellHeight, gridColor) {
+      const width = 1270;
+      const height = 830;
 
-        const scaleBy = 1.05; // 缩放因子
-        const oldScale = this.stage.scaleX(); // 获取当前缩放比例
-        const pointer = this.stage.getPointerPosition(); // 获取鼠标位置
+      // 绘制竖线
+      for (let i = 0; i <= width; i += cellWidth) {
+        const verticalLine = new Konva.Line({
+          points: [i, 0, i, height],
+          stroke: gridColor,
+          strokeWidth: 1,
+        });
+        this.layer.add(verticalLine);
+      }
 
-        const mousePointTo = {
-          x: (pointer.x - this.stage.x()) / oldScale,
-          y: (pointer.y - this.stage.y()) / oldScale,
-        };
+      // 绘制横线
+      for (let j = 0; j <= height; j += cellHeight) {
+        const horizontalLine = new Konva.Line({
+          points: [0, j, width, j],
+          stroke: gridColor,
+          strokeWidth: 1,
+        });
+        this.layer.add(horizontalLine);
+      }
+
+      this.layer.draw();
+    },
+    renderGrid(imageSrc) {
+      this.selectedStates = [];
 
-        // 根据滚轮滚动的方向决定缩放
-        const newScale =
-          e.evt.deltaY > 0 ? oldScale / scaleBy : oldScale * scaleBy;
+      const positions = [
+        { row: 2, col: 9 }, // E-1
+        { row: 2, col: 11 }, // E-2
+        { row: 2, col: 13 }, // E-3
+        { row: 4, col: 9 }, // E-4
+        { row: 4, col: 11 }, // E-5
+        { row: 4, col: 13 },  // E-6
+        { row: 6, col: 9 }, // E-7
+        { row: 6, col: 11 }, // E-8
+        { row: 6, col: 13 }, // E-9
+        { row: 8, col: 9 }, // E-10
+        { row: 8, col: 11 }, // E-11
+        { row: 8, col: 13 },  // E-12
+        { row: 10, col: 9 }, // E-13
+        { row: 10, col: 11 }, // E-14
+        { row: 10, col: 13 }, // E-15
+        { row: 12, col: 9 }, // E-16
+        { row: 12, col: 11 }, // E-17
+        { row: 12, col: 13 },  // E-18
+      ];
 
-        this.stage.scale({ x: newScale, y: newScale });
+      positions.forEach((pos, index) => {
+        const x = pos.col * 50; // 每个单元格宽度为50
+        const y = pos.row * 50; // 每个单元格高度为50
 
-        const newPos = {
-          x: pointer.x - mousePointTo.x * newScale,
-          y: pointer.y - mousePointTo.y * newScale,
-        };
-        this.stage.position(newPos);
-        this.stage.batchDraw();
-      });
+        const point = new Image();
+        point.src = imageSrc;
+        point.onload = () => {
+          const knovaImage = new Konva.Image({
+            x: x,
+            y: y,
+            image: point,
+            width: 50,
+            height: 50,
+            draggable: false,
+          });
 
-      this.stage.on(
-        "mousedown",
-        function () {
-          this.stage.container().style.cursor = "move";
-        }.bind(this)
-      );
-
-      this.stage.on(
-        "mouseup",
-        function () {
-          this.stage.container().style.cursor = "default";
-        }.bind(this)
-      );
-      this.stage.draggable(true);
-    },
-    renderGrid(
-      imageSrc,
-      rows,
-      cols,
-      startX,
-      startY,
-      xOffset,
-      yOffset,
-      imageWidth,
-      imageHeight,
-      rectWidth,
-      rectHeight
-    ) {
-      for (let row = 0; row < rows; row++) {
-        for (let col = 0; col < cols; col++) {
-          const x = startX + col * xOffset; // 每个图片的 x 轴位置
-          const y = startY + row * yOffset; // 每个图片的 y 轴位置
-          const index = row * cols + col + 1; // 唯一标识的编号
-
-          const point = new Image();
-          point.src = imageSrc;
-          point.onload = () => {
-            // 创建图片
-            const knovaImage = new Konva.Image({
-              x: x,
-              y: y,
-              image: point,
-              width: imageWidth,
-              height: imageHeight,
-              draggable: false,
-            });
-            // 状态变量用于追踪当前图片
-            // 点击事件
-            knovaImage.on("click", () => {
-              console.log(this.isSelected, "isSelected");
-              if (this.isSelected) {
-                point.src = require("@/assets/images/localSetSelect.jpg"); // 替换成选中的图片
-              } else {
-                point.src = imageSrc; // 恢复成原来的图片
-              }
-              this.isSelected = !this.isSelected; // 切换状态
-              knovaImage.image(point); // 更新图片
-              this.layer.draw(); // 重绘图层
-            });
-            this.layer.add(knovaImage);
-
-            // 创建矩形框
-            const rect = new Konva.Rect({
-              x: x - 3,
-              y: y + imageHeight + 10, // 矩形在图片下方
-              width: rectWidth,
-              height: rectHeight,
-              cornerRadius: 10,
-              stroke: "red",
-              strokeWidth: 2,
-              fill: "white",
-            });
-            this.layer.add(rect);
-
-            // 创建文本
-            const text = new Konva.Text({
-              x: x + 12, // 调整文本在矩形内的位置
-              y: y + imageHeight + 15, // 在矩形内部居中显示
-              fontSize: 20,
-              text: `E-${index}`,
-              fontFamily: "Calibri",
-              fill: "red",
-            });
-            this.layer.add(text);
-
-            // 渲染图层
+          knovaImage.on('click', () => {
+            this.selectedStates[index] = !this.selectedStates[index];
+
+            if (this.selectedStates[index]) {
+              point.src = require('@/assets/images/localSetSelect.jpg');
+              this.selectedText.push({ label: `E-${index + 1}`, value: index + 1 });
+            } else {
+              point.src = imageSrc;
+              this.selectedText = this.selectedText.filter(item => item.value !== index + 1);
+            }
+
+            knovaImage.image(point);
             this.layer.draw();
-          };
-        }
-      }
+
+            // 传递选中的元素文本到父组件
+            this.$emit('selection-changed', this.selectedText);
+          });
+
+          this.layer.add(knovaImage);
+
+          const rect = new Konva.Rect({
+            x: x - 3,
+            y: y + 55,
+            width: 60,
+            height: 25,
+            cornerRadius: 10,
+            stroke: 'red',
+            strokeWidth: 2,
+            fill: 'white',
+          });
+          this.layer.add(rect);
+
+          const text = new Konva.Text({
+            x: x + 12,
+            y: y + 60,
+            fontSize: 20,
+            text: `E-${index + 1}`,
+            fontFamily: 'Calibri',
+            fill: 'red',
+          });
+          this.layer.add(text);
+
+          this.layer.draw();
+        };
+      });
     },
 
+
+
+
     //     methods结束
-  },
-};
+  }
+
+}
 </script>
 
 <style scoped lang="scss">
 #container {
   width: 100%;
   height: 100%;
-  //   background: #000;
 }
 </style>

+ 37 - 41
src/views/mes/sop/sopm/NewSop.vue

@@ -4,7 +4,7 @@
     <div class="left">
       <!-- <h1>我是左边</h1> -->
       <SopLeft v-if="this.activeName == 'first'" />
-      <IsolationLeftVue v-else />
+      <IsolationLeftVue v-else @selection-changed="handleSelectPoint"/>
     </div>
     <div class="right">
       <div class="right_top">
@@ -182,7 +182,6 @@ export default {
   data() {
     return {
       activeName: "first",
-
       form: {
         sopName: "",
         sopId: "",
@@ -191,6 +190,7 @@ export default {
         workline: "", //产线
         spoint: [], //已选隔离点
       },
+
       pickerOptions: {
         shortcuts: [
           {
@@ -224,44 +224,7 @@ export default {
         { label: "保养", value: 3 },
       ],
       // 右侧底部已选隔离点
-      tableData: [
-        {
-          id: 1,
-          point: "E-1",
-          isolation: "挂锁",
-          type: "电能",
-        },
-        {
-          id: 2,
-          point: "E-2",
-          isolation: "挂锁",
-          type: "电能",
-        },
-        {
-          id: 3,
-          point: "E-3",
-          isolation: "挂锁",
-          type: "电能",
-        },
-        {
-          id: 4,
-          point: "E-4",
-          isolation: "挂锁",
-          type: "电能",
-        },
-        {
-          id: 5,
-          point: "E-5",
-          isolation: "挂锁",
-          type: "电能",
-        },
-        {
-          id: 6,
-          point: "E-6",
-          isolation: "挂锁",
-          type: "电能",
-        },
-      ],
+      tableData: [],
     };
   },
   methods: {
@@ -275,6 +238,39 @@ export default {
       this.activeName = "second";
       console.log("我点击了下一步");
     },
+    // 子组件逆向传递选中的隔离点
+    // 子组件逆向传递选中的隔离点
+    handleSelectPoint(points) {
+      console.log(points, '逆向传递选中的隔离点');
+
+      // 使用 Set 来存储传递过来的点值
+      const newValues = new Set(points.map(point => point.value));
+
+      // 1. 删除取消选中的点
+      this.tableData = this.tableData.filter(item => newValues.has(item.id));
+
+      // 2. 确保新增点不会重复
+      const existingValues = new Set(this.tableData.map(item => item.id));
+
+      points.forEach(point => {
+        // 如果当前传递的点不在已有的点集中,则添加
+        if (!existingValues.has(point.value)) {
+          this.tableData.push({
+            point: point.label,  // 显示的名称
+            id: point.value,     // 对应的值
+            isolation: "挂锁",
+            type: "电能",
+          });
+          // 将新点值添加到 Set 中
+          existingValues.add(point.value);
+        }
+      });
+
+      // 更新 form.spoint 为最新选中的隔离点数组
+      this.form.spoint = points.map(point => point.value);
+    }
+
+    //   methods结束
   },
 };
 </script>
@@ -291,7 +287,7 @@ export default {
   .left {
     width: 75%;
     height: 830px;
-    // background: #eee;
+     background: #eee;
     margin-right: 10px;
   }
   .right {