Explorar el Código

3/21日 修改作业票物资柜底图从接口渲染 以及新增系统管理下基础数据 地图参数 地图点位信息页面

pm hace 8 meses
padre
commit
0a7dae5409

+ 45 - 0
src/api/system/configuration.js

@@ -0,0 +1,45 @@
+import request from '@/utils/request'
+
+// 查询基础数据-全局配置列表
+export function getIsSystemAttributePage(query) {
+  return request({
+    url: '/iscs/attribute/getIsSystemAttributePage',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询基础数据-全局配置详细
+export function selectIsSystemAttributeById(id) {
+  return request({
+    url: '/iscs/attribute/selectIsSystemAttributeById?id=' + id,
+    method: 'get'
+  })
+}
+
+// 新增基础数据-全局配置配置
+export function insertIsSystemAttribute(data) {
+  return request({
+    url: '/iscs/attribute/insertIsSystemAttribute',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改基础数据-全局配置配置
+export function updateIsSystemAttribute(data) {
+  return request({
+    url: '/iscs/attribute/updateIsSystemAttribute',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除基础数据-全局配置配置
+export function deleteIsSystemAttributeByIds(ids) {
+  return request({
+    url: '/iscs/attribute/deleteIsSystemAttributeByIds?ids=' + ids,
+    method: 'post'
+  })
+}
+

+ 45 - 0
src/api/system/mapconfig.js

@@ -0,0 +1,45 @@
+import request from '@/utils/request'
+
+// 查询地图参数列表
+export function getIsMapPage(query) {
+  return request({
+    url: '/iscs/map/getIsMapPage',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询地图参数详细
+export function selectIsMapById(id) {
+  return request({
+    url: '/iscs/map/selectIsMapById?id=' + id,
+    method: 'get'
+  })
+}
+
+// 新增地图参数配置
+export function insertIsMap(data) {
+  return request({
+    url: '/iscs/map/insertIsMap',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改地图参数配置
+export function updateIsMap(data) {
+  return request({
+    url: '/iscs/map/updateIsMap',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除地图参数配置
+export function deleteIsMapByIds(ids) {
+  return request({
+    url: '/iscs/map/deleteIsMapByIds?ids=' + ids,
+    method: 'post'
+  })
+}
+

+ 45 - 0
src/api/system/mappoint.js

@@ -0,0 +1,45 @@
+import request from '@/utils/request'
+
+// 查询地图点位数据列表
+export function getIsMapPointPage(query) {
+  return request({
+    url: '/iscs/map-point/getIsMapPointPage',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询地图点位数据详细
+export function selectIsMapPointById(id) {
+  return request({
+    url: '/iscs/map-point/selectIsMapPointById?id=' + id,
+    method: 'get'
+  })
+}
+
+// 新增地图点位数据配置
+export function insertIsMapPoint(data) {
+  return request({
+    url: '/iscs/map-point/insertIsMapPoint',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改地图点位数据配置
+export function updateIsMapPoint(data) {
+  return request({
+    url: '/iscs/map-point/updateIsMapPoint',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除地图点位数据配置
+export function deleteIsMapPointByIds(ids) {
+  return request({
+    url: '/iscs/map-point/deleteIsMapPointByIds?ids=' + ids,
+    method: 'post'
+  })
+}
+

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 340 - 314
src/views/mes/dv/lotoStation/MapData.vue


+ 15 - 2
src/views/mes/dv/lotoStation/index.vue

@@ -104,7 +104,7 @@
         prop="orderNum"
       />
       <el-table-column label="岗位" align="center" prop="workstationName" />
-
+      <el-table-column label="地图名称" align="center" prop="mapName" />
       <el-table-column
         label="锁定站详情"
         align="center"
@@ -202,7 +202,12 @@
         <el-form-item label="岗位" prop="workstationId" >
           <treeselect v-model="form.workstationId" :options="marsOptions" :normalizer="Marsnormalizer" placeholder="选择岗位"/>
         </el-form-item>
-
+        <el-form-item label="地图名称" prop="mapId">
+          <el-select style="width:290px" v-model="form.mapId" placeholder="地图名称">
+            <el-option v-for="item in this.MapOptions" :key="item.id" :label="item.name" :value="item.id">
+            </el-option>
+          </el-select>
+        </el-form-item>
         <el-form-item label="锁定站信息" prop="map">
           <el-input
             v-model="form.map"
@@ -233,6 +238,7 @@ import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 import { listMarsDept } from '@/api/system/marsdept'
 import { listTechnology } from '@/api/system/machinery'
+import { getIsMapPage } from '@/api/system/mapconfig'
 export default {
   name: "lock",
   dicts: ["hardware_status"],
@@ -274,6 +280,8 @@ export default {
       // 表单参数
       form: {
       },
+      // 地图名称 下拉
+      MapOptions: null,
       // 表单校验
       rules: {
         lotoCode: [
@@ -354,6 +362,11 @@ export default {
         pasge:1,
         size:-1
       }
+      // 获取地图类型 锁定站or地图
+      getIsMapPage(data).then(response => {
+        this.MapOptions = response.data.records
+      })
+      // 岗位
       listMarsDept(data).then(response => {
         this.marsOptions = this.handleTree(response.data.records,"workstationId","parentId")
       })

+ 81 - 49
src/views/mes/dv/technology/technologyDetail/MapData.vue

@@ -49,7 +49,7 @@
 import Konva from 'konva'
 import { getLotoMapInfo, getLotoInfo, updateLoto } from '@/api/mes/lotoStation/lotoStation'
 import { getTechnologyInfo, saveMachineryPoints } from '@/api/system/machinery'
-
+import { selectIsMapById } from '@/api/system/mapconfig'
 export default {
   name: 'KonvaExample',
   props: {
@@ -62,6 +62,8 @@ export default {
     return {
       stage: null,
       layer: null,
+      backgroundLayer:null,//背景图层
+      gridLayer:null,//网格图层
       selectedStates: [], // 用于存储每个元素的选中状态
       selectedText: [], // 用于存储未选中的元素文本
       rects: [], // 白色r        ect合集
@@ -72,13 +74,20 @@ export default {
       form: {},//拿到单个数据
       orignData: null,//原始数据
       pointIdList: [],//选中的隔离点
-      selectPoints: []//回显之前选中的隔离点
+      selectPoints: [],//回显之前选中的隔离点
+      imageUrl: '',//获取底图
+      width: '',//底图宽
+      height: '',//底图高
+      x: '',//底图横坐标
+      y: '',//底图纵坐标
+      pointList:null,//接口给的点位信息
     }
   },
   mounted() {
     this.$nextTick(() => {
       this.getLoToInfo()
     })
+
   },
 
   methods: {
@@ -94,10 +103,6 @@ export default {
         const lotoId = response.data.lotoId
         const sopId = ''
         const ticketId = ''
-        getLotoInfo(lotoId).then((response) => {
-          console.log(response, '电柜信息')
-          this.form = response.data
-        })
         getLotoMapInfo(lotoId, sopId, ticketId).then(response => {
           console.log(response, '电柜预览接口调用')
           this.form.map = response.data
@@ -105,18 +110,36 @@ export default {
             try {
               this.value = JSON.stringify(response.data, null, 4)
               this.orignData = this.value
+              this.initKonva()
             } catch (err) {
             }
           }
-          this.initKonva()
         })
+        getLotoInfo(lotoId).then((response) => {
+          console.log(response, '电柜信息')
+          this.form = response.data
+          // 获取不同底图 如地图或者柜子
+          selectIsMapById(response.data.mapId).then((response) => {
+            console.log(response, '获取底图')
+            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
+            this.initKonva()
+          })
+        })
+
       })
 
       //   设备工艺详情
       getTechnologyInfo(this.$route.query.machineryId).then(response => {
         console.log(response, '设备/工艺详情')
         this.selectPoints = response.data.pointIdList
+        this.initKonva()
       })
+
     },
     // 重置
     reset() {
@@ -183,46 +206,55 @@ export default {
         container: this.$refs.container, // 容器元素
         width: 1200,
         height: 860
-      })
+      });
 
-      // 创建图层
-      this.layer = new Konva.Layer()
+      // 创建网格图层(最底层)
+      this.gridLayer = new Konva.Layer();
+      this.stage.add(this.gridLayer);
 
-      // 创建底图
-      const bgImage = new Image()
-      bgImage.src = require('@/assets/images/table.png')
+      // 先绘制网格(不变)
+      this.drawGrid(50, 50, '#e0e0e0', this.gridLayer);
+
+      // 创建底图图层(第二层)
+      this.backgroundLayer = new Konva.Layer();
+      this.stage.add(this.backgroundLayer);
+
+      // 加载底图
+      const bgImage = new Image();
+      bgImage.src = this.imageUrl;
       bgImage.onload = () => {
-        const knovaImage = new Konva.Image({
-          x: 330,
-          y: 10,
+        const konvaImage = new Konva.Image({
+          x: this.x || 0,
+          y: this.y || 0,
           image: bgImage,
-          width: 500,
-          height: 790,
+          width: this.width || 1200,
+          height: this.height || 860,
           draggable: false
-        })
-        this.layer.add(knovaImage)
-        this.layer.draw()
-      }
+        });
+
+        // 添加底图到底图图层
+        this.backgroundLayer.add(konvaImage);
+        this.backgroundLayer.draw();
+      };
 
-      // 绘制无限网格
-      this.drawGrid(50, 50, '#e0e0e0') // 每个单元格50x50,浅灰色网格
+      // 创建主图层(第三层)用于存放隔离点
+      this.layer = new Konva.Layer();
+      this.stage.add(this.layer);
 
-      // 渲染数据
-      const imageSrc = require('@/assets/images/localSetIcon.jpg') // 图片路径
-      this.renderGrid(imageSrc, 6, 3, 450, 100, 120, 100, 50, 50, 60, 25)
+      // 渲染隔离点等数据
+      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.layer.draw();
 
       // 禁止舞台拖拽
-      this.stage.draggable(false)
+      this.stage.draggable(false);
     },
 
-    // 绘制无限网格
-    drawGrid(cellWidth, cellHeight, gridColor) {
-      const width = 1200
-      const height = 860
+// 绘制无限网格
+    drawGrid(cellWidth, cellHeight, gridColor, layer) {
+      const width = 1200;
+      const height = 860;
 
       // 绘制竖线
       for (let i = 0; i <= width; i += cellWidth) {
@@ -230,8 +262,8 @@ export default {
           points: [i, 0, i, height],
           stroke: gridColor,
           strokeWidth: 1
-        })
-        this.layer.add(verticalLine)
+        });
+        layer.add(verticalLine);
       }
 
       // 绘制横线
@@ -240,11 +272,11 @@ export default {
           points: [0, j, width, j],
           stroke: gridColor,
           strokeWidth: 1
-        })
-        this.layer.add(horizontalLine)
+        });
+        layer.add(horizontalLine);
       }
 
-      this.layer.draw()
+      layer.draw();
     },
 
     renderGrid(imageSrc) {
@@ -257,12 +289,12 @@ export default {
       this.selectedText = []
       this.pointIdList = [] // 初始化选中的点ID列表
 
-      const positions = JSON.parse(this.value)
-
+      // const positions = JSON.parse(this.value)
+const positions=this.pointList
       positions.forEach((pos, index) => {
-        const x = pos.col * 50 // 每个单元格宽度为50
-        const y = pos.row * 50 // 每个单元格高度为50
-        const labelText = pos.pointName // 对应的文字
+        const x = pos.x * 50 // 每个单元格宽度为50
+        const y = pos.y * 50 // 每个单元格高度为50
+        const labelText = pos.entityName // 对应的文字
 
         const point = new Image()
         point.src = pos.pointIcon
@@ -284,12 +316,12 @@ export default {
               // 如果当前已选中,则取消选中
               this.redrects[labelText].visible(false)
               this.redtexts[labelText].visible(false)
-              this.pointIdList = this.pointIdList.filter(id => id !== pos.pointId) // 移除ID
+              this.pointIdList = this.pointIdList.filter(id => id !== pos.entityId) // 移除ID
             } else {
               // 如果当前未选中,则选中
               this.redrects[labelText].visible(true)
               this.redtexts[labelText].visible(true)
-              this.pointIdList.push(pos.pointId) // 添加ID
+              this.pointIdList.push(pos.entityId) // 添加ID
             }
 
             this.layer.batchDraw() // 更新图层显示
@@ -370,11 +402,11 @@ export default {
 
           // 检查 selectPoints 是否存在并且不为空
           if (Array.isArray(this.selectPoints) && this.selectPoints.length > 0) {
-            if (this.selectPoints.includes(pos.pointId)) {
+            if (this.selectPoints.includes(pos.entityId)) {
               // 设置选中状态
               this.redrects[labelText].visible(true)
               this.redtexts[labelText].visible(true)
-              this.pointIdList.push(pos.pointId) // 添加ID
+              this.pointIdList.push(pos.entityId) // 添加ID
             }
           }
 

+ 162 - 102
src/views/mes/job/jobm/LockDetail.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="mapdata">
-    <div id="container" ref="container" style="width:300px"></div>
+    <div id="container" ref="container" style="width:100%;"></div>
   </div>
 
 </template>
@@ -9,6 +9,8 @@
 import Konva from 'konva'
 import { getLotoMapInfo, getLotoInfo } from '@/api/mes/lotoStation/lotoStation'
 import { getTechnologyInfo } from '@/api/system/machinery'
+import { selectIsMapById } from '@/api/system/mapconfig'
+
 export default {
   name: 'KonvaExample',
   props: {
@@ -31,13 +33,19 @@ export default {
       form: {},//拿到单个数据
       orignData: null,//原始数据
       pointIdList: [],//选中的隔离点
-      selectPoints: []//回显之前选中的隔离点
+      selectPoints: [],//回显之前选中的隔离点
+      imageUrl: '',//获取底图
+      width: '',//底图宽
+      height: '',//底图高
+      x: '',//底图横坐标
+      y: '',//底图纵坐标
+      pointList: null//接口给的所有点位数据
     }
   },
   watch: {
-    "machineryId":{
-      handler(newValue){
-        if(newValue){
+    'machineryId': {
+      handler(newValue) {
+        if (newValue) {
           console.log(this.machineryId, 'Mapdata拿到的父组件machineryId')
           this.getLoToInfo()
         }
@@ -47,10 +55,10 @@ export default {
   },
   mounted() {
     this.$nextTick(() => {
-      if(this.machineryId){
+      if (this.machineryId) {
         this.getLoToInfo()
         const machineryId = this.machineryId
-        console.log(machineryId,'Mapdata拿到的父组件传递数据')
+        console.log(machineryId, 'Mapdata拿到的父组件传递数据')
       }
     })
   },
@@ -65,6 +73,17 @@ export default {
         getLotoInfo(lotoId).then((response) => {
           console.log(response, '电柜信息')
           this.form = response.data
+          // 获取不同底图 如地图或者柜子
+          selectIsMapById(response.data.mapId).then((response) => {
+            console.log(response, '获取底图')
+            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
+            this.initKonva()
+          })
         })
         getLotoMapInfo(lotoId, sopId, ticketId).then(response => {
           console.log(response, '电柜预览接口调用')
@@ -79,7 +98,7 @@ export default {
           }
           this.initKonva()
         })
-      });
+      })
 
       //   设备工艺详情
       getTechnologyInfo(this.machineryId).then(response => {
@@ -99,86 +118,127 @@ export default {
     },
     initKonva() {
       // 创建舞台
-      this.stage = new Konva.Stage({
-        container: this.$refs.container, // 容器元素
-        width: 450,
-        height: 500
-      });
+      if (this.width > 1000) {
+        this.stage = new Konva.Stage({
+          container: this.$refs.container, // 容器元素
+          width: 1200,
+          height: 600
+        })
+      } else {
+        this.stage = new Konva.Stage({
+          container: this.$refs.container, // 容器元素
+          width: 1000,
+          height: 600
+        })
+      }
 
       // 创建底图图层
-      this.bgLayer = new Konva.Layer();
-// // 绘制无限网格
-//       this.drawGrid(20, 20, '#e0e0e0'); // 每个单元格50x50,浅灰色网格
+      this.bgLayer = new Konva.Layer()
+
       // 创建底图
-      const bgImage = new Image();
-      bgImage.src = require('@/assets/images/table.png');
+      const bgImage = new Image()
+
+      // bgImage.src = require('@/assets/images/MapImage.png')
+      bgImage.src = this.imageUrl
       bgImage.onload = () => {
-        const knovaImage = new Konva.Image({
-          x: 20,
-          y: -15,
-          image: bgImage,
-          width: 300,
-          height: 450,
-          draggable: false
-        });
-        this.bgLayer.add(knovaImage);
-        this.bgLayer.draw(); // 绘制底图图层
-      };
+        if (this.width > 1000) {
+          const knovaImage = new Konva.Image({
+            x: this.x,
+            y: this.y,
+            image: bgImage,
+            width: this.width / 1.3,
+            height: this.height / 1.4,
+            draggable: false
+          })
+          this.bgLayer.add(knovaImage)
+          this.bgLayer.draw() // 绘制底图图层
+        } else {
+          const knovaImage = new Konva.Image({
+            x: this.x - 130,
+            y: this.y - 20,
+            image: bgImage,
+            width: this.width / 1.5,
+            height: this.height / 1.5,
+            draggable: false
+          })
+          this.bgLayer.add(knovaImage)
+          this.bgLayer.draw() // 绘制底图图层
+        }
+
+      }
 
       // 将底图图层添加到舞台
-      this.stage.add(this.bgLayer);
+      this.stage.add(this.bgLayer)
 
       // 创建点位图层
-      this.layer = new Konva.Layer();
+      this.layer = new Konva.Layer()
 
       // 将点位图层添加到舞台
-      this.stage.add(this.layer);
+      this.stage.add(this.layer)
 
       // 禁止舞台拖拽
-      this.stage.draggable(false);
+      this.stage.draggable(false)
 
       // 渲染数据
-      const imageSrc = require('@/assets/images/localSetIcon.jpg'); // 图片路径
-      this.renderGrid(imageSrc, 6, 3, 450, 100, 120, 100, 50, 50, 60, 25);
+      const imageSrc = require('@/assets/images/localSetIcon.jpg') // 图片路径
+      this.renderGrid(imageSrc, 6, 3, 450, 100, 120, 100, 50, 50, 60, 25)
     },
 
     renderGrid(imageSrc) {
-      this.selectedStates = []; // 用数组存储选中状态
-      this.rects = {};
-      this.texts = {};
-      this.bgrects = {};
-      this.redrects = {};
-      this.redtexts = {};
-      this.selectedText = [];
-      this.pointIdList = []; // 初始化选中的点ID列表
-
-      const positions = JSON.parse(this.value); // 获取点位数据
-
+      this.selectedStates = [] // 用数组存储选中状态
+      this.rects = {}
+      this.texts = {}
+      this.bgrects = {}
+      this.redrects = {}
+      this.redtexts = {}
+      this.selectedText = []
+      this.pointIdList = [] // 初始化选中的点ID列表
+
+      // const positions = JSON.parse(this.value) // 获取点位数据
+      const positions = this.pointList
       // **计算柜子的布局范围**
-      const cabinetWidth = this.stage.width(); // 柜子的宽度
-      const cabinetHeight = this.stage.height(); // 柜子的高度
-      const cols = Math.max(...positions.map((p) => p.col)) + 1; // 根据数据动态计算总列数
-      const rows = Math.max(...positions.map((p) => p.row)) + 1; // 根据数据动态计算总行数
+      const cabinetWidth = this.stage.width() // 柜子的宽度
+      const cabinetHeight = this.stage.height() // 柜子的高度
+      const cols = Math.max(...positions.map((p) => p.x)) + 1 // 根据数据动态计算总列数
+      const rows = Math.max(...positions.map((p) => p.y)) + 1 // 根据数据动态计算总行数
       // 调整横向和纵向间距
-      const horizontalSpacingFactor = 1.032; // 横向间距放大倍数
-      const verticalSpacingFactor = 0.53; // 纵向间距缩小倍数
+      let horizontalSpacingFactor
+      let verticalSpacingFactor
+      if(this.width>1000){
+        horizontalSpacingFactor = 1.032 // 横向间距放大倍数
+        verticalSpacingFactor = 0.53 // 纵向间距缩小倍数
+      }else{
+        horizontalSpacingFactor = 0.4 // 横向间距放大倍数
+        verticalSpacingFactor = 0.53 // 纵向间距缩小倍数
+      }
+
 
-      const cellWidth = (cabinetWidth / cols) * horizontalSpacingFactor; // 调整横向间距
-      const cellHeight = (cabinetHeight / rows) * verticalSpacingFactor; // 调整纵向间距
+      const cellWidth = (cabinetWidth / cols) * horizontalSpacingFactor // 调整横向间距
+      const cellHeight = (cabinetHeight / rows) * verticalSpacingFactor // 调整纵向间距
 
       // 遍历点位,按行列布局计算位置
       positions.forEach((pos) => {
-        const col = pos.col; // 当前点位的列
-        const row = pos.row; // 当前点位的行
-
-        // 计算点位的实际位置,确保它们位于柜子显示区域内
-        const x = col * cellWidth - 220; // 调整偏移量,使其向左移动
-        const y = row * cellHeight - 20; // 调整偏移量,使其向上移动
+        let x, y
+
+        if (this.width > 1000) {
+          // 直接使用 positions 中的 x 和 y 坐标
+          const col = pos.x  // 当前点位的列
+          const row = pos.y  // 当前点位的行
+          x = col * cellWidth - 700 // 调整偏移量,使其向左移动
+          y = row * cellHeight - 20 // 调整偏移量,使其向上移动
+          console.log(pos, '位置信息')
+        } else {
+          // 计算点位的实际位置,确保它们位于柜子显示区域内
+          const col = pos.x // 当前点位的列
+          const row = pos.y // 当前点位的行
+          x = col * cellWidth + 30 // 调整偏移量,使其向左移动
+          y = row * cellHeight - 20 // 调整偏移量,使其向上移动
+        }
 
-        const labelText = pos.pointName; // 对应的文字
+        const labelText = pos.entityName // 对应的文字
 
-        const point = new Image();
-        point.src = pos.pointIcon;
+        const point = new Image()
+        point.src = pos.pointIcon
         point.onload = () => {
           const knovaImage = new Konva.Image({
             x: x + 6, // 适当的偏移确保点位不重叠
@@ -186,8 +246,8 @@ export default {
             image: point,
             width: 29, // 增加宽度
             height: 28, // 增加高度
-            draggable: false,
-          });
+            draggable: false
+          })
 
           // **绘制背景矩形**(以单元格大小为基础)
           const bgrect = new Konva.Rect({
@@ -196,12 +256,12 @@ export default {
             width: 40, // 增加宽度
             height: 46, // 增加高度
             cornerRadius: 5,
-            stroke: "white",
+            stroke: 'white',
             strokeWidth: 2,
-            fill: "white",
-          });
-          this.layer.add(bgrect);
-          this.bgrects[labelText] = bgrect;
+            fill: 'white'
+          })
+          this.layer.add(bgrect)
+          this.bgrects[labelText] = bgrect
 
           // **普通矩形边框**(同样按照单元格尺寸)
           const rect = new Konva.Rect({
@@ -210,15 +270,15 @@ export default {
             width: 40 - 5, // 增加宽度
             height: 46 - 4, // 增加高度
             cornerRadius: 5,
-            stroke: "red",
+            stroke: 'red',
             strokeWidth: 2,
-            fill: "white",
-          });
-          this.layer.add(rect);
-          this.rects[labelText] = rect;
+            fill: 'white'
+          })
+          this.layer.add(rect)
+          this.rects[labelText] = rect
 
           // 添加图片
-          this.layer.add(knovaImage);
+          this.layer.add(knovaImage)
 
           // **绘制点位的文字**(确保与背景矩形不重叠)
           const text = new Konva.Text({
@@ -226,11 +286,11 @@ export default {
             y: y + 46 - 15, // 文字放在底部
             fontSize: 14,
             text: labelText,
-            fontFamily: "Calibri",
-            fill: "red",
-          });
-          this.layer.add(text);
-          this.texts[labelText] = text;
+            fontFamily: 'Calibri',
+            fill: 'red'
+          })
+          this.layer.add(text)
+          this.texts[labelText] = text
 
           // **选中覆盖矩形**(保持与背景矩形相同的尺寸)
           const redrect = new Konva.Rect({
@@ -239,45 +299,45 @@ export default {
             width: 40, // 增加宽度
             height: 46, // 增加高度
             cornerRadius: 5,
-            fill: "rgba(97, 97, 97, 0.5)", // 半透明灰色
+            fill: 'rgba(97, 97, 97, 0.5)', // 半透明灰色
             visible: false, // 初始状态隐藏
-            listening: false,
-          });
-          this.layer.add(redrect);
-          this.redrects[labelText] = redrect;
+            listening: false
+          })
+          this.layer.add(redrect)
+          this.redrects[labelText] = redrect
 
           // **对号文字(表示选中)**
           const redtext = new Konva.Text({
             x: x + 40 / 2 - 5, // 水平居中
             y: y + 46 / 2 - 5, // 垂直居中
             fontSize: 13,
-            text: "✔",
-            fontFamily: "Arial",
-            fill: "white",
-            align: "center",
+            text: '✔',
+            fontFamily: 'Arial',
+            fill: 'white',
+            align: 'center',
             visible: false, // 初始隐藏状态
-            listening: false,
-          });
-          this.layer.add(redtext);
-          this.redtexts[labelText] = redtext;
+            listening: false
+          })
+          this.layer.add(redtext)
+          this.redtexts[labelText] = redtext
 
           // 如果初始化时有选中的点位
           if (
             Array.isArray(this.selectPoints) &&
             this.selectPoints.length > 0
           ) {
-            if (this.selectPoints.includes(pos.pointId)) {
+            if (this.selectPoints.includes(pos.entityId)) {
               // 设置选中状态
-              this.redrects[labelText].visible(true);
-              this.redtexts[labelText].visible(true);
-              this.pointIdList.push(pos.pointId); // 添加ID
+              this.redrects[labelText].visible(true)
+              this.redtexts[labelText].visible(true)
+              this.pointIdList.push(pos.entityId) // 添加ID
             }
           }
 
-          this.layer.draw(); // 刷新画布
-        };
-      });
-    },
+          this.layer.draw() // 刷新画布
+        }
+      })
+    }
 
   }
 }

+ 80 - 29
src/views/mes/job/jobm/Mapdata.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="mapdata">
-    <div id="container" ref="container" style="width: 300px"></div>
+    <div id="container" ref="container" style="width: 580px"></div>
   </div>
 </template>
 
@@ -8,6 +8,7 @@
 import Konva from "konva";
 import { getLotoMapInfo, getLotoInfo } from "@/api/mes/lotoStation/lotoStation";
 import { getTechnologyInfo } from "@/api/system/machinery";
+import { selectIsMapById } from '@/api/system/mapconfig'
 export default {
   name: "KonvaExample",
   props: {
@@ -31,6 +32,12 @@ export default {
       orignData: null, //原始数据
       pointIdList: [], //选中的隔离点
       selectPoints: [], //回显之前选中的隔离点
+      imageUrl: '',//获取底图
+      width: '',//底图宽
+      height: '',//底图高
+      x: '',//底图横坐标
+      y: '',//底图纵坐标
+      pointList:null,//接口给的所有点位数据
     };
   },
   watch: {
@@ -64,6 +71,17 @@ export default {
         getLotoInfo(lotoId).then((response) => {
           console.log(response, "电柜信息");
           this.form = response.data;
+          // 获取不同底图 如地图或者柜子
+          selectIsMapById(response.data.mapId).then((response) => {
+            console.log(response, '获取底图')
+            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
+            this.initKonva()
+          })
         });
         getLotoMapInfo(lotoId, sopId, ticketId).then((response) => {
           console.log(response, "电柜预览接口调用");
@@ -90,8 +108,8 @@ export default {
       // 创建舞台
       this.stage = new Konva.Stage({
         container: this.$refs.container, // 容器元素
-        width: 300,
-        height: 410,
+        width: 580,
+        height: 400,
       });
 
       // 创建底图图层
@@ -99,19 +117,36 @@ export default {
 
       // 创建底图
       const bgImage = new Image();
-      bgImage.src = require("@/assets/images/table.png");
-      bgImage.onload = () => {
-        const knovaImage = new Konva.Image({
-          x: 50,
-          y: -25,
-          image: bgImage,
-          width: 220,
-          height: 410,
-          draggable: false,
-        });
-        this.bgLayer.add(knovaImage);
-        this.bgLayer.draw(); // 绘制底图图层
-      };
+      // bgImage.src = require("@/assets/images/table.png");
+      bgImage.src=this.imageUrl;
+      if(this.width>1000){
+        bgImage.onload = () => {
+          const knovaImage = new Konva.Image({
+            x: this.x,
+            y: this.y,
+            image: bgImage,
+            width: this.width/2,
+            height: this.height/2,
+            draggable: false,
+          });
+          this.bgLayer.add(knovaImage);
+          this.bgLayer.draw(); // 绘制底图图层
+        };
+      }else {
+        bgImage.onload = () => {
+          const knovaImage = new Konva.Image({
+            x: this.x-220,
+            y: this.y,
+            image: bgImage,
+            width: this.width/2,
+            height: this.height/2,
+            draggable: false,
+          });
+          this.bgLayer.add(knovaImage);
+          this.bgLayer.draw(); // 绘制底图图层
+        };
+      }
+
 
       // 将底图图层添加到舞台
       this.stage.add(this.bgLayer);
@@ -140,30 +175,46 @@ export default {
       this.selectedText = [];
       this.pointIdList = []; // 初始化选中的点ID列表
 
-      const positions = JSON.parse(this.value); // 获取点位数据
-
+      // const positions = JSON.parse(this.value); // 获取点位数据
+      const positions=this.pointList
       // **计算柜子的布局范围**
       const cabinetWidth = this.stage.width(); // 柜子的宽度
       const cabinetHeight = this.stage.height(); // 柜子的高度
-      const cols = Math.max(...positions.map((p) => p.col)) + 1; // 根据数据动态计算总列数
-      const rows = Math.max(...positions.map((p) => p.row)) + 1; // 根据数据动态计算总行数
+      const cols = Math.max(...positions.map((p) => p.x)) + 1; // 根据数据动态计算总列数
+      const rows = Math.max(...positions.map((p) => p.y)) + 1; // 根据数据动态计算总行数
       // 调整横向和纵向间距
-      const horizontalSpacingFactor = 1.032; // 横向间距放大倍数
-      const verticalSpacingFactor = 0.53; // 纵向间距缩小倍数
+      let horizontalSpacingFactor
+      let verticalSpacingFactor
+      if(this.width>1000){
+        horizontalSpacingFactor = 1; // 横向间距放大倍数
+        verticalSpacingFactor = 0.43; // 纵向间距缩小倍数
+      }else{
+        horizontalSpacingFactor = 0.7; // 横向间距放大倍数
+        verticalSpacingFactor = 0.49; // 纵向间距缩小倍数
+      }
+
 
       const cellWidth = (cabinetWidth / cols) * horizontalSpacingFactor; // 调整横向间距
       const cellHeight = (cabinetHeight / rows) * verticalSpacingFactor; // 调整纵向间距
 
       // 遍历点位,按行列布局计算位置
       positions.forEach((pos) => {
-        const col = pos.col; // 当前点位的列
-        const row = pos.row; // 当前点位的行
+        const col = pos.x; // 当前点位的列
+        const row = pos.y; // 当前点位的行
 
         // 计算点位的实际位置,确保它们位于柜子显示区域内
-        const x = col * cellWidth - 100;
-        const y = row * cellHeight - 30;
+        let x
+        let y
+        if(this.width>1000){
+          x = col * cellWidth - 250;
+          y = row * cellHeight - 0;
+        }else{
+          x = col * cellWidth - 100;
+          y = row * cellHeight + 15;
+        }
+
 
-        const labelText = pos.pointName; // 对应的文字
+        const labelText = pos.entityName; // 对应的文字
 
         const point = new Image();
         point.src = pos.pointIcon;
@@ -254,11 +305,11 @@ export default {
             Array.isArray(this.selectPoints) &&
             this.selectPoints.length > 0
           ) {
-            if (this.selectPoints.includes(pos.pointId)) {
+            if (this.selectPoints.includes(pos.entityId)) {
               // 设置选中状态
               this.redrects[labelText].visible(true);
               this.redtexts[labelText].visible(true);
-              this.pointIdList.push(pos.pointId); // 添加ID
+              this.pointIdList.push(pos.entityId); // 添加ID
             }
           }
 

+ 110 - 170
src/views/mes/job/jobm/NewMarsJob.vue

@@ -26,59 +26,43 @@
         }"
       >
         <img
-          style="width: 100%; height: 100%"
-          src="@/assets/images/marsBg.png"
+          :style="{width:jobconfig.width+'px',height:jobconfig.height+'px'}"
+          :src="jobconfig.imageUrl"
           alt=""
         />
-        <img
-          v-for="(ticket, index) in TicketListPage"
-          :key="ticket.ticketId"
-          :style="{
-            width: '35px',
-            height: '35px',
-            position: 'absolute',
-            cursor: 'pointer',
-            // 图标垂直居中
-            top: `${deptXLGCenter.top - 53}px`,
-            // 图标水平居中,动态计算偏移
-            left: `${
-              deptXLGCenter.left -
-              (TicketListPage.length * 35 + (TicketListPage.length - 1) * 5) /
-                2 +
-              index * 40
-            }px`,
-          }"
-          :src="require(`@/assets/images/${imageMap[ticket.ticketType]}.png`)"
-          alt=""
-          @click="handleTicketClick(ticket)"
-        />
+        <div v-for="(item, index) in jobconfigPoint.records" :key="item.id">
+          <div
+            class="deptGreen"
+            :style="{left:item.x+'px',top:item.y+'px'}"
+            @click="handelChange('second', item.entityId, item.entityName)"
+          >
+            {{ item.entityName }}
+          </div>
+
+          <!--          // 使图标位于岗位上方-->
+          <img
+            v-for="(ticket, index) in TicketListPage[item.entityId] || []"
+            :key="ticket.ticketId"
+            :style="{
+    width: '35px',
+    height: '35px',
+    position: 'absolute',
+    cursor: 'pointer',
+    top: (item.y - 40) + 'px',  // 让图标浮在岗位的上方
+    left: (
+      item.x -
+      ((TicketListPage[item.entityId] ? TicketListPage[item.entityId].length * 35 : 0) - 53) / 2 +  // 计算总宽度并居中,减去单个图标宽度,确保居中
+      index * 40  // 处理图标间隔
+    ) + 'px'
+  }"
+            :src="require(`@/assets/images/${imageMap[ticket.ticketType]}.png`)"
+            alt=""
+            @click="handleTicketClick(ticket)"
+          />
+
+
+        </div>
 
-        <!-- deptCCO 区域的图标 -->
-        <img
-          v-for="(ticket, index) in COCOTicketListPage"
-          :key="ticket.ticketId"
-          :style="{
-            width: '35px',
-            height: '35px',
-            position: 'absolute',
-            cursor: 'pointer',
-            // 图标垂直居中
-            top: `${deptCCOCenter.top - 53}px`,
-            // 图标水平居中,动态计算偏移
-            left: `${
-              deptCCOCenter.left -
-              (COCOTicketListPage.length * 35 +
-                (COCOTicketListPage.length - 1) * 5) /
-                2 +
-              index * 40
-            }px`,
-          }"
-          :src="require(`@/assets/images/${imageMap[ticket.ticketType]}.png`)"
-          alt=""
-          @click="handleTicketClick(ticket)"
-        />
-        <div class="deptXLG" @click="handelChange('second', 8, 'R&R')">R&R</div>
-        <div class="deptCCO" @click="handelChange('second', 7, 'CCO')">CCO</div>
       </div>
     </div>
 
@@ -176,34 +160,34 @@
               ></i>
             </div>
             <el-row>
-              <el-col :span="9">
-                <el-table
-                  :data="selectPointList"
-                  :show-header="false"
-                  height="200"
-                  @row-click="handleChangeTable"
-                  v-if="tableVisible"
-                >
-                  <el-table-column prop="pointName" label=""></el-table-column>
-                  <el-table-column prop="remark" label=""></el-table-column>
-                </el-table>
-                <span
-                  v-if="!tableVisible"
-                  style="color: #53a3ef; cursor: pointer"
-                  @click="handleChangeTable"
-                >锁定站</span
-                >
-                <img
-                  src="@/assets/images/sopbgimg.png"
-                  style="width: 200px; height: 130px; margin-top: 10px"
-                />
-              </el-col>
-              <el-col :span="8">
-                <MapData
-                  style="width: 300px; height: 320px; margin-left: 18%"
-                  :machineryId="this.machineryId"
-                ></MapData>
-              </el-col>
+              <MapData
+                :machineryId="this.machineryId"
+              ></MapData>
+<!--              <el-col :span="9">-->
+<!--                <el-table-->
+<!--                  :data="selectPointList"-->
+<!--                  :show-header="false"-->
+<!--                  height="200"-->
+<!--                  @row-click="handleChangeTable"-->
+<!--                  v-if="tableVisible"-->
+<!--                >-->
+<!--                  <el-table-column prop="pointName" label=""></el-table-column>-->
+<!--                  <el-table-column prop="remark" label=""></el-table-column>-->
+<!--                </el-table>-->
+<!--                <span-->
+<!--                  v-if="!tableVisible"-->
+<!--                  style="color: #53a3ef; cursor: pointer"-->
+<!--                  @click="handleChangeTable"-->
+<!--                >锁定站</span-->
+<!--                >-->
+<!--                <img-->
+<!--                  src="@/assets/images/MapImage.png"-->
+<!--                  style="width: 200px; height: 130px; margin-top: 10px"-->
+<!--                />-->
+<!--              </el-col>-->
+<!--              <el-col :span="8">-->
+
+<!--              </el-col>-->
             </el-row>
           </el-card>
         </div>
@@ -725,57 +709,29 @@
     <el-dialog
       :visible.sync="LockDetailvisible"
       title="锁定站信息"
-      height="500px"
       width="1200px"
       append-to-body
     >
       <!--      这里为了没有地图数据而设置的-->
-      <!--      <el-row>-->
-      <!--        <el-col :span="8">-->
-      <!--          <div style="padding: 10px">-->
-      <!--            <el-table :data="selectPointList" :show-header="false" style="width: 200px;height: 175px;margin-left: 15%">-->
-      <!--              <el-table-column-->
-      <!--                prop="pointName"-->
-      <!--                label=""-->
-      <!--              ></el-table-column>-->
-      <!--              <el-table-column-->
-      <!--                prop="remark"-->
-      <!--                label=""-->
-      <!--              ></el-table-column>-->
-      <!--            </el-table>-->
-      <!--          </div>-->
-      <!--        </el-col>-->
-      <!--        <el-col :span="8">-->
-      <!--          <LockDetail-->
-      <!--            style=" margin-left: 5%"-->
-      <!--            :machineryId="this.machineryId"-->
-      <!--          ></LockDetail>-->
-      <!--        </el-col>-->
-      <!--        <el-col :span="8">-->
-      <!--          <div style="padding: 10px"></div>-->
-      <!--        </el-col>-->
-      <!--      </el-row>-->
-
       <el-row>
-        <el-col :span="8">
+        <el-col :span="6">
+          <div>
+            <el-table :data="selectPointList" :show-header="false" style="width: 200px;height: 175px;">
+              <el-table-column
+                prop="pointName"
+                label=""
+              ></el-table-column>
+              <el-table-column
+                prop="remark"
+                label=""
+              ></el-table-column>
+            </el-table>
+          </div>
+        </el-col>
+        <el-col :span="18">
           <LockDetail
-            style="width: 300px; height: 520px; margin-left: 5%"
             :machineryId="this.machineryId"
           ></LockDetail>
-          <el-table
-            :data="selectPointList"
-            :show-header="false"
-            style="width: 200px; height: 175px; margin-left: 15%"
-          >
-            <el-table-column prop="pointName" label=""></el-table-column>
-            <el-table-column prop="remark" label=""></el-table-column>
-          </el-table>
-        </el-col>
-        <el-col :span="16">
-          <img
-            src="@/assets/images/sopbgimg.png"
-            style="width: 100%; height: 100%"
-          />
         </el-col>
       </el-row>
     </el-dialog>
@@ -805,6 +761,8 @@ import { getUserList } from '@/api/mes/workCard'
 import { getJobPlayTicketInfo } from '@/api/mes/jobplay/jobplay'
 import { getLotoInfo, getLotoMapInfo } from '@/api/mes/lotoStation/lotoStation'
 import LockDetail from '@/views/mes/job/jobm/LockDetail.vue'
+import { selectIsMapById } from '@/api/system/mapconfig'
+import { getIsMapPointPage } from '@/api/system/mappoint'
 
 export default {
   name: 'NewSop',
@@ -812,6 +770,8 @@ export default {
   dicts: ['sop_type', 'ticket_status', 'ticket_user_type'],
   data() {
     return {
+      jobconfig: null,//接口传递地图与宽高数据
+      jobconfigPoint: null,//接口传递的岗位位置信息
       imageMap: {
         0: 'ticketType0', //维修
         1: 'ticketType1', //Pm
@@ -858,7 +818,6 @@ export default {
       jobTicket: [], //第五步详情的作业票信息
       TicketListPage: [], //作业票列表page接口传递的数据 底图循环渲染图标 RR岗位作业票
       selectPointList: [], //隔离点选中的表格渲染
-      COCOTicketListPage: [], //CCO岗位的作业票
       scaleFactor: 1, // 缩放比例,初始值为1
       EightDetailvisible: false, //第八步受影响作业票
       AffectedTickets: [], //第八步查看详情信息表格
@@ -887,36 +846,16 @@ export default {
     }
   },
   computed: {
-    // filteredSopTypes() {
-    //   const sopTypesInMarsSopPage = this.marsSopPage.map(
-    //     (item) => item.sopType
-    //   )
-    //   return this.dict.type.sop_type.filter((option) =>
-    //     sopTypesInMarsSopPage.includes(option.value)
-    //   )
-    // },
     isStepFourExecuted() {
       const stepFour = this.EightStepForm.find((step) => step.stepIndex == '4')
       return stepFour && stepFour.stepStatus === '1'
-    },
-    deptXLGCenter() {
-      return {
-        left: this.deptXLGPosition.left + this.deptXLGPosition.width / 2,
-        top: this.deptXLGPosition.top + this.deptXLGPosition.height / 2
-      }
-    },
-    deptCCOCenter() {
-      return {
-        left: this.deptCCOPosition.left + this.deptCCOPosition.width / 2,
-        top: this.deptCCOPosition.top + this.deptCCOPosition.height / 2
-      }
     }
   },
   watch: {
     tabPosition: function(val, oldVal) {
       if (val == 'first') {
         this.sopTypeOption = []
-        this.technologyList=[]
+        this.technologyList = []
         this.sopId = null
         this.getList()
       }
@@ -935,9 +874,9 @@ export default {
   },
   methods: {
     // 锁定站信息部分表格收缩
-    handleChangeTable() {
-      this.tableVisible = !this.tableVisible
-    },
+    // handleChangeTable() {
+    //   this.tableVisible = !this.tableVisible
+    // },
     // 锁定站进入详细页面
     goLockDetail() {
       // this.$router.push({
@@ -1042,14 +981,17 @@ export default {
       }
       getWorkstationTicketList(data).then((res) => {
         console.log(res, '查看-正在进行中作业票列表')
+        let ticketsByWorkstation = {}
 
-        this.TicketListPage = res.data.filter(
-          (item) => item.workstationId == '8'
-        )
+        res.data.forEach((ticket) => {
+          if (!ticketsByWorkstation[ticket.workstationId]) {
+            ticketsByWorkstation[ticket.workstationId] = []
+          }
+          ticketsByWorkstation[ticket.workstationId].push(ticket)
+        })
+
+        this.TicketListPage = ticketsByWorkstation
 
-        this.COCOTicketListPage = res.data.filter(
-          (item) => item.workstationId == '7'
-        )
       })
       // 这里注释掉是为了 初始化跳转数据为空
       const data1 = {
@@ -1065,6 +1007,20 @@ export default {
         console.log(res, 'marsDeptList')
         this.marsDeptList = res.data.records
       })
+      // 这里获取全局配置地图参数里的作业票地图
+      selectIsMapById(1).then((res) => {
+        console.log(res, '作业票地图 图片数据')
+        this.jobconfig = res.data
+      })
+      const dataMap={
+        pages: 1,
+        size: -1,
+        mapId:1
+      }
+      getIsMapPointPage(dataMap).then((res) => {
+        console.log(res, '作业票地图岗位位置信息接口')
+        this.jobconfigPoint = res.data
+      })
     },
     // sop类型 el-radio
     handleSopchange(data) {
@@ -1103,7 +1059,7 @@ export default {
         //   this.marsSopPage = res.data.records
         // })
       }
-      if (!this.sopId&&val == 'third') {
+      if (!this.sopId && val == 'third') {
         this.$message.error('请先选择对应设备工艺或sop类型')
         return
       }
@@ -1459,26 +1415,10 @@ export default {
 
 
 <style scoped lang="scss">
-.deptXLG {
-  position: absolute;
-  width: 65px;
-  height: 25px;
-  left: 500px;
-  top: 260px;
-  background: #70b26f;
-  line-height: 25px;
-  text-align: center;
-  border-radius: 5px;
-  color: #fff;
-  cursor: pointer;
-}
-
-.deptCCO {
+.deptGreen {
   position: absolute;
   width: 65px;
   height: 25px;
-  left: 670px;
-  top: 480px;
   background: #70b26f;
   line-height: 25px;
   text-align: center;

+ 2 - 6
src/views/mes/material/inspectionplan/index.vue

@@ -6,11 +6,10 @@
       size="small"
       :inline="true"
       v-show="showSearch"
-      label-width="100px"
+      label-width="90px"
     >
       <el-form-item label="计划名称" prop="planName" v-if="!visibleSelect">
         <el-input
-
           v-model="queryParams.planName"
           placeholder="请输入计划名称"
           clearable
@@ -20,7 +19,7 @@
       <el-form-item label="物资柜" prop="cabinetId">
         <el-select
           v-model="queryParams.cabinetId"
-          placeholder="请选择需要检查的物资柜"
+          placeholder="请选择检查的物资柜"
           clearable
           :disabled="visibleSelect"
         >
@@ -32,10 +31,8 @@
           />
         </el-select>
       </el-form-item>
-
       <el-form-item label="计划日期">
         <el-date-picker
-          style="width: 300px"
           :default-time="['00:00:00', '23:59:59']"
           v-model="createTime"
           type="datetimerange"
@@ -72,7 +69,6 @@
           />
         </el-select>
       </el-form-item>
-
       <el-form-item>
         <el-button
           v-no-more-click

+ 89 - 97
src/views/mes/material/lockers/index.vue

@@ -27,60 +27,66 @@
       >
 
         <img
-          style="width: 100%; height: 100%"
-          src="@/assets/images/marsBg.png"
+          :style="{width:jobconfig.width+'px',height:jobconfig.height+'px'}"
+          :src="jobconfig.imageUrl"
           alt=""
         />
 
-        <img
-          v-for="(cabinet, index) in TicketListPage"
-          :key="cabinet.cabinetId"
-          :style="{
-            width: '35px',
-            height: '35px',
-            position: 'absolute',
-            cursor: 'pointer',
-            // 图标垂直居中
-            top: `${deptXLGCenter.top - 53}px`,
-            // 图标水平居中,动态计算偏移
-            left: `${
-              deptXLGCenter.left -
-              (TicketListPage.length * 35 + (TicketListPage.length - 1) * 5) /
-                2 +
-              index * 40
-            }px`,
-          }"
-          :src="require(`@/assets/images/${imageMap[cabinet.status]}.jpg`)"
-          alt=""
-          @click="handleCabinetClick(cabinet)"
-        />
+<!--        <img-->
+<!--          v-for="(cabinet, index) in TicketListPage"-->
+<!--          :key="cabinet.cabinetId"-->
+<!--          :style="{-->
+<!--            width: '35px',-->
+<!--            height: '35px',-->
+<!--            position: 'absolute',-->
+<!--            cursor: 'pointer',-->
+<!--            // 图标垂直居中-->
+<!--            top: `${deptXLGCenter.top - 53}px`,-->
+<!--            // 图标水平居中,动态计算偏移-->
+<!--            left: `${-->
+<!--              deptXLGCenter.left - -->
+<!--              (TicketListPage.length * 35 + (TicketListPage.length - 1) * 5) /-->
+<!--                2 +-->
+<!--              index * 40-->
+<!--            }px`,-->
+<!--          }"-->
+<!--          :src="require(`@/assets/images/${imageMap[cabinet.status]}.jpg`)"-->
+<!--          alt=""-->
+<!--          @click="handleCabinetClick(cabinet)"-->
+<!--        />-->
+
+        <div v-for="(item, index) in jobconfigPoint.records" :key="item.id">
+          <div
+            class="deptXLG"
+            :style="{left:item.x+'px',top:item.y+'px'}"
+          >
+            {{ item.entityName }}
+          </div>
 
-        <!-- deptCCO 区域的图标 -->
-        <!--        <img-->
-        <!--          v-for="(cabinet, index) in COCOTicketListPage"-->
-        <!--          :key="cabinet.cabinetId"-->
-        <!--          :style="{-->
-        <!--            width: '35px',-->
-        <!--            height: '35px',-->
-        <!--            position: 'absolute',-->
-        <!--            cursor: 'pointer',-->
-        <!--            // 图标垂直居中-->
-        <!--            top: `${deptCCOCenter.top - 53}px`,-->
-        <!--            // 图标水平居中,动态计算偏移-->
-        <!--            left: `${-->
-        <!--              deptCCOCenter.left - -->
-        <!--              (COCOTicketListPage.length * 35 +-->
-        <!--                (COCOTicketListPage.length - 1) * 5) /-->
-        <!--                2 +-->
-        <!--              index * 40-->
-        <!--            }px`,-->
-        <!--          }"-->
-        <!--          :src="require('@/assets/images/table_map2.jpg')"-->
-        <!--          alt=""-->
-        <!--          @click="handleCabinetClick(cabinet)"-->
-        <!--        />-->
-        <div class="deptXLG">LD</div>
-        <!--        <div class="deptCCO">CCO</div>-->
+          <!--          // 使图标位于岗位上方-->
+          <img
+            v-for="(cabinet, index) in TicketListPage[item.entityId] || []"
+            :key="cabinet.cabinetId"
+            :style="{
+    width: '35px',
+    height: '35px',
+    position: 'absolute',
+    cursor: 'pointer',
+    top: (item.y - 40) + 'px',  // 让图标浮在岗位的上方
+    left: (
+      item.x -
+      ((TicketListPage[item.entityId] ? TicketListPage[item.entityId].length * 35 : 0) - 53) / 2 +  // 计算总宽度并居中,减去单个图标宽度,确保居中
+      index * 40  // 处理图标间隔
+    ) + 'px'
+  }"
+            :src="require(`@/assets/images/${imageMap[cabinet.status]}.jpg`)"
+            alt=""
+            @click="handleCabinetClick(cabinet)"
+          />
+
+
+        </div>
+<!--        左侧警告部分内容-->
         <img style="width: 40px;height: 40px;position: absolute;top:2%;right: -4%" src="@/assets/images/警告.png" alt=""
              @click="showExTable"
         >
@@ -391,6 +397,8 @@ import { listMarsDept } from '@/api/system/marsdept'
 import { listLoto } from '@/api/mes/lotoStation/lotoStation'
 import { listMaterials } from '@/api/mes/material/information'
 import { MaterialsLoanExceptionPage } from '@/api/mes/material/exception'
+import { selectIsMapById } from '@/api/system/mapconfig'
+import { getIsMapPointPage } from '@/api/system/mappoint'
 
 export default {
   name: 'Team',
@@ -400,6 +408,8 @@ export default {
   dicts: ['material_status', 'cabinet_status', 'exception_reason'],
   data() {
     return {
+      jobconfig: null,//接口传递地图与宽高数据
+      jobconfigPoint: null,//接口传递的岗位位置信息
       //自动生成编码
       autoGenFlag: false,
       optType: undefined,
@@ -490,20 +500,9 @@ export default {
       },
       marsOptions: [], //岗位
       TicketListPage: [], //R&R岗位
-      COCOTicketListPage: [], //CCO岗位
+
       scaleFactor: 1, // 缩放比例,初始值为1
-      deptXLGPosition: {
-        left: 500,
-        top: 260,
-        width: 65,
-        height: 25
-      },
-      deptCCOPosition: {
-        left: 670,
-        top: 480,
-        width: 65,
-        height: 25
-      },
+
       exceptionTableVisible: false,//地图显示异常物资柜具体信息
       exceptionTable: [],//地图异常数据table数据
       workstationOptions: [], //岗位
@@ -513,20 +512,7 @@ export default {
       }
     }
   },
-  computed: {
-    deptXLGCenter() {
-      return {
-        left: this.deptXLGPosition.left + this.deptXLGPosition.width / 2,
-        top: this.deptXLGPosition.top + this.deptXLGPosition.height / 2
-      }
-    },
-    deptCCOCenter() {
-      return {
-        left: this.deptCCOPosition.left + this.deptCCOPosition.width / 2,
-        top: this.deptCCOPosition.top + this.deptCCOPosition.height / 2
-      }
-    }
-  },
+
   watch: {
     'queryParams.workstationId': function(newVal, oldVal) {
       if (newVal) {
@@ -673,12 +659,17 @@ export default {
       }
       getMaterialsCabinet(data).then((response) => {
         console.log(response, '所有物资柜')
-        this.TicketListPage = response.data.records.filter((item) => {
-          return item.workstationId == '6'
-        })
-        this.COCOTicketListPage = response.data.records.filter((item) => {
-          return item.workstationId == '7'
+        let cabinetByWorkstation = {}
+
+        response.data.records.forEach((cabinet) => {
+          if (!cabinetByWorkstation[cabinet.workstationId]) {
+            cabinetByWorkstation[cabinet.workstationId] = []
+          }
+          cabinetByWorkstation[cabinet.workstationId].push(cabinet)
         })
+
+        this.TicketListPage = cabinetByWorkstation
+
         this.total = response.data.total
         this.loading = false
       })
@@ -702,6 +693,21 @@ export default {
           console.log('未找到匹配的节点')
         }
       })
+
+      // 这里获取全局配置地图参数里的作业票地图
+      selectIsMapById(4).then((res) => {
+        console.log(res, '作业票地图 图片数据')
+        this.jobconfig = res.data
+      })
+      const dataMap={
+        pages: 1,
+        size: -1,
+        mapId:4
+      }
+      getIsMapPointPage(dataMap).then((res) => {
+        console.log(res, '作业票地图岗位位置信息接口')
+        this.jobconfigPoint = res.data
+      })
     },
     // mars岗位树点击事件
     handleNodeClick(data) {
@@ -922,22 +928,7 @@ export default {
   position: absolute;
   width: 65px;
   height: 25px;
-  left: 500px;
-  top: 260px;
-  background: #70b26f;
-  line-height: 25px;
-  text-align: center;
-  border-radius: 5px;
-  color: #fff;
-  cursor: pointer;
-}
 
-.deptCCO {
-  position: absolute;
-  width: 65px;
-  height: 25px;
-  left: 670px;
-  top: 480px;
   background: #70b26f;
   line-height: 25px;
   text-align: center;
@@ -946,6 +937,7 @@ export default {
   cursor: pointer;
 }
 
+
 //图片放大
 .img-box {
   width: 75px;

+ 1 - 1
src/views/mes/statisticians/LockerOne.vue

@@ -21,7 +21,7 @@
                  size="mini"
                  @click="handleExport"
 
-      >导出</el-button>
+      >导出数据表</el-button>
     </div>
     <div style="display: flex; flex-wrap: wrap; gap: 10px;">
       <div style="flex: 1 1 45%; min-width: 620px;"> <!-- Adjust width and allow flexibility -->

+ 1 - 1
src/views/mes/statisticians/LockerTwo.vue

@@ -20,7 +20,7 @@
                  size="mini"
                  @click="handleExport"
 
-      >导出</el-button>
+      >导出数据表</el-button>
     </div>
     <div style="display: flex; flex-wrap: wrap; gap: 10px;">
       <div style="flex: 1 1 45%; min-width: 620px;"> <!-- Adjust width and allow flexibility -->

+ 292 - 0
src/views/system/configuration/index.vue

@@ -0,0 +1,292 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="参数名称" prop="sysAttrName">
+        <el-input
+          v-model="queryParams.sysAttrName"
+          placeholder="请输入参数名称"
+          clearable
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="参数键名" prop="sysAttrKey">
+        <el-input
+          v-model="queryParams.sysAttrKey"
+          placeholder="请输入参数键名"
+          clearable
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="参数键值" prop="sysAttrValue">
+        <el-input
+          v-model="queryParams.sysAttrValue"
+          placeholder="请输入参数键值"
+          clearable
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button v-no-more-click type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索
+        </el-button>
+        <el-button v-no-more-click icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button v-no-more-click
+                   type="primary"
+                   plain
+                   icon="el-icon-plus"
+                   size="mini"
+                   @click="handleAdd"
+                   v-hasPermi="['iscs:attribute:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button v-no-more-click
+                   type="danger"
+                   plain
+                   icon="el-icon-delete"
+                   size="mini"
+                   :disabled="multiple"
+                   @click="handleDelete"
+                   v-hasPermi="['iscs:attribute:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="List" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="参数名称" align="center" width="210px" prop="sysAttrName">
+        <template slot-scope="scope">
+          <span>{{ scope.row.sysAttrName }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="参数键名" align="center" prop="sysAttrKey" :show-overflow-tooltip="true"/>
+      <el-table-column label="参数键值" align="center" prop="sysAttrValue" :show-overflow-tooltip="true"/>
+      <el-table-column label="备注" align="center" prop="remark" width="180">
+        <template slot-scope="scope">
+          <span>{{ scope.row.remark }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ scope.row.createTime }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button v-no-more-click
+                     size="mini"
+                     type="text"
+                     icon="el-icon-edit"
+                     @click="handleUpdate(scope.row)"
+                     v-hasPermi="['iscs:attribute:edit']"
+          >修改
+          </el-button>
+          <el-button v-no-more-click
+                     size="mini"
+                     type="text"
+                     icon="el-icon-delete"
+                     @click="handleDelete(scope.row)"
+                     v-hasPermi="['iscs:attribute:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.current"
+      :limit.sync="queryParams.size"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改基础数据配置对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="参数名称" prop="sysAttrName">
+          <el-input v-model="form.sysAttrName" placeholder="请输入参数名称"/>
+        </el-form-item>
+        <el-form-item label="参数键名" prop="sysAttrKey">
+          <el-input v-model="form.sysAttrKey" placeholder="请输入参数键名"/>
+        </el-form-item>
+        <el-form-item label="参数键值" prop="sysAttrValue">
+          <el-input v-model="form.sysAttrValue" placeholder="请输入参数键值"/>
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" placeholder="请输入备注"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button v-no-more-click type="primary" @click="submitForm">确 定</el-button>
+        <el-button v-no-more-click @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  deleteIsSystemAttributeByIds,
+  getIsSystemAttributePage,
+  insertIsSystemAttribute,
+  selectIsSystemAttributeById, updateIsSystemAttribute
+} from '@/api/system/configuration'
+
+export default {
+  name: 'autoCodeRule',
+  dicts: ['sys_yes_no'],
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 字典表格数据
+      List: [],
+      // 弹出层标题
+      title: '',
+      // 是否显示弹出层
+      open: false,
+
+      // 查询参数
+      queryParams: {
+        current: 1,
+        size: 10,
+        sysAttrName: '',
+        sysAttrValue: '',
+        sysAttrKey: '',
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        sysAttrName: [
+          { required: true, message: '参数名称', trigger: 'blur' }
+        ],
+        sysAttrKey: [
+          { required: true, message: '参数键名', trigger: 'blur' }
+        ],
+        sysAttrValue: [
+          { required: true, message: '参数键值', trigger: 'blur' }
+        ]
+      }
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    /** 查询字典类型列表 */
+    getList() {
+      this.loading = true
+      getIsSystemAttributePage(this.queryParams).then(response => {
+          this.List = response.data.records
+          this.total = response.data.total
+          this.loading = false
+        }
+      )
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false
+      this.reset()
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        sysAttrName: '',
+        sysAttrKey: '',
+        sysAttrValue: '',
+        remark: ''
+      }
+      this.resetForm('form')
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.current = 1
+      this.getList()
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm('queryForm')
+      this.handleQuery()
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset()
+      this.open = true
+      this.title = '添加基础数据'
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.sysAttrId)
+      this.single = selection.length != 1
+      this.multiple = !selection.length
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset()
+      const ruleId = row.sysAttrId || this.ids
+      selectIsSystemAttributeById(ruleId).then(response => {
+        this.form = response.data
+        this.open = true
+        this.title = '修改编码规则'
+      })
+    },
+    /** 提交按钮 */
+    submitForm: function() {
+      this.$refs['form'].validate(valid => {
+        if (valid) {
+          if (this.form.sysAttrId != undefined) {
+            updateIsSystemAttribute(this.form).then(response => {
+              this.$modal.msgSuccess('修改成功')
+              this.open = false
+              this.getList()
+            })
+          } else {
+            insertIsSystemAttribute(this.form).then(response => {
+              this.$modal.msgSuccess('新增成功')
+              this.open = false
+              this.getList()
+            })
+          }
+        }
+      })
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      console.log(row, '删除')
+      debugger;
+      const ruleIds = row.sysAttrId || this.ids
+      this.$modal.confirm('是否确认删除所选数据项?').then(function() {
+        return deleteIsSystemAttributeByIds(ruleIds)
+      }).then(() => {
+        this.getList()
+        this.$modal.msgSuccess('删除成功')
+      }).catch(() => {
+      })
+    }
+
+  }
+}
+</script>

+ 451 - 0
src/views/system/mapconfig/index.vue

@@ -0,0 +1,451 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="地图名称" prop="name">
+        <el-input
+          v-model="queryParams.name"
+          placeholder="请输入地图名称"
+          clearable
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button v-no-more-click type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button v-no-more-click icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button v-no-more-click
+                   type="primary"
+                   plain
+                   icon="el-icon-plus"
+                   size="mini"
+                   @click="handleAdd"
+                   v-hasPermi="['iscs:map:add']"
+        >新增</el-button>
+      </el-col>
+      <el-button
+        v-no-more-click
+        type="info"
+        plain
+        icon="el-icon-upload2"
+        size="mini"
+        @click="handleOpenImport"
+
+      >导入</el-button
+      >
+      <el-col :span="1.5">
+        <el-button v-no-more-click
+                   type="danger"
+                   plain
+                   icon="el-icon-delete"
+                   size="mini"
+                   :disabled="multiple"
+                   @click="handleDelete"
+                   v-hasPermi="['iscs:map:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="List" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="地图名称" align="center"  prop="name" >
+        <template slot-scope="scope">
+          <span>{{ scope.row.name }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="地图图片" align="left" prop="imageUrl" :show-overflow-tooltip="true" >
+        <template slot-scope="scope">
+          <div class="img-box" v-if="scope.row.imageUrl">
+            <el-image
+              style="width: 75px; height: 75px"
+              :preview-teleported="true"
+              class="images"
+              :hide-on-click-modal="true"
+              :src="scope.row.imageUrl"
+              :zoom-rate="1.2"
+              :preview-src-list="[scope.row.imageUrl]"
+              :initial-index="1"
+
+            >
+            </el-image>
+            <i class="el-icon-zoom-in" id="eyeicon"></i>
+          </div>
+          <span v-else>-</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="地图宽度" align="center" prop="width" >
+
+      </el-table-column>
+      <el-table-column label="地图高度" align="center" prop="height" >
+
+      </el-table-column>
+      <el-table-column label="横坐标" align="center" prop="x" >
+
+      </el-table-column>
+      <el-table-column label="纵坐标" align="center" prop="y" >
+
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" >
+        <template slot-scope="scope">
+          <span>{{ scope.row.createTime }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button v-no-more-click
+                     size="mini"
+                     type="text"
+                     icon="el-icon-edit"
+                     @click="handleUpdate(scope.row)"
+                     v-hasPermi="['iscs:map:edit']"
+          >修改</el-button>
+<!--          <el-button v-no-more-click-->
+<!--                     size="mini"-->
+<!--                     type="text"-->
+<!--                     icon="el-icon-edit"-->
+<!--                     @click="handleDetail(scope.row)"-->
+<!--                     v-hasPermi="['iscs:map:edit']"-->
+<!--          >详情</el-button>-->
+          <el-button v-no-more-click
+                     size="mini"
+                     type="text"
+                     icon="el-icon-delete"
+                     @click="handleDelete(scope.row)"
+                     v-hasPermi="['iscs:map:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.current"
+      :limit.sync="queryParams.size"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改参数配置对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="地图名称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入地图名称" />
+        </el-form-item>
+        <el-form-item label="地图图片" prop="imageUrl">
+          <ImageUploadSingle
+            :limit="1"
+            :value="form.imageUrl"
+            :fileSize="5"
+            @onUploaded="handleIconUplaoded"
+            @onRemoved="handleIconRemoved"
+          ></ImageUploadSingle>
+        </el-form-item>
+        <el-form-item label="图片宽度" prop="width">
+          <el-input v-model="form.width" placeholder="请输入图片宽度" />
+        </el-form-item>
+        <el-form-item label="图片高度" prop="height">
+          <el-input v-model="form.height" placeholder="请输入图片高度" />
+        </el-form-item>
+        <el-form-item label="横坐标" prop="x">
+          <el-input v-model="form.x" placeholder="请输入横坐标" />
+        </el-form-item>
+        <el-form-item label="纵坐标" prop="y">
+          <el-input v-model="form.y" placeholder="请输入纵坐标" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button v-no-more-click type="primary" @click="submitForm">确 定</el-button>
+        <el-button v-no-more-click @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+<!--    车总测试-->
+    <el-dialog  :visible.sync="ImportVisible" width="500px" append-to-body>
+      <el-form ref="form" :model="ImportForm" :rules="rules" label-width="80px">
+        <el-form-item label="userName" prop="userName">
+          <el-input v-model="ImportForm.userName" placeholder="请输入userName" />
+        </el-form-item>
+        <el-button
+          v-no-more-click
+          type="info"
+          plain
+          icon="el-icon-upload2"
+          size="mini"
+          @click="handleImport"
+          v-hasPermi="['iscs:sop:import']"
+        >导入</el-button
+        >
+      </el-form>
+
+    </el-dialog>
+<!--    车总测试-->
+    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
+      <el-upload
+        ref="upload"
+        :limit="1"
+        accept=".xlsx, .xls,.png,.jpg,.jpeg,.doc,.docx,.pdf"
+        :headers="upload.headers"
+        :action="upload.url + '?userName=' + upload.userName"
+        :disabled="upload.isUploading"
+        :on-progress="handleFileUploadProgress"
+        :on-success="handleFileSuccess"
+        :auto-upload="false"
+        drag
+      >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+        <div class="el-upload__tip text-center" slot="tip">
+          <div class="el-upload__tip" slot="tip">
+            <el-checkbox v-model="upload.userName" /> 是否更新已经存在的设备数据
+          </div>
+          <span>仅允许导入xls、xlsx格式文件。</span>
+        </div>
+      </el-upload>
+      <div slot="footer" class="dialog-footer">
+        <el-button v-no-more-click type="primary" @click="submitFileForm">确 定</el-button>
+        <el-button v-no-more-click @click="upload.open = false">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+
+import { deleteIsMapByIds, getIsMapPage, insertIsMap, selectIsMapById, updateIsMap } from '@/api/system/mapconfig'
+import { getToken } from '@/utils/auth'
+
+export default {
+  name: "autoCodeRule",
+  dicts: ['sys_yes_no'],
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 字典表格数据
+      List: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+
+      // 查询参数
+      queryParams: {
+        current: 1,
+        size: 10,
+        name:''
+      },
+      // 表单参数
+      form: {},
+      ImportVisible:false,//车总测试导入
+      ImportForm:{},//车总测试
+      // 车总测试 用户导入参数
+      upload: {
+        // 是否显示弹出层(用户导入)
+        open: false,
+        // 弹出层标题(用户导入)
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        userName: 0,
+        // 设置上传的请求头部
+        headers: { Authorization: "Bearer " + getToken() },
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/system/user/characteristic/insertUserFingerprintDat"
+      },
+      // 表单校验
+      rules: {
+        name: [
+          { required: true, message: "地图名称", trigger: "blur" }
+        ],
+        imageUrl: [
+          { required: true, message: "地图图片", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    // 车总测试用的
+    handleImport() {
+      this.upload.title = "导入";
+      this.upload.open = true;
+      this.upload.userName=this.ImportForm.userName;
+    },
+    handleOpenImport(){
+      this.ImportVisible = true;
+    },
+    // 文件上传中处理
+    handleFileUploadProgress(event, file, fileList) {
+      this.upload.isUploading = true;
+    },
+    // 文件上传成功处理
+    handleFileSuccess(response, file, fileList) {
+      this.upload.open = false;
+      this.upload.isUploading = false;
+      this.$refs.upload.clearFiles();
+      this.$alert(
+        "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
+        response.msg +
+        "</div>",
+        "导入结果",
+        { dangerouslyUseHTMLString: true }
+      );
+      this.getList();
+    },
+    // 提交上传文件
+    submitFileForm() {
+
+      this.$refs.upload.submit();
+    },
+    // 上面都是车总测试
+
+    handleDetail(row){
+      selectIsMapById(row.id).then((res)=>{
+        console.log(res);
+      })
+    },
+    /** 查询字典类型列表 */
+    getList() {
+      this.loading = true;
+      getIsMapPage(this.queryParams).then(response => {
+          this.List = response.data.records;
+          this.total = response.data.total;
+          this.loading = false;
+        }
+      );
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        attribute:"",
+        value:"",
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.current = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加地图数据";
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!=1
+      this.multiple = !selection.length
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const ruleId = row.id || this.ids
+      selectIsMapById(ruleId).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改地图数据";
+      });
+    },
+    /** 提交按钮 */
+    submitForm: function() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != undefined) {
+            updateIsMap(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            insertIsMap(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    //图标上传成功
+    handleIconUplaoded(imgUrl) {
+      this.form.imageUrl = imgUrl[0].url
+    },
+    // 图标移除
+    handleIconRemoved(imgUrl) {
+      this.form.imageUrl = null
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      debugger;
+      const ruleIds = row.id || this.ids;
+      this.$modal.confirm('是否确认删除所选数据项?').then(function() {
+        return deleteIsMapByIds(ruleIds);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {});
+    },
+
+  }
+};
+</script>
+<style scoped lang="scss">
+//图片放大
+.img-box {
+  width: 75px;
+  height: 75px;
+  position: relative;
+
+  #eyeicon {
+    display: none;
+  }
+}
+
+.img-box:hover {
+  background: #000;
+
+  .images {
+    opacity: 0.6;
+  }
+
+  #eyeicon {
+    display: block;
+    position: absolute;
+    top: 40%;
+    left: 40%;
+    z-index: 100;
+    color: white;
+    pointer-events: none;
+  }
+}
+</style>

+ 433 - 0
src/views/system/mappoint/index.vue

@@ -0,0 +1,433 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="地图名称" prop="mapId">
+        <el-select v-model="queryParams.mapId" placeholder="地图名称">
+          <el-option v-for="item in this.MapOptions" :key="item.id" :label="item.name" :value="item.id">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button v-no-more-click type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索
+        </el-button>
+        <el-button v-no-more-click icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button v-no-more-click
+                   type="primary"
+                   plain
+                   icon="el-icon-plus"
+                   size="mini"
+                   @click="handleAdd"
+                   v-hasPermi="['iscs:map-point:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button v-no-more-click
+                   type="danger"
+                   plain
+                   icon="el-icon-delete"
+                   size="mini"
+                   :disabled="multiple"
+                   @click="handleDelete"
+                   v-hasPermi="['iscs:map-point:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-button v-no-more-click
+                 type="info"
+                 plain
+                 icon="el-icon-upload2"
+                 size="mini"
+                 @click="handleImport"
+
+      >导入</el-button>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="List" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="地图名称" align="center" width="210px" prop="mapName">
+        <template slot-scope="scope">
+          <span>{{ scope.row.mapName }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="地图类型" align="center" prop="mapType" :show-overflow-tooltip="true">
+        <template slot-scope="scope">
+          <dict-tag
+            :options="dict.type.map_type"
+            :value="scope.row.mapType"
+          />
+        </template>
+      </el-table-column>
+      <el-table-column label="实体名称" align="center" width="210px" prop="entityName">
+        <template slot-scope="scope">
+          <span>{{ scope.row.entityName }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="横坐标" align="center" prop="x" width="180">
+      </el-table-column>
+      <el-table-column label="纵坐标" align="center" prop="y" width="180">
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ scope.row.createTime }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button v-no-more-click
+                     size="mini"
+                     type="text"
+                     icon="el-icon-edit"
+                     @click="handleUpdate(scope.row)"
+                     v-hasPermi="['iscs:map-point:edit']"
+          >修改
+          </el-button>
+          <el-button v-no-more-click
+                     size="mini"
+                     type="text"
+                     icon="el-icon-delete"
+                     @click="handleDelete(scope.row)"
+                     v-hasPermi="['iscs:map-point:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.current"
+      :limit.sync="queryParams.size"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改参数配置对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="400px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="地图名称" prop="mapId">
+          <el-select style="width: 280px" v-model="form.mapId" placeholder="地图名称">
+            <el-option v-for="item in this.MapOptions" :key="item.id" :label="item.name" :value="item.id">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="地图类型" prop="mapType">
+          <el-select style="width: 280px" v-model="form.mapType" placeholder="地图类型">
+            <el-option
+              v-for="dict in dict.type.map_type"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item v-if="form.mapType=='1'" label="实体" prop="entityId">
+          <treeselect
+            style="width: 280px"
+            v-model="form.entityId"
+            :options="deptOptions"
+            :normalizer="Marsnormalizer"
+            placeholder="选择实体"
+            @change="handleWorkstationChange"
+          />
+        </el-form-item>
+        <el-form-item v-if="form.mapType=='2'" label="实体" prop="entityId">
+          <el-select style="width: 280px" v-model="form.entityId" placeholder="实体">
+            <el-option v-for="item in this.spmOptions" :key="item.pointId" :label="item.pointName" :value="item.pointId">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="横坐标" prop="x">
+          <el-input v-model="form.x" placeholder="请输入横坐标"/>
+        </el-form-item>
+        <el-form-item label="纵坐标" prop="y">
+          <el-input v-model="form.y" placeholder="请输入纵坐标"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button v-no-more-click type="primary" @click="submitForm">确 定</el-button>
+        <el-button v-no-more-click @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+<!--    测试-->
+    <el-dialog
+      :title="upload.title"
+      :visible.sync="upload.open"
+      width="400px"
+      append-to-body
+    >
+      <el-upload
+        ref="upload"
+        :limit="1"
+        accept=".mp4, .pdf, .doc, .docx, .xls, .xlsx"
+        :headers="upload.headers"
+        :action="upload.url"
+        :disabled="upload.isUploading"
+        :on-progress="handleFileUploadProgress"
+        :on-success="handleFileSuccess"
+        :auto-upload="false"
+        drag
+      >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+        <div class="el-upload__tip text-center" slot="tip">
+          <span>mp4、pdf, .doc, .docx, .xls, .xlsx格式文件。</span>
+        </div>
+      </el-upload>
+      <div slot="footer" class="dialog-footer">
+        <el-button v-no-more-click type="primary" @click="submitFileForm"
+        >确 定</el-button
+        >
+        <el-button v-no-more-click @click="upload.open = false"
+        >取 消</el-button
+        >
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+
+
+import {
+  deleteIsMapPointByIds,
+  getIsMapPointPage,
+  insertIsMapPoint,
+  selectIsMapPointById,
+  updateIsMapPoint
+} from '@/api/system/mappoint'
+import { getIsMapPage } from '@/api/system/mapconfig'
+import Treeselect from '@riophae/vue-treeselect'
+import '@riophae/vue-treeselect/dist/vue-treeselect.css'
+import { listMarsDept } from '@/api/system/marsdept'
+import { getIsIsolationPointPage } from '@/api/mes/spm/segregationPoint'
+import { getToken } from '@/utils/auth'
+
+export default {
+  name: 'autoCodeRule',
+  components: { Treeselect },
+  dicts: ['sys_yes_no', 'map_type'],
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 字典表格数据
+      List: [],
+      // 弹出层标题
+      title: '',
+      // 是否显示弹出层
+      open: false,
+
+      // 查询参数
+      queryParams: {
+        current: 1,
+        size: 10
+      },
+      // 表单参数
+      form: {},
+      // 地图名称 下拉
+      MapOptions: null,
+      // 岗位下拉
+      deptOptions: null,
+      // 隔离点下拉
+      spmOptions: null,
+      // 用户导入参数
+      upload: {
+        // 是否显示弹出层(用户导入)
+        open: false,
+        // 弹出层标题(用户导入)
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        updateSupport: 0,
+        // 设置上传的请求头部
+        headers: { Authorization: "Bearer " + getToken() },
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/loginByFingerprintDat"
+      },
+      // 表单校验
+      rules: {
+        mapId: [
+          { required: true, message: '地图名称', trigger: 'blur' }
+        ],
+        mapType: [
+          { required: true, message: '地图类型', trigger: 'blur' }
+        ]
+      }
+    }
+  },
+  created() {
+    this.getList()
+    this.getOtherList()
+  },
+  methods: {
+    /** 导入按钮操作 */
+    handleImport() {
+      this.upload.title = "导入";
+      this.upload.open = true;
+    },
+    // 文件上传中处理
+    handleFileUploadProgress(event, file, fileList) {
+      this.upload.isUploading = true;
+    },
+    // 文件上传成功处理
+    handleFileSuccess(response, file, fileList) {
+      this.upload.open = false;
+      this.upload.isUploading = false;
+      this.$refs.upload.clearFiles();
+      this.$alert(
+        "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
+        response.msg +
+        "</div>",
+        "导入结果",
+        { dangerouslyUseHTMLString: true }
+      );
+      this.getList();
+    },
+    // 提交上传文件
+    submitFileForm() {
+      this.$refs.upload.submit();
+    },
+    /** 查询字典类型列表 */
+    getList() {
+      this.loading = true
+      getIsMapPointPage(this.queryParams).then(response => {
+          this.List = response.data.records
+          this.total = response.data.total
+          this.loading = false
+        }
+      )
+    },
+    getOtherList() {
+      const data = {
+        current: 1,
+        size: -1
+      }
+      getIsMapPage(data).then(response => {
+        this.MapOptions = response.data.records
+      })
+      listMarsDept(data).then(response => {
+        //
+        console.log(response,'岗位')
+        this.deptOptions = this.handleTree(response.data.records,"workstationId","parentId")
+      })
+      getIsIsolationPointPage(data).then(response => {
+        console.log(response,'隔离点数据')
+        this.spmOptions = response.data.records
+      })
+    },
+    /** 转换mars岗位数据结构 */
+    Marsnormalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.workstationId,
+        label: node.workstationName,
+        children: node.children,
+      };
+    },
+    handleWorkstationChange(value) {
+      this.form.entityId = value;
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false
+      this.reset()
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+       mapId: undefined,
+        mapType: undefined,
+        x: undefined,
+        y: undefined,
+      }
+      this.resetForm('form')
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.current = 1
+      this.getList()
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm('queryForm')
+      this.handleQuery()
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset()
+      this.open = true
+      this.title = '添加地图点位数据'
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length != 1
+      this.multiple = !selection.length
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset()
+      const ruleId = row.id || this.ids
+      selectIsMapPointById(ruleId).then(response => {
+        this.form = response.data
+        this.open = true
+        this.title = '修改地图点位数据'
+      })
+    },
+    /** 提交按钮 */
+    submitForm: function() {
+      this.$refs['form'].validate(valid => {
+        if (valid) {
+          if (this.form.id != undefined) {
+            updateIsMapPoint(this.form).then(response => {
+              this.$modal.msgSuccess('修改成功')
+              this.open = false
+              this.getList()
+            })
+          } else {
+            insertIsMapPoint(this.form).then(response => {
+              this.$modal.msgSuccess('新增成功')
+              this.open = false
+              this.getList()
+            })
+          }
+        }
+      })
+    },
+
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      debugger;
+      const ruleIds = row.id || this.ids
+      this.$modal.confirm('是否确认删除所选数据项?').then(function() {
+        return deleteIsMapPointByIds(ruleIds)
+      }).then(() => {
+        this.getList()
+        this.$modal.msgSuccess('删除成功')
+      }).catch(() => {
+      })
+    }
+
+  }
+}
+</script>

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio