695593266@qq.com 2 дней назад
Родитель
Сommit
ca2ef0b2b1

+ 50 - 17
src/views/home/index.vue

@@ -467,28 +467,61 @@
     min-width: 0;
 
     i {
+      position: relative;
       flex: 0 0 auto;
-      width: 40px;
-      height: 40px;
+      width: 46px;
+      height: 46px;
       margin-right: 14px;
+      overflow: hidden;
       border: 1px solid rgba(82, 217, 230, 0.72);
-      border-radius: 50%;
-      background: linear-gradient(
+      border-radius: 8px;
+      background:
+        url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2048%2048'%20fill='none'%3E%3Cpath%20d='M9%2023L24%2010L39%2023'%20stroke='%2352d9e6'%20stroke-width='3.2'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3Cpath%20d='M14.5%2021.5V37H33.5V21.5'%20stroke='%2352d9e6'%20stroke-width='2.4'%20stroke-linejoin='round'/%3E%3Cpath%20d='M30%2014V10H35V18'%20stroke='%23ecb257'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3Crect%20x='18.5'%20y='25.5'%20width='11'%20height='7.5'%20rx='1.3'%20stroke='%23c9fbff'%20stroke-width='1.4'%20opacity='.92'/%3E%3Cpath%20d='M21%2031V28.8M24%2031V27.2M27%2031V29.5'%20stroke='%23ecb257'%20stroke-width='1.7'%20stroke-linecap='round'/%3E%3Cpath%20d='M13%2039H35'%20stroke='%2352d9e6'%20stroke-width='1.5'%20stroke-linecap='round'%20opacity='.65'/%3E%3C/svg%3E") center / 34px 34px no-repeat,
+        linear-gradient(135deg, rgba(82, 217, 230, 0.24), transparent 34%),
+        linear-gradient(315deg, rgba(236, 178, 87, 0.16), transparent 40%),
+        radial-gradient(circle at 50% 52%, rgba(82, 217, 230, 0.13), transparent 58%),
+        repeating-linear-gradient(
           90deg,
-          transparent 46%,
-          rgba(82, 217, 230, 0.9) 47%,
-          rgba(82, 217, 230, 0.9) 53%,
-          transparent 54%
-        ),
-        linear-gradient(
-          transparent 46%,
-          rgba(236, 178, 87, 0.9) 47%,
-          rgba(236, 178, 87, 0.9) 53%,
-          transparent 54%
+          rgba(82, 217, 230, 0.08) 0 1px,
+          transparent 1px 10px
         ),
-        #102224;
-      box-shadow: 0 0 16px rgba(82, 217, 230, 0.38),
-        inset 0 0 14px rgba(82, 217, 230, 0.18);
+        #0a2023;
+      box-shadow: 0 0 18px rgba(82, 217, 230, 0.32),
+        inset 0 0 0 1px rgba(255, 255, 255, 0.05),
+        inset 0 0 18px rgba(82, 217, 230, 0.16);
+
+      &::before {
+        position: absolute;
+        inset: 5px;
+        content: '';
+        pointer-events: none;
+        border: 1px solid rgba(82, 217, 230, 0.16);
+        border-radius: 5px;
+        background:
+          linear-gradient(90deg, #52d9e6 0 8px, transparent 8px) left top / 14px 1px no-repeat,
+          linear-gradient(#52d9e6 0 8px, transparent 8px) left top / 1px 14px no-repeat,
+          linear-gradient(270deg, #ecb257 0 8px, transparent 8px) right bottom / 14px 1px no-repeat,
+          linear-gradient(0deg, #ecb257 0 8px, transparent 8px) right bottom / 1px 14px no-repeat;
+        opacity: 0.72;
+      }
+
+      &::after {
+        position: absolute;
+        left: 10px;
+        right: 10px;
+        bottom: 6px;
+        height: 2px;
+        content: '';
+        pointer-events: none;
+        background: linear-gradient(
+          90deg,
+          transparent,
+          rgba(82, 217, 230, 0.82),
+          rgba(236, 178, 87, 0.72),
+          transparent
+        );
+        box-shadow: 0 0 10px rgba(82, 217, 230, 0.52);
+      }
     }
 
     strong {

+ 14 - 13
src/views/productionPlan/components/auxiliaryMaterial.vue

@@ -308,8 +308,9 @@
         </div>
       </div>
       <div slot="footer">
-        <el-button plain @click="cancel">取消</el-button>
-        <el-button type="primary" @click="confirm('齐套')">确定</el-button>
+        <el-button plain @click="cancel">返回</el-button>
+        <el-button type="primary" @click="confirm('齐套')">齐套</el-button>
+        <el-button type="primary" @click="confirm('不齐套')">不齐套</el-button>
       </div>
     </ele-modal>
 
@@ -333,13 +334,11 @@
     bomVersionList,
     listBomType,
     getProductKitting,
-    updatePreRelease,
     findFrockMaterialInfoByPlanId
   } from '@/api/productionPlan/index.js';
   import factoryAdd from './factoryAdd';
   import stockDetailDialog from './stockDetailDialog.vue';
   import currentDetailDialog from './currentDetailDialog.vue';
-  import producePlan from '@/views/materialPlan/components/producePlan.vue';
   import purchaseDialog from './purchaseDialog.vue';
   import { issueProductionPlan } from '@/api/productionPlan/index.js';
   import routeResourceData from './routeResourceData.vue';
@@ -347,7 +346,6 @@
     components: {
       stockDetailDialog,
       currentDetailDialog,
-      producePlan,
       purchaseDialog,
       factoryAdd,
       routeResourceData
@@ -1008,14 +1006,17 @@
         this.attributeChange(this.formInline.attributeType);
       },
       confirm(statusStr) {
-        this.preData.statusStr = statusStr;
-        this.updatePreRelease(this.preData);
-      },
-
-      updatePreRelease(item) {
-        updatePreRelease(item);
-        this.$emit('success', this.type);
-        this.visible = false;
+        const typeText = this.type == 2 ? '辅材' : '工装';
+        this.$confirm(`${typeText}是否确认设置为"${statusStr}"?`, '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        })
+          .then(() => {
+            this.$emit('success', this.type, statusStr);
+            this.visible = false;
+          })
+          .catch(() => {});
       }
       // async merge() {
       //   this.reload({ planIds: this.ids, productType: 1, merge: 2 });

+ 38 - 12
src/views/productionPlan/components/checkProductionPreparations.vue

@@ -14,14 +14,10 @@
     <ele-pro-table
       ref="table"
       :columns="columns"
-      :datasource="
-        type == 'plan'
-          ? preReleaseList.filter((item) => item.preType != 6)
-          : preReleaseList
-      "
+      :datasource="preReleaseTableData"
       :needPage="false"
       :selection.sync="selection"
-      row-key="id"
+      row-key="_preReleaseSelectionKey"
       @columns-change="handleColumnChange"
       :cacheKey="cacheKeyUrl"
       :page-size="20"
@@ -172,7 +168,7 @@
             {{ row.code }}
           </el-link>
         </template>
-        <template v-slot:action="{ row, $index }">
+        <template v-slot:action="{ row }">
           <!-- <el-link
             type="primary"
             @click="fileDetails(row, fileTitle == 'NC代码' ? 'nc' : '')"
@@ -197,7 +193,7 @@
           >
         </template>
 
-        <template v-slot:versions="{ row, $index }">
+        <template v-slot:versions="{ row }">
           <span v-if="row.versions">V{{ row.versions }}.0</span>
         </template>
         <template v-slot:statusStr="{ row }">
@@ -463,6 +459,12 @@
     },
 
     computed: {
+      preReleaseTableData() {
+        if (this.type == 'plan') {
+          return this.preReleaseList.filter((item) => item.preType != 6);
+        }
+        return this.preReleaseList;
+      },
       columns() {
         return [
           {
@@ -526,7 +528,8 @@
         if (apsWorkOrderId) {
           params.apsWorkOrderId = apsWorkOrderId;
         }
-        this.preReleaseList = await completenessCheck(params);
+        const list = await completenessCheck(params);
+        this.preReleaseList = this.normalizePreReleaseList(list);
       },
 
       // reload(where) {
@@ -563,10 +566,26 @@
         return item ? item.label : '';
       },
 
+      normalizePreReleaseList(list = []) {
+        return (Array.isArray(list) ? list : []).map((item, index) => ({
+          ...item,
+          _preReleaseSelectionKey: [
+            item.id,
+            item.preType,
+            item.apsWorkOrderId,
+            item.productionPlanId,
+            index
+          ]
+            .filter((value) => value || value === 0)
+            .join('_')
+        }));
+      },
+
       open(item) {
         this.visible = true;
         this.itemData = item;
         this.preReleaseList = [];
+        this.selection = [];
         // if (item.preRelease.length) {
         //   this.preReleaseList = item.preRelease;
         // } else {
@@ -848,10 +867,15 @@
         });
       },
 
-      updateStatus(type) {
+      updateStatus(type, statusStr = '齐套') {
         const index = this.preReleaseList.findIndex((it) => it.preType == type);
 
-        this.$set(this.preReleaseList[index], 'statusStr', '齐套');
+        if (index !== -1) {
+          const data = this.preReleaseList[index];
+          data.statusStr = statusStr;
+          this.$set(this.preReleaseList, index, data);
+          this.updatePreRelease(data);
+        }
       },
 
       async batchConfirm() {
@@ -885,7 +909,9 @@
           eventType: 1
         }));
 
-        await Promise.all(releaseParams.map((params) => taskReleaseWork(params)))
+        await Promise.all(
+          releaseParams.map((params) => taskReleaseWork(params))
+        )
           .then(() => {
             loading.close();
             this.$message.success('派单成功');

+ 28 - 5
src/views/productionPlan/components/disassemblePlanPop.vue

@@ -436,11 +436,7 @@
         ) {
           row = m.processRoute.list[0];
         }
-        let _num =
-          ((this.formData.requiredFormingNum || 0) / (this.baseCount || 0)) *
-          m.dosage;
-        // _num = _num.toFixed(3);
-        _num = this.formattedNum(_num);
+        let _num = this.getRequiredFormingNum(m);
         let data = {
           id: m.id,
           categoryId: m.categoryId,
@@ -479,6 +475,9 @@
       },
       // 格式化后的结果
       formattedNum(num) {
+        if (!Number.isFinite(num)) {
+          return '';
+        }
         // 检查是否为整数(小数部分为0)
         if (Number.isInteger(num)) {
           return num; // 整数直接返回
@@ -487,6 +486,23 @@
           return num.toFixed(3);
         }
       },
+      // 根据BOM用量计算计划数量,避免除以0生成Infinity
+      getRequiredFormingNum(row) {
+        const requiredFormingNum = Number(this.formData.requiredFormingNum);
+        const baseCount = Number(this.baseCount);
+        const dosage = Number(row.dosage);
+
+        if (
+          !Number.isFinite(requiredFormingNum) ||
+          !Number.isFinite(baseCount) ||
+          baseCount <= 0 ||
+          !Number.isFinite(dosage)
+        ) {
+          return '';
+        }
+
+        return this.formattedNum((requiredFormingNum / baseCount) * dosage);
+      },
       // 删除计划信息
       removeRow(row, index) {
         // 如果删除的是当前列表BOM信息的数据 就将它的勾选去掉
@@ -631,6 +647,13 @@
           return this.$message.warning('不能有生产数量为0的数据');
         }
 
+        const hasInvalidNum = this.jhList.some((item) => {
+          return !Number.isFinite(Number(item.requiredFormingNum));
+        });
+        if (hasInvalidNum) {
+          return this.$message.warning('请填写正确的生产数量');
+        }
+
         let param = {
           addPOList: this.jhList,
           produceType: this.formData.produceType,

+ 97 - 8
src/views/productionPlan/components/newFactoryProductionScheduling.vue

@@ -74,10 +74,10 @@
           </el-tabs>
         </div>
         <ele-pro-table
-          :key="planTableRenderKey"
           width="100%"
           ref="planTable"
           :columns="columns"
+          cacheKeyUrl="paln_factory_production_scheduling"
           :datasource="planDataList"
           row-key="id"
           :selection.sync="selection"
@@ -169,10 +169,12 @@
                 @submit="submitDotLineConfig"
                 @execution-type-change="onExecutionTypeChange"
                 @execution-object-change="onExecutionObjectChange"
+                @parallelism-change="handleParallelismChange"
                 @time-change="handleTimeChange"
                 @add-task-row="addTaskRow"
                 @remove-task-row="removeTaskRow"
                 @add-dispatch-stations="addDispatchStations"
+                @remove-dispatch-station="removeDispatchStation"
                 @dispatch-action-success="handleDispatchActionSuccess"
                 @row-submit="submitDotLineRow"
                 @approve="handleApproveCurrentPlan"
@@ -294,7 +296,6 @@
         planPickerSelectionSyncing: false,
         planTableSelectionSyncing: false,
         planTableStatusTab: 'published',
-        planTableRenderKey: 0,
         dialogRenderKey: 0,
         dotLineLoading: false,
         dotLineFullscreen: false,
@@ -695,7 +696,6 @@
                 (item) => this.getPlanRowKey(item) === currentPlanKey
               ) || null;
           }
-          this.planTableRenderKey += 1;
         } catch (e) {
           this.$message.error(e.message || '获取计划数据失败');
         } finally {
@@ -1082,6 +1082,7 @@
         return {
           ...item,
           _taskKey: item.id ?? `detail-${item.taskId ?? index}`,
+          isParallelism: toSafeNumber(item.isParallelism) === 1 ? 1 : 0,
           executionStartTime,
           executionEndTime,
           dispatchDefaultStartTime: executionStartTime,
@@ -1137,6 +1138,7 @@
           planCode: plan.code,
           routingId: plan.produceRoutingId,
           routingName: plan.produceRoutingName ?? plan.routingName,
+          isParallelism: 0,
           executionType: EXEC_TYPE.HOMEMADE,
           executionTeamId: '',
           executionObjectType: '',
@@ -1481,6 +1483,14 @@
           this.$set(row, changeKey, '');
           return;
         }
+        if (
+          changeKey === 'executionStartTime' &&
+          this.isExecutionStartBeforePlanStart(row.executionStartTime)
+        ) {
+          this.$message.warning('执行开始时间不能小于计划开始时间');
+          this.$set(row, changeKey, '');
+          return;
+        }
         if (!this.validateTaskSequence(row, { resetKey: changeKey })) {
           return;
         }
@@ -1520,6 +1530,19 @@
           }
         }
       },
+      handleParallelismChange(row) {
+        if (this.isCurrentPlanReadonly || !row?.executionStartTime) {
+          return;
+        }
+        if (this.isTaskParallel(row)) {
+          if (this.isExecutionStartBeforePlanStart(row.executionStartTime)) {
+            this.$message.warning('执行开始时间不能小于计划开始时间');
+            this.$set(row, 'executionStartTime', '');
+          }
+          return;
+        }
+        this.validateTaskSequence(row, { resetKey: 'executionStartTime' });
+      },
       isExecutionEndOverDelivery(row) {
         const deadline =
           this.currentPlan?.planDeliveryTime || this.currentPlan?.deliveryTime;
@@ -1692,6 +1715,33 @@
           startTime < endTime
         );
       },
