Kaynağa Gözat

sop编辑和查看小问题修复

pm 11 ay önce
ebeveyn
işleme
596306dff2

+ 67 - 91
src/components/separationPoint/index.vue

@@ -27,6 +27,8 @@ export default {
       selectedText: [], // 用于存储未选中的元素文本
       rects: [], //白色rect合集
       texts: [], //白色text合集
+      overlayBox:[],//覆盖盒子
+      checkTexts:[],//对号文字
       redrects: [], //红色rect合集
       redtexts: [] //白色text合集
     }
@@ -144,6 +146,7 @@ export default {
       this.texts = {}
       this.redrects = {}
       this.redtexts = {}
+
       this.selectedText = []
 
       // const positions = JSON.parse(this.points.map);
@@ -195,6 +198,7 @@ export default {
             height: 50,
             draggable: false
           })
+
           // 添加点击事件,仅当 getSopEdit 为 true 时才允许点击a
           if (this.getSopEdit == true && this.getSopLook == false) {
             knovaImage.on('click', () => {
@@ -203,13 +207,13 @@ export default {
 
               if (this.selectedStates[labelText]) {
                 // 选中状态,显示红色矩形和文字,切换为选中的图片
-                this.rects[labelText].visible(false)
-                this.texts[labelText].visible(false)
+                this.rects[labelText].visible(true)
+                this.texts[labelText].visible(true)
                 this.redrects[labelText].visible(true)
                 this.redtexts[labelText].visible(true)
 
                 const selectedImage = new Image()
-                selectedImage.src = require('@/assets/images/localSetSelect.jpg')
+                selectedImage.src = pos.pointIcon
                 selectedImage.onload = () => {
                   knovaImage.image(selectedImage) // 更新图像
                   this.layer.draw() // 更新图层
@@ -230,19 +234,11 @@ export default {
                       prePointId:pos.prePointId
                     })
                     this.$emit('selection-changed', this.selectedText)
-                    // selectIsIsolationPointById(pos.pointId).then((res) => {
-                    //   this.selectedText.push({
-                    //     pointName: res.data.pointName,
-                    //     pointId: res.data.pointId,
-                    //     pointType: res.data.pointType,
-                    //     powerType: res.data.powerType,
-                    //   });
-                    //   console.log(this.selectedText, "$emit");
-                    //   this.$emit("selection-changed", this.selectedText);
-                    // });
+
                   }
                 })
               } else {
+
                 // 取消选中状态,恢复普通矩形和文字,切换为未选中的图片
                 this.rects[labelText].visible(true)
                 this.texts[labelText].visible(true)
@@ -261,6 +257,7 @@ export default {
                 this.selectedText = this.selectedText.filter(
                   (item) => item.pointName !== labelText
                 )
+
               }
 
               // 确保图层重新渲染
@@ -297,46 +294,75 @@ export default {
           this.layer.add(text)
           this.texts[labelText] = text // 用文字作为键存储
 
-          // 红色矩形(初始隐藏)
+          // // 红色矩形(初始隐藏)
+          // const redrect = new Konva.Rect({
+          //   x: x - 3,
+          //   y: y + 55,
+          //   width: 60,
+          //   height: 25,
+          //   cornerRadius: 10,
+          //   stroke: 'red',
+          //   strokeWidth: 2,
+          //   fill: 'red',
+          //   visible: false
+          // })
+          // this.layer.add(redrect)
+          // this.redrects[labelText] = redrect // 用文字作为键存储
+          //
+          // // 红色文字(初始隐藏)
+          // const redtext = new Konva.Text({
+          //   x: x + 12,
+          //   y: y + 60,
+          //   fontSize: 20,
+          //   text: labelText,
+          //   fontFamily: 'Calibri',
+          //   fill: 'white',
+          //   visible: false
+          // })
+          // this.layer.add(redtext)
+          // this.redtexts[labelText] = redtext // 用文字作为键存储
+
+          // 覆盖层(表示选中状态)
           const redrect = new Konva.Rect({
-            x: x - 3,
-            y: y + 55,
-            width: 60,
-            height: 25,
-            cornerRadius: 10,
-            stroke: 'red',
-            strokeWidth: 2,
-            fill: 'red',
-            visible: false
-          })
+            x: x-5,
+            y: y,
+            width: 62,
+            height: 82,
+            cornerRadius: 5,
+            fill: 'rgba(97, 97, 97, 0.5)', // 半透明灰色
+            visible: false, // 初始状态隐藏
+            listening:false
+          });
           this.layer.add(redrect)
           this.redrects[labelText] = redrect // 用文字作为键存储
-
-          // 红色文字(初始隐藏)
+          // 创建对号文本
           const redtext = new Konva.Text({
-            x: x + 12,
-            y: y + 60,
-            fontSize: 20,
-            text: labelText,
-            fontFamily: 'Calibri',
+            x: x - 5 + 42 / 2, // 水平居中
+            y: y + 62 / 2, // 垂直居中
+            fontSize: 24, // 根据需要调整字体大小
+            text: '✔',
+            fontFamily: 'Arial',
             fill: 'white',
-            visible: false
-          })
-          this.layer.add(redtext)
-          this.redtexts[labelText] = redtext // 用文字作为键存储
-
+            align: 'center',
+            verticalAlign: 'middle',
+            visible: false,//初始隐藏状态
+            listening:false,
+          });
+          this.layer.add(redtext);
+          this.redtexts[labelText] = redtext; // 用文字作为键存储
           // 检查 this.getSelectSopPoints 是否包含当前点的 pointId
           if (pos.state) {
             // 设置为选中状态
             this.selectedStates[labelText] = true
-            this.rects[labelText].visible(false)
-            this.texts[labelText].visible(false)
+
+            this.rects[labelText].visible(true)
+            this.texts[labelText].visible(true)
             this.redrects[labelText].visible(true)
             this.redtexts[labelText].visible(true)
 
             // 切换图片为选中状态的图片
             const selectedImage = new Image()
-            selectedImage.src = require('@/assets/images/localSetSelect.jpg') // 选中的图片路径
+            selectedImage.src = pos.pointIcon // 选中的图片路径
             selectedImage.onload = () => {
               knovaImage.image(selectedImage) // 更新图像
               this.layer.draw() // 更新图层
@@ -357,63 +383,13 @@ export default {
             this.texts[labelText].visible(true)
             this.redrects[labelText].visible(false)
             this.redtexts[labelText].visible(false)
+
           }
 
           // 触发父组件的 selection-changed 事件
           this.$emit('selection-changed', this.selectedText)
 
-          // if (this.getSelectSopPoints.includes(pos.pointId.toString())) {
-          //   // 设置为选中状态
-          //   this.selectedStates[labelText] = true;
-          //   this.rects[labelText].visible(false);
-          //   this.texts[labelText].visible(false);
-          //   this.redrects[labelText].visible(true);
-          //   this.redtexts[labelText].visible(true);
-          //
-          //   // 切换图片为选中状态的图片
-          //   const selectedImage = new Image();
-          //   selectedImage.src = require("@/assets/images/localSetSelect.jpg"); // 选中的图片路径
-          //   selectedImage.onload = () => {
-          //     knovaImage.image(selectedImage); // 更新图像
-          //     this.layer.draw(); // 更新图层
-          //   };
-          //   // 将选中的 labelText 推入数组
-          //   this.$nextTick(() => {
-          //     getIsIsolationPointPage({ current: 1, size: 100 })
-          //       .then((res) => {
-          //         const allPoints = res.data.records; // 假设返回的数据结构是 { records: [点数据] }
-          //
-          //         // 根据 pos.pointId 查找对应的 pointType 和 powerType
-          //         const pointInfo = allPoints.find(
-          //           (point) => point.pointId == pos.pointId
-          //         );
-          //
-          //         if (pointInfo) {
-          //           this.selectedText.push({
-          //             pointName: labelText,
-          //             pointId: pos.pointId,
-          //             pointType: pointInfo.pointType,
-          //             powerType: pointInfo.powerType,
-          //           });
-          //         } else {
-          //           // 如果没有找到对应的点信息,可以处理这种情况
-          //           console.warn(`未找到 pointId 为 ${pos.pointId} 的点信息`);
-          //           this.selectedText.push({
-          //             pointName: labelText,
-          //             pointId: pos.pointId,
-          //             pointType: "",
-          //             powerType: "",
-          //           });
-          //         }
-          //         // console.log(this.selectedText,'默认拿到的points')
-          //         // 触发父组件的 selection-changed 事件
-          //         this.$emit("selection-changed", this.selectedText);
-          //       })
-          //       .catch((error) => {
-          //         console.error("获取隔离点信息失败", error);
-          //       });
-          //   });
-          // }
+
 
           this.layer.draw()
 

+ 50 - 19
src/components/separationPoint/workshop.vue

@@ -3,11 +3,13 @@
     <el-row :gutter="20">
       <!--部门数据-->
       <el-col :span="4" :xs="24">
+
         <div class="head-container">
           <el-input
             v-model="workareaName"
             placeholder="请输入作业区域"
             clearable
+            :disabled="isDisabled"
             size="small"
             prefix-icon="el-icon-search"
             style="margin-bottom: 20px"
@@ -15,12 +17,14 @@
           />
         </div>
         <div class="head-container">
+          <div v-if="isDisabled" class="overlay"></div>
           <el-tree
             :data="deptOptions"
             :props="defaultProps"
             :expand-on-click-node="false"
             :filter-node-method="filterNode"
             ref="tree"
+
             node-key="id"
             default-expand-all
             @node-click="handleNodeClick"
@@ -76,6 +80,7 @@ export default {
       defaultProps: {
         children: 'children',
         label: 'label'
+
       },
       // 工作区域名称 树形结构
       workareaName: undefined,
@@ -84,19 +89,21 @@ export default {
         current: 1,
         size: -1
 
-      }
+      },
+      isDisabled: false//控制编辑的时候禁止点击树形结构
     }
   },
   watch: {
     // 监听父组件传递的数据
     sopProps: {
       handler(newVal, oldVal) {
-        if(newVal){
+        if (newVal) {
           console.log('sopProps 发生变化', newVal)
 
-          if(newVal[0].workareaId){
+          if (newVal[0].workareaId) {
             this.workareaName = newVal[0].workareaId  //新工作区域所返回
-            this.handleselectProductLine(newVal[0].workareaId);
+            this.handleselectProductLine(newVal[0].workareaId)
+
           }
 
           this.getTreeselect()
@@ -172,10 +179,16 @@ export default {
 
   mounted() {
     this.getTreeselect()//获取工作区域下拉
-
+    if (this.$route.query.sopId == 'null' || this.$route.query.ticketId == 'null') {
+      console.log(this.isDisabled, 'isDisabled 我走这里')
+      this.isDisabled = false
+    } else {
+      console.log(this.isDisabled, 'isDisabled 我走这里2')
+      this.isDisabled = true
+    }
   },
   computed: {
-    ...mapGetters('sopSelectPoints', ['getSopLook','getMapData'])
+    ...mapGetters('sopSelectPoints', ['getSopLook', 'getMapData'])
   },
   methods: {
     ...mapActions('sopSelectPoints', [
@@ -184,6 +197,7 @@ export default {
       'setSopEdit',
       'setMapData'
     ]),
+    // 如果是查看和编辑禁止点击树形结构
 
     // 区域下拉
     handleselectProductLine(val) {
@@ -251,15 +265,14 @@ export default {
 
         // 使用递归函数查找匹配的节点
 
-          console.log(this.workareaName,'name')
-          const selectedTreeNode = this.findNodeById(this.deptOptions, this.workareaName)
-          // 调用 handleNodeClick 方法
-          if (selectedTreeNode) {
-            this.handleNodeClick(selectedTreeNode)
-          } else {
-            console.log('未找到匹配的节点')
-          }
-
+        console.log(this.workareaName, 'name')
+        const selectedTreeNode = this.findNodeById(this.deptOptions, this.workareaName)
+        // 调用 handleNodeClick 方法
+        if (selectedTreeNode) {
+          this.handleNodeClick(selectedTreeNode)
+        } else {
+          console.log('未找到匹配的节点')
+        }
 
       })
     },
@@ -292,6 +305,7 @@ export default {
           map: record.map,
           mapImg: record.mapImg,
           children: []
+
         }
       })
 
@@ -318,18 +332,21 @@ export default {
     },
     // 监听输入框变化
     handleInputChange() {
+
       this.$refs.tree.filter(this.workareaName) // 调用树的 filter 方法
     },
     // 节点单击事件
     handleNodeClick(data) {
+
       console.log(data, '单节点点击')
       this.treeSelectMap = data
-      if (this.$route.query.sopId === 'null' || this.$route.query.ticketId === 'null') {
-        this.setMapData(data.map);
-        console.log('设置了地图数据');
-      }
+
       // 传递车间地图
       this.imgsrc = data.mapImg
+      if (this.$route.query.sopId === 'null' || this.$route.query.ticketId === 'null') {
+        this.setMapData(data.map)
+        console.log('设置了地图数据')
+      }
       this.workareaName = data.label
       this.handleInputChange()
       this.$emit('work-shop-selected', data)
@@ -340,6 +357,20 @@ export default {
 
 
 <style scoped>
+.head-container {
+  position: relative;
+}
+
+.overlay {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(255, 255, 255, 0.7); /* 半透明背景 */
+  z-index: 1000; /* 确保覆盖层在树形结构之上 */
+}
+
 .workshop {
   width: 100%;
   height: 100%;

+ 1305 - 0
src/views/mes/job/jobm/NewOperation1.vue

@@ -0,0 +1,1305 @@
+<template>
+  <div class="newOperations">
+    <!--    newOperations盒子开始-->
+    <div class="left">
+      <!--        左边第一个是隔离点组件-->
+      <!--        第二个是车间组件-->
+
+      <SeparationPoint
+        v-show="this.activeName == 'second'"
+        @selection-changed="handleSelectPoint"
+        :points="points"
+      ></SeparationPoint>
+      <keep-alive>
+        <WorkShop
+          v-show="this.activeName == 'first' || this.activeName == 'third'"
+          @product-line-selected="handleProductLineSelected"
+          @work-shop-selected="handleWorkshopSelected"
+          :jobProps="jobProps"
+        ></WorkShop>
+      </keep-alive>
+    </div>
+    <div class="right">
+      <div class="right_top">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <span style="font-size: 18px">{{ this.getTicketTitle }}</span>
+            <span
+              style="
+                float: right;
+                padding: 1px 0;
+                font-size: 22px;
+                cursor: pointer;
+              "
+              type="text"
+              @click="goBack"
+            >×</span
+            >
+          </div>
+          <div class="text item">
+            <el-tabs v-model="activeName" @tab-click="handleClick">
+              <el-tab-pane label="作业票信息" name="first">
+                <!--                  新增作业票信息-->
+                <el-form ref="form" :model="form" label-width="90px">
+                  <el-form-item label="选择SOP" prop="sop">
+                    <el-select
+                      :disabled="this.getSopLook"
+                      v-model="form.sopId"
+                      placeholder="请选择sop"
+                      clearable
+                      style="width: 100%"
+                      @clear="handleClearSop"
+                      @change="handleSelectSOP"
+                    >
+                      <el-option
+                        v-for="dict in this.sopOptions"
+                        :key="dict.sopId"
+                        :label="dict.sopName"
+                        :value="dict.sopId"
+                      />
+                    </el-select>
+                  </el-form-item>
+                  <el-row>
+                    <el-col :span="16">
+                      <el-form-item label="作业票编号" prop="ticketCode">
+                        <el-input
+                          :disabled="this.getSopLook"
+                          v-model="form.ticketCode"
+                          placeholder="请输入作业票编号"
+                          style="width: 100%"
+                        />
+                      </el-form-item>
+                    </el-col>
+                    <el-col :span="8">
+                      <el-form-item label-width="80">
+                        <el-switch
+                          :disabled="this.getSopLook"
+                          v-model="autoGenFlag"
+                          active-color="#13ce66"
+                          active-text="自动生成"
+                          @change="handleAutoGenChange(autoGenFlag)"
+                        >
+                        </el-switch>
+                      </el-form-item>
+                    </el-col>
+                  </el-row>
+
+                  <el-form-item label="作业票名称" prop="ticketName">
+                    <el-input
+                      :disabled="this.getSopLook"
+                      v-model="form.ticketName"
+                      placeholder="请输入作业票名称"
+                      style="width: 100%"
+                    />
+                  </el-form-item>
+                  <el-form-item label="作业票类型" prop="ticketType">
+                    <el-select
+                      :disabled="this.getSopLook"
+                      v-model="form.ticketType"
+                      placeholder="请选择作业类型"
+                      clearable
+                      style="width: 100%"
+                    >
+                      <el-option
+                        v-for="dict in dict.type.ticket_type"
+                        :key="dict.value"
+                        :label="dict.label"
+                        :value="dict.value"
+                      />
+                    </el-select>
+                  </el-form-item>
+                  <el-form-item label="作业内容" prop="ticketContent">
+                    <el-input
+                      :disabled="this.getSopLook"
+                      type="textarea"
+                      v-model="form.ticketContent"
+                      :rows="4"
+                    ></el-input>
+                  </el-form-item>
+                  <el-form-item label="" prop="" style="margin-top: 80%">
+                    <el-button
+                      type="primary"
+                      class="workTicket_btn"
+                      @click="nextStep('second')"
+                    >下一步
+                    </el-button>
+                  </el-form-item>
+                </el-form>
+              </el-tab-pane>
+              <el-tab-pane label="选择隔离点" name="second">
+                <!-- 隔离点信息-->
+                <el-form ref="form" :model="form" label-width="90px">
+                  <el-form-item label="车间名称" prop="workshopName">
+                    <el-input
+                      v-model="form.workshopName"
+                      placeholder="请输入车间名称"
+                      style="width: 100%"
+                      disabled
+                    />
+                  </el-form-item>
+                  <el-form-item label="区域" prop="workline">
+                    <el-input
+                      v-model="form.workline"
+                      placeholder="请输入区域"
+                      style="width: 100%"
+                      disabled
+                    />
+                  </el-form-item>
+                  <div class="text item">
+                    <p
+                      style="color: #606266; font-weight: 600; font-size: 14px"
+                    >
+                      已选隔离点
+                    </p>
+                    <el-table
+                      :data="tableData"
+                      stripe
+                      height="480"
+                      style="width: 100%"
+                    >
+                      <el-table-column prop="pointId" label="序号" width="60">
+                      </el-table-column>
+                      <el-table-column prop="pointName" label="已选隔离点">
+                        <template slot-scope="scope">
+                          <span style="color: #2a87ff">{{
+                              scope.row.pointName
+                            }}</span>
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="pointType" label="隔离点类型">
+                        <template slot-scope="scope">
+                          {{ scope.row.pointType }}
+                          <!--                          <dict-tag-->
+                          <!--                            :options="dict.type.point_type"-->
+                          <!--                            :value="scope.row.pointType"-->
+                          <!--                          />-->
+                        </template>
+                      </el-table-column>
+                      <el-table-column
+                        prop="powerType"
+                        label="危险能量类型"
+                        width="100"
+                      >
+                        <template slot-scope="scope">
+                          {{ scope.row.powerType }}
+                          <!--                          <dict-tag-->
+                          <!--                            :options="dict.type.power_type"-->
+                          <!--                            :value="scope.row.powerType"-->
+                          <!--                          />-->
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                  <el-form-item label="" prop="">
+                    <el-button
+                      style="float: right; height: 30px; line-height: 10px"
+                      type="primary"
+                      @click="nextStep('third')"
+                    >下一步
+                    </el-button>
+                    <el-button
+                      plain
+                      style="
+                        float: right;
+                        height: 30px;
+                        line-height: 10px;
+                        margin-right: 19%;
+                      "
+                      type="primary"
+                      @click="previousStep('first')"
+                    >上一步
+                    </el-button>
+                  </el-form-item>
+                </el-form>
+              </el-tab-pane>
+              <el-tab-pane label="人员选择" name="third">
+                <!--人员选择-->
+                <el-form ref="form" :model="form" label-width="70px">
+                  <el-form-item label="开始时间" prop="ticketStartTime">
+                    <el-date-picker
+                      :disabled="this.getSopLook"
+                      v-model="form.ticketStartTime"
+                      type="datetime"
+                      placeholder="选择日期时间"
+                      align="right"
+                      :picker-options="pickerOptions"
+                      style="width: 100%"
+                      @change="ticketStartTimeChange"
+                    >
+                    </el-date-picker>
+                  </el-form-item>
+                  <el-form-item label="结束时间" prop="ticketEndTime">
+                    <el-date-picker
+                      :disabled="this.getSopLook"
+                      v-model="form.ticketEndTime"
+                      type="datetime"
+                      placeholder="选择日期时间"
+                      align="right"
+                      :picker-options="pickerOptions"
+                      style="width: 100%"
+                      @change="ticketEndTimeChange"
+                    >
+                    </el-date-picker>
+                  </el-form-item>
+                  <el-form-item label="上锁人" prop="locker">
+                    <el-select
+                      :disabled="this.getSopLook"
+                      v-model="form.locker"
+                      placeholder="上锁人"
+                      clearable
+                      style="width: 100%"
+                      @change="handlelockerChage"
+                    >
+                      <el-option
+                        v-for="dict in this.listUserOption"
+                        :key="dict.value"
+                        :label="dict.label"
+                        :value="dict.value"
+                      />
+                    </el-select>
+                  </el-form-item>
+                  <!--
+                  <el-form-item label="共锁人" prop="coLocker">
+                    <el-select
+                      v-model="form.coLocker"
+                      placeholder="共锁人"
+                      clearable
+                      multiple
+                      style="width: 100%"
+                      @change="handleCoLockerChange"
+                      ref="coLockerSelect"
+                    >
+                      <el-option
+                        v-for="dict in sortedTicketUserDTOList"
+                        :key="dict.userId"
+                        :label="dict.username"
+                        :value="dict.username"
+                      >
+                      </el-option>
+                    </el-select>
+                  </el-form-item> -->
+                  <el-form-item label="共锁人" prop="coLocker">
+                    <el-button
+                      type="primary"
+                      @click="addInside"
+                      class="gsr"
+                      size="mini"
+                    >添加内部人员
+                    </el-button>
+                    <el-button type="primary" @click="addOutside" size="mini"
+                    >添加外部人员
+                    </el-button>
+                  </el-form-item>
+                  <div class="text item">
+                    <el-table
+                      :data="sortedTicketUserDTOList"
+                      stripe
+                      height="400"
+                      style="width: 100%"
+                    >
+                      <el-table-column prop="userId" label="序号" width="50">
+                      </el-table-column>
+                      <el-table-column
+                        prop="userName"
+                        label="共锁人"
+                        width="120"
+                      >
+                        <template slot-scope="scope">
+                          <span style="color: #2a87ff">{{
+                              scope.row.userName
+                            }}</span>
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="userRole" label="共锁人来源">
+                        <template slot-scope="scope">
+                          <span>{{
+                              scope.row.userRole == "0" ? "内部" : "外部"
+                            }}</span>
+                        </template>
+                      </el-table-column>
+                      <el-table-column label="" width="80">
+                        <template slot-scope="scope">
+                          <el-button
+                            @click.native.prevent="
+                              deleteRow(scope.$index, sortedTicketUserDTOList)
+                            "
+                            type="text"
+                            size="small"
+                          >
+                            移除
+                          </el-button>
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                  </div>
+
+                  <el-form-item label="" prop="">
+                    <el-button
+                      style="float: right; height: 30px; line-height: 10px"
+                      type="primary"
+                      @click="confirm"
+                    >完 成
+                    </el-button>
+                  </el-form-item>
+                </el-form>
+              </el-tab-pane>
+            </el-tabs>
+          </div>
+        </el-card>
+      </div>
+    </div>
+    <!-- 添加或修改设备维修单对话框 -->
+    <el-dialog
+      :visible.sync="open"
+      width="450px"
+      append-to-body
+      style="margin-top: 13%"
+    >
+      <div slot="title" class="dialog-title">
+        <i></i>
+        <span class="title">{{ title }}</span>
+      </div>
+      <el-form
+        ref="dialogForm"
+        :model="dialogForm"
+        :rules="rules"
+        label-width="70px"
+      >
+        <el-form-item label="部门" prop="deptId" v-if="insideMumber">
+          <el-select
+            v-model="dialogForm.deptId"
+            placeholder="请选择部门"
+            clearable
+            style="width: 100%"
+            @change="DeptChage"
+          >
+            <el-option
+              v-for="dict in this.listDeptOption"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="选择人员" prop="nickName" v-if="insideMumber">
+          <el-select
+            v-model="dialogForm.nickName"
+            placeholder="请选择人员"
+            clearable
+            style="width: 100%"
+            multiple
+            @change="changeInsideUser"
+          >
+            <el-option
+              v-for="dict in this.listUserOption"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="人员ID" prop="mumberId" v-if="outsideMumber">
+          <el-input
+            v-model="dialogForm.username"
+            placeholder="请输入人员ID"
+            style="width: 100%"
+            @change="outSideUserInput"
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="cancel">确认</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+    <!--    newOperations盒子结束-->
+  </div>
+</template>
+
+
+<script>
+import SeparationPoint from "@/components/separationPoint/index1.vue";
+import WorkShop from "@/components/separationPoint/workshop.vue";
+import {
+  listJobTicket,
+  getJobTicketInfo,
+  addJobTicket,
+  updateJobTicket,
+  deleteIsJobTicket,
+  getworkareaList,
+} from "@/api/mes/job/job";
+
+import { mapGetters, mapActions } from "vuex";
+
+import { listWorkshop } from "@/api/mes/md/workshop";
+import { listWorkarea } from "@/api/mes/wa/workarea";
+import { getIsSopPage } from "@/api/mes/sop/sopindex";
+import { listUser } from "@/api/system/user";
+import { listDept } from "@/api/system/dept";
+import IsolationLeftVue from "@/components/separationPoint/index1.vue";
+import { genCode } from "@/api/system/autocode/rule";
+
+export default {
+  name: "addView",
+  dicts: ["ticket_type", "power_type", "point_type", "is_user_type"],
+  components: {
+    IsolationLeftVue,
+    SeparationPoint,
+    WorkShop,
+  },
+  data() {
+    return {
+      //自动生成编码
+      autoGenFlag: false,
+      activeName: "first",
+      form: {
+        sopId: "",
+        pointIds: "",
+        ticketId: "",
+        ticketType: "",
+        ticketName: "",
+        ticketCode: "",
+        ticketContent: "",
+        workshopName: "", //车间名称
+        workline: "", //区域
+        spoint: [], //已选隔离点
+        locker: "", //上锁人
+        coLocker: "", //共锁人
+        ticketStartTime: "", //开始时间
+        ticketEndTime: "", //结束时间
+        ticketUserDTOList: [
+          // {
+          //   userId: '',
+          //   userName: '',
+          //   userRole: '',//作业票角色 暂时不传递 内部人还是外部人
+          //   userType: ''//用户类型 上锁人或共锁人
+          // }
+        ], //所选择的用户
+      },
+      // 用来清空form
+      initialFormState: {
+        // 初始状态对象
+        sopId: "",
+        pointIds: "",
+        ticketId: "",
+        ticketType: "",
+        ticketName: "",
+        ticketCode: "",
+        ticketContent: "",
+        workshopName: "", //车间名称
+        workline: "", //区域
+        spoint: [], //已选隔离点
+        locker: "", //上锁人
+        coLocker: "", //共锁人
+        ticketStartTime: "", //开始时间
+        ticketEndTime: "", //结束时间
+        ticketUserDTOList: [
+          // {
+          //   userId: '',
+          //   userName: '',
+          //   userRole: '',//作业票角色 暂时不传递 内部人还是外部人
+          //   userType: ''//用户类型 上锁人或共锁人
+          // }
+        ], //所选择的用户
+      },
+      dialogForm: {
+        deptId: "",
+        nickName: "",
+        username: "",
+      },
+      listUserOption: null,
+      listDeptOption: null,
+      // 已选隔离点
+      tableData: [],
+      pickerOptions: {
+        shortcuts: [
+          {
+            text: "今天",
+            onClick(picker) {
+              picker.$emit("pick", new Date());
+            },
+          },
+          {
+            text: "昨天",
+            onClick(picker) {
+              const date = new Date();
+              date.setTime(date.getTime() - 3600 * 1000 * 24);
+              picker.$emit("pick", date);
+            },
+          },
+          {
+            text: "一周前",
+            onClick(picker) {
+              const date = new Date();
+              date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
+              picker.$emit("pick", date);
+            },
+          },
+        ],
+      },
+      // 是否显示弹出层
+      open: false,
+      // 弹出层标题
+      title: "",
+      // 弹框中显示的form表单内容
+      insideMumber: false,
+      outsideMumber: false,
+      points: null, //逆向传递拿到隔离点的数据
+      sopOptions: [], //sop下拉
+      jobProps: [], //正向传递给车间components
+
+      // 表单校验
+      rules: {
+        teamCode: [
+          { required: true, message: "班组编号不能为空", trigger: "blur" },
+        ],
+        teamName: [
+          { required: true, message: "班组名称不能为空", trigger: "blur" },
+        ],
+        calendarType: [
+          { required: true, message: "清选择班组类型", trigger: "blur" },
+        ],
+      },
+      newticketUserDTOList: [], //为了上锁人单独传递数据
+    };
+  },
+  watch: {
+    tableData: {
+      handler(newVal) {
+        // 将 pointId 提取出来并连接成一个字符串
+        if (newVal && newVal.length > 0) {
+          this.form.pointIds = this.tableData
+            .map((item) => item.pointId)
+            .join(",");
+          // console.log(this.form.pointIds, this.tableData, 'pointIds')
+        }
+      },
+      deep: true,
+    },
+    "form.ticketStartTime": {
+      handler(newVal) {
+        if (newVal && newVal.length > 0) {
+          console.log(newVal, "编辑监听开始时间");
+          this.ticketStartTimeChange(newVal);
+        }
+      },
+    },
+  },
+  computed: {
+    ...mapGetters("sopSelectPoints", [
+      "getPointTableData",
+      "getSelectSopPoints",
+      "getSopEdit",
+      "getTicketTitle",
+      "getSopLook",
+    ]),
+    // 排序 ticketUserDTOList,将 userRole 为 0 的选项放在前面
+    sortedTicketUserDTOList() {
+      return this.form.ticketUserDTOList.sort(
+        (a, b) => Number(a.userRole) - Number(b.userRole)
+      );
+    },
+  },
+  mounted() {
+    this.getSopList();
+    this.getUser();
+    if (this.$route.query.ticketId !== "null") {
+      this.getTicket();
+      this.form.ticketId = this.$route.query.ticketId;
+      if (this.getSopLook) {
+        this.setTicketTitle("查看作业票");
+      } else {
+        this.setTicketTitle("编辑作业票");
+      }
+    } else {
+      this.setSelectSopPoints([]);
+      this.setPointTableData([]);
+      this.setTicketTitle("新建作业票");
+    }
+    // console.log(this.getPointTableData, 'this.getPointTableData')
+    if (this.getPointTableData) {
+      this.tableData = this.getPointTableData.pointDetailVOList.map((item) => {
+        return {
+          pointId: item.pointId,
+          pointName: item.pointName,
+          pointType: item.pointType,
+          powerType: item.powerType,
+        };
+      });
+    }
+  },
+
+  methods: {
+    // 编辑的时候给隔离点重新存储值
+    ...mapActions("sopSelectPoints", [
+      "setSelectSopPoints",
+      "setPointTableData",
+      "setSopEdit",
+      "setTicketTitle",
+    ]),
+    formatDateTime(date) {
+      const year = date.getFullYear().toString().padStart(2, "0");
+      const month = (date.getMonth() + 1).toString().padStart(2, "0");
+      const day = date.getDate().toString().padStart(2, "0");
+      const hours = date.getHours().toString().padStart(2, "0");
+      const minutes = date.getMinutes().toString().padStart(2, "0");
+      const seconds = date.getSeconds().toString().padStart(2, "0");
+
+      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+    },
+    getTicket() {
+      this.getUser();
+
+      const ticketId = this.$route.query.ticketId;
+      getJobTicketInfo(ticketId).then((response) => {
+        console.log(response, "编辑拿到路由参数");
+        this.form = {
+          ...this.form,
+          workshopId: response.data.workshopId,
+          workareaId: response.data.workareaId,
+          sopId: response.data.sopId,
+          ticketCode: response.data.ticketCode,
+          ticketContent: response.data.ticketContent,
+          spoint: response.data.pointDetailVOList,
+          ticketUserDTOList: response.data.jobTicketUserList
+            .filter((item) => item.userType !== "0")
+            .map((item) => ({
+              userName: item.userName,
+              userType: item.userType,
+              userRole: item.userRole,
+              userId: item.userId,
+            })),
+          // ticketUserDTOList: response.data.jobTicketUserList.map((item) => {
+          //   return {
+          //     userName: item.userName,
+          //     userType: item.userType,
+          //     userRole: item.userRole,
+          //     userId: item.userId
+          //   }
+          // }),
+          locker: response.data.jobTicketUserList
+            .filter((item) => item.userType == "0")
+            .map((item) => item.userName),
+          coLocker: response.data.jobTicketUserList.map((item) => {
+            return item.userType !== "0" ? item.userName : null;
+          }),
+          ticketStartTime: response.data.ticketStartTime,
+          ticketEndTime: response.data.ticketEndTime,
+          ticketId: response.data.ticketId,
+          ticketName: response.data.ticketName,
+          ticketStatus: response.data.ticketStatus,
+          ticketType: response.data.ticketType,
+          EditBool: true,
+        };
+        this.jobProps = [this.form];
+        // this.listUserOption = response.data.jobTicketUserList
+        console.log(this.form, "form");
+      });
+    },
+
+    getSopList() {
+      const query = {
+        current: 1,
+        size: 100000,
+      };
+      getIsSopPage(query).then((res) => {
+        console.log(res, "sop列表接口");
+        // 插入一个默认的空选项
+        const defaultOption = {
+          sopId: null,
+          sopName: "不使用sop模板  ",
+        };
+
+        // 将默认选项添加到结果的最前面
+        this.sopOptions = [defaultOption, ...res.data.records];
+      });
+    },
+    getUser() {
+      const query = {
+        pageNum: 1,
+        pageSize: 100000,
+      };
+      listUser(query).then((res) => {
+        // console.log(res, '用户列表')
+        this.listUserOption = res.rows.map((item) => {
+          return {
+            label: item.nickName,
+            value: item.userId,
+          };
+        });
+      }),
+        listDept(query).then((res) => {
+          // console.log(res, '部门列表')
+          this.listDeptOption = res.data.map((item) => {
+            return {
+              label: item.deptName,
+              value: item.deptId,
+            };
+          });
+        });
+    },
+    // 添加内部人员 部门下拉的chage事件
+    DeptChage(val) {
+      console.log(val, " 部门下拉");
+      // 每次选中先清空用户下拉
+      // this.listUserOption = []
+      this.dialogForm.nickName = null;
+      const query = {
+        pageNum: 1,
+        pageSize: 100000,
+        deptId: this.dialogForm.deptId,
+      };
+      listUser(query).then((res) => {
+        console.log(res, "用户列表");
+        this.listUserOption = res.rows.map((item) => {
+          return {
+            label: item.nickName,
+            value: item.userId,
+          };
+        });
+      });
+    },
+    // sop下拉change事件 可以传递sopOptions一整个对象过去
+    handleSelectSOP(value) {
+      if (value == null) {
+        this.jobProps = [];
+        console.log(this.form.sopId, this.form, "sop下拉change事件");
+      } else {
+        this.jobProps = this.sopOptions.filter((item) => item.sopId == value);
+        this.form.ticketType = this.jobProps[0].sopType;
+        this.form.ticketName = "sop_";
+        console.log(this.jobProps, "父组件jobProps");
+      }
+    },
+    // 清除sop下拉框
+    handleClearSop() {
+      this.form.ticketType = "";
+      this.form.ticketName = "";
+    },
+    // 上锁人下拉选择change事件
+    handlelockerChage(val) {
+      console.log(val, "上锁人chage");
+      const user = this.listUserOption.find((item) => item.value === val);
+
+      if (user && this.form.locker !== "") {
+        const existingUser = this.form.ticketUserDTOList.find(
+          (u) => u.userName === user.label
+        );
+        if (!existingUser) {
+          this.newticketUserDTOList.push({
+            userName: user.label,
+            userId: user.value,
+            userType: 0,
+            userRole: "0",
+          });
+          // this.form.ticketUserDTOList.push({
+          //   userName: user.label,
+          //   userId: user.value,
+          //   userType: 0,
+          //   userRole: '0',
+          // })
+          console.log(this.newticketUserDTOList, "用户");
+        } else {
+          // console.log('用户已存在', user.label)
+        }
+      }
+    },
+
+    // 添加内部人员的用户新增到ticketUserDTOList这个数据里
+    changeInsideUser(values) {
+      const usersinside = values
+        .map((value) =>
+          this.listUserOption.find((item) => item.value === value)
+        )
+        .filter(Boolean);
+      usersinside.forEach((user) => {
+        const existingUser = this.form.ticketUserDTOList.find(
+          (u) => u.userName === user.label
+        );
+        // console.log(usersinside, 'usersinside----67')
+        if (!existingUser) {
+          this.form.ticketUserDTOList.push({
+            userName: user.label,
+            userId: user.value,
+            userType: 1,
+            userRole: 0,
+            bgColor: "green",
+          });
+          console.log(this.form.ticketUserDTOList, "用户");
+        } else {
+          // console.log('用户已存在', user.label)
+        }
+      });
+      this.updateCoLocker();
+
+      // console.log(this.form.ticketUserDTOList, '用户')
+    },
+    // 添加外部人员 输入名称 userType==1是共锁人 0是上锁人 userId==0
+    outSideUserInput(value) {
+      // console.log(value, '外部人员名称')
+      const existingUser = this.form.ticketUserDTOList.find(
+        (u) => u.userName === value
+      );
+
+      if (!existingUser) {
+        this.form.ticketUserDTOList.push({
+          userName: value,
+          userId: 0,
+          userType: 1,
+          userRole: 1,
+          bgColor: "red",
+        });
+        console.log(this.form.ticketUserDTOList, "用户");
+      } else {
+        // console.log('用户已存在', value)
+      }
+      this.updateCoLocker();
+    },
+    // 更新界面中共锁人下拉框显示的内容
+    // 更新 coLocker 数据
+    updateCoLocker() {
+      // 获取现有的 coLocker 数据
+      const existingCoLocker = new Set(this.form.coLocker);
+      // console.log(existingCoLocker, 'existingCoLocker----1');
+
+      // 将 ticketUserDTOList 中的新用户名字添加到 existingCoLocker 中
+
+      this.form.ticketUserDTOList.forEach((user) => {
+        existingCoLocker.add(user.userName);
+      });
+      // console.log(this.form.ticketUserDTOList, 'this.form.ticketUserDTOList----2');
+
+      // 将 Set 转换回数组
+      this.form.coLocker = Array.from(existingCoLocker);
+      // console.log(this.form.coLocker, 'this.form.coLocker----3');
+
+      // 检查并补充 ticketUserDTOList 中缺少的用户
+      this.form.coLocker.forEach((name) => {
+        const existingUser = this.form.ticketUserDTOList.find(
+          (u) => u.userName === name
+        );
+
+        if (!existingUser) {
+          this.form.ticketUserDTOList.push({
+            userName: name,
+            userId: 0,
+            userType: 1,
+            userRole: 1,
+            bgColor: "red",
+          });
+        }
+      });
+
+      console.log(this.form.ticketUserDTOList, "最终的 ticketUserDTOList");
+    },
+    // 设置多选下拉框样式
+    // updateTagBackgrounds() {
+    //   this.$nextTick(() => {
+    //     const elTags = this.$refs.coLockerSelect.$el.querySelectorAll('.el-tag')
+    //
+    //     elTags.forEach(tag => {
+    //       const tagText = tag.textContent.trim()
+    //       const option = this.form.ticketUserDTOList.find(dict => dict.userName === tagText)
+    //
+    //       if (option) {
+    //         tag.style.backgroundColor = option.bgColor
+    //
+    //       }
+    //     })
+    //   })
+    // },
+    // 共锁人下拉框删除事件
+    // handleCoLockerChange(newValues) {
+    //   console.log(newValues, 'ticketUserDTOList-newsValue')
+    //
+    //   // 根据新值更新 this.form.ticketUserDTOList
+    //   this.form.ticketUserDTOList = this.form.ticketUserDTOList.filter((user) =>
+    //     newValues.includes(user.userName)
+    //   )
+    //
+    //   // 更新 coLocker 显示的内容
+    //   this.updateCoLocker()
+    // },
+    handleClick(tab, event) {
+      // console.log(tab, event);
+    },
+    previousStep(val) {
+      this.activeName = val;
+    },
+    nextStep(val) {
+      console.log(val, "nextStep");
+      this.activeName = val;
+      console.log("我点击了下一步");
+    },
+    async getWorkareaId(query) {
+      try {
+        const res = await listWorkarea(query);
+        console.log(res, "工作区域page");
+        return res.data.records[0].workareaId;
+      } catch (error) {
+        console.error("获取工作区域ID失败", error);
+        throw error;
+      }
+    },
+
+    async getWorkshopId(query) {
+      try {
+        const res = await listWorkshop(query);
+        console.log(res, "车间id");
+        return res.rows[0].workshopId;
+      } catch (error) {
+        console.error("获取车间ID失败", error);
+        throw error;
+      }
+    },
+
+    async confirm() {
+      try {
+        // 格式化时间
+        this.form.ticketStartTime = this.formatDateTime(
+          new Date(this.form.ticketStartTime)
+        );
+        this.form.ticketEndTime = this.formatDateTime(
+          new Date(this.form.ticketEndTime)
+        );
+        console.log(this.form, "拿到的所有参数确认");
+
+        const query = {
+          current: 1,
+          size: 100000,
+          workareaName: this.form.workline,
+        };
+
+        const query1 = {
+          current: 1,
+          size: 100000,
+          workshopName: this.form.workshopName,
+        };
+
+        const workareaId = await this.getWorkareaId(query);
+        const workshopId = await this.getWorkshopId(query1);
+
+        // 合并 newticketUserDTOList 到 this.form.ticketUserDTOList
+        if (this.form.locker) {
+          const selectedUser = this.listUserOption.find(
+            (option) => option.label === this.form.locker
+          );
+          if (selectedUser) {
+            this.form.ticketUserDTOList.push({
+              userName: selectedUser.label,
+              userId: selectedUser.value,
+              userType: "0",
+              userRole: "0",
+            });
+          }
+        }
+        this.form.ticketUserDTOList.push(...this.newticketUserDTOList);
+        const data = {
+          pointIds: this.form.pointIds,
+          sopId: this.form.sopId,
+          ticketCode: this.form.ticketCode,
+          ticketContent: this.form.ticketContent,
+          ticketEndTime: this.form.ticketEndTime,
+          ticketName: this.form.ticketName,
+          ticketStartTime: this.form.ticketStartTime,
+          ticketType: this.form.ticketType,
+          ticketUserDTOList: this.form.ticketUserDTOList,
+          workareaId: workareaId,
+          workshopId: workshopId,
+        };
+        const editdata = {
+          pointIds: this.form.spoint.join(","),
+          sopId: this.form.sopId,
+          ticketCode: this.form.ticketCode,
+          ticketContent: this.form.ticketContent,
+          ticketId: this.form.ticketId,
+          ticketEndTime: this.form.ticketEndTime,
+          ticketName: this.form.ticketName,
+          ticketStartTime: this.form.ticketStartTime,
+          ticketType: this.form.ticketType,
+          ticketUserDTOList: this.form.ticketUserDTOList,
+          workareaId: workareaId,
+          workshopId: workshopId,
+        };
+
+        // 检查 route.query.ticketId 是否为 null
+        console.log(this.$route.query.ticketId, "this.$route.query.ticketId");
+        if (this.$route.query.ticketId !== "null") {
+          // 调用编辑接口
+          const res = await updateJobTicket(editdata);
+          if (res.code === 200) {
+            // this.$router.go(-1);
+            this.$router.push("/job/jobm");
+            localStorage.removeItem("workshopId");
+            localStorage.removeItem("workareaId");
+          } else {
+            console.error("编辑工单失败", res);
+          }
+        } else {
+          // 调用新增接口
+          const res = await addJobTicket(data);
+          if (res.code === 200) {
+            // this.$router.go(-1);
+            this.$router.push("/job/jobm");
+          } else {
+            console.error("提交工单失败", res);
+          }
+        }
+      } catch (error) {
+        console.error("确认过程中发生错误", error);
+      }
+
+      console.log("确认");
+    },
+    // 子组件逆向传递选中的隔离点
+
+    handleSelectPoint(points) {
+      // console.log(points, '父组件接收逆向传递选中的隔离点')
+
+      // 使用 Set 来存储传递过来的点值
+      const newValues = new Set(points.map((point) => point.pointId));
+
+      // 1. 删除取消选中的点
+      this.tableData = this.tableData.filter((item) =>
+        newValues.has(item.pointId)
+      );
+
+      // 2. 确保新增点不会重复
+      const existingValues = new Set(
+        this.tableData.map((item) => item.pointId)
+      );
+
+      points.forEach((point) => {
+        // 如果当前传递的点不在已有的点集中,则添加
+        if (!existingValues.has(point.pointId)) {
+          this.tableData.push({
+            pointName: point.pointName, // 显示的名称
+            pointId: point.pointId, // 对应的值
+            pointType: point.pointType,
+            powerType: point.powerType,
+          });
+          // 将新点值添加到 Set 中
+          existingValues.add(point.value);
+        }
+      });
+
+      // 更新 form.spoint 为最新选中的隔离点数组
+      this.form.spoint = points.map((point) => point.pointId);
+    },
+    // 车间你逆向传递拿到的隔离点数据产线
+    handleProductLineSelected(selectedOption) {
+      // console.log(selectedOption, '父组件接收到的 selectedOption');
+      this.points = selectedOption;
+      this.form.workline = selectedOption.label;
+    },
+    // 车间子组件逆传递车间相关数据车间
+    handleWorkshopSelected(selectedOption) {
+      console.log(selectedOption, "handleWorkshopSelected");
+      this.emitWorkShop = selectedOption;
+      this.form.workshopName = selectedOption.label;
+    },
+    // 添加内部人员
+    addInside() {
+      this.open = true;
+      this.title = "添加内部人员";
+      this.insideMumber = true;
+      this.outsideMumber = false;
+      // this.form.ticketUserDTOList = [];
+      this.dialogForm.deptId = "";
+      this.dialogForm.nickName = "";
+    },
+    addOutside() {
+      this.open = true;
+      this.title = "添加外部人员";
+      this.insideMumber = false;
+      this.outsideMumber = true;
+      this.dialogForm.username = null;
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+    },
+    // 人员列表删除
+    // deleteRow(index, rows) {
+    //   console.log(index, rows, '删除的行')
+    //   rows.splice(index, 1)
+    //   this.form.ticketUserDTOList.splice(index, 1)
+    // },
+    deleteRow(index, rows) {
+      console.log(index, rows, "删除的行");
+      const deletedItem = rows[index]; // 获取要删除的项
+      rows.splice(index, 1); // 从显示的列表中删除
+      const formIndex = this.form.ticketUserDTOList.findIndex(
+        (item) => item.userId === deletedItem.userId
+      );
+      if (formIndex !== -1) {
+        this.form.ticketUserDTOList.splice(formIndex, 1); // 从 form.ticketUserDTOList 中删除
+      }
+    },
+    //   时间选项
+    ticketStartTimeChange(value) {
+      this.form.ticketStartTime = value;
+      // 更新 pickerOptions 中的 disabledDate 方法
+      this.updatePickerOptions();
+    },
+    ticketEndTimeChange(value) {
+      this.form.ticketEndTime = value;
+    },
+    disabledDate(time) {
+      const startTime = new Date(this.form.ticketStartTime);
+      return startTime && !isNaN(startTime.getTime())
+        ? time.getTime() < startTime.getTime()
+        : false;
+    },
+    updatePickerOptions() {
+      this.pickerOptions.disabledDate = this.disabledDate;
+    },
+
+    reset() {
+      (this.form = {
+        sopId: "",
+        pointIds: "",
+        ticketType: "",
+        ticketName: "",
+        ticketCode: "",
+        ticketContent: "",
+        workshopName: "", //车间名称
+        workline: "", //区域
+        spoint: [], //已选隔离点
+        locker: "", //上锁人
+        coLocker: "", //共锁人
+        ticketStartTime: "", //开始时间
+        ticketEndTime: "", //结束时间
+        ticketUserDTOList: [
+          // {
+          //   userId: '',
+          //   userName: '',
+          //   userRole: '',//作业票角色 暂时不传递
+          //   userType: ''//用户类型 上锁人或共锁人
+          // }
+        ],
+      }),
+        (this.autoGenFlag = false);
+    },
+
+    // 侧边x关闭函数
+    goBack() {
+      this.$router.push("/job/jobm");
+    },
+    //自动生成编码
+    handleAutoGenChange(autoGenFlag) {
+      if (autoGenFlag) {
+        genCode("JOB_TICKET_CODE").then((response) => {
+          this.form.ticketCode = response;
+        });
+      } else {
+        this.form.ticketCode = null;
+      }
+    },
+  },
+};
+</script>
+
+
+<style scoped lang="scss">
+.newOperations {
+  width: 99%;
+  height: 100%;
+  //background: pink;
+  margin: 10px;
+  display: flex;
+
+  .left {
+    width: 75%;
+    height: 830px;
+    // background: #eee;
+    margin-right: 10px;
+  }
+
+  .right {
+    height: 100%;
+    flex: 1;
+
+    .right_top {
+      height: 550px;
+    }
+
+    .workTicket_btn {
+      position: relative;
+      left: 63%;
+      height: 30px;
+      line-height: 10px;
+    }
+
+    .gsr {
+      margin-left: 60px;
+    }
+  }
+}
+
+//右侧卡片样式开始
+.text {
+  font-size: 14px;
+}
+
+.item {
+  margin-bottom: 18px;
+
+  p {
+    font-size: 18px;
+    font-weight: bolder;
+    font-family: SourceHanSansSC-bold;
+  }
+}
+
+.clearfix:before,
+.clearfix:after {
+  display: table;
+  content: "";
+  width: 320px;
+}
+
+.clearfix:after {
+  clear: both;
+}
+
+.box-card {
+  // width: 390px;
+  width: 95%;
+  height: 850px;
+}
+
+//右侧卡片样式结束
+//隔离点多选框样式
+.selects {
+  .el-input.el-input--medium.el-input--suffix {
+    // 调整箭头符号块的宽度
+    width: 175px !important;
+  }
+
+  .el-input.el-input--medium.el-input--suffix {
+    .el-input__inner {
+      // 调整输入框的宽高
+      height: 36px !important;
+      width: 220px !important;
+    }
+
+    .el-input__suffix-inner {
+      // 调整箭头符号的位置
+      position: absolute;
+      right: -45px;
+    }
+  }
+
+  .el-select__tags {
+    // 调整输入框里面的多选不换行
+    flex-wrap: nowrap !important;
+  }
+}
+
+//隔离点多选框样式结束
+</style>
+
+<style scoped lang="scss" src="@/assets/styles/dialog-title.scss">
+</style>

+ 374 - 298
src/views/mes/job/jobm/NewOperations.vue

@@ -35,6 +35,7 @@
               @click="goBack"
               >×</span
             >
+
           </div>
           <div class="text item">
             <el-tabs v-model="activeName" @tab-click="handleClick">
@@ -126,21 +127,12 @@
                   </el-form-item>
                 </el-form>
               </el-tab-pane>
-              <el-tab-pane label="选择隔离点" name="second">
+              <el-tab-pane label="隔离点信息" name="second">
                 <!-- 隔离点信息-->
                 <el-form ref="form" :model="form" label-width="90px">
-                  <el-form-item label="车间名称" prop="workshopName">
-                    <el-input
-                      v-model="form.workshopName"
-                      placeholder="请输入车间名称"
-                      style="width: 100%"
-                      disabled
-                    />
-                  </el-form-item>
-                  <el-form-item label="区域" prop="workline">
+                  <el-form-item label="工作区域" prop="workline">
                     <el-input
                       v-model="form.workline"
-                      placeholder="请输入区域"
                       style="width: 100%"
                       disabled
                     />
@@ -157,9 +149,9 @@
                       height="480"
                       style="width: 100%"
                     >
-                      <el-table-column prop="pointId" label="序号" width="60">
-                      </el-table-column>
-                      <el-table-column prop="pointName" label="已选隔离点">
+<!--                      <el-table-column prop="pointId" label="序号" width="60">-->
+<!--                      </el-table-column>-->
+                      <el-table-column prop="pointName" label="隔离点" width="60">
                         <template slot-scope="scope">
                           <span style="color: #2a87ff">{{
                             scope.row.pointName
@@ -169,10 +161,7 @@
                       <el-table-column prop="pointType" label="隔离点类型">
                         <template slot-scope="scope">
                           {{ scope.row.pointType }}
-                          <!--                          <dict-tag-->
-                          <!--                            :options="dict.type.point_type"-->
-                          <!--                            :value="scope.row.pointType"-->
-                          <!--                          />-->
+
                         </template>
                       </el-table-column>
                       <el-table-column
@@ -182,10 +171,24 @@
                       >
                         <template slot-scope="scope">
                           {{ scope.row.powerType }}
-                          <!--                          <dict-tag-->
-                          <!--                            :options="dict.type.power_type"-->
-                          <!--                            :value="scope.row.powerType"-->
-                          <!--                          />-->
+                        </template>
+                      </el-table-column>
+                      <el-table-column
+                        prop="prePointId"
+                        label="前置节点"
+                        width="100"
+                      >
+                        <template slot-scope="scope">
+                          <el-select size="mini" v-model="scope.row.prePointId" @change="prePointIdChange(scope.row)"
+                                     @visible-change="onDropdownVisibleChange(scope.row)"
+                          >
+                            <el-option v-for="item in prePointIdOptions"
+                                       :key="item.pointId"
+                                       :label="item.pointName"
+                                       :value="item.pointId"
+                            >
+                            </el-option>
+                          </el-select>
                         </template>
                       </el-table-column>
                     </el-table>
@@ -251,33 +254,14 @@
                       @change="handlelockerChage"
                     >
                       <el-option
-                        v-for="dict in this.listUserOption"
+                        v-for="dict in this.listLockerOption"
                         :key="dict.value"
                         :label="dict.label"
                         :value="dict.value"
                       />
                     </el-select>
                   </el-form-item>
-                  <!--
-                  <el-form-item label="共锁人" prop="coLocker">
-                    <el-select
-                      v-model="form.coLocker"
-                      placeholder="共锁人"
-                      clearable
-                      multiple
-                      style="width: 100%"
-                      @change="handleCoLockerChange"
-                      ref="coLockerSelect"
-                    >
-                      <el-option
-                        v-for="dict in sortedTicketUserDTOList"
-                        :key="dict.userId"
-                        :label="dict.username"
-                        :value="dict.username"
-                      >
-                      </el-option>
-                    </el-select>
-                  </el-form-item> -->
+
                   <el-form-item label="共锁人" prop="coLocker">
                     <el-button
                       type="primary"
@@ -362,25 +346,9 @@
       <el-form
         ref="dialogForm"
         :model="dialogForm"
-        :rules="rules"
+
         label-width="70px"
       >
-        <el-form-item label="部门" prop="deptId" v-if="insideMumber">
-          <el-select
-            v-model="dialogForm.deptId"
-            placeholder="请选择部门"
-            clearable
-            style="width: 100%"
-            @change="DeptChage"
-          >
-            <el-option
-              v-for="dict in this.listDeptOption"
-              :key="dict.value"
-              :label="dict.label"
-              :value="dict.value"
-            />
-          </el-select>
-        </el-form-item>
         <el-form-item label="选择人员" prop="nickName" v-if="insideMumber">
           <el-select
             v-model="dialogForm.nickName"
@@ -391,7 +359,7 @@
             @change="changeInsideUser"
           >
             <el-option
-              v-for="dict in this.listUserOption"
+              v-for="dict in this.listCoLockerOption"
               :key="dict.value"
               :label="dict.label"
               :value="dict.value"
@@ -399,17 +367,63 @@
           </el-select>
         </el-form-item>
 
-        <el-form-item label="人员ID" prop="mumberId" v-if="outsideMumber">
-          <el-input
-            v-model="dialogForm.username"
-            placeholder="请输入人员ID"
-            style="width: 100%"
-            @change="outSideUserInput"
-          />
+        <el-form-item label="人员ID" prop="username" v-if="outsideMumber">
+          <el-row>
+            <el-col :span="16">
+              <el-input
+                v-model="dialogForm.username"
+                placeholder="请输入人员ID"
+                clearable
+                style="width: 80%"
+                @change="outSideUserInput"
+              />
+            </el-col>
+            <el-col :span="4">
+              <el-button type="primary" @click="insertOutSideTable">添加</el-button>
+            </el-col>
+          </el-row>
         </el-form-item>
+        <el-row>
+          <el-table :data="OutSideUserTableData"
+                    stripe
+                    height="200"
+                    v-if="outsideMumber"
+          >
+            <el-table-column prop="userId" label="序号">
+            </el-table-column>
+            <el-table-column
+              prop="userName"
+              label="人员ID"
+
+            >
+              <template slot-scope="scope">
+                          <span style="color: #2a87ff">{{
+                              scope.row.userName
+                            }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="80">
+              <template slot-scope="scope">
+                <el-button
+                  @click.native.prevent="
+                              deleteRow(scope.$index, OutSideUserTableData)
+                            "
+                  type="text"
+                  size="small"
+                >
+                  移除
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-row>
+
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="cancel">确认</el-button>
+        <!--  内部人员确认-->
+        <el-button type="primary" @click="cancel" v-if="insideMumber">确认</el-button>
+        <!--        外部人员确认-->
+        <el-button type="primary" @click="outSideDialogConfirm" v-if="outsideMumber">确认</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
@@ -429,7 +443,7 @@ import {
   deleteIsJobTicket,
   getworkareaList,
 } from "@/api/mes/job/job";
-
+import {SopUser} from "@/api/mes/sop/sopindex"
 import { mapGetters, mapActions } from "vuex";
 
 import { listWorkshop } from "@/api/mes/md/workshop";
@@ -452,6 +466,7 @@ export default {
     return {
       //自动生成编码
       autoGenFlag: false,
+      openStaffing:false,
       activeName: "first",
       form: {
         sopId: "",
@@ -494,6 +509,7 @@ export default {
         coLocker: "", //共锁人
         ticketStartTime: "", //开始时间
         ticketEndTime: "", //结束时间
+        pointDetailVOList: [],//隔离点数据
         ticketUserDTOList: [
           // {
           //   userId: '',
@@ -504,9 +520,8 @@ export default {
         ], //所选择的用户
       },
       dialogForm: {
-        deptId: "",
-        nickName: "",
-        username: "",
+        nickName: '',
+        username: ''
       },
       listUserOption: null,
       listDeptOption: null,
@@ -546,9 +561,9 @@ export default {
       insideMumber: false,
       outsideMumber: false,
       points: null, //逆向传递拿到隔离点的数据
+      emitWorkShop: null, //车间逆向传递拿到车间相关数据
       sopOptions: [], //sop下拉
       jobProps: [], //正向传递给车间components
-
       // 表单校验
       rules: {
         teamCode: [
@@ -562,6 +577,15 @@ export default {
         ],
       },
       newticketUserDTOList: [], //为了上锁人单独传递数据
+      prePointIdOptions: [],//前置节点的下拉选项
+      initprePointIdOptions: [],//前置节点初始化数据选项
+      prePointId: null,//回显选中的前置节点id
+      relations: [],//维护父子关系的前置节点
+      listLockerOption: null,//上锁人下拉数据
+      listCoLockerOption: null,//共锁人下拉数据
+      OutSideUserTableData: [],//添加外部人员多个表格
+      nextUserId: 0,//新增外部人员表格序号自定义
+      worklineMap:null,//工作区域拿到的mapjson
     };
   },
   watch: {
@@ -604,6 +628,7 @@ export default {
   mounted() {
     this.getSopList();
     this.getUser();
+    this.handleOpenStaffing()
     if (this.$route.query.ticketId !== "null") {
       this.getTicket();
       this.form.ticketId = this.$route.query.ticketId;
@@ -625,6 +650,7 @@ export default {
           pointName: item.pointName,
           pointType: item.pointType,
           powerType: item.powerType,
+
         };
       });
     }
@@ -777,150 +803,6 @@ export default {
       this.form.ticketType = "";
       this.form.ticketName = "";
     },
-    // 上锁人下拉选择change事件
-    handlelockerChage(val) {
-      console.log(val, "上锁人chage");
-      const user = this.listUserOption.find((item) => item.value === val);
-
-      if (user && this.form.locker !== "") {
-        const existingUser = this.form.ticketUserDTOList.find(
-          (u) => u.userName === user.label
-        );
-        if (!existingUser) {
-          this.newticketUserDTOList.push({
-            userName: user.label,
-            userId: user.value,
-            userType: 0,
-            userRole: "0",
-          });
-          // this.form.ticketUserDTOList.push({
-          //   userName: user.label,
-          //   userId: user.value,
-          //   userType: 0,
-          //   userRole: '0',
-          // })
-          console.log(this.newticketUserDTOList, "用户");
-        } else {
-          // console.log('用户已存在', user.label)
-        }
-      }
-    },
-
-    // 添加内部人员的用户新增到ticketUserDTOList这个数据里
-    changeInsideUser(values) {
-      const usersinside = values
-        .map((value) =>
-          this.listUserOption.find((item) => item.value === value)
-        )
-        .filter(Boolean);
-      usersinside.forEach((user) => {
-        const existingUser = this.form.ticketUserDTOList.find(
-          (u) => u.userName === user.label
-        );
-        // console.log(usersinside, 'usersinside----67')
-        if (!existingUser) {
-          this.form.ticketUserDTOList.push({
-            userName: user.label,
-            userId: user.value,
-            userType: 1,
-            userRole: 0,
-            bgColor: "green",
-          });
-          console.log(this.form.ticketUserDTOList, "用户");
-        } else {
-          // console.log('用户已存在', user.label)
-        }
-      });
-      this.updateCoLocker();
-
-      // console.log(this.form.ticketUserDTOList, '用户')
-    },
-    // 添加外部人员 输入名称 userType==1是共锁人 0是上锁人 userId==0
-    outSideUserInput(value) {
-      // console.log(value, '外部人员名称')
-      const existingUser = this.form.ticketUserDTOList.find(
-        (u) => u.userName === value
-      );
-
-      if (!existingUser) {
-        this.form.ticketUserDTOList.push({
-          userName: value,
-          userId: 0,
-          userType: 1,
-          userRole: 1,
-          bgColor: "red",
-        });
-        console.log(this.form.ticketUserDTOList, "用户");
-      } else {
-        // console.log('用户已存在', value)
-      }
-      this.updateCoLocker();
-    },
-    // 更新界面中共锁人下拉框显示的内容
-    // 更新 coLocker 数据
-    updateCoLocker() {
-      // 获取现有的 coLocker 数据
-      const existingCoLocker = new Set(this.form.coLocker);
-      // console.log(existingCoLocker, 'existingCoLocker----1');
-
-      // 将 ticketUserDTOList 中的新用户名字添加到 existingCoLocker 中
-
-      this.form.ticketUserDTOList.forEach((user) => {
-        existingCoLocker.add(user.userName);
-      });
-      // console.log(this.form.ticketUserDTOList, 'this.form.ticketUserDTOList----2');
-
-      // 将 Set 转换回数组
-      this.form.coLocker = Array.from(existingCoLocker);
-      // console.log(this.form.coLocker, 'this.form.coLocker----3');
-
-      // 检查并补充 ticketUserDTOList 中缺少的用户
-      this.form.coLocker.forEach((name) => {
-        const existingUser = this.form.ticketUserDTOList.find(
-          (u) => u.userName === name
-        );
-
-        if (!existingUser) {
-          this.form.ticketUserDTOList.push({
-            userName: name,
-            userId: 0,
-            userType: 1,
-            userRole: 1,
-            bgColor: "red",
-          });
-        }
-      });
-
-      console.log(this.form.ticketUserDTOList, "最终的 ticketUserDTOList");
-    },
-    // 设置多选下拉框样式
-    // updateTagBackgrounds() {
-    //   this.$nextTick(() => {
-    //     const elTags = this.$refs.coLockerSelect.$el.querySelectorAll('.el-tag')
-    //
-    //     elTags.forEach(tag => {
-    //       const tagText = tag.textContent.trim()
-    //       const option = this.form.ticketUserDTOList.find(dict => dict.userName === tagText)
-    //
-    //       if (option) {
-    //         tag.style.backgroundColor = option.bgColor
-    //
-    //       }
-    //     })
-    //   })
-    // },
-    // 共锁人下拉框删除事件
-    // handleCoLockerChange(newValues) {
-    //   console.log(newValues, 'ticketUserDTOList-newsValue')
-    //
-    //   // 根据新值更新 this.form.ticketUserDTOList
-    //   this.form.ticketUserDTOList = this.form.ticketUserDTOList.filter((user) =>
-    //     newValues.includes(user.userName)
-    //   )
-    //
-    //   // 更新 coLocker 显示的内容
-    //   this.updateCoLocker()
-    // },
     handleClick(tab, event) {
       // console.log(tab, event);
     },
@@ -932,28 +814,7 @@ export default {
       this.activeName = val;
       console.log("我点击了下一步");
     },
-    async getWorkareaId(query) {
-      try {
-        const res = await listWorkarea(query);
-        console.log(res, "工作区域page");
-        return res.data.records[0].workareaId;
-      } catch (error) {
-        console.error("获取工作区域ID失败", error);
-        throw error;
-      }
-    },
-
-    async getWorkshopId(query) {
-      try {
-        const res = await listWorkshop(query);
-        console.log(res, "车间id");
-        return res.rows[0].workshopId;
-      } catch (error) {
-        console.error("获取车间ID失败", error);
-        throw error;
-      }
-    },
-
+    // 作业票确认
     async confirm() {
       try {
         // 格式化时间
@@ -1052,25 +913,99 @@ export default {
 
       console.log("确认");
     },
-    // 子组件逆向传递选中的隔离点
+    // 选中隔离点 前置节点的change函数
+    onDropdownVisibleChange(row) {
+      console.log(row, '我执行这里拉')
+
+      // 当前节点 ID
+      const currentPointId = row.pointId
+
+      // 获取当前行的 prePointId
+      const currentPrePointId = row.prePointId
+
+      // 已经被选为前置节点的 ID 集合
+      const selectedPrePointIds = new Set(
+        this.tableData
+          .filter((item) => item.prePointId !== null)
+          .map((item) => item.prePointId)
+      )
+
+      // console.log(selectedPrePointIds, 'selectedPrePointIds')
+      // 构建 form.prePointId 数组对象
+      this.form.prePointId = this.tableData.map((item) => ({
+        pointId: item.pointId,
+        prePointId: item.prePointId || null
+      }))
+      // 每次都从原始数据开始过滤
+      let filteredOptions = [...this.initprePointIdOptions]
 
+      // 过滤规则:
+      // 1. 排除自身
+      // 2. 排除已经被选为前置节点的隔离点
+      // 3. 排除所有已经选为前置节点的节点及其前置节点
+      const allExcludedPoints = new Set([currentPointId])
+      this.getAllExcludedPoints(currentPointId, allExcludedPoints)
+
+      filteredOptions = filteredOptions.filter((option) => {
+        return !allExcludedPoints.has(option.pointId)
+      })
+
+      this.prePointIdOptions = filteredOptions
+
+      console.log('过滤后的前置节点选项', this.prePointIdOptions)
+    },
+
+    // 递归获取所有需要排除的节点
+    getAllExcludedPoints(pointId, excludedPoints) {
+      const relatedRows = this.tableData.filter(item => item.prePointId === pointId)
+      for (const row of relatedRows) {
+        excludedPoints.add(row.pointId)
+        this.getAllExcludedPoints(row.pointId, excludedPoints)
+      }
+    },
+
+    // 前置节点改变时的处理函数
+    prePointIdChange(row) {
+      console.log(row, '前置节点改变')
+
+      // 更新 tableData 中对应行的 prePointId
+      const index = this.tableData.findIndex(item => item.pointId === row.pointId)
+      if (index !== -1) {
+        this.$set(this.tableData, index, row)
+      }
+
+      // 重新调用 onDropdownVisibleChange 确保其他节点的选项更新
+      this.onDropdownVisibleChange(row)
+    },
+    // 子组件逆向传递选中的隔离点
     handleSelectPoint(points) {
-      // console.log(points, '父组件接收逆向传递选中的隔离点')
+      console.log(points, '父组件接收逆向传递选中的隔离点');
+
+      // 1. 去除重复的点,使用 Set 确保每个 pointId 唯一
+      const uniquePoints = Array.from(
+        new Set(points.map(point => point.pointId))
+      ).map(id => points.find(point => point.pointId === id));
+
+      console.log(uniquePoints, '去重后的选中节点');
+
+      this.tableData = uniquePoints; // 子组件传递过来的选中节点(去重后)
 
       // 使用 Set 来存储传递过来的点值
-      const newValues = new Set(points.map((point) => point.pointId));
+      const newValues = new Set(uniquePoints.map((point) => point.pointId));
+
+      // 2. 删除取消选中的点
+      const removedPoints = this.tableData
+        .filter((item) => !newValues.has(item.pointId))
+        .map((item) => item.pointId); // 记录被删除的点
 
-      // 1. 删除取消选中的点
       this.tableData = this.tableData.filter((item) =>
         newValues.has(item.pointId)
       );
 
-      // 2. 确保新增点不会重复
-      const existingValues = new Set(
-        this.tableData.map((item) => item.pointId)
-      );
+      // 3. 确保新增点不会重复
+      const existingValues = new Set(this.tableData.map((item) => item.pointId));
 
-      points.forEach((point) => {
+      uniquePoints.forEach((point) => {
         // 如果当前传递的点不在已有的点集中,则添加
         if (!existingValues.has(point.pointId)) {
           this.tableData.push({
@@ -1078,64 +1013,61 @@ export default {
             pointId: point.pointId, // 对应的值
             pointType: point.pointType,
             powerType: point.powerType,
+            prePointId: null
+          });
+
+          this.prePointIdOptions.push({
+            pointName: point.pointName, // 显示的名称
+            pointId: point.pointId // 对应的值
           });
-          // 将新点值添加到 Set 中
-          existingValues.add(point.value);
+          this.initprePointIdOptions = [...this.prePointIdOptions];
+          console.log(this.prePointIdOptions, '前置节点设置下拉');
+          existingValues.add(point.pointId);
+        }
+      });
+
+      // 4. 处理被删除的点,如果这些点作为父节点绑定,则将对应的 prePointId 设置为 null
+      this.tableData.forEach((item) => {
+        if (removedPoints.includes(item.prePointId)) {
+          item.prePointId = null;
         }
       });
 
+      // 5. 从下拉选项中移除被删除的点
+      this.prePointIdOptions = this.prePointIdOptions.filter(
+        (option) => !removedPoints.includes(option.pointId)
+      );
+      this.initprePointIdOptions = [...this.prePointIdOptions];
+
+      // 6. 确保下拉选项中仍然保留所有未被删除的点
+      const allPoints = uniquePoints.map((point) => ({
+        pointName: point.pointName,
+        pointId: point.pointId
+      }));
+
+      this.prePointIdOptions = allPoints.filter(
+        (option) => !removedPoints.includes(option.pointId)
+      );
+      this.initprePointIdOptions = [...this.prePointIdOptions];
+
       // 更新 form.spoint 为最新选中的隔离点数组
-      this.form.spoint = points.map((point) => point.pointId);
+      this.form.spoint = uniquePoints.map((point) => point.pointId);
     },
-    // 车间你逆向传递拿到的隔离点数据产线
+    // 车间逆向传递拿到的隔离点数据产线
     handleProductLineSelected(selectedOption) {
-      // console.log(selectedOption, '父组件接收到的 selectedOption');
-      this.points = selectedOption;
-      this.form.workline = selectedOption.label;
+      // console.log(selectedOption, "父组件接收到的 selectedOption");
+      this.points = selectedOption
+      this.form.workline = selectedOption.label
+      // console.log(this.worklineMap.length, '父组件接收到的 worklineMap')
     },
     // 车间子组件逆传递车间相关数据车间
     handleWorkshopSelected(selectedOption) {
-      console.log(selectedOption, "handleWorkshopSelected");
-      this.emitWorkShop = selectedOption;
-      this.form.workshopName = selectedOption.label;
-    },
-    // 添加内部人员
-    addInside() {
-      this.open = true;
-      this.title = "添加内部人员";
-      this.insideMumber = true;
-      this.outsideMumber = false;
-      // this.form.ticketUserDTOList = [];
-      this.dialogForm.deptId = "";
-      this.dialogForm.nickName = "";
-    },
-    addOutside() {
-      this.open = true;
-      this.title = "添加外部人员";
-      this.insideMumber = false;
-      this.outsideMumber = true;
-      this.dialogForm.username = null;
-    },
-    // 取消按钮
-    cancel() {
-      this.open = false;
-    },
-    // 人员列表删除
-    // deleteRow(index, rows) {
-    //   console.log(index, rows, '删除的行')
-    //   rows.splice(index, 1)
-    //   this.form.ticketUserDTOList.splice(index, 1)
-    // },
-    deleteRow(index, rows) {
-      console.log(index, rows, "删除的行");
-      const deletedItem = rows[index]; // 获取要删除的项
-      rows.splice(index, 1); // 从显示的列表中删除
-      const formIndex = this.form.ticketUserDTOList.findIndex(
-        (item) => item.userId === deletedItem.userId
-      );
-      if (formIndex !== -1) {
-        this.form.ticketUserDTOList.splice(formIndex, 1); // 从 form.ticketUserDTOList 中删除
-      }
+      console.log(selectedOption, 'handleWorkshopSelected')
+      // this.emitWorkShop = selectedOption
+      // this.form.workshopName = selectedOption.label;//这里是回显车间的 暂时不需要
+      this.form.workline = selectedOption.label//这里是回显工作区域的
+      this.emitworklineId = selectedOption.id
+      this.worklineMap = selectedOption.map
     },
     //   时间选项
     ticketStartTimeChange(value) {
@@ -1187,6 +1119,131 @@ export default {
     goBack() {
       this.$router.push("/job/jobm");
     },
+    // 添加内部人员
+    addInside() {
+      this.open = true
+      this.title = '添加内部人员'
+      this.insideMumber = true
+      this.outsideMumber = false
+      // this.form.ticketUserDTOList = [];
+
+      this.dialogForm.nickName = ''
+    },
+    addOutside() {
+      this.open = true
+      this.title = '添加外部人员'
+      this.insideMumber = false
+      this.outsideMumber = true
+      this.dialogForm.username = null
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false
+    },
+    // 人员列表删除
+    deleteRow(index, rows) {
+      console.log(index, rows, '删除的行')
+      const deletedItem = rows[index] // 获取要删除的项
+      rows.splice(index, 1) // 从显示的列表中删除
+      const formIndex = this.form.ticketUserDTOList.findIndex(
+        (item) => item.userId === deletedItem.userId
+      )
+      if (formIndex !== -1) {
+        this.form.ticketUserDTOList.splice(formIndex, 1) // 从 form.ticketUserDTOList 中删除
+      }
+    },
+    // 上锁人下拉选择change事件
+    handlelockerChage(val) {
+      console.log(val, '上锁人chage')
+      const user = this.listLockerOption.find((item) => item.value === val)
+
+      if (user && this.form.locker !== '') {
+        const existingUser = this.form.ticketUserDTOList.find(
+          (u) => u.userName === user.label
+        )
+        if (!existingUser) {
+          this.newticketUserDTOList.push({
+            userName: user.label,
+            userId: user.value,
+            userType: 0,
+            userRole: '0'
+          })
+
+          console.log(this.newticketUserDTOList, '用户')
+        } else {
+          // console.log('用户已存在', user.label)
+        }
+      }
+    },
+
+    // 添加内部人员的用户新增到ticketUserDTOList这个数据里
+    changeInsideUser(values) {
+      const usersinside = values
+        .map((value) =>
+          this.listCoLockerOption.find((item) => item.value === value)
+        )
+        .filter(Boolean)
+
+      usersinside.forEach((user) => {
+        const existingUser = this.form.ticketUserDTOList.find(
+          (u) => u.userName === user.label
+        )
+        // console.log(usersinside, 'usersinside----67')
+        if (!existingUser) {
+          this.form.ticketUserDTOList.push({
+            userName: user.label,
+            userId: user.value,
+            userType: 1,
+            userRole: 0
+
+          })
+          console.log(this.form.ticketUserDTOList, '用户')
+        } else {
+          // console.log('用户已存在', user.label)
+        }
+      })
+      this.updateCoLocker()
+
+      // console.log(this.form.ticketUserDTOList, '用户')
+    },
+    // 添加外部人员 输入名称 userType==1是共锁人 0是上锁人 userId==0
+    outSideUserInput(event) {
+      this.dialogForm.username = event
+    },
+    // 添加外部人员弹窗 添加给表格数据的按钮事件
+    insertOutSideTable() {
+      this.OutSideUserTableData.push({
+        userName: this.dialogForm.username,
+        userId: this.nextUserId++
+      })
+      this.dialogForm.username = ''
+      console.log(this.OutSideUserTableData, 'OutSideUserTableData')
+    },
+    // 添加外部人员 确认弹窗
+    outSideDialogConfirm() {
+      this.updateCoLocker()
+      this.open = false
+    },
+    // 更新界面中共锁人下拉框显示的内容
+    updateCoLocker() {
+      // 检查并补充 ticketUserDTOList 中缺少的用户
+      this.OutSideUserTableData.forEach((item) => {
+        const existingUser = this.form.ticketUserDTOList.find(
+          (u) => u.userName === item.userName
+        )
+        if (!existingUser) {
+          this.form.ticketUserDTOList.push({
+            userName: item.userName,
+            userId: 0,
+            userType: 1,
+            userRole: 1
+
+          })
+        }
+      })
+
+      console.log(this.form.ticketUserDTOList, '最终的 ticketUserDTOList')
+    },
     //自动生成编码
     handleAutoGenChange(autoGenFlag) {
       if (autoGenFlag) {
@@ -1196,8 +1253,27 @@ export default {
       } else {
         this.form.ticketCode = null;
       }
+
     },
-  },
+    //是否开启人员配置界面
+    handleOpenStaffing(openStaffing) {
+      // 定义一个函数来封装接口调用逻辑
+      const fetchUserData = (roleKey) => {
+        const data = {
+          pageNum: 1,
+          pageSize: 10000,
+          roleKey: roleKey
+        }
+        return SopUser(data).then((res) => {
+          // console.log(res, `上锁人 - ${roleKey}`);
+          return res // 返回结果以便后续处理
+        }).catch((err) => {
+          // console.error(err, `请求失败 - ${roleKey}`);
+          throw err // 抛出错误以便捕获
+        })
+      }
+    },
+  }
 };
 </script>
 

+ 114 - 68
src/views/mes/sop/sopm/NewSop.vue

@@ -533,7 +533,6 @@ export default {
       // 弹出层标题
       title: '',
       dialogForm: {
-
         nickName: '',
         username: ''
       },
@@ -602,8 +601,9 @@ export default {
         selectIsSopById(sopId).then((response) => {
           console.log(response, '详细内容')
           this.form = response.data
-          console.log(response.data.ticketUserDTOList,'response.data.ticketUserDTOList')
-          if (response.data.ticketUserDTOList.length > 0) {
+          this.sopProps = [response.data]
+          console.log(this.sopProps ,'编辑拿到的sopProps数据')
+          if (response.data.ticketUserDTOList) {
             this.openStaffing = true;
           }
 
@@ -615,7 +615,6 @@ export default {
           this.form.ticketUserDTOList=response.data.ticketUserDTOList.filter((item)=>{return item.userType=='1'}) ;//过滤上锁人
           this.tableData = response.data.pointDetailVOList
           console.log(this.tableData, '编辑拿到的隔离点数据')
-          this.sopProps = [response.data]
 
           this.title = '修改隔离点信息'
         })
@@ -650,28 +649,6 @@ export default {
         this.form.spoint = this.tableData.map((point) => point.pointId)
       }
 
-      const selectedpointIds = this.form.spoint.join(',')
-      const UserList=[...this.form.ticketUserDTOList,...this.newticketUserDTOList]
-      const pointsList=this.form.pointDetailVOList.map((item)=>{
-        return {
-          pointId:item.pointId,
-          prePointId:item.prePointId
-        }
-      })
-      console.log(this.form.pointsList)
-      const data = {
-        pointIds: selectedpointIds,
-        sopContent: this.form.sopContent,
-        sopCode: this.form.sopCode,
-        sopName: this.form.sopName,
-        sopType: this.form.sopType,
-        workareaId: this.emitworklineId,
-        ticketUserDTOList: UserList,
-        pointsList: pointsList
-        // workshopId: this.emitWorkShop.value
-      }
-      console.log(data, '新增sop参数')
-
       // 编辑模式
       if (this.$route.query.sopId !== 'null') {
         console.log(this.$route.query.sopId, 'sopIdaaa')
@@ -681,9 +658,35 @@ export default {
           this.$message.error('隔离点id不可为空!') // 使用消息提示
           return
         }
+        const selectedpointIds = this.form.spoint.join(',')
+        const UserList=[...(this.form.ticketUserDTOList|| []),...(this.newticketUserDTOList|| [])]
+        // const pointsList=this.form.pointDetailVOList.map((item)=>{
+        //   return {
+        //     pointId:item.pointId,
+        //     prePointId:item.prePointId
+        //   }
+        // })
+        const pointsList=this.tableData.map((item)=>{
+          return {
+            pointId:item.pointId,
+            prePointId:item.prePointId
+          }
+        })
+        const data = {
+          sopId:this.form.sopId,
+          pointIds: selectedpointIds,
+          sopContent: this.form.sopContent,
+          sopCode: this.form.sopCode,
+          sopName: this.form.sopName,
+          sopType: this.form.sopType,
+          workareaId: this.emitworklineId,
+          ticketUserDTOList: UserList,
+          pointsList: pointsList
+          // workshopId: this.emitWorkShop.value
+        }
+
 
-        data.sopId = this.form.sopId
-console.log(data,'编辑的参数')
+        console.log(data,'编辑的参数')
         updateIsSop(data).then((res) => {
           console.log(res, '修改接口')
           if (res.code == 200) {
@@ -693,6 +696,24 @@ console.log(data,'编辑的参数')
         })
       } else {
         // 新增模式
+        const selectedpointIds = this.form.spoint.join(',')
+        const UserList=[...this.form.ticketUserDTOList,...this.newticketUserDTOList]
+        const pointsList=this.tableData.map((item)=>{
+          return {
+            pointId:item.pointId,
+            prePointId:item.prePointId
+          }
+        })
+        const data = {
+          pointIds: selectedpointIds,
+          sopContent: this.form.sopContent,
+          sopCode: this.form.sopCode,
+          sopName: this.form.sopName,
+          sopType: this.form.sopType,
+          workareaId: this.emitworklineId,
+          ticketUserDTOList: UserList,
+          pointsList: pointsList
+        }
         console.log(data, '新增参数')
         addinsertIsSop(data).then((res) => {
           console.log(res, '新增接口')
@@ -771,26 +792,35 @@ console.log(data,'编辑的参数')
 
     // 子组件选中的隔离点逆传递拿到的数据
     handleSelectPoint(points) {
-      // console.log(points, '父组件接收逆向传递选中的隔离点')
-      this.tableData = points //子组件传递过来的选中节点
+      console.log(points, "父组件接收逆向传递选中的隔离点");
+
+      // 1. 去除重复的点,使用 Set 确保每个 pointId 唯一
+      const uniquePoints = Array.from(
+        new Set(points.map((point) => point.pointId))
+      ).map((id) => points.find((point) => point.pointId === id));
+
+      console.log(uniquePoints, "去重后的选中节点");
+
+      this.tableData = uniquePoints; // 子组件传递过来的选中节点(去重后)
+
       // 使用 Set 来存储传递过来的点值
-      const newValues = new Set(points.map((point) => point.pointId))
+      const newValues = new Set(uniquePoints.map((point) => point.pointId));
 
-      // 1. 删除取消选中的点
+      // 2. 删除取消选中的点
       const removedPoints = this.tableData
         .filter((item) => !newValues.has(item.pointId))
-        .map((item) => item.pointId) // 记录被删除的点
+        .map((item) => item.pointId); // 记录被删除的点
 
       this.tableData = this.tableData.filter((item) =>
         newValues.has(item.pointId)
-      )
-      // console.log(this.tableData,'handleSelectPoint函数里的tableData')
-      // 2. 确保新增点不会重复
+      );
+
+      // 3. 确保新增点不会重复
       const existingValues = new Set(
         this.tableData.map((item) => item.pointId)
-      )
+      );
 
-      points.forEach((point) => {
+      uniquePoints.forEach((point) => {
         // 如果当前传递的点不在已有的点集中,则添加
         if (!existingValues.has(point.pointId)) {
           this.tableData.push({
@@ -798,46 +828,45 @@ console.log(data,'编辑的参数')
             pointId: point.pointId, // 对应的值
             pointType: point.pointType,
             powerType: point.powerType,
-            prePointId: null
-          })
-          // console.log(this.tableData,'handleSelectPoint函数里的tableData2')
+            prePointId: null,
+          });
+
           this.prePointIdOptions.push({
             pointName: point.pointName, // 显示的名称
-            pointId: point.pointId // 对应的值
-          })
-          this.initprePointIdOptions = [...this.prePointIdOptions]
-          console.log(this.prePointIdOptions, '前置节点设置下拉')
-          existingValues.add(point.pointId)
+            pointId: point.pointId, // 对应的值
+          });
+          this.initprePointIdOptions = [...this.prePointIdOptions];
+          console.log(this.prePointIdOptions, "前置节点设置下拉");
+          existingValues.add(point.pointId);
         }
-      })
+      });
 
-      // 3. 处理被删除的点,如果这些点作为父节点绑定,则将对应的 prePointId 设置为 null
+      // 4. 处理被删除的点,如果这些点作为父节点绑定,则将对应的 prePointId 设置为 null
       this.tableData.forEach((item) => {
         if (removedPoints.includes(item.prePointId)) {
-          item.prePointId = null
+          item.prePointId = null;
         }
-      })
-      // console.log(this.tableData,'handleSelectPoint函数里的tableData3')
-      // 4. 从下拉选项中移除被删除的点
+      });
+
+      // 5. 从下拉选项中移除被删除的点
       this.prePointIdOptions = this.prePointIdOptions.filter(
         (option) => !removedPoints.includes(option.pointId)
-      )
-      this.initprePointIdOptions = [...this.prePointIdOptions]
+      );
+      this.initprePointIdOptions = [...this.prePointIdOptions];
 
-      // 5. 确保下拉选项中仍然保留所有未被删除的点
-      const allPoints = points.map((point) => ({
+      // 6. 确保下拉选项中仍然保留所有未被删除的点
+      const allPoints = uniquePoints.map((point) => ({
         pointName: point.pointName,
-        pointId: point.pointId
-      }))
+        pointId: point.pointId,
+      }));
 
       this.prePointIdOptions = allPoints.filter(
         (option) => !removedPoints.includes(option.pointId)
-      )
-      this.initprePointIdOptions = [...this.prePointIdOptions]
+      );
+      this.initprePointIdOptions = [...this.prePointIdOptions];
 
       // 更新 form.spoint 为最新选中的隔离点数组
-      this.form.spoint = points.map((point) => point.pointId)
-
+      this.form.spoint = uniquePoints.map((point) => point.pointId);
     },
 
     // 车间逆向传递拿到的隔离点数据产线
@@ -867,6 +896,7 @@ console.log(data,'编辑的参数')
 
       this.dialogForm.nickName = ''
     },
+    // 添加外部人员
     addOutside() {
       this.open = true
       this.title = '添加外部人员'
@@ -907,7 +937,7 @@ console.log(data,'编辑的参数')
             userRole: '0'
           })
 
-          console.log(this.newticketUserDTOList, '用户')
+          console.log(this.newticketUserDTOList, '上锁人用户')
         } else {
           // console.log('用户已存在', user.label)
         }
@@ -935,7 +965,7 @@ console.log(data,'编辑的参数')
             userRole: 0
 
           })
-          console.log(this.form.ticketUserDTOList, '用户')
+          console.log(this.form.ticketUserDTOList, '共锁人用户')
         } else {
           // console.log('用户已存在', user.label)
         }
@@ -950,12 +980,28 @@ console.log(data,'编辑的参数')
     },
     // 添加外部人员弹窗 添加给表格数据的按钮事件
     insertOutSideTable() {
+      const newUserName = this.dialogForm.username.trim();
+      if (newUserName === '') {
+        this.$message.warning('请输入用户名');
+        return;
+      }
+      // 检查新用户是否已存在于表格中
+      const existingUser = this.OutSideUserTableData.find(user => user.userName === newUserName);
+      if (existingUser) {
+        this.$message.warning('该用户已存在');
+        return;
+      }
+      // 添加新用户
       this.OutSideUserTableData.push({
-        userName: this.dialogForm.username,
+        userName: newUserName,
         userId: this.nextUserId++
-      })
-      this.dialogForm.username = ''
-      console.log(this.OutSideUserTableData, 'OutSideUserTableData')
+      });
+
+      // 清空对话框表单
+      this.dialogForm.username = '';
+
+      // 打印当前的外部人员表格数据
+      console.log(this.OutSideUserTableData, 'OutSideUserTableData');
     },
     // 添加外部人员 确认弹窗
     outSideDialogConfirm() {

+ 15 - 10
src/views/mes/sop/sopm/sopmLook.vue

@@ -28,7 +28,7 @@
         <b class="title">作业区域</b>
         <div class="head-container">
           <el-input
-            v-model="form.workline"
+            v-model="workareaName"
             placeholder="请输入作业区域"
             clearable
             size="small"
@@ -56,18 +56,21 @@
       <div class="right_top">
         <el-card class="box-card">
           <div slot="header" class="clearfix">
-            <span style="font-size: 18px">{{ this.getSopTitle }}</span>
-            <span
-              style="
+
+              <span style="font-size: 18px">{{ this.getSopTitle }}</span>
+              <span
+                style="
                 float: right;
                 padding: 1px 15px;
                 font-size: 22px;
                 cursor: pointer;
               "
-              type="text"
-              @click="goBack"
+                type="text"
+                @click="goBack"
               >×</span
-            >
+              >
+
+
             <el-tooltip
               content="开启人员配置"
               placement="top"
@@ -672,7 +675,7 @@ export default {
         this.$route.query.sopId === "null" ||
         this.$route.query.ticketId === "null"
       ) {
-        this.setMapData(data.map);
+        // this.setMapData(data.map);
         console.log("设置了地图数据");
       }
       // 传递车间地图
@@ -689,7 +692,7 @@ export default {
         selectIsSopById(sopId).then((response) => {
           console.log(response, "详细内容");
           this.form = response.data;
-          this.workareaName = response.data.workline;
+          this.workareaName = response.data.workareaId;
 
           console.log(
             response.data,
@@ -703,7 +706,8 @@ export default {
           const value = response.data.ticketUserDTOList //找到上锁人  这里一定要先筛选locker再去给表格筛选 否则表格筛选之后直接不会有上锁人数据了
             .filter((item) => item.userType == "0")
             .map((item) => item.userName);
-          (this.form.locker = value[0]), //map返回的是数字 所以这样写
+          console.log(value,'上锁人')
+          this.form.locker = value[0], //map返回的是数字 所以这样写
             console.log(value, response.data.ticketUserDTOList, "form.locker");
           this.form.ticketUserDTOList = response.data.ticketUserDTOList.filter(
             (item) => {
@@ -1340,6 +1344,7 @@ export default {
   display: table;
   content: "";
   width: 320px;
+
 }
 
 .clearfix:after {