Просмотр исходного кода

Merge branch 'dev' of http://110.41.163.243:9980/kd-aiot/kd-aiot-frontend-mes into dengfei

695593266@qq.com 11 месяцев назад
Родитель
Сommit
55baf11b29

+ 77 - 0
src/utils/date.js

@@ -0,0 +1,77 @@
+// 开始时间禁用范围(日期)
+// data 是表单数据 time 是当前时间 endTime 结束时间
+function startDisabledDate(data, endTime, time) {
+  const end = data[endTime];
+  if (!end) return false; // 无结束时间,不禁用
+  // 将结束时间和当前时间都转换为“当天0点”,仅比较年月日
+  const endDay = new Date(end);
+  endDay.setHours(0, 0, 0, 0);
+  const currentDay = new Date(time);
+  currentDay.setHours(0, 0, 0, 0);
+  return currentDay > endDay; // 仅当天0点更晚时禁用
+}
+
+// 结束时间禁用范围(日期)
+// data 是表单数据 time 是当前时间 startTime 开始时间
+function endDisabledDate(data, startTime, time) {
+  const start = data[startTime];
+  if (!start) return false; // 无开始时间,不禁用
+  // 将开始时间和当前时间都转换为“当天0点”,仅比较年月日
+  const startDay = new Date(start);
+  startDay.setHours(0, 0, 0, 0);
+  const currentDay = new Date(time);
+  currentDay.setHours(0, 0, 0, 0);
+  return currentDay < startDay; // 仅当天0点更早时禁用
+}
+
+// 新增:限制同一天内的时间必须晚于开始时间
+function endDisabledTime(data, startTime, date) {
+  const start = data[startTime];
+  if (!start) {
+    return {
+      disabledHours: () => [],
+      disabledMinutes: () => [],
+      disabledSeconds: () => []
+    };
+  }
+  const startDate = new Date(start);
+  const currentDate = new Date(date);
+
+  // 判断是否是同一天
+  if (
+    currentDate.getFullYear() === startDate.getFullYear() &&
+    currentDate.getMonth() === startDate.getMonth() &&
+    currentDate.getDate() === startDate.getDate()
+  ) {
+    const startHour = startDate.getHours();
+    const startMinute = startDate.getMinutes();
+    const startSecond = startDate.getSeconds();
+    return {
+      // 禁用比 startHour 早的小时
+      disabledHours: () => Array.from({ length: startHour }, (_, i) => i),
+      // 若小时相同,禁用比 startMinute 早的分钟
+      disabledMinutes: (hour) =>
+        hour === startHour
+          ? Array.from({ length: startMinute }, (_, i) => i)
+          : [],
+      // 若小时和分钟都相同,禁用比 startSecond 早的秒
+      disabledSeconds: (hour, minute) =>
+        hour === startHour && minute === startMinute
+          ? Array.from({ length: startSecond }, (_, i) => i)
+          : []
+    };
+  } else {
+    // 不同天,时间无限制
+    return {
+      disabledHours: () => [],
+      disabledMinutes: () => [],
+      disabledSeconds: () => []
+    };
+  }
+}
+
+export default {
+  startDisabledDate,
+  endDisabledDate,
+  endDisabledTime
+}

+ 241 - 27
src/views/produceOrder/components/releaseDialog/index.vue

@@ -243,6 +243,13 @@
                 >
                   该工序已完成派单!
                 </div>
+
+                <div
+                  style="margin-left: 50px; display: inline-block"
+                  v-if="timeSlot(item)"
+                >
+                  时间段: {{ item.startDate }} ----- {{ item.endDate }}
+                </div>
               </template>
               <template v-slot:quantity="{ row }">
                 <el-input
@@ -267,7 +274,7 @@
                   v-model="row.teamTimeDetailId"
                   placeholder="班次"
                   :disabled="permissions(row, item)"
-                  @change="(e) => shiftSelection(e, row)"
+                  @change="(e) => shiftSelection(e, row, item)"
                 >
                   <el-option
                     v-for="item in shiftList"
@@ -283,12 +290,11 @@
                   v-model="row.startTime"
                   :disabled="permissions(row, item)"
                   :picker-options="{
-                    disabledDate: (time) => {
-                      return (
-                        row.endTime && time.getTime() > new Date(row.endTime)
-                      );
+                    disabledDate: function (time) {
+                      return validDate.startDisabledDate(row, 'endTime', time);
                     }
                   }"
+                  @change="handleStartTimeChange(row, item)"
                   class="w100"
                   placeholder="开始时间"
                   type="datetime"
@@ -300,12 +306,10 @@
                   v-model="row.endTime"
                   :disabled="permissions(row, item)"
                   :picker-options="{
-                    disabledDate: (time) => {
-                      return (
-                        row.startTime &&
-                        time.getTime() < new Date(row.startTime)
-                      );
-                    }
+                    disabledDate: (time) =>
+                      validDate.endDisabledDate(row, 'startTime', time),
+                    disabledTime: (date) =>
+                      validDate.endDisabledTime(row, 'startTime', date)
                   }"
                   class="w100"
                   placeholder="完成时间"
@@ -343,6 +347,7 @@
 </template>
 
 <script>
+  import validDate from '@/utils/date';
   import {
     lineByCurrentUser,
     listAssign,
@@ -412,7 +417,10 @@
         ],
         shiftList: [],
         dateValue: '',
-        dispatchType:1
+        factoriesId: '', // 工厂id
+        dispatchType: 1,
+        time_calc_code: '0', // 是否进行时间赋值 0 否 1 是
+        validDate
       };
     },
     computed: {
@@ -452,6 +460,15 @@
           if (row.status.code == 1) return true;
         };
       },