+      getCurrentPlanStartTime() {
+        return (
+          this.currentPlan?.startTime ||
+          this.currentPlan?.planStartTime ||
+          this.currentPlan?.executionStartTime ||
+          ''
+        );
+      },
+      isExecutionStartBeforePlanStart(executionStartTime) {
+        if (this.isOrderScheduling || !executionStartTime) {
+          return false;
+        }
+        const planStartTime = this.getCurrentPlanStartTime();
+        if (!planStartTime) {
+          return false;
+        }
+        const executionStart = new Date(executionStartTime).getTime();
+        const planStart = new Date(planStartTime).getTime();
+        return (
+          !Number.isNaN(executionStart) &&
+          !Number.isNaN(planStart) &&
+          executionStart < planStart
+        );
+      },
+      isTaskParallel(row) {
+        return toSafeNumber(row?.isParallelism) === 1;
+      },
       validateTaskSequence(row, options = {}) {
         const sequence = this.getTaskSequenceContext(row);
         if (!sequence) {
@@ -1699,8 +1749,12 @@
         }
         const { index, prev, prevIndex, next, nextIndex } = sequence;
         const resetKey = options.resetKey;
-        const checkPrev = !resetKey || resetKey === 'executionStartTime';
-        const checkNext = !resetKey || resetKey === 'executionEndTime';
+        const checkPrev =
+          (!resetKey || resetKey === 'executionStartTime') &&
+          !this.isTaskParallel(row);
+        const checkNext =
+          (!resetKey || resetKey === 'executionEndTime') &&
+          !this.isTaskParallel(next);
 
         if (
           checkPrev &&
@@ -1800,6 +1854,12 @@
           );
           return false;
         }
