|
|
@@ -0,0 +1,1260 @@
|
|
|
+<template>
|
|
|
+ <div class="mapdata">
|
|
|
+ <div id="container" ref="container" style="width: 1600px"></div>
|
|
|
+ <div class="left">
|
|
|
+ <div
|
|
|
+ class="bottombtn"
|
|
|
+ style="width: 100%; height: 35px; padding: 10px;display: flex;flex-direction: column;"
|
|
|
+ >
|
|
|
+ <!-- <el-button-->
|
|
|
+ <!-- v-no-more-click-->
|
|
|
+ <!-- @click="close"-->
|
|
|
+ <!-- type="primary"-->
|
|
|
+ <!-- icon="el-icon-close"-->
|
|
|
+ <!-- style="align-self: flex-end;margin-top: 10px"-->
|
|
|
+ <!-- >关闭-->
|
|
|
+ <!-- </el-button>-->
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ v-no-more-click
|
|
|
+ @click="save"
|
|
|
+ type="primary"
|
|
|
+ icon="el-icon-check"
|
|
|
+ style="align-self: flex-end;margin-top: 10px"
|
|
|
+ >保存
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ v-no-more-click
|
|
|
+ @click="reset"
|
|
|
+ type="primary"
|
|
|
+ icon="el-icon-setting"
|
|
|
+ style="align-self: flex-end;margin-top: 10px"
|
|
|
+ >重置
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import Konva from 'konva'
|
|
|
+import {
|
|
|
+ selectLotoMapById,
|
|
|
+ selectIsLotoSwitchMapById,
|
|
|
+ updateIsLotoSwitchMap,
|
|
|
+ updatePointsBindingSwitchMap
|
|
|
+} from '@/api/mes/switchmanagement/switchmanagement'
|
|
|
+import {getIsIsolationPointPage} from '@/api/mes/spm/segregationPoint'
|
|
|
+import {getIsMapPointPage, selectIsMapPointById, updateMapPointList} from '@/api/system/mappoint'
|
|
|
+import {selectIsMapById} from '@/api/system/mapconfig'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'KonvaExample',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ stage: null,
|
|
|
+ layer: null,
|
|
|
+ selectedStates: [], // 用于存储每个元素的选中状态
|
|
|
+ selectedText: [], // 用于存储未选中的元素文本
|
|
|
+ rects: [], // 白色rect合集
|
|
|
+ texts: [], // 白色text合集
|
|
|
+ redrects: [], // 红色rect合集
|
|
|
+ redtexts: [], // 白色text合集
|
|
|
+ value: '',
|
|
|
+ form: {}, //拿到单个数据
|
|
|
+ originData: null, //原始数据
|
|
|
+ filterData: null, //用来过滤掉已经渲染出来的隔离点
|
|
|
+ leftPoints: [], //绑定的但未指定位置的集合
|
|
|
+ orgLeftPoints: [], //原始左边数据
|
|
|
+ rightPoints: [], //解绑的数据集合
|
|
|
+ orgRightPoints: [], //原始右边数据
|
|
|
+ groups: [], //组移动数据
|
|
|
+ bindingPointIds: [], //存放从未绑定中放入物资柜的数据 id集合
|
|
|
+ unbindPointIds: [], //解绑的数据接口参数 id集合
|
|
|
+ isSave: true,
|
|
|
+ isInitialized: false, // 添加初始化标志
|
|
|
+ imageUrl: '',//获取底图
|
|
|
+ width: '',//底图宽
|
|
|
+ height: '',//底图高
|
|
|
+ x: '',//底图横坐标
|
|
|
+ y: '',//底图纵坐标
|
|
|
+ mapId: null,//地图Id
|
|
|
+ mapType: 2,//地图类型
|
|
|
+ pointList: null,//接口给的所有点位数据
|
|
|
+ bindingPoints: [],//给地图点位界面更新的绑定隔离点
|
|
|
+ movePoints: [],//给地图点位界面更新位置
|
|
|
+ unbindingPoints: [],//给地图点位界面更新解绑数据
|
|
|
+ blinkLights : [], // 所有需要闪烁的 light 节点
|
|
|
+ globalBlinkTimer : null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // watch: {
|
|
|
+ // bindingPointIds(newVal, oldVal) {
|
|
|
+ // if (newVal) {
|
|
|
+ // this.isSave = false;
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ // unbindPointIds(newVal, oldVal) {
|
|
|
+ // if (newVal) {
|
|
|
+ // this.isSave = false;
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ // // value: {
|
|
|
+ // // handler(newVal, oldVal) {
|
|
|
+ // // if (this.isInitialized && newVal) {
|
|
|
+ // // // 只有在初始化后才监听 value 变化
|
|
|
+ // // const parsedValue = JSON.parse(newVal);
|
|
|
+ // // console.log(parsedValue, "deep watch for value");
|
|
|
+ // // this.isSave = false;
|
|
|
+ // // }
|
|
|
+ // // },
|
|
|
+ // // deep: true,
|
|
|
+ // // },
|
|
|
+ // },
|
|
|
+
|
|
|
+ created() {
|
|
|
+ // this.getIsIsolationPointPage()
|
|
|
+ this.isInitialized = true
|
|
|
+ },
|
|
|
+ beforeRouteEnter(to, from, next) {
|
|
|
+ next((vm) => {
|
|
|
+ // vm.getIsIsolationPointPage()
|
|
|
+ vm.addPointsToRightPointsBox()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.getInfo()
|
|
|
+ this.getIsIsolationPointPage()
|
|
|
+ this.addPointsToRightPointsBox()
|
|
|
+ })
|
|
|
+ console.log(this.$route.query.switchMapId, 'switchMapId')
|
|
|
+ },
|
|
|
+
|
|
|
+ methods: {
|
|
|
+ getInfo() {
|
|
|
+ const switchMapId = this.$route.query.switchMapId
|
|
|
+ selectIsLotoSwitchMapById(switchMapId).then((response) => {
|
|
|
+ console.log(response, '作业区域信息')
|
|
|
+ this.form = response.data
|
|
|
+ this.mapId = response.data.mapId
|
|
|
+
|
|
|
+ // 获取不同底图 如地图或者柜子
|
|
|
+ selectIsMapById(response.data.mapId).then((response) => {
|
|
|
+ console.log(response, '获取底图')
|
|
|
+ if (response.data) {
|
|
|
+ try {
|
|
|
+ this.value = JSON.stringify(response.data.pointList, null, 4)
|
|
|
+
|
|
|
+ this.originData = this.value
|
|
|
+ } catch (err) {
|
|
|
+ console.error(err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.imageUrl = response.data.imageUrl
|
|
|
+ this.width = response.data.width
|
|
|
+ this.height = response.data.height
|
|
|
+ this.x = response.data.x
|
|
|
+ this.y = response.data.y
|
|
|
+ this.pointList = response.data.pointList
|
|
|
+
|
|
|
+ const data = {
|
|
|
+ current: 1,
|
|
|
+ size: -1,
|
|
|
+ switchMapId: this.$route.query.switchMapId
|
|
|
+ }
|
|
|
+
|
|
|
+ getIsIsolationPointPage(data).then((res) => {
|
|
|
+ const data1 = res.data.records // 该柜子或地图所有点
|
|
|
+ const data2 = this.pointList // 该柜子里 json 拿到的点位(已渲染)
|
|
|
+
|
|
|
+ console.log(data1, '该柜子或地图所有点')
|
|
|
+ console.log(data2, '柜子里json拿到的点位')
|
|
|
+
|
|
|
+ // 当前柜子已经存在的点位 id
|
|
|
+ const pointListIds = new Set(this.pointList.map((item) => item.pointId))
|
|
|
+
|
|
|
+ // 过滤掉已经在 pointList 里的点
|
|
|
+ const filterData = data1.filter(item => !pointListIds.has(item.pointId))
|
|
|
+
|
|
|
+ console.log([...pointListIds], '已有点位 ID')
|
|
|
+ console.log(filterData, 'filterData-需要显示在左侧的数据')
|
|
|
+
|
|
|
+ // 左侧需要显示的数据
|
|
|
+ // this.leftPoints = filterData.map((item) => {
|
|
|
+ // return {
|
|
|
+ // pointId: item.pointId,
|
|
|
+ // entityId: item.pointId,
|
|
|
+ // entityName: item.pointName,
|
|
|
+ // pointName: item.pointName,
|
|
|
+ // remark: item.remark,
|
|
|
+ // prePointId: item.prePointId,
|
|
|
+ // pointType: item.pointType,
|
|
|
+ // pointTypeName: item.pointTypeName,
|
|
|
+ // powerType: item.powerType,
|
|
|
+ // powerTypeName: item.powerTypeName,
|
|
|
+ // pointIcon: item.pointIcon,
|
|
|
+ // status: false,
|
|
|
+ // pointPicture: item.pointPicture,
|
|
|
+ // mapImg: null,
|
|
|
+ // mapId:this.form.mapId,
|
|
|
+ // mapType: 2,
|
|
|
+ // mapName:'你好4',
|
|
|
+ // x: 0,
|
|
|
+ // y: 0,
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
+ // 调用你已有的渲染逻辑
|
|
|
+ // this.addPointsToLeftPointsBox(filterData)
|
|
|
+
|
|
|
+ // 保存完整数据
|
|
|
+ this.orgLeftPoints = res.data.records.map((item) => {
|
|
|
+ return {
|
|
|
+ pointId: item.pointId,
|
|
|
+ entityId: item.pointId,
|
|
|
+ entityName: item.pointName,
|
|
|
+ pointName: item.pointName,
|
|
|
+ remark: item.remark,
|
|
|
+ prePointId: item.prePointId,
|
|
|
+ pointType: item.pointType,
|
|
|
+ pointTypeName: item.pointTypeName,
|
|
|
+ powerType: item.powerType,
|
|
|
+ powerTypeName: item.powerTypeName,
|
|
|
+ pointIcon: item.pointIcon,
|
|
|
+ status: false,
|
|
|
+ pointPicture: item.pointPicture,
|
|
|
+ mapImg: null,
|
|
|
+ mapId:this.form.mapId,
|
|
|
+ mapType: this.form.mapType,
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ this.initKonva()
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取未绑定的所有隔离点
|
|
|
+ getIsIsolationPointPage() {
|
|
|
+
|
|
|
+ // 拿到解绑的隔离点数据
|
|
|
+ const data1 = {
|
|
|
+ current: 1,
|
|
|
+ size: -1,
|
|
|
+ switchMapId: 0
|
|
|
+ }
|
|
|
+ getIsIsolationPointPage(data1).then((res) => {
|
|
|
+ this.rightPoints = res.data.records.map((item) => {
|
|
|
+ return {
|
|
|
+ entityId: item.pointId,
|
|
|
+ entityName: item.pointName,
|
|
|
+ pointId: item.pointId,
|
|
|
+ pointName: item.pointName,
|
|
|
+ remark: item.remark,
|
|
|
+ prePointId: item.prePointId,
|
|
|
+ pointType: item.pointType,
|
|
|
+ pointTypeName: item.pointTypeName,
|
|
|
+ powerType: item.powerType,
|
|
|
+ powerTypeName: item.powerTypeName,
|
|
|
+ pointIcon: item.pointIcon,
|
|
|
+ status: false,
|
|
|
+ pointPicture: item.pointPicture,
|
|
|
+ mapImg: null,
|
|
|
+ mapId: this.mapId,
|
|
|
+ mapType: this.mapType
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.orgRightPoints = res.data.records.map((item) => {
|
|
|
+ return {
|
|
|
+ entityId: item.pointId,
|
|
|
+ entityName: item.pointName,
|
|
|
+ pointId: item.pointId,
|
|
|
+ pointName: item.pointName,
|
|
|
+ remark: item.remark,
|
|
|
+ prePointId: item.prePointId,
|
|
|
+ pointType: item.pointType,
|
|
|
+ pointTypeName: item.pointTypeName,
|
|
|
+ powerType: item.powerType,
|
|
|
+ powerTypeName: item.powerTypeName,
|
|
|
+ pointIcon: item.pointIcon,
|
|
|
+ status: false,
|
|
|
+ pointPicture: item.pointPicture,
|
|
|
+ mapImg: null,
|
|
|
+ mapId: this.mapId,
|
|
|
+ mapType: this.mapType
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 重置
|
|
|
+ reset() {
|
|
|
+ this.value = this.originData
|
|
|
+ // 清空并重新赋值
|
|
|
+ this.rightPoints = JSON.parse(JSON.stringify(this.orgRightPoints)) // 深拷贝
|
|
|
+ this.leftPoints = JSON.parse(JSON.stringify(this.orgLeftPoints)) // 深拷贝
|
|
|
+ this.initKonva() // 重新初始化 Konva
|
|
|
+ },
|
|
|
+
|
|
|
+ close() {
|
|
|
+ // this.$router.push('/mes/dv/lotoStation')
|
|
|
+ this.getInfo()
|
|
|
+ // this.initKonva()
|
|
|
+ },
|
|
|
+ save() {
|
|
|
+ this.$confirm('请确认是否保存修改内容', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ // 校验 this.value 是否为有效的 JSON
|
|
|
+ if (this.isJson(this.value)) {
|
|
|
+ const mapData =
|
|
|
+ typeof this.value === 'string'
|
|
|
+ ? this.value
|
|
|
+ : JSON.stringify(this.value)
|
|
|
+ const formData = {
|
|
|
+ ...this.form,
|
|
|
+ map: mapData
|
|
|
+ }
|
|
|
+ console.log(formData, 'map')
|
|
|
+
|
|
|
+ updateIsLotoSwitchMap(formData).then((response) => {
|
|
|
+ console.log(response, '修改车间区域地图')
|
|
|
+ this.$message({
|
|
|
+ type: 'success',
|
|
|
+ message: '保存成功!'
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ let dataMap = {
|
|
|
+ bindingPoints: this.leftPoints,
|
|
|
+ movePoints: this.movePoints,
|
|
|
+ unbindingPoints: this.rightPoints
|
|
|
+ }
|
|
|
+ console.log(dataMap, '先拿到数据看看再说')
|
|
|
+ updateMapPointList(dataMap).then((res) => {
|
|
|
+ console.log(res, '拿到的新绑定数据')
|
|
|
+ })
|
|
|
+ const data = {
|
|
|
+ bindingPointIds: this.bindingPointIds,
|
|
|
+ switchMapId: this.$route.query.switchMapId,
|
|
|
+ unbindPointIds: this.unbindPointIds
|
|
|
+ }
|
|
|
+ console.log(data, '解绑与绑定数据参数')
|
|
|
+ updatePointsBindingSwitchMap(data).then((res) => {
|
|
|
+ console.log(res, '解绑接口返回值')
|
|
|
+ this.bindingPointIds = []
|
|
|
+ this.unbindPointIds = []
|
|
|
+ })
|
|
|
+ // this.close()
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ type: 'error',
|
|
|
+ message: '地图数据格式不正确,请输入有效的 JSON 格式!'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ // 取消操作
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 校验字符串是否为有效的 JSON
|
|
|
+ isJson(str) {
|
|
|
+ try {
|
|
|
+ JSON.parse(str)
|
|
|
+ return true
|
|
|
+ } catch (e) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ initKonva() {
|
|
|
+
|
|
|
+ // 创建舞台
|
|
|
+ this.stage = new Konva.Stage({
|
|
|
+ container: this.$refs.container, // 容器元素
|
|
|
+ width: 1600,
|
|
|
+ height: 860
|
|
|
+ })
|
|
|
+
|
|
|
+ // 创建图层
|
|
|
+ this.layer = new Konva.Layer()
|
|
|
+ // 绘制隔离点等其他内容
|
|
|
+ this.drawGrid(50, 50, '#e0e0e0') // 每个单元格50x50,浅灰色网格
|
|
|
+ // 创建物资柜底图
|
|
|
+ const bgImage = new Image()
|
|
|
+ const imageConfig = {
|
|
|
+ x: this.x,
|
|
|
+ y: this.y,
|
|
|
+ width: this.width,
|
|
|
+ height: this.height,
|
|
|
+ draggable: false
|
|
|
+ }
|
|
|
+ bgImage.src = this.imageUrl
|
|
|
+ bgImage.onload = () => {
|
|
|
+ const knovaImage = new Konva.Image({
|
|
|
+ ...imageConfig,
|
|
|
+ image: bgImage
|
|
|
+ })
|
|
|
+ this.layer.add(knovaImage)
|
|
|
+
|
|
|
+ // 创建背景图并添加到图层
|
|
|
+ // 创建所有隔离点父盒子 放置于网格线上
|
|
|
+ // const rightPointsBox = new Konva.Rect({
|
|
|
+ // x: 1100,
|
|
|
+ // y: 15,
|
|
|
+ // width: 200,
|
|
|
+ // height: 800,
|
|
|
+ // cornerRadius: 5,
|
|
|
+ // stroke: 'black',
|
|
|
+ // strokeWidth: 2,
|
|
|
+ // fill: 'white'
|
|
|
+ // })
|
|
|
+ // const rightnoLoto = new Konva.Text({
|
|
|
+ // x: 1110, // 调整位置以适应网格
|
|
|
+ // y: 20, // 调整位置以适应网格
|
|
|
+ // text: '未绑定锁定站的隔离点数据',
|
|
|
+ // fontSize: 15,
|
|
|
+ // fill: 'black'
|
|
|
+ // })
|
|
|
+
|
|
|
+ // this.layer.add(rightPointsBox)
|
|
|
+ // this.layer.add(rightnoLoto)
|
|
|
+
|
|
|
+ // 将隔离点添加到 rightPointsBox
|
|
|
+ // this.addPointsToRightPointsBox(rightPointsBox)
|
|
|
+
|
|
|
+ // 渲染数据
|
|
|
+ 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 = 1600
|
|
|
+ const height = 860
|
|
|
+
|
|
|
+ // 绘制竖线
|
|
|
+ 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)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加网格坐标文本
|
|
|
+ // for (let row = 0; row < height / cellHeight; row++) {
|
|
|
+ // for (let col = 0; col < width / cellWidth; col++) {
|
|
|
+ // const text = new Konva.Text({
|
|
|
+ // x: col * cellWidth + 5, // 调整位置以适应网格
|
|
|
+ // y: row * cellHeight + 5, // 调整位置以适应网格
|
|
|
+ // text: `(${col},${row})`,
|
|
|
+ // fontSize: 10,
|
|
|
+ // fill: 'gray',
|
|
|
+ // });
|
|
|
+ // this.layer.add(text);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ this.layer.draw()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 绘制柜内所有点
|
|
|
+ renderGrid(imageSrc) {
|
|
|
+
|
|
|
+ this.selectedStates = [] // 用数组来存储选中状态
|
|
|
+ this.rects = []
|
|
|
+ this.texts = []
|
|
|
+ this.bgrects = {}
|
|
|
+ this.redrects = []
|
|
|
+ this.redtexts = []
|
|
|
+ this.selectedText = []
|
|
|
+
|
|
|
+ // ✅ 每次渲染前清空
|
|
|
+ this.rightPoints = []
|
|
|
+ this.leftPoints = []
|
|
|
+ this.bindingPointIds = []
|
|
|
+ this.unbindPointIds = []
|
|
|
+ this.movePoints = []
|
|
|
+
|
|
|
+ // 点位数据
|
|
|
+ console.log(this.pointList, '点位数据')
|
|
|
+ const positions = (this.pointList || []).map(item => ({
|
|
|
+ row: item.x,
|
|
|
+ col: item.y,
|
|
|
+ id: item.id,
|
|
|
+ pointId: item.entityId,
|
|
|
+ pointName: item.entityName,
|
|
|
+ entityId: item.entityId,
|
|
|
+ entityName: item.entityName,
|
|
|
+ mapId: item.mapId,
|
|
|
+ mapType: parseInt(item.mapType),
|
|
|
+ x: item.x,
|
|
|
+ y: item.y,
|
|
|
+ remark: item.remark,
|
|
|
+ pointIcon: item.pointIcon,
|
|
|
+ pointPicture: item.pointPicture,
|
|
|
+ }))
|
|
|
+ console.log(positions, 'positions')
|
|
|
+
|
|
|
+ positions.forEach((pos) => {
|
|
|
+ const x = pos.x * 50
|
|
|
+ const y = pos.y * 50
|
|
|
+ const labelText = pos.entityName
|
|
|
+
|
|
|
+ const point = new Image()
|
|
|
+ point.src = pos.pointIcon
|
|
|
+
|
|
|
+ point.onload = () => {
|
|
|
+ const group = new Konva.Group({
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ draggable: true
|
|
|
+ })
|
|
|
+
|
|
|
+ const bgrect = new Konva.Rect({
|
|
|
+ x: -1,
|
|
|
+ y: -5,
|
|
|
+ width: 50,
|
|
|
+ height: 78,
|
|
|
+ cornerRadius: 5,
|
|
|
+ stroke: 'white',
|
|
|
+ strokeWidth: 2,
|
|
|
+ fill: 'white'
|
|
|
+ })
|
|
|
+
|
|
|
+ const rect = new Konva.Rect({
|
|
|
+ x: 1,
|
|
|
+ y: -1,
|
|
|
+ width: 45,
|
|
|
+ height: 70,
|
|
|
+ cornerRadius: 5,
|
|
|
+ stroke: 'red',
|
|
|
+ strokeWidth: 2,
|
|
|
+ fill: 'white'
|
|
|
+ })
|
|
|
+ // 确定灯的颜色
|
|
|
+ let lightColor, shadowColor, stroke;
|
|
|
+
|
|
|
+ if (pos.switchStatus == "0") {
|
|
|
+ // lightColor = '#ff000d'; // Red
|
|
|
+ // shadowColor = '#ffcae8';
|
|
|
+ // stroke = '#ffcae8';
|
|
|
+ lightColor = '#e0e0e0'; // Gray (unknown)
|
|
|
+ shadowColor = '#e0e0e0';
|
|
|
+ stroke = '#e0e0e0';
|
|
|
+ } else if (pos.switchStatus == "1") {
|
|
|
+ lightColor = '#0ea562'; // Green
|
|
|
+ shadowColor = '#3ab890';
|
|
|
+ stroke = '#3ab890';
|
|
|
+ } else {
|
|
|
+ lightColor = 'white';
|
|
|
+ shadowColor="white";
|
|
|
+ stroke="white"
|
|
|
+ // lightColor = '#e0e0e0'; // Gray (unknown)
|
|
|
+ // shadowColor = '#e0e0e0';
|
|
|
+ // stroke = '#e0e0e0';
|
|
|
+ }
|
|
|
+ const isRed = pos.switchStatus == "0";
|
|
|
+ const isGrey = pos.switchStatus == null;
|
|
|
+// Create the light
|
|
|
+ const light = new Konva.Circle({
|
|
|
+ x: 22.5, // Circle center position
|
|
|
+ y: 25, // Circle center position
|
|
|
+ radius: 12,
|
|
|
+ fill: lightColor,
|
|
|
+ stroke: stroke,
|
|
|
+ strokeWidth: 2,
|
|
|
+ shadow: {
|
|
|
+ color: shadowColor,
|
|
|
+ blur: 5,
|
|
|
+ offset: {x: 0, y: 0},
|
|
|
+ opacity: 0.8
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // const knovaImage = new Konva.Image({
|
|
|
+ // x: 1,
|
|
|
+ // y: 0,
|
|
|
+ // image: point,
|
|
|
+ // width: 45,
|
|
|
+ // height: 45
|
|
|
+ // })
|
|
|
+
|
|
|
+ const text = new Konva.Text({
|
|
|
+ x: 8,
|
|
|
+ y: 50,
|
|
|
+ fontSize: 17,
|
|
|
+ text: labelText,
|
|
|
+ fontFamily: 'Calibri',
|
|
|
+ fill: 'red'
|
|
|
+ })
|
|
|
+
|
|
|
+ group.add(bgrect)
|
|
|
+ group.add(rect)
|
|
|
+ // group.add(knovaImage)
|
|
|
+ group.add(light)
|
|
|
+ group.add(text)
|
|
|
+
|
|
|
+ this.layer.add(group)
|
|
|
+
|
|
|
+ // 定义右侧盒子的范围
|
|
|
+ // const rightBoxBounds = { x: 1100, y: 15, width: 200, height: 800 }
|
|
|
+
|
|
|
+ // group.on('dragend', () => {
|
|
|
+ // const groupPos = group.getAbsolutePosition()
|
|
|
+ // const movedLabel = labelText
|
|
|
+ //
|
|
|
+ // const isInRightBox =
|
|
|
+ // groupPos.x >= rightBoxBounds.x &&
|
|
|
+ // groupPos.x <= rightBoxBounds.x + rightBoxBounds.width &&
|
|
|
+ // groupPos.y >= rightBoxBounds.y &&
|
|
|
+ // groupPos.y <= rightBoxBounds.y + rightBoxBounds.height
|
|
|
+ //
|
|
|
+ // const indexToRemove = positions ? positions.findIndex(item => item.entityName === movedLabel) : -1
|
|
|
+ //
|
|
|
+ // if (indexToRemove !== -1) {
|
|
|
+ // const movedPoint = positions[indexToRemove]
|
|
|
+ // if (isInRightBox) {
|
|
|
+ // // 移动到右侧
|
|
|
+ // positions.splice(indexToRemove, 1)
|
|
|
+ // if (!this.rightPoints.some(p => p.entityName === movedPoint.entityName)) {
|
|
|
+ // this.rightPoints.push(movedPoint)
|
|
|
+ // this.unbindPointIds.push(movedPoint.entityId)
|
|
|
+ // this.bindingPointIds = this.bindingPointIds.filter(id => id !== movedPoint.entityId)
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // // 在柜子内/外更新位置
|
|
|
+ // const newCol = Math.round(groupPos.y / 50)
|
|
|
+ // const newRow = Math.round(groupPos.x / 50)
|
|
|
+ //
|
|
|
+ // const boundedCol = Math.max(0, Math.min(newCol, Math.floor(860 / 50) - 1))
|
|
|
+ // const boundedRow = Math.max(0, Math.min(newRow, Math.floor(1200 / 50) - 1))
|
|
|
+ //
|
|
|
+ // const updatedPoint = {
|
|
|
+ // ...movedPoint,
|
|
|
+ // row: boundedRow,
|
|
|
+ // col: boundedCol,
|
|
|
+ // x: boundedRow,
|
|
|
+ // y: boundedCol,
|
|
|
+ // mapId: this.form.mapId,
|
|
|
+ // mapType: this.form.mapType,
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // positions[indexToRemove] = updatedPoint
|
|
|
+ //
|
|
|
+ // // ✅ 只有位置不为 0 才加入 movePoints
|
|
|
+ // if (!(updatedPoint.row == 0 && updatedPoint.col == 0 && updatedPoint.x == 0 && updatedPoint.y == 0)) {
|
|
|
+ // if (!this.movePoints) this.movePoints = []
|
|
|
+ // // 防止重复 push,先找一下
|
|
|
+ // const existIdx = this.movePoints.findIndex(p => p.pointId === updatedPoint.pointId)
|
|
|
+ // if (existIdx !== -1) {
|
|
|
+ // this.movePoints.splice(existIdx, 1, updatedPoint) // 覆盖旧的
|
|
|
+ // } else {
|
|
|
+ // this.movePoints.push(updatedPoint)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // // movedLabel 不在 positions,可能是从右侧拖出来
|
|
|
+ // const rightIndex = this.rightPoints.findIndex(item => item.entityName === movedLabel)
|
|
|
+ // if (rightIndex !== -1) {
|
|
|
+ // const movedPoint = this.rightPoints.splice(rightIndex, 1)[0]
|
|
|
+ // const newCol = Math.round(groupPos.y / 50)
|
|
|
+ // const newRow = Math.round(groupPos.x / 50)
|
|
|
+ // const boundedCol = Math.max(0, Math.min(newCol, Math.floor(860 / 50) - 1))
|
|
|
+ // const boundedRow = Math.max(0, Math.min(newRow, Math.floor(1200 / 50) - 1))
|
|
|
+ //
|
|
|
+ // const newPoint = {
|
|
|
+ // ...movedPoint,
|
|
|
+ // row: boundedRow,
|
|
|
+ // col: boundedCol,
|
|
|
+ // x: boundedRow,
|
|
|
+ // y: boundedCol,
|
|
|
+ // mapId: this.form.mapId,
|
|
|
+ // mapType: this.form.mapType,
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // positions.push(newPoint)
|
|
|
+ //
|
|
|
+ // if (!this.leftPoints.some(p => p.entityName === movedPoint.entityName)) {
|
|
|
+ // this.leftPoints.push(movedPoint)
|
|
|
+ // }
|
|
|
+ // this.bindingPointIds.push(movedPoint.entityId)
|
|
|
+ // this.unbindPointIds = this.unbindPointIds.filter(id => id !== movedPoint.entityId)
|
|
|
+ //
|
|
|
+ // // ✅ 判断 row/col/x/y 不为 0 再 push
|
|
|
+ // if (!(newPoint.row == 0 && newPoint.col == 0 && newPoint.x == 0 && newPoint.y == 0)) {
|
|
|
+ // if (!this.movePoints) this.movePoints = []
|
|
|
+ // const existIdx = this.movePoints.findIndex(p => p.pointId === newPoint.pointId)
|
|
|
+ // if (existIdx !== -1) {
|
|
|
+ // this.movePoints.splice(existIdx, 1, newPoint)
|
|
|
+ // } else {
|
|
|
+ // this.movePoints.push(newPoint)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // // 清理无效数据
|
|
|
+ // this.rightPoints = (this.rightPoints || []).filter(Boolean)
|
|
|
+ // this.leftPoints = (this.leftPoints || []).filter(Boolean)
|
|
|
+ //
|
|
|
+ // this.value = JSON.stringify(positions, null, 4)
|
|
|
+ // this.layer.draw()
|
|
|
+ //
|
|
|
+ // console.log('Updated positions:', positions)
|
|
|
+ // console.log('MovePoints:', this.movePoints)
|
|
|
+ // })
|
|
|
+// 添加绿灯或红灯闪烁动画
|
|
|
+ this.addBlinkAnimation(light, isRed,isGrey);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 全局控制闪烁频率同步函数
|
|
|
+ startGlobalBlinkTimer() {
|
|
|
+ if (this.globalBlinkTimer) return; // 已经启动了
|
|
|
+
|
|
|
+ this.globalBlinkTimer = setInterval(() => {
|
|
|
+ const currentSecond = Math.floor(Date.now() / 200) % 2;
|
|
|
+ const isOn = currentSecond === 1;
|
|
|
+
|
|
|
+ this.blinkLights.forEach(light => {
|
|
|
+ light.opacity(isOn ? 1 : 0.6);
|
|
|
+ light.scale({ x: isOn ? 1 : 1.1, y: isOn ? 1 : 1.1 });
|
|
|
+ });
|
|
|
+
|
|
|
+ if (this.blinkLights.length > 0) {
|
|
|
+ this.blinkLights[0].getLayer().batchDraw(); // 统一刷新一次就行
|
|
|
+ }
|
|
|
+ }, 50);
|
|
|
+ },
|
|
|
+ // 绿灯动画
|
|
|
+ addBlinkAnimation(light, isRed, isGrey) {
|
|
|
+ if (!isGrey&&!isRed) {
|
|
|
+ if (!this.blinkLights.includes(light)) {
|
|
|
+ this.blinkLights.push(light);
|
|
|
+ }
|
|
|
+ this.startGlobalBlinkTimer();
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 左侧的列表 现在左侧列表通过地图点位接口获取pointList里直接有左侧的数据 不用再去隔离点管理接口拿数据
|
|
|
+ addPointsToLeftPointsBox(filterData) {
|
|
|
+ // 获取接口返回的 leftPoints 数据
|
|
|
+ const pointsData = filterData
|
|
|
+
|
|
|
+ let row = 1 // 当前行
|
|
|
+ let col = 1 // 当前列
|
|
|
+
|
|
|
+ // 遍历 pointsData 并根据是否存在于 this.value 中来决定位置
|
|
|
+ pointsData.forEach((point) => {
|
|
|
+ const existingPoint = JSON.parse(this.value).find(
|
|
|
+ (item) => item.pointId == point.pointId
|
|
|
+ )
|
|
|
+
|
|
|
+ // 如果该点在 this.value 中,使用它的原始位置
|
|
|
+ if (existingPoint) {
|
|
|
+ point.row = existingPoint.row
|
|
|
+ point.col = existingPoint.col
|
|
|
+ } else {
|
|
|
+ // 否则,按顺序从 (0, 0) 位置开始,每行三个点
|
|
|
+ point.row = 0
|
|
|
+ point.col = 0
|
|
|
+
|
|
|
+ }
|
|
|
+ // 渲染该点
|
|
|
+ this.renderPoint(point)
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 渲染每个点
|
|
|
+ renderPoint(point) {
|
|
|
+
|
|
|
+ const x = point.col * 50 // 每个单元格宽度为50
|
|
|
+ const y = point.row * 50 // 每个单元格高度为50
|
|
|
+
|
|
|
+ const labelText = point.pointName // 对应的文字
|
|
|
+ const pointImage = new Image()
|
|
|
+ pointImage.src = point.pointIcon
|
|
|
+
|
|
|
+ pointImage.onload = () => {
|
|
|
+ // 创建一个新的 Group 来包含整个隔离点
|
|
|
+ const group = new Konva.Group({
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ draggable: true // 设置为可拖拽
|
|
|
+ })
|
|
|
+
|
|
|
+ // 背景矩形
|
|
|
+ const bgrect = new Konva.Rect({
|
|
|
+ x: -6,
|
|
|
+ y: -5,
|
|
|
+ width: 62,
|
|
|
+ height: 80,
|
|
|
+ cornerRadius: 5,
|
|
|
+ stroke: 'white',
|
|
|
+ strokeWidth: 2,
|
|
|
+ fill: 'white'
|
|
|
+ })
|
|
|
+
|
|
|
+ // 普通矩形
|
|
|
+ const rect = new Konva.Rect({
|
|
|
+ x: 0,
|
|
|
+ y: -1,
|
|
|
+ width: 50,
|
|
|
+ height: 72,
|
|
|
+ cornerRadius: 5,
|
|
|
+ stroke: 'red',
|
|
|
+ strokeWidth: 2,
|
|
|
+ fill: 'white'
|
|
|
+ })
|
|
|
+
|
|
|
+ // 图片
|
|
|
+ const knovaImage = new Konva.Image({
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ image: pointImage,
|
|
|
+ width: 50,
|
|
|
+ height: 50
|
|
|
+ })
|
|
|
+
|
|
|
+ // 文字
|
|
|
+ const text = new Konva.Text({
|
|
|
+ x: 8,
|
|
|
+ y: 50,
|
|
|
+ fontSize: 17,
|
|
|
+ text: labelText,
|
|
|
+ fontFamily: 'Calibri',
|
|
|
+ fill: 'red'
|
|
|
+ })
|
|
|
+
|
|
|
+ // 将所有元素添加到 group 中
|
|
|
+ group.add(bgrect)
|
|
|
+ group.add(rect)
|
|
|
+ group.add(knovaImage)
|
|
|
+ group.add(text)
|
|
|
+
|
|
|
+ // 将 group 添加到 layer
|
|
|
+ this.layer.add(group)
|
|
|
+
|
|
|
+ // 定义右侧盒子的范围
|
|
|
+ const rightBoxBounds = {
|
|
|
+ x: 1100,
|
|
|
+ y: 15,
|
|
|
+ width: 200,
|
|
|
+ height: 800
|
|
|
+ }
|
|
|
+
|
|
|
+ // 定义物资柜的范围
|
|
|
+ const cabinetBounds = {
|
|
|
+ x: 330,
|
|
|
+ y: 10,
|
|
|
+ width: 500,
|
|
|
+ height: 790
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理拖拽事件
|
|
|
+ // group.on('dragend', () => {
|
|
|
+ // const groupPos = group.getAbsolutePosition()
|
|
|
+ // const isInRightBox =
|
|
|
+ // groupPos.x >= rightBoxBounds.x &&
|
|
|
+ // groupPos.x <= rightBoxBounds.x + rightBoxBounds.width &&
|
|
|
+ // groupPos.y >= rightBoxBounds.y &&
|
|
|
+ // groupPos.y <= rightBoxBounds.y + rightBoxBounds.height
|
|
|
+ //
|
|
|
+ // const isInCabinet =
|
|
|
+ // groupPos.x >= cabinetBounds.x &&
|
|
|
+ // groupPos.x <= cabinetBounds.x + cabinetBounds.width &&
|
|
|
+ // groupPos.y >= cabinetBounds.y &&
|
|
|
+ // groupPos.y <= cabinetBounds.y + cabinetBounds.height
|
|
|
+ //
|
|
|
+ // // 如果点进入右侧列表,执行删除操作
|
|
|
+ // if (isInRightBox) {
|
|
|
+ // this.removePointFromJson(point)
|
|
|
+ // } else if (isInCabinet) {
|
|
|
+ // // 如果点回到物资柜,执行更新操作
|
|
|
+ // this.updatePointInJson(point, groupPos)
|
|
|
+ // } else if (!isInCabinet && !isInRightBox) {
|
|
|
+ // // 如果点位在物资柜外但不在右侧列表中,进行位置更新
|
|
|
+ // this.updatePointInJson(point, groupPos)
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
+ this.layer.draw()
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 从 json 删除对应的点
|
|
|
+ removePointFromJson(point) {
|
|
|
+ // 更新 leftPoints 和 rightPoints
|
|
|
+ this.rightPoints.push(point)
|
|
|
+ this.unbindPointIds.push(point.pointId) // 给接口传递需要解绑的数据Id
|
|
|
+
|
|
|
+ // 删除 JSON 中对应的点
|
|
|
+ const updatedData = JSON.parse(this.value).filter(
|
|
|
+ (item) => item.pointId !== point.pointId
|
|
|
+ )
|
|
|
+ this.value = JSON.stringify(updatedData, null, 4)
|
|
|
+
|
|
|
+ // console.log('Updated value after removal:', this.value)
|
|
|
+ console.log('removePointFromJson', updatedData)
|
|
|
+ },
|
|
|
+
|
|
|
+ // 更新 JSON 中对应点的位置
|
|
|
+ updatePointInJson(point, groupPos) {
|
|
|
+ // 计算新的位置
|
|
|
+ const newCol = Math.round(groupPos.x / 50)
|
|
|
+ const newRow = Math.round(groupPos.y / 50)
|
|
|
+
|
|
|
+ // 更新 positions 数组中的点位
|
|
|
+ const updatedPosition = {
|
|
|
+ row: newRow,
|
|
|
+ col: newCol,
|
|
|
+ x: newRow,
|
|
|
+ y: newCol,
|
|
|
+ pointId: point.pointId,
|
|
|
+ pointName: point.pointName,
|
|
|
+ entityId: point.pointId,
|
|
|
+ entityName: point.pointName,
|
|
|
+ remark: point.remark,
|
|
|
+ prePointId: point.prePointId,
|
|
|
+ pointType: point.pointType,
|
|
|
+ pointTypeName: point.pointTypeName,
|
|
|
+ powerType: point.powerType,
|
|
|
+ powerTypeName: point.powerTypeName,
|
|
|
+ state: point.state,
|
|
|
+ pointIcon: point.pointIcon,
|
|
|
+ pointPicture: point.pointPicture,
|
|
|
+ mapImg: point.mapImg,
|
|
|
+ mapId: this.form.mapId,
|
|
|
+ mapType: this.form.mapType,
|
|
|
+ mapName:'你好5'
|
|
|
+ }
|
|
|
+
|
|
|
+ let positions = JSON.parse(this.value)
|
|
|
+ const index = positions.findIndex(
|
|
|
+ (item) => item.pointId === point.pointId
|
|
|
+ )
|
|
|
+ if (index !== -1) {
|
|
|
+ // positions[index] = updatedPosition;
|
|
|
+ // this.value = JSON.stringify(positions, null, 4);
|
|
|
+ const updatedPositionCopy = JSON.parse(JSON.stringify(updatedPosition))
|
|
|
+ positions[index] = updatedPositionCopy
|
|
|
+
|
|
|
+ console.log(updatedPositionCopy, positions[index], 'updatedPosition-1')
|
|
|
+ this.value = JSON.stringify(positions, null, 4)
|
|
|
+ } else {
|
|
|
+ // 如果点位不在 this.value 中,则重新插入
|
|
|
+ positions.push(updatedPosition)
|
|
|
+ this.value = JSON.stringify(positions, null, 4)
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log('Updated value after update:', this.value)
|
|
|
+ },
|
|
|
+ // 解绑隔离点函数
|
|
|
+ addPointsToRightPointsBox(rightPointsBox) {
|
|
|
+ if (this.rightPoints && this.rightPoints.length > 0) {
|
|
|
+ const boxWidth = rightPointsBox.width()
|
|
|
+ const boxHeight = rightPointsBox.height()
|
|
|
+ const boxX = rightPointsBox.x()
|
|
|
+ const boxY = rightPointsBox.y()
|
|
|
+ const padding = 10 // 每个隔离点之间的间距
|
|
|
+ const pointWidth = 50 // 每个隔离点的宽度
|
|
|
+ const pointHeight = 70 // 每个隔离点的高度(包括图片和文字)
|
|
|
+
|
|
|
+ let currentX = boxX + padding
|
|
|
+ let currentY = boxY + padding
|
|
|
+ const rightBoxBounds = {
|
|
|
+ x: 1100,
|
|
|
+ y: 15,
|
|
|
+ width: 200,
|
|
|
+ height: 800
|
|
|
+ }
|
|
|
+ const cabinetBounds = {
|
|
|
+ x: 330,
|
|
|
+ y: 10,
|
|
|
+ width: 500,
|
|
|
+ height: 790
|
|
|
+ }
|
|
|
+
|
|
|
+ this.rightPoints.forEach((point) => {
|
|
|
+ // 创建一个组来组合红色边框、图片和文字
|
|
|
+ const group = new Konva.Group({
|
|
|
+ x: currentX,
|
|
|
+ y: currentY + 14,
|
|
|
+ draggable: true // 启用拖拽功能
|
|
|
+ })
|
|
|
+
|
|
|
+ // 创建红色边框
|
|
|
+ const borderRect = new Konva.Rect({
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ width: pointWidth,
|
|
|
+ height: pointHeight,
|
|
|
+ cornerRadius: 5,
|
|
|
+ stroke: 'red',
|
|
|
+ strokeWidth: 2,
|
|
|
+ fill: 'white'
|
|
|
+ })
|
|
|
+ group.add(borderRect)
|
|
|
+
|
|
|
+ // 创建图片
|
|
|
+ const image = new Image()
|
|
|
+ image.src = point.pointIcon
|
|
|
+ image.onload = () => {
|
|
|
+ const knovaImage = new Konva.Image({
|
|
|
+ x: 1, // 图片在组内的位置
|
|
|
+ y: 5, // 图片在组内的位置
|
|
|
+ image: image,
|
|
|
+ width: 50, // 图片宽度
|
|
|
+ height: 50 // 图片高度
|
|
|
+ })
|
|
|
+ group.add(knovaImage)
|
|
|
+
|
|
|
+ // 创建文字
|
|
|
+ const pointText = new Konva.Text({
|
|
|
+ x: 12, // 文字在组内的位置
|
|
|
+ y: 53, // 文字在组内的位置
|
|
|
+ text: point.pointName,
|
|
|
+ fontSize: 12,
|
|
|
+ fill: 'red'
|
|
|
+ })
|
|
|
+ group.add(pointText)
|
|
|
+
|
|
|
+ // 将组添加到图层
|
|
|
+ this.layer.add(group)
|
|
|
+ this.groups[point.pointName] = group // 用文字作为键存储
|
|
|
+
|
|
|
+ // 监听组的拖拽移动事件
|
|
|
+ group.on('dragmove', () => {
|
|
|
+ // 获取当前组的位置
|
|
|
+ const groupPos = group.getAbsolutePosition()
|
|
|
+ // 更新组的位置
|
|
|
+ group.x(groupPos.x)
|
|
|
+ group.y(groupPos.y)
|
|
|
+ })
|
|
|
+
|
|
|
+ // 监听组的拖拽结束事件
|
|
|
+ group.on('dragend', () => {
|
|
|
+ const gridX = 50 // 网格单元格宽度
|
|
|
+ const gridY = 50 // 网格单元格高度
|
|
|
+
|
|
|
+ // 计算最近的网格点位置
|
|
|
+ const snappedX = Math.round(group.x() / gridX) * gridX
|
|
|
+ const snappedY = Math.round(group.y() / gridY) * gridY
|
|
|
+
|
|
|
+ // 设置组到最近的网格点位置
|
|
|
+ group.x(snappedX)
|
|
|
+ group.y(snappedY)
|
|
|
+
|
|
|
+ // 计算网格坐标
|
|
|
+ const row = Math.floor(snappedY / gridY)
|
|
|
+ const col = Math.floor(snappedX / gridX)
|
|
|
+
|
|
|
+ // 更新点位数据
|
|
|
+ const updatedPointData = {
|
|
|
+ row: row,
|
|
|
+ col: col,
|
|
|
+ pointId: point.pointId,
|
|
|
+ entityId: point.entityId,
|
|
|
+ entityName: point.entityName,
|
|
|
+ pointName: point.pointName,
|
|
|
+ remark: point.remark,
|
|
|
+ prePointId: point.prePointId,
|
|
|
+ pointType: point.pointType,
|
|
|
+ pointTypeName: point.pointTypeName,
|
|
|
+ powerType: point.powerType,
|
|
|
+ powerTypeName: point.powerTypeName,
|
|
|
+ state: point.status,
|
|
|
+ pointIcon: point.pointIcon,
|
|
|
+ pointPicture: point.pointPicture,
|
|
|
+ mapImg: null,
|
|
|
+ mapId: point.mapId,
|
|
|
+ mapName:'你好6',
|
|
|
+ mapType: point.mapType,
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析 this.value 为数组
|
|
|
+ let valueArray = []
|
|
|
+ try {
|
|
|
+ valueArray = JSON.parse(this.value)
|
|
|
+ } catch (e) {
|
|
|
+ console.error('Failed to parse value:', e)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断拖拽目标区域
|
|
|
+ if (
|
|
|
+ snappedX >= rightBoxBounds.x &&
|
|
|
+ snappedX <= rightBoxBounds.x + rightBoxBounds.width &&
|
|
|
+ snappedY >= rightBoxBounds.y &&
|
|
|
+ snappedY <= rightBoxBounds.y + rightBoxBounds.height
|
|
|
+ ) {
|
|
|
+ // 进入右侧盒子区域
|
|
|
+ console.log('进入右侧盒子区域')
|
|
|
+// 更新 point 对象的 col 和 row 值
|
|
|
+ point.row = col
|
|
|
+ point.col = row
|
|
|
+ point.x = col
|
|
|
+ point.y = row
|
|
|
+ // 如果之前已在右侧区域,需要移除值,并更新绑定点ID
|
|
|
+ const index = valueArray.findIndex(
|
|
|
+ (item) => item.pointId === point.pointId
|
|
|
+ )
|
|
|
+ if (index !== -1) {
|
|
|
+ valueArray.splice(index, 1) // 从 valueArray 中删除该点
|
|
|
+ }
|
|
|
+ this.value = JSON.stringify(valueArray, null, 4)
|
|
|
+
|
|
|
+ // 删除绑定点
|
|
|
+ this.bindingPointIds = this.bindingPointIds.filter(
|
|
|
+ (id) => id !== point.pointId
|
|
|
+ )
|
|
|
+
|
|
|
+ // 将该点加入解绑点ID
|
|
|
+ this.unbindPointIds.push(point.pointId)
|
|
|
+
|
|
|
+ // 将点重新添加到 rightPoints
|
|
|
+ this.rightPoints.push(point)
|
|
|
+ }
|
|
|
+ // 这里的if判断是为了 移动在物资柜内部才做的操作 现在我只要离开右侧 就做这个操作
|
|
|
+ // if (
|
|
|
+ // snappedX >= cabinetBounds.x &&
|
|
|
+ // snappedX <= cabinetBounds.x + cabinetBounds.width &&
|
|
|
+ // snappedY >= cabinetBounds.y &&
|
|
|
+ // snappedY <= cabinetBounds.y + cabinetBounds.height
|
|
|
+ // )
|
|
|
+ else if (snappedX < rightBoxBounds.x ||
|
|
|
+ snappedX > rightBoxBounds.x + rightBoxBounds.width ||
|
|
|
+ snappedY < rightBoxBounds.y ||
|
|
|
+ snappedY > rightBoxBounds.y + rightBoxBounds.height
|
|
|
+ ) {
|
|
|
+
|
|
|
+ // 进入物资柜区域
|
|
|
+ console.log('进入物资柜区域')
|
|
|
+ // 更新 point 对象的 col 和 row 值
|
|
|
+ point.row = col
|
|
|
+ point.col = row
|
|
|
+ point.x = col
|
|
|
+ point.y = row
|
|
|
+ // 检查点是否已经存在于 valueArray 中
|
|
|
+ const index = valueArray.findIndex(
|
|
|
+ (item) => item.pointId === point.pointId
|
|
|
+ )
|
|
|
+ if (index === -1) {
|
|
|
+ // 如果点位不存在,则新增
|
|
|
+ valueArray.push(updatedPointData)
|
|
|
+ this.value = JSON.stringify(valueArray, null, 4)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加到绑定点ID数组
|
|
|
+ this.bindingPointIds.push(point.pointId)
|
|
|
+
|
|
|
+ // 从右侧盒子移除点
|
|
|
+ this.rightPoints = this.rightPoints.filter(
|
|
|
+ (item) => item.pointId !== point.pointId
|
|
|
+ )
|
|
|
+ this.leftPoints.push(point)
|
|
|
+ console.log(point, '进入左侧区域进行隔离点绑定操作!')
|
|
|
+ } else {
|
|
|
+ // 未进入任何目标区域,保持原状态
|
|
|
+ console.log('未进入目标区域,保持原状态')
|
|
|
+ // 更新 point 对象的 col 和 row 值
|
|
|
+ point.row = col
|
|
|
+ point.col = row
|
|
|
+ point.x = col
|
|
|
+ point.y = row
|
|
|
+ // 如果点不在目标区域,从 valueArray 中移除
|
|
|
+ // this.value = JSON.stringify(
|
|
|
+ // valueArray.filter((item) => item.pointId !== point.pointId),
|
|
|
+ // null,
|
|
|
+ // 4
|
|
|
+ // );
|
|
|
+ // 检查点是否已经存在于 valueArray 中
|
|
|
+ const index = valueArray.findIndex(
|
|
|
+ (item) => item.pointId === point.pointId
|
|
|
+ )
|
|
|
+ if (index === -1) {
|
|
|
+ // 如果点位不存在,则新增
|
|
|
+ valueArray.push(updatedPointData)
|
|
|
+ this.value = JSON.stringify(valueArray, null, 4)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加到绑定点ID数组
|
|
|
+ this.bindingPointIds.push(point.pointId)
|
|
|
+
|
|
|
+ // 从右侧盒子移除点
|
|
|
+ this.rightPoints = this.rightPoints.filter(
|
|
|
+ (item) => item.pointId !== point.pointId
|
|
|
+ )
|
|
|
+ // 如果点不在目标区域,重新添加到 rightPoints
|
|
|
+ this.rightPoints.push(point)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重新绘制图层
|
|
|
+ this.layer.draw()
|
|
|
+ })
|
|
|
+
|
|
|
+ // 重新绘制图层
|
|
|
+ this.layer.draw()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新下一个隔离点的位置
|
|
|
+ currentX += pointWidth + padding
|
|
|
+ if (currentX + pointWidth > boxX + boxWidth) {
|
|
|
+ currentX = boxX + padding
|
|
|
+ currentY += pointHeight + padding
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+#container {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.mapdata {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+}
|
|
|
+
|
|
|
+.left {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: flex-start;
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+</style>
|