+      // 时间段显示
+      timeSlot() {
+        return (item) => {
+          if (!item.startDate || !item.endDate) {
+            return false;
+          }
+          return true;
+        };
+      },
       columns() {
         return [
           {
@@ -544,30 +561,30 @@
     },
     watch: {},
     created() {
-      this.dispatchType = this.current.singleReport;
-      console.log(this.current,'1111111')
+      this.dispatchType = this.current.singleReport || 0;
       this.workCenterData();
-      this.getClassesData();
       this.form.singleReport = this.clientEnvironmentId == 2 ? 0 : 1;
       this.dateValue = this.getFormattedDate();
     },
     methods: {
+      getCode() {
+        parameterGetByCode({
+          code: 'time_calculation_rules'
+        }).then((res) => {
+          if (res) {
+            this.time_calc_code = res.value || '0';
+          }
+        });
+      },
       // 查询班次
       getClassesData() {
-        if (!this.current.factoriesId) return;
-        listByFactoryId(this.current.factoriesId).then((res) => {
+        if (!this.factoriesId) return;
+        listByFactoryId(this.factoriesId).then((res) => {
+          console.log(res, 'res ++++');
           if (!res) return;
           this.shiftList = res;
         });
       },
-      // 选中班次
-      shiftSelection(e, row) {
-        let data = this.shiftList.find((item) => item.id == e);
-        let startTime = `${this.dateValue} ${data.startTime}`;
-        let endTime = `${this.dateValue} ${data.endTime}`;
-        this.$set(row, 'startTime', startTime);
-        this.$set(row, 'endTime', endTime);
-      },
       // 获取当前年月日
       getFormattedDate() {
         const now = new Date();
@@ -581,12 +598,16 @@
         const res = await listWorkCenter(this.current.taskInstanceId);
         this.workCenterList = res;
         if (res.length > 0) {
+          console.log(res, '工作中心');
           this.form.factoryName = res[0].factoryName;
           this.form.workCenterId = res[0].id;
+          this.factoriesId = res[0].factoryId;
+          console.log(res, 'res 工作中心数据');
           // 查首工序
           this.changeWork(res[0].id); // 选择工作中心
           this.getProductionData(res[0].id); // 查询产线
           this.FirstTaskIdFn(); // 查询工位数据
+          this.getClassesData();
         }
       },
       // 查询工序列表数据
@@ -656,7 +677,9 @@
             list.push(obj);
           });
           this.processList = list;
-          this.handleClick({ name: res[0].sourceTaskId });
+          this.processId = res[0].sourceTaskId;
+          // this.handleClick({ name: res[0].sourceTaskId });
+          this.initializeQuery();
         } catch (err) {
           this.processList = [];
           this.$message.error(err.message);
@@ -664,6 +687,44 @@
           this.tabsLoading = false;
         }
       },
+
+      // 初始化查询 查询全部工序操作过的数据
+      async initializeQuery() {
+        try {
+          // 不存在 班组数据的话 就不调用这个方法
+          if (!this.form.teamId) {
+            return;
+          }
+          let params = {
+            workOrderId: this.current.id,
+            workCenterId: this.form.workCenterId,
+            teamId: this.form.teamId
+          };
+          let processMap = {};
+          this.processList.map((el, index) => (processMap[el.id] = index));
+          const res = await listAssign(params);
+          let isFirstData = false; // 判断默认第一道工序是否操作过
+          if (res && res.length > 0) {
+            res.map((el) => {
+              let index = processMap[el.taskId];
+              if (index === 0 && el.assignees && el.assignees.length > 0) {
+                isFirstData = true; // 操作过
+              }
+              // 这里第三个参数传空数组就好了 会自动计算的
+              setTimeout(() => {
+                this.operationalData(index, [el], []);
+              });
+            });
+            // 没有操作过 默认获取一下表格数据
+            if (!isFirstData) {
+              this.handleClick({ name: this.processId });
+            }
+          } else {
+            this.handleClick({ name: this.processId });
+          }
+        } catch (err) {}
+      },
+
       // 选择工作中心
       async changeWork(e) {
         this.form.workCenterId = e;
@@ -810,7 +871,7 @@
         } else {
           data = {
             dispatchMethod: 0,
-            dispatchType:this.dispatchType,
+            dispatchType: this.dispatchType,
             taskId: this.processId,
             taskName: row.name,
             taskCode: row.code,
@@ -1094,6 +1155,155 @@
         // 更新绑定值
         row.weight = value;
         this.calculateWeight(row, item);
+      },
+      // 选中班次
+      shiftSelection(e, row, item) {
+        let data = this.shiftList.find((item) => item.id == e);
+        let startTime = `${this.dateValue} ${data.startTime}`;
+        let endTime = `${this.dateValue} ${data.endTime}`;
+        this.$set(row, 'startTime', startTime);
+        this.$set(row, 'endTime', endTime);
+        this.handleStartTimeChange(row, item);
+        this.handleEndTimeChange(row, item);
+      },
+      // 【开始时间变化时】触发
+      handleStartTimeChange(row, item) {
+        if (!row.startTime) {
+          return;
+        }
+        // 这一道工序的开始时间 不能小于前一道工序的结束时间
+        const startTime = new Date(row.startTime); // 开始时间
+        if (item.index !== 0) {
+          // let frontIdx = item.index - 1;
+          let frontIdx = this.calculateIndex(item.index).startIdx;
+          if (frontIdx !== 'none') {
+            let frontName = this.processList[frontIdx].name;
+            let time = this.processList[frontIdx].endDate;
+            const frontTime = new Date(time); // 前面工序的结束时间
+            if (time && startTime < frontTime) {
+              this.$message.closeAll();
+              this.$message.info(
+                `开始时间不能小于前面工序${frontName}的结束时间${time}`
+              );
+              // 判断是否 配置时间更改规则
+              if (this.time_calc_code == '1') {
+                row.startTime = time;
+              }
+              return;
+            }
+          }
+        }
+        // 这一道工序的开始时间更不能大于后一道工序的开始时间
+        if (item.index !== this.processList.length - 1) {
+          // let latterIdx = item.index + 1;
+          let latterIdx = this.calculateIndex(item.index).endIdx;
+          if (latterIdx !== 'none') {
+            let time = this.processList[latterIdx].startDate;
+            let latterName = this.processList[latterIdx].name;
+            const latterTime = new Date(time); // 下一道工序的结束时间
+            if (time && startTime > latterTime) {
+              this.$message.closeAll();
+              this.$message.info(
+                `开始时间不能大于后面工序${latterName}的开始时间${time}`
+              );
+              // 判断是否 配置时间更改规则
+              if (this.time_calc_code == '1') {
+                row.startTime = '';
+              }
+              return;
+            }
+          }
+        }
+        // 校验 是否 大于结束时间  wda
+        this.checkEndTimeValid(row);
+      },
+      // 当更改一个工序开始时间 结束时间的时候
+      // 开始时间 不能小于之前工序的结束时间 ( 要先去上一道工序找 是否存在结束时间 不存在就再往前找 直到 第一道工序 )
+      // 结束时间 不能大于后面工序的开始时间 ( 要先去后一道工序找 是否存在开始时间 不存在就再往后找 直到 最后一道工序 )
+      // 计算出当前下标数据 的前后 有 开始时间 结束时间的数据下标
+      calculateIndex(index) {
+        let startIdx = 'none';
+        let endIdx = 'none';
+        // 前面工序下标
+        for (let i = index - 1; i >= 0; i--) {
+          let row = this.processList[i];
+          if (row && row.endDate) {
+            startIdx = i;
+            break;
+          }
+        }
+        // 后面工序的下标
+        for (let i = index + 1; i <= this.processList.length; i++) {
+          let row = this.processList[i];
+          if (row && row.startDate) {
+            endIdx = i;
+            break;
+          }
+        }
+        return {
+          startIdx,
+          endIdx
+        };
+      },
+      // 【结束时间变化时】触发
+      handleEndTimeChange(row, item) {
+        if (!row.endTime) {
+          return;
+        }
+        const endTime = new Date(row.endTime); // 结束时间
+        // 当前工序的结束时间 不能大于后一道工序的开始时间
+        if (item.index !== this.processList.length - 1) {
+          let latterIdx = this.calculateIndex(item.index).endIdx;
+          if (latterIdx !== 'none') {
+            let latterName = this.processList[latterIdx].name;
+            let time = this.processList[latterIdx].startDate;
+            const latterTime = new Date(time); // 后面工序的开始时间
+            if (time && endTime > latterTime) {
+              this.$message.closeAll();
+              this.$message.info(
+                `结束时间不能大于后面工序${latterName}的开始时间${time}`
+              );
+              // 判断是否 配置时间更改规则
+              if (this.time_calc_code == '1') {
+                row.endTime = time;
+              }
+              return;
+            }
+          }
+        }
+        // 这一道工序的开始时间更不能小于于前一道工序的结束时间
+        if (item.index !== 0) {
+          // let frontIdx = item.index - 1;
+          let frontIdx = this.calculateIndex(item.index).startIdx;
+          if (frontIdx !== 'none') {
+            let frontName = this.processList[frontIdx].name;
+            let time = this.processList[frontIdx].endDate;
+            const frontTime = new Date(time); // 上一道工序的结束时间
+            if (time && endTime < frontTime) {
+              this.$message.closeAll();
+              this.$message.info(
+                `结束时间不能小于前面工序${frontName}的结束时间${time}`
+              );
+              // 判断是否 配置时间更改规则
+              if (this.time_calc_code == '1') {
+                row.endTime = '';
+              }
+              return;
+            }
+          }
+        }
+        this.checkEndTimeValid(row, item);
+      },
+      // 时间校验
+      checkEndTimeValid(row) {
+        const { startTime: start, endTime: end } = row;
+        // if (!start || !end) return; // 开始/结束时间未填,跳过
+        const startTime = new Date(start); // 开始时间
+        const endTime = new Date(end); // 结束时间
+        if (endTime < startTime) {
+          row.endTime = new Date(startTime); // 修正为开始时间
+          this.$message.info('结束时间不能早于开始时间,已自动设为开始时间');
+        }
       }
     }
   };
@@ -1158,4 +1368,8 @@
   //     width: 100%;
   //   }
   // }
+
+  .describe {
+    display: inline-block;
+  }
 </style>

+ 1 - 1
src/views/produceOrder/index.vue

@@ -159,7 +159,7 @@
               :underline="false"
               @click="toReleaseOpen(row)"
             >
-              派单
+              任务派单
             </el-link>
           </template>
         </template>