+        if (this.isExecutionStartBeforePlanStart(item.executionStartTime)) {
+          this.$message.warning(
+            `${label(item)}执行开始时间不能小于计划开始时间`
+          );
+          return false;
+        }
 
         const deadline =
           this.currentPlan?.planDeliveryTime || this.currentPlan?.deliveryTime;
@@ -1858,6 +1918,37 @@
         });
         this.$set(this.workstationOptionsMap, key, nextList);
       },
+      removeDispatchStation({ task, row }) {
+        if (!this.isOrderScheduling || !task || !row) {
+          return;
+        }
+        const key = this.getTaskWorkstationKey(task);
+        if (!key) {
+          return;
+        }
+        const rowIds = new Set(
+          [row.id, row.rawId, row.workstationId, row.factoryWorkstationId]
+            .filter(
+              (item) => item !== null && item !== undefined && item !== ''
+            )
+            .map((item) => String(item))
+        );
+        const currentList = this.workstationOptionsMap[key] || [];
+        const nextList = currentList.filter((item) => {
+          const itemIds = [
+            item.id,
+            item.rawId,
+            item.workstationId,
+            item.factoryWorkstationId
+          ]
+            .filter(
+              (value) => value !== null && value !== undefined && value !== ''
+            )
+            .map((value) => String(value));
+          return !itemIds.some((id) => rowIds.has(id));
+        });
+        this.$set(this.workstationOptionsMap, key, nextList);
+      },
       async handleDispatchActionSuccess(event = {}) {
         if (!this.isOrderScheduling) {
           return;
@@ -1894,6 +1985,7 @@
             executionTeamLeaderId: row.executionTeamLeaderId || '',
             executionTeamName: row.executionTeamName || '',
             executionType: execType,
+            isParallelism: this.isTaskParallel(row) ? 1 : 0,
             planCode: row.planCode || plan?.code,
             planId: row.planId ?? plan?.id,
             routingId:
@@ -2015,8 +2107,6 @@
           );
           this.selectedWorkOrders = this.buildWorkOrderTableRows(list);
           this.planDataList = this.selectedWorkOrders;
-          this.planTableRenderKey += 1;
-
           const currentWorkOrderId = this.currentPlan?.workOrderId;
           const matchedCurrentOrder = currentWorkOrderId
             ? this.selectedWorkOrders.find(
@@ -2445,7 +2535,6 @@
           loading?.close();
         }
         this.dialogRenderKey += 1;
-        this.planTableRenderKey += 1;
         this.schedulingMode = mode;
         this.planTableStatusTab = this.getDefaultPlanTableStatusTab(mode);
         this.orderListLoader = orderListLoader;

+ 59 - 0
src/views/productionPlan/components/newFactoryProductionScheduling/TaskConfigPanel.vue

@@ -391,6 +391,14 @@
               align="center"
             >
               <template slot-scope="{ row }">
+                <el-link
+                  v-if="canDeleteAddedDispatchStation(row)"
+                  type="danger"
+                  :underline="false"
+                  @click="handleDeleteAddedDispatchStation(row)"
+                >
+                  删除
+                </el-link>
                 <el-popconfirm
                   v-if="canResetDispatchRow(row)"
                   title="确定要重置该条数据吗?"
@@ -489,6 +497,20 @@
               <span class="task-name-text">{{ taskName(row, $index) }}</span>
             </template>
           </el-table-column>
+          <el-table-column label="工序并行" min-width="92" align="center">
+            <template slot-scope="{ row }">
+              <el-select
+                v-model="row.isParallelism"
+                placeholder="工序并行"
+                :disabled="readonlyMode"
+                class="config-table-control"
+                @change="$emit('parallelism-change', row)"
+              >
+                <el-option label="否" :value="0" />
+                <el-option label="是" :value="1" />
+              </el-select>
+            </template>
+          </el-table-column>
           <el-table-column label="执行模式" min-width="84" align="center">
             <template slot-scope="{ row }">
               <el-select
@@ -1580,6 +1602,28 @@
         }
         return String(this.getAssignmentTypeCode(data.status)) !== '1';
       },
