|
@@ -0,0 +1,345 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div id="container" ref="container"></div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script>
|
|
|
|
|
+import Konva from "konva";
|
|
|
|
|
+import { selectIsIsolationPointById,getIsIsolationPointPage } from "@/api/mes/spm/segregationPoint";
|
|
|
|
|
+import { mapGetters } from "vuex";
|
|
|
|
|
+
|
|
|
|
|
+export default {
|
|
|
|
|
+ name: "KonvaExample",
|
|
|
|
|
+ // props: {
|
|
|
|
|
+ // points: {
|
|
|
|
|
+ // type: Object,
|
|
|
|
|
+ // default: null,
|
|
|
|
|
+ // },
|
|
|
|
|
+ // },
|
|
|
|
|
+ data() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ stage: null,
|
|
|
|
|
+ layer: null,
|
|
|
|
|
+ selectedStates: [], // 用于存储每个元素的选中状态
|
|
|
|
|
+ selectedText: [], // 用于存储未选中的元素文本
|
|
|
|
|
+ rects: [], //白色rect合集
|
|
|
|
|
+ texts: [], //白色text合集
|
|
|
|
|
+ redrects: [], //红色rect合集
|
|
|
|
|
+ redtexts: [], //白色text合集
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ mounted() {
|
|
|
|
|
+ this.initKonva();
|
|
|
|
|
+ console.log(this.points, "points");
|
|
|
|
|
+ console.log(
|
|
|
|
|
+ this.getSelectSopPoints,
|
|
|
|
|
+ this.getSopEdit,
|
|
|
|
|
+ "getSopEdit - getSelectSopPoints"
|
|
|
|
|
+ );
|
|
|
|
|
+ },
|
|
|
|
|
+ computed: {
|
|
|
|
|
+ ...mapGetters("sopSelectPoints", ["getSelectSopPoints", "getSopEdit"]),
|
|
|
|
|
+ },
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ initKonva() {
|
|
|
|
|
+ // 创建舞台
|
|
|
|
|
+ this.stage = new Konva.Stage({
|
|
|
|
|
+ container: this.$refs.container, // 容器元素
|
|
|
|
|
+ width: 1270,
|
|
|
|
|
+ height: 830,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 创建图层
|
|
|
|
|
+ this.layer = new Konva.Layer();
|
|
|
|
|
+
|
|
|
|
|
+ // 创建底图
|
|
|
|
|
+ const bgImage = new Image();
|
|
|
|
|
+ bgImage.src = require("@/assets/images/table.png");
|
|
|
|
|
+ bgImage.onload = () => {
|
|
|
|
|
+ const knovaImage = new Konva.Image({
|
|
|
|
|
+ x: 330,
|
|
|
|
|
+ y: 10,
|
|
|
|
|
+ image: bgImage,
|
|
|
|
|
+ width: 500,
|
|
|
|
|
+ height: 790,
|
|
|
|
|
+ draggable: false,
|
|
|
|
|
+ });
|
|
|
|
|
+ this.layer.add(knovaImage);
|
|
|
|
|
+ this.layer.draw();
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 绘制无限网格
|
|
|
|
|
+ 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.draggable(false);
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 绘制无限网格
|
|
|
|
|
+ drawGrid(cellWidth, cellHeight, gridColor) {
|
|
|
|
|
+ const width = 1270;
|
|
|
|
|
+ const height = 830;
|
|
|
|
|
+
|
|
|
|
|
+ // 绘制竖线
|
|
|
|
|
+ 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);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 绘制横线
|
|
|
|
|
+ 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 = {}; // 用对象来存储选中状态,键为文字内容
|
|
|
|
|
+ this.rects = {};
|
|
|
|
|
+ this.texts = {};
|
|
|
|
|
+ this.redrects = {};
|
|
|
|
|
+ this.redtexts = {};
|
|
|
|
|
+ this.selectedText = [];
|
|
|
|
|
+
|
|
|
|
|
+ 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
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ positions.forEach((pos, index) => {
|
|
|
|
|
+ const x = pos.col * 50; // 每个单元格宽度为50
|
|
|
|
|
+ const y = pos.row * 50; // 每个单元格高度为50
|
|
|
|
|
+ const labelText = pos.pointName; // 对应的文字
|
|
|
|
|
+
|
|
|
|
|
+ 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,
|
|
|
|
|
+ });
|
|
|
|
|
+ // // 添加点击事件,仅当 getSopEdit 为 true 时才允许点击a
|
|
|
|
|
+ // if (this.getSopEdit == true) {
|
|
|
|
|
+ // knovaImage.on("click", () => {
|
|
|
|
|
+ // // 切换选中状态,基于文本内容
|
|
|
|
|
+ // this.selectedStates[labelText] = !this.selectedStates[labelText];
|
|
|
|
|
+ //
|
|
|
|
|
+ // if (this.selectedStates[labelText]) {
|
|
|
|
|
+ // // 选中状态,显示红色矩形和文字,切换为选中的图片
|
|
|
|
|
+ // this.rects[labelText].visible(false);
|
|
|
|
|
+ // this.texts[labelText].visible(false);
|
|
|
|
|
+ // this.redrects[labelText].visible(true);
|
|
|
|
|
+ // this.redtexts[labelText].visible(true);
|
|
|
|
|
+ //
|
|
|
|
|
+ // const selectedImage = new Image();
|
|
|
|
|
+ // selectedImage.src = require("@/assets/images/localSetSelect.jpg");
|
|
|
|
|
+ // selectedImage.onload = () => {
|
|
|
|
|
+ // knovaImage.image(selectedImage); // 更新图像
|
|
|
|
|
+ // this.layer.draw(); // 更新图层
|
|
|
|
|
+ // };
|
|
|
|
|
+ //
|
|
|
|
|
+ // // 获取隔离点信息,并将选中的 labelText 推入数组
|
|
|
|
|
+ //
|
|
|
|
|
+ // this.$nextTick(() => {
|
|
|
|
|
+ // selectIsIsolationPointById(pos.pointId).then((res) => {
|
|
|
|
|
+ // this.selectedText.push({
|
|
|
|
|
+ // pointName: res.data.pointName,
|
|
|
|
|
+ // pointId: res.data.pointId,
|
|
|
|
|
+ // pointType: res.data.pointType,
|
|
|
|
|
+ // powerType: res.data.powerType,
|
|
|
|
|
+ // });
|
|
|
|
|
+ // console.log(this.selectedText,'$emit');
|
|
|
|
|
+ // this.$emit("selection-changed", this.selectedText);
|
|
|
|
|
+ // });
|
|
|
|
|
+ // });
|
|
|
|
|
+ // } else {
|
|
|
|
|
+ // // 取消选中状态,恢复普通矩形和文字,切换为未选中的图片
|
|
|
|
|
+ // this.rects[labelText].visible(true);
|
|
|
|
|
+ // this.texts[labelText].visible(true);
|
|
|
|
|
+ // this.redrects[labelText].visible(false);
|
|
|
|
|
+ // this.redtexts[labelText].visible(false);
|
|
|
|
|
+ //
|
|
|
|
|
+ // const normalImage = new Image();
|
|
|
|
|
+ // normalImage.src = imageSrc; // 未选中的默认图片路径
|
|
|
|
|
+ // normalImage.onload = () => {
|
|
|
|
|
+ // knovaImage.image(normalImage); // 更新图像
|
|
|
|
|
+ // this.layer.draw(); // 更新图层
|
|
|
|
|
+ // };
|
|
|
|
|
+ //
|
|
|
|
|
+ // // 从选中数组中移除该项
|
|
|
|
|
+ // this.selectedText = this.selectedText.filter(
|
|
|
|
|
+ // (item) => item.pointName !== labelText
|
|
|
|
|
+ // );
|
|
|
|
|
+ // }
|
|
|
|
|
+ //
|
|
|
|
|
+ // // 确保图层重新渲染
|
|
|
|
|
+ // 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);
|
|
|
|
|
+ this.rects[labelText] = rect; // 用文字作为键存储
|
|
|
|
|
+
|
|
|
|
|
+ // 普通文字
|
|
|
|
|
+ const text = new Konva.Text({
|
|
|
|
|
+ x: x + 12,
|
|
|
|
|
+ y: y + 60,
|
|
|
|
|
+ fontSize: 20,
|
|
|
|
|
+ text: labelText,
|
|
|
|
|
+ fontFamily: "Calibri",
|
|
|
|
|
+ fill: "red",
|
|
|
|
|
+ });
|
|
|
|
|
+ this.layer.add(text);
|
|
|
|
|
+ this.texts[labelText] = text; // 用文字作为键存储
|
|
|
|
|
+
|
|
|
|
|
+ // 红色矩形(初始隐藏)
|
|
|
|
|
+ const redrect = new Konva.Rect({
|
|
|
|
|
+ x: x - 3,
|
|
|
|
|
+ y: y + 55,
|
|
|
|
|
+ width: 60,
|
|
|
|
|
+ height: 25,
|
|
|
|
|
+ cornerRadius: 10,
|
|
|
|
|
+ stroke: "red",
|
|
|
|
|
+ strokeWidth: 2,
|
|
|
|
|
+ fill: "red",
|
|
|
|
|
+ visible: false,
|
|
|
|
|
+ });
|
|
|
|
|
+ this.layer.add(redrect);
|
|
|
|
|
+ this.redrects[labelText] = redrect; // 用文字作为键存储
|
|
|
|
|
+
|
|
|
|
|
+ // 红色文字(初始隐藏)
|
|
|
|
|
+ const redtext = new Konva.Text({
|
|
|
|
|
+ x: x + 12,
|
|
|
|
|
+ y: y + 60,
|
|
|
|
|
+ fontSize: 20,
|
|
|
|
|
+ text: labelText,
|
|
|
|
|
+ fontFamily: "Calibri",
|
|
|
|
|
+ fill: "white",
|
|
|
|
|
+ visible: false,
|
|
|
|
|
+ });
|
|
|
|
|
+ this.layer.add(redtext);
|
|
|
|
|
+ this.redtexts[labelText] = redtext; // 用文字作为键存储
|
|
|
|
|
+
|
|
|
|
|
+ // 检查 this.getSelectSopPoints 是否包含当前点的 pointId
|
|
|
|
|
+ if (this.getSelectSopPoints.includes(pos.pointId.toString())) {
|
|
|
|
|
+ // 设置为选中状态
|
|
|
|
|
+ this.selectedStates[labelText] = true;
|
|
|
|
|
+ this.rects[labelText].visible(false);
|
|
|
|
|
+ this.texts[labelText].visible(false);
|
|
|
|
|
+ this.redrects[labelText].visible(true);
|
|
|
|
|
+ this.redtexts[labelText].visible(true);
|
|
|
|
|
+
|
|
|
|
|
+ // 切换图片为选中状态的图片
|
|
|
|
|
+ const selectedImage = new Image();
|
|
|
|
|
+ selectedImage.src = require("@/assets/images/localSetSelect.jpg"); // 选中的图片路径
|
|
|
|
|
+ selectedImage.onload = () => {
|
|
|
|
|
+ knovaImage.image(selectedImage); // 更新图像
|
|
|
|
|
+ this.layer.draw(); // 更新图层
|
|
|
|
|
+ };
|
|
|
|
|
+ // 将选中的 labelText 推入数组
|
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
|
+ getIsIsolationPointPage({ current: 1, size: 100 }).then((res) => {
|
|
|
|
|
+ const allPoints = res.data.records; // 假设返回的数据结构是 { records: [点数据] }
|
|
|
|
|
+
|
|
|
|
|
+ // 根据 pos.pointId 查找对应的 pointType 和 powerType
|
|
|
|
|
+ const pointInfo = allPoints.find(point => point.pointId == pos.pointId);
|
|
|
|
|
+
|
|
|
|
|
+ if (pointInfo) {
|
|
|
|
|
+ this.selectedText.push({
|
|
|
|
|
+ pointName: labelText,
|
|
|
|
|
+ pointId: pos.pointId,
|
|
|
|
|
+ pointType: pointInfo.pointType,
|
|
|
|
|
+ powerType: pointInfo.powerType,
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果没有找到对应的点信息,可以处理这种情况
|
|
|
|
|
+ console.warn(`未找到 pointId 为 ${pos.pointId} 的点信息`);
|
|
|
|
|
+ this.selectedText.push({
|
|
|
|
|
+ pointName: labelText,
|
|
|
|
|
+ pointId: pos.pointId,
|
|
|
|
|
+ pointType: '',
|
|
|
|
|
+ powerType: '',
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ // console.log(this.selectedText,'默认拿到的points')
|
|
|
|
|
+ // 触发父组件的 selection-changed 事件
|
|
|
|
|
+ this.$emit("selection-changed", this.selectedText);
|
|
|
|
|
+ }).catch((error) => {
|
|
|
|
|
+ console.error("获取隔离点信息失败", error);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.layer.draw();
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // methods结束
|
|
|
|
|
+ },
|
|
|
|
|
+};
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+#container {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|