+      canDeleteAddedDispatchStation(row) {
+        if (!row || String(row.isNew ?? '') !== '1') {
+          return false;
+        }
+        const data = this.getDispatchActionRowData(row);
+        const rawStatusCode = this.getAssignmentTypeCode(data?.status);
+        const statusCode =
+          rawStatusCode === null ||
+          rawStatusCode === undefined ||
+          rawStatusCode === ''
+            ? NaN
+            : Number(rawStatusCode);
+        const statusText = this.getDispatchStatusText(data?.status);
+        return (
+          statusCode !== 0 &&
+          statusCode !== 1 &&
+          statusText !== '已保存' &&
+          statusText !== '保存' &&
+          statusText !== '已派单' &&
+          statusText !== '派单'
+        );
+      },
       isDispatchRowAssigned(row) {
         const data =
           typeof this.getDispatchActionRowData === 'function'
@@ -2144,6 +2188,21 @@
           this.dispatchToolbarLoading = false;
         }
       },
+      handleDeleteAddedDispatchStation(row) {
+        if (!this.canDeleteAddedDispatchStation(row)) {
+          this.$message.warning(
+            '只有通过添加工位新增且状态不是保存或派单的数据才能删除'
+          );
+          return;
+        }
+        const task = this.getDispatchRowTask(row);
+        this.clearDispatchObject(row, task);
+        this.$emit('remove-dispatch-station', {
+          task: this.activeTask,
+          row
+        });
+        this.$message.success('删除成功');
+      },
       validateDispatchActionRows(rows, type) {
         if (!rows.length) {
           this.$message.warning('请最少选择一条数据');

+ 86 - 2
src/views/productionPlan/components/planDotLine.vue

@@ -91,6 +91,19 @@
                 }}</span>
               </template>
             </el-table-column>
+            <el-table-column label="工序并行" min-width="92" align="center">
+              <template slot-scope="{ row }">
+                <el-select
+                  v-model="row.isParallelism"
+                  placeholder="工序并行"
+                  class="config-table-control"
+                  @change="handleParallelismChange(row)"
+                >
+                  <el-option label="否" :value="0" />
+                  <el-option label="是" :value="1" />
+                </el-select>
+              </template>
+            </el-table-column>
             <el-table-column label="执行模式" min-width="100" align="center">
               <template slot-scope="{ row }">
                 <el-select
@@ -458,6 +471,7 @@
         return {
           ...item,
           _taskKey: item.id ?? `detail-${item.taskId ?? index}`,
+          isParallelism: toSafeNumber(item.isParallelism) === 1 ? 1 : 0,
           executionStartTime: formatDateTime(item.executionStartTime),
           executionEndTime: formatDateTime(item.executionEndTime),
           executionType: execType,
@@ -494,6 +508,7 @@
           planCode: plan.code,
           routingId: plan.produceRoutingId,
           routingName: plan.produceRoutingName ?? plan.routingName,
+          isParallelism: 0,
           executionType: EXEC_TYPE.HOMEMADE,
           executionTeamId: '',
           executionTeamLeader: '',
@@ -549,6 +564,7 @@
       handleClearAll() {
         this.taskList.forEach((row) => {
           this.$set(row, 'executionType', EXEC_TYPE.HOMEMADE);
+          this.$set(row, 'isParallelism', 0);
           this.clearExecutionTeamFields(row);
           this.$set(row, 'executionStartTime', '');
           this.$set(row, 'executionEndTime', '');
@@ -603,6 +619,36 @@
         );
       },
 
+      isTaskParallel(row) {
+        return toSafeNumber(row?.isParallelism) === 1;
+      },
+
+      getCurrentPlanStartTime() {
+        return (
+          this.currentPlan?.startTime ||
+          this.currentPlan?.planStartTime ||
+          this.currentPlan?.executionStartTime ||
+          ''
+        );
+      },
+
+      isExecutionStartBeforePlanStart(executionStartTime) {
+        if (!executionStartTime) {
+          return false;
+        }
+        const planStartTime = this.getCurrentPlanStartTime();
+        if (!planStartTime) {
+          return false;
+        }
+        const executionStart = new Date(executionStartTime).getTime();
+        const planStart = new Date(planStartTime).getTime();
+        return (
+          !Number.isNaN(executionStart) &&
+          !Number.isNaN(planStart) &&
+          executionStart < planStart
+        );
+      },
+
       validateTaskSequence(row, options = {}) {
         const index = this.taskList.findIndex((item) => item === row);
         if (index < 0) {
@@ -611,8 +657,12 @@
         const prev = this.taskList[index - 1];
         const next = this.taskList[index + 1];
         const resetKey = options.resetKey;
-        const checkPrev = !resetKey || resetKey === 'executionStartTime';
-        const checkNext = !resetKey || resetKey === 'executionEndTime';
+        const checkPrev =
+          (!resetKey || resetKey === 'executionStartTime') &&
+          !this.isTaskParallel(row);
+        const checkNext =
+          (!resetKey || resetKey === 'executionEndTime') &&
+          !this.isTaskParallel(next);
 
         if (
           checkPrev &&
@@ -667,6 +717,15 @@
           this.$set(row, changeKey, '');
           return;
         }
+        if (
+          changeKey === 'executionStartTime' &&
+          this.isTaskParallel(row) &&
+          this.isExecutionStartBeforePlanStart(row.executionStartTime)
+        ) {
+          this.$message.warning('执行开始时间不能小于计划开始时间');
+          this.$set(row, changeKey, '');
+          return;
+        }
         if (!this.validateTaskSequence(row, { resetKey: changeKey })) {
           return;
         }
@@ -707,6 +766,20 @@
         }
       },
 
+      handleParallelismChange(row) {
+        if (!row?.executionStartTime) {
+          return;
+        }
+        if (this.isTaskParallel(row)) {
+          if (this.isExecutionStartBeforePlanStart(row.executionStartTime)) {
+            this.$message.warning('执行开始时间不能小于计划开始时间');
+            this.$set(row, 'executionStartTime', '');
+          }
+          return;
+        }
+        this.validateTaskSequence(row, { resetKey: 'executionStartTime' });
+      },
+
       /** 执行结束时间晚于计划交付时间(选择框标红,可保存) */
       isExecutionEndOverDelivery(row) {
         const deadline = this.currentPlan?.planDeliveryTime;
@@ -786,6 +859,16 @@
             return false;
           }
 
+          if (
+            this.isTaskParallel(item) &&
+            this.isExecutionStartBeforePlanStart(item.executionStartTime)
+          ) {
+            this.$message.warning(
+              `${label(item)}执行开始时间不能小于计划开始时间`
+            );
+            return false;
+          }
+
           const deadline = this.currentPlan?.planDeliveryTime;
           if (deadline) {
             const d = new Date(deadline).getTime();
@@ -829,6 +912,7 @@
             executionTeamLeaderId: row.executionTeamLeaderId || '',
             executionTeamName: row.executionTeamName || '',
             executionType: execType,
+            isParallelism: this.isTaskParallel(row) ? 1 : 0,
             planCode: row.planCode || plan?.code,
             planId: row.planId ?? plan?.id,
             routingId:

+ 37 - 1
src/views/productionPlan/index.vue

@@ -319,6 +319,16 @@
             {{ statusFormatter(row.status) }}
           </span>
         </template>
+
+        <template v-slot:approvalStatus="{ row }">
+          <el-tag
+            v-if="approvalStatusFormatter(row.approvalStatus)"
+            :type="approvalStatusTagType(row.approvalStatus)"
+            size="mini"
+          >
+            {{ approvalStatusFormatter(row.approvalStatus) }}
+          </el-tag>
+        </template>
         <!-- 操作列 -->
         <template v-slot:action="{ row }">
           <el-link
@@ -529,6 +539,7 @@
   import factoryProductionScheduling from './components/factoryProductionScheduling.vue';
   import newFactoryProductionScheduling from './components/newFactoryProductionScheduling.vue';
   import productionScheduling from './components/productionScheduling.vue';
+  import { reviewStatus } from '@/enum/dict';
 
   import {
     findBomCategoryByCategoryId,
@@ -1090,6 +1101,16 @@
               return obj && obj.label;
             }
           },
+          {
+            prop: 'approvalStatus',
+            columnKey: 'approvalStatus',
+            slot: 'approvalStatus',
+            label: '审批状态',
+            align: 'center',
+            minWidth: 100,
+            showOverflowTooltip: true,
+            formatter: (row) => reviewStatus[row.approvalStatus]
+          },
           {
             prop: 'customerName',
             label: '客户名称',
@@ -1198,6 +1219,17 @@
 
         return obj && obj.label;
       },
+      approvalStatusFormatter(status) {
+        return reviewStatus[status];
+      },
+      approvalStatusTagType(status) {
+        const statusMap = {
+          1: 'warning',
+          2: 'success',
+          3: 'danger'
+        };
+        return statusMap[status] || 'info';
+      },
       /* 表格数据源 */
       datasource({ page, limit, where }) {
         return getList({
@@ -1471,7 +1503,11 @@
           if (!table) return;
           if (typeof table.doLayout === 'function') {
             table.doLayout();
-          } else if (table.$refs && table.$refs.table && typeof table.$refs.table.doLayout === 'function') {
+          } else if (
+            table.$refs &&
+            table.$refs.table &&
+            typeof table.$refs.table.doLayout === 'function'
+          ) {
             table.$refs.table.doLayout();
           }
         });

+ 16 - 0
src/views/requirementListPlan/details.vue

@@ -496,14 +496,18 @@
         //   text: isBorrow ? '领用中...' : '领料中...'
         // });
 
+        const creatorFields = this.getCurrentCreatorFields();
+
         const detailList = this.selection.map((item) => ({
           ...item,
+          ...creatorFields,
           quantity: item.unPickQuantity,
           id: undefined
         }));
 
         const params = {
           ...this.form,
+          ...creatorFields,
           detailList,
           materialRequirements: this.form.code,
           type,
@@ -533,6 +537,18 @@
         // }
       },
 
+      getCurrentCreatorFields() {
+        const userInfo = this.$store.state.user.info || {};
+        return {
+          createUserId: userInfo.userId || userInfo.id,
+          createUserName:
+            userInfo.nickname ||
+            userInfo.name ||
+            userInfo.userName ||
+            userInfo.loginName
+        };
+      },
+
       borrowOrder() {
         this.$refs.borrowListRef.open(this.form);
       },

+ 588 - 0
src/views/workOrder/components/dispatch-tech-dialog.scss

@@ -0,0 +1,588 @@
+.dispatch-tech-dialog {
+  height: auto !important;
+  max-height: none !important;
+  overflow: hidden;
+  border: 1px solid rgba(32, 128, 168, 0.24);
+  border-radius: 8px;
+  background: #f4f7fa;
+  box-shadow: 0 18px 48px rgba(23, 40, 58, 0.28);
+
+  .el-dialog__header {
+    position: relative;
+    padding: 18px 28px 16px;
+    overflow: hidden;
+    background:
+      linear-gradient(135deg, rgba(12, 41, 59, 0.96), rgba(18, 64, 77, 0.94)),
+      linear-gradient(90deg, rgba(35, 194, 225, 0.15) 1px, transparent 1px);
+    border-bottom: 1px solid rgba(42, 203, 231, 0.28);
+  }
+
+  .el-dialog__header::before {
+    content: '';
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    height: 2px;
+    background: linear-gradient(90deg, #13c2c2, #27c46b 38%, #f6b83f 72%, transparent);
+  }
+
+  .el-dialog__header::after {
+    content: '';
+    position: absolute;
+    top: 0;
+    right: 72px;
+    width: 180px;
+    height: 100%;
+    background:
+      linear-gradient(90deg, transparent 0 18px, rgba(42, 203, 231, 0.18) 18px 20px, transparent 20px 40px),
+      linear-gradient(135deg, transparent 0 46%, rgba(39, 196, 107, 0.18) 46% 48%, transparent 48%);
+    opacity: 0.9;
+    pointer-events: none;
+  }
+
+  .el-dialog__title {
+    position: relative;
+    color: #f4fbff;
+    font-size: 18px;
+    font-weight: 700;
+    letter-spacing: 0;
+  }
+
+  .el-dialog__title::before {
+    content: '';
+    display: inline-block;
+    width: 4px;
+    height: 18px;
+    margin-right: 10px;
+    vertical-align: -3px;
+    border-radius: 2px;
+    background: linear-gradient(180deg, #28d8ff, #27c46b);
+    box-shadow: 0 0 12px rgba(40, 216, 255, 0.55);
+  }
+
+  .el-dialog__headerbtn {
+    top: 18px;
+
+    .el-dialog__close {
+      color: rgba(244, 251, 255, 0.78);
+      font-weight: 700;
+    }
+
+    &:hover .el-dialog__close {
+      color: #28d8ff;
+    }
+  }
+
+  .el-dialog__body {
+    max-height: none !important;
+    padding: 0;
+    overflow: visible !important;
+    background:
+      linear-gradient(rgba(32, 128, 168, 0.055) 1px, transparent 1px),
+      linear-gradient(90deg, rgba(32, 128, 168, 0.055) 1px, transparent 1px),
+      #f6f8fb;
+    background-size: 24px 24px;
+  }
+
+  .form-wrapper {
+    max-height: none !important;
+    padding: 22px 28px 0;
+    overflow: visible !important;
+  }
+
+  .form-wrapper::-webkit-scrollbar,
+  .el-table__body-wrapper::-webkit-scrollbar {
+    width: 8px;
+    height: 8px;
+  }
+
+  .form-wrapper::-webkit-scrollbar-thumb,
+  .el-table__body-wrapper::-webkit-scrollbar-thumb {
+    border-radius: 8px;
+    background: linear-gradient(180deg, #72d1df, #7f8c99);
+  }
+
+  .form-wrapper::-webkit-scrollbar-track,
+  .el-table__body-wrapper::-webkit-scrollbar-track {
+    background: rgba(217, 225, 232, 0.7);
+  }
+
+  .basic,
+  .basic + .el-row {
+    position: relative;
+    margin: 0 0 10px !important;
+    padding: 14px 14px 2px;
+    border: 1px solid rgba(53, 103, 129, 0.16);
+    border-radius: 8px;
+    background: rgba(255, 255, 255, 0.86);
+    box-shadow: 0 8px 22px rgba(29, 58, 78, 0.06);
+  }
+
+  .basic::before,
+  .basic + .el-row::before {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 3px;
+    background: linear-gradient(90deg, #18b6d2, rgba(39, 196, 107, 0.8), transparent);
+  }
+
+  .el-form-item {
+    display: flex;
+    align-items: center;
+    width: 100%;
+    margin-bottom: 14px;
+    margin-right: 0;
+  }
+
+  .el-form-item__label {
+    flex: 0 0 132px;
+    width: 132px !important;
+    min-width: 132px;
+    color: #4f5d68;
+    font-weight: 700;
+    line-height: 36px;
+    white-space: nowrap;
+    word-break: keep-all;
+  }
+
+  .el-form-item__content {
+    flex: 1;
+    min-width: 0;
+    line-height: 36px;
+  }
+
+  .el-form-item__content > .el-input,
+  .el-form-item__content > .el-select,
+  .el-form-item__content > .el-date-editor {
+    width: 100%;
+  }
+
+  .el-input__inner,
+  .el-textarea__inner {
+    height: 36px;
+    border-color: #d7e1e8;
+    border-radius: 6px;
+    color: #263743;
+    font-weight: 600;
+    background: #ffffff;
+    box-shadow: inset 0 1px 2px rgba(21, 48, 66, 0.04);
+  }
+
+  .el-input.is-disabled .el-input__inner,
+  .el-textarea.is-disabled .el-textarea__inner {
+    color: #52616d;
+    border-color: #dfe8ee;
+    background: linear-gradient(180deg, #fbfcfd, #f1f5f8);
+  }
+
+  .el-input__inner:focus,
+  .el-textarea__inner:focus {
+    border-color: #18b6d2;
+    box-shadow: 0 0 0 2px rgba(24, 182, 210, 0.12);
+  }
+
+  .el-radio {
+    margin-right: 36px;
+    color: #445765;
+    font-weight: 700;
+    line-height: 36px;
+    -webkit-font-smoothing: antialiased;
+    text-shadow: none;
+  }
+
+  .el-radio__input {
+    line-height: 1;
+  }
+
+  .el-radio__inner {
+    width: 18px;
+    height: 18px;
+    border: 1px solid #c9d6df;
+    background: #ffffff;
+    box-shadow: none;
+  }
+
+  .el-radio__inner::after {
+    width: 8px;
+    height: 8px;
+    background: #ffffff;
+  }
+
+  .el-radio__input.is-checked .el-radio__inner {
+    border-color: #11a8bd;
+    background: #11a8bd;
+    box-shadow: none;
+  }
+
+  .el-radio__input.is-checked + .el-radio__label {
+    color: #087d8e;
+    font-weight: 800;
+    text-shadow: none;
+  }
+
+  .el-radio__label {
+    padding-left: 9px;
+    font-size: 15px;
+    letter-spacing: 0;
+    white-space: nowrap;
+  }
+
+  .el-radio-button__inner {
+    min-width: 64px;
+    border-color: #d7e1e8;
+    color: #52616d;
+    background: #ffffff;
+  }
+
+  .el-radio-button__orig-radio:checked + .el-radio-button__inner {
+    border-color: #17b7b9 !important;
+    background: linear-gradient(135deg, #16b8c7, #27c46b) !important;
+    box-shadow: 0 4px 12px rgba(22, 184, 199, 0.2) !important;
+  }
+
+  .process_list {
+    margin-top: 16px;
+    overflow: hidden;
+    border: 1px solid rgba(53, 103, 129, 0.18);
+    border-radius: 8px;
+    background: rgba(255, 255, 255, 0.94);
+    box-shadow: 0 12px 28px rgba(29, 58, 78, 0.08);
+  }
+
+  .process_list > .el-tabs__header {
+    margin: 0;
+    border-bottom-color: #dce7ed;
+    background: linear-gradient(180deg, #f8fbfd, #eef4f7);
+  }
+
+  .process_list > .el-tabs__header .el-tabs__item {
+    height: 46px;
+    padding: 0 22px;
+    color: #6a7884;
+    line-height: 46px;
+    font-weight: 700;
+    border-right-color: #e2ebf0;
+  }
+
+  .process_list > .el-tabs__header .el-tabs__item.is-active {
+    color: #098da4;
+    background: #ffffff;
+    border-top: 3px solid #18b6d2;
+    box-shadow: inset 0 -1px 0 #ffffff;
+  }
+
+  .process_list > .el-tabs__content {
+    padding: 14px 8px 0;
+  }
+
+  .process_list .el-tab-pane > span[style*='green'] {
+    display: block;
+    margin: 0 0 12px;
+    padding: 9px 12px;
+    color: #118a55 !important;
+    font-weight: 700;
+    border: 1px solid rgba(39, 196, 107, 0.22);
+    border-left: 4px solid #27c46b;
+    border-radius: 6px;
+    background: linear-gradient(90deg, rgba(39, 196, 107, 0.11), rgba(24, 182, 210, 0.07));
+  }
+
+  .table {
+    margin-top: 0;
+    border: 1px solid #e1e9ee;
+    border-radius: 8px;
+    background: #ffffff;
+  }
+
+  .table .el-button {
+    height: 34px;
+    padding: 9px 16px;
+    border-radius: 5px;
+    font-weight: 700;
+  }
+
+  .table .el-button--primary {
+    border-color: #1a9fc2;
+    background: linear-gradient(135deg, #1890c2, #17b7b9);
+    box-shadow: 0 5px 12px rgba(24, 144, 194, 0.18);
+  }
+
+  .table .el-button--success {
+    border-color: #33bf65;
+    background: linear-gradient(135deg, #29b862, #48c928);
+    box-shadow: 0 5px 12px rgba(41, 184, 98, 0.18);
+  }
+
+  .table .el-button.is-disabled,
+  .table .el-button.is-disabled:hover {
+    border-color: #d8e1e7;
+    color: #a2adb7;
+    background: #f2f5f7;
+    box-shadow: none;
+  }
+
+  .table .text {
+    color: #4d5f6d;
+  }
+
+  .table .el-table {
+    color: #3c4b55;
+  }
+
+  .table .el-table th.el-table__cell {
+    color: #263743;
+    font-weight: 800;
+    background: linear-gradient(180deg, #f8fbfd, #edf3f6);
+  }
+
+  .table .el-table td.el-table__cell,
+  .table .el-table th.el-table__cell.is-leaf {
+    border-bottom-color: #e8eef2;
+  }
+
+  .table .el-table__body tr:hover > td.el-table__cell {
+    background: rgba(24, 182, 210, 0.06);
+  }
+
+  .table .el-table__fixed-right::before,
+  .table .el-table__fixed::before {
+    background-color: #e1e9ee;
+  }
+
+  .table .el-table__fixed-right {
+    box-shadow: -8px 0 18px rgba(31, 64, 84, 0.08);
+  }
+
+  .table .el-input__inner {
+    height: 34px;
+    text-align: center;
+    border-color: #dbe6ec;
+    font-weight: 700;
+  }
+
+  .table .el-select {
+    width: 100%;
+  }
+
+  .table .el-link {
+    font-weight: 700;
+  }
+
+  .table .el-pagination {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    min-height: 64px;
+    margin-top: 12px;
+    padding: 8px 0 10px;
+    color: #4f5d68;
+    font-weight: 700;
+    line-height: 40px;
+    overflow: visible;
+  }
+
+  .table .el-pagination > * {
+    display: inline-flex;
+    align-items: center;
+    justify-content: center;
+    height: 40px;
+    vertical-align: middle;
+    overflow: visible;
+  }
+
+  .table .el-pagination .el-pagination__total {
+    margin-right: 14px;
+  }
+
+  .table .el-pagination .el-pagination__sizes {
+    margin-right: 22px;
+  }
+
+  .table .el-pagination .el-pagination__sizes .el-select,
+  .table .el-pagination .el-pagination__sizes .el-input {
+    width: 106px;
+  }
+
+  .table .el-pagination .el-pagination__jump {
+    margin-left: 22px;
+    color: #4f5d68;
+    line-height: 40px;
+    overflow: visible;
+  }
+
+  .table .el-pagination .el-pagination__jump .el-input {
+    width: 70px;
+    height: 40px;
+    margin: 0 8px;
+    line-height: 40px;
+    overflow: visible;
+  }
+
+  .table .el-pagination .el-select .el-input__inner,
+  .table .el-pagination .el-pagination__jump .el-input__inner {
+    box-sizing: border-box;
+    height: 40px;
+    padding: 0 30px 0 12px;
+    color: #253847;
+    line-height: 40px;
+    text-align: center;
+    border: 1px solid #d8e5ec;
+    border-radius: 5px;
+    background: #ffffff;
+    box-shadow: none;
+  }
+
+  .table .el-pagination .el-pagination__jump .el-input__inner {
+    padding: 0 8px;
+  }
+
+  .table .el-pagination button,
+  .table .el-pagination .el-pager li {
+    display: inline-flex;
+    align-items: center;
+    justify-content: center;
+    min-width: 32px;
+    height: 32px;
+    padding: 0;
+    line-height: 32px;
+  }
+
+  .table .el-pagination .el-pager li.active {
+    color: #ffffff;
+    background: #1890ff;
+    border-radius: 50%;
+  }
+
+  .table div[style*='margin-left: 50px'] {
+    margin-left: 28px !important;
+    vertical-align: middle;
+    color: #5b6975;
+    font-weight: 700;
+  }
+
+  .el-dialog__footer {
+    padding: 14px 28px 18px;
+    border-top: 1px solid rgba(53, 103, 129, 0.14);
+    background: linear-gradient(180deg, rgba(246, 248, 251, 0.96), #eef4f7);
+  }
+
+  .el-dialog__footer .el-button {
+    min-width: 86px;
+    height: 36px;
+    border-radius: 5px;
+    font-weight: 700;
+  }
+
+  .el-dialog__footer .el-button--primary {
+    border-color: #18a7c1;
+    background: linear-gradient(135deg, #18a7c1, #27c46b);
+    box-shadow: 0 6px 16px rgba(24, 167, 193, 0.22);
+  }
+
+  &.is-fullscreen {
+    display: flex;
+    flex-direction: column;
+    width: 100vw !important;
+    height: 100vh !important;
+    max-height: 100vh !important;
+    margin: 0 !important;
+    border-radius: 0;
+    overflow: hidden;
+
+    .el-dialog__header,
+    .el-dialog__footer {
+      flex: 0 0 auto;
+    }
+
+    .el-dialog__body {
+      flex: 1 1 auto;
+      min-height: 0;
+      height: calc(100vh - 136px) !important;
+      max-height: calc(100vh - 136px) !important;
+      overflow-x: hidden !important;
+      overflow-y: auto !important;
+    }
+
+    .form-wrapper {
+      height: auto !important;
+      min-height: 100%;
+      max-height: none !important;
+      padding: 22px 28px 18px;
+      overflow: visible !important;
+    }
+
+    .process_list {
+      margin-bottom: 0;
+    }
+  }
+
+  &.is-fullscreen .el-dialog__body::-webkit-scrollbar {
+    width: 8px;
+    height: 8px;
+  }
+
+  &.is-fullscreen .el-dialog__body::-webkit-scrollbar-thumb {
+    border-radius: 8px;
+    background: linear-gradient(180deg, #72d1df, #7f8c99);
+  }
+
+  &.is-fullscreen .el-dialog__body::-webkit-scrollbar-track {
+    background: rgba(217, 225, 232, 0.7);
+  }
+
+  @media (max-width: 1366px) {
+    .form-wrapper {
+      padding: 18px 20px 0;
+    }
+
+    .process_list > .el-tabs__header .el-tabs__item {
+      padding: 0 16px;
+    }
+  }
+}
+
+.ele-modal-wrap-fullscreen > .dispatch-tech-dialog {
+  display: flex !important;
+  flex-direction: column;
+  height: 100% !important;
+  max-height: 100% !important;
+  overflow: hidden !important;
+
+  > .el-dialog__header,
+  > .el-dialog__footer {
+    flex: 0 0 auto;
+  }
+
+  > .el-dialog__body {
+    flex: 1 1 auto !important;
+    min-height: 0;
+    height: auto !important;
+    max-height: none !important;
+    overflow-x: hidden !important;
+    overflow-y: auto !important;
+  }
+
+  > .el-dialog__body > .form-wrapper {
+    min-height: 100%;
+    padding-bottom: 18px;
+    overflow: visible !important;
+  }
+}
+
+.ele-modal-wrap-fullscreen > .dispatch-tech-dialog > .el-dialog__body::-webkit-scrollbar {
+  width: 8px;
+  height: 8px;
+}
+
+.ele-modal-wrap-fullscreen > .dispatch-tech-dialog > .el-dialog__body::-webkit-scrollbar-thumb {
+  border-radius: 8px;
+  background: linear-gradient(180deg, #72d1df, #7f8c99);
+}
+
+.ele-modal-wrap-fullscreen > .dispatch-tech-dialog > .el-dialog__body::-webkit-scrollbar-track {
+  background: rgba(217, 225, 232, 0.7);
+}

+ 3 - 1
src/views/workOrder/components/planDotLinReleaseDialog.vue

@@ -3,7 +3,7 @@
     :width="modelWidth"
     :visible.sync="dispatchVisible"
     :close-on-click-modal="false"
-    custom-class="ele-dialog-form"
+    custom-class="ele-dialog-form dispatch-tech-dialog"
     :maxable="true"
     :title="'派单'"
     append-to-body
@@ -809,6 +809,8 @@
 </style>
 
 <style lang="scss">
+  @import './dispatch-tech-dialog.scss';
+
   .device-snapshot-lock-tooltip.el-tooltip__popper {
     padding: 10px 14px;
     color: #7a2e00;

+ 5 - 1
src/views/workOrder/components/releaseDialog.vue

@@ -3,7 +3,7 @@
     :width="modelWidth"
     :visible.sync="dispatchVisible"
     :close-on-click-modal="false"
-    custom-class="ele-dialog-form"
+    custom-class="ele-dialog-form dispatch-tech-dialog"
     :maxable="true"
     :title="'派单'"
     append-to-body
@@ -755,3 +755,7 @@
   //   }
   // }
 </style>
+
+<style lang="scss">
+  @import './dispatch-tech-dialog.scss';
+</style>

+ 3 - 3
vue.config.js

@@ -35,14 +35,14 @@ module.exports = {
         // target: 'http://192.168.1.103:18086',
         // target: 'http://192.168.1.158:18086',
         // target: 'http://192.168.158:18086',
-        // target: 'http://192.168.1.251:18086',
+        target: 'http://192.168.1.251:18086',
         // target: 'http://192.168.1.144:18086',
         // target: 'http://192.168.1.251:18186',
         // target: 'http://192.168.1.211:18086',
         // target: 'http://192.168.1.251:18186',
         // target: 'http://192.168.1.102:18086',
-        // target: 'http://aiot.zoomwin.com.cn:51005/api',
-        target: 'http://192.168.1.125:18086',
+        // target: 'http://aiot.zoomwin.com.cn:51001/api',
+        // target: 'http://192.168.1.125:18086',
 
         // target: 'http://192.168.1.116:18086',