Parcourir la source

修改工厂排产和班组排程的bug

695593266@qq.com il y a 2 semaines
Parent
commit
f271cc4f47

+ 5 - 1
src/views/productionPlan/components/gantt/components/GanttFilterBar.vue

@@ -22,7 +22,7 @@
         ></el-input>
       </div>
       <div class="calendar-filter-item">
-        <span class="calendar-filter-label">计划编号:</span>
+        <span class="calendar-filter-label">{{ planCodeLabel }}:</span>
         <el-input
           v-model="localQuery.planCode"
           size="small"
@@ -46,6 +46,10 @@
       query: {
         type: Object,
         required: true
+      },
+      planCodeLabel: {
+        type: String,
+        default: '计划编号'
       }
     },
     data() {

+ 34 - 1
src/views/productionPlan/components/gantt/project-gantt.constants.js

@@ -24,5 +24,38 @@ export const PLAN_COLOR_PALETTE = Object.freeze([
   '#8e24aa',
   '#00897b',
   '#fb8c00',
-  '#3949ab'
+  '#3949ab',
+  '#5e97f6',
+  '#7e57c2',
+  '#26a69a',
+  '#ef5350',
+  '#66bb6a',
+  '#ab47bc',
+  '#29b6f6',
+  '#ff7043',
+  '#5c6bc0',
+  '#009688',
+  '#ec407a',
+  '#78909c',
+  '#9ccc65',
+  '#ffb300',
+  '#42a5f5',
+  '#8d6e63',
+  '#26c6da',
+  '#d4a017',
+  '#7cb342',
+  '#6d4c41',
+  '#5c7cfa',
+  '#00acc1',
+  '#f06292',
+  '#558b2f',
+  '#9575cd',
+  '#00838f',
+  '#c0ca33',
+  '#bf360c',
+  '#536dfe',
+  '#ad1457',
+  '#2e7d32',
+  '#0277bd',
+  '#6a1b9a'
 ]);

+ 148 - 32
src/views/productionPlan/components/gantt/project-gantt.vue

@@ -43,6 +43,9 @@
         <gantt-filter-bar
           v-show="!isFullscreen"
           :query="ganttQuery"
+          :plan-code-label="
+            resourceLabelMode === 'order' ? '生产订单号' : '计划编号'
+          "
           @update:query="ganttQuery = $event"
           @apply="applyGanttFilters"
           @reset="resetGanttFilters"
@@ -55,6 +58,9 @@
         <gantt-filter-bar
           v-show="!isFullscreen"
           :query="calendarQuery"
+          :plan-code-label="
+            resourceLabelMode === 'order' ? '生产订单号' : '计划编号'
+          "
           @update:query="calendarQuery = $event"
           @apply="applyCalendarFilters"
           @reset="resetCalendarFilters"
@@ -233,10 +239,7 @@
         );
       },
       filteredGanttTasks() {
-        return this.ganttTasks.filter(
-          (item) =>
-            this.matchesResourceFilter(item) && this.matchesGanttFilters(item)
-        );
+        return this.buildFilteredGanttTasks();
       },
       planMetaByCode() {
         return this.planList.reduce((result, item) => {
@@ -905,25 +908,54 @@
         this.calendarFilters = createSearchQuery();
         this.calendarExpand = true;
       },
+      joinSearchValues(values = []) {
+        return values
+          .filter((item) => item !== '' && item !== null && item !== undefined)
+          .map((item) => String(item))
+          .join(' ');
+      },
       normalizePlanSearchEntry(entry) {
         const planKey = entry.planCode || entry.code || entry.id;
         const planMeta = this.planMetaByCode[planKey] || {};
+        const isOrderScheduling = this.resourceLabelMode === 'order';
+        const visibleTaskText = [
+          entry.taskName,
+          entry.title,
+          entry.name,
+          entry.text,
+          entry.executor
+        ];
         return {
-          routingName:
+          routingName: this.joinSearchValues([
             entry.routingName ||
-            entry.produceRoutingName ||
-            planMeta.routingName ||
-            planMeta.produceRoutingName ||
-            planMeta.routeName ||
-            '',
-          productName: entry.productName || planMeta.productName || '',
-          planCode:
+              entry.produceRoutingName ||
+              planMeta.routingName ||
+              planMeta.produceRoutingName ||
+              planMeta.routeName,
+            ...visibleTaskText
+          ]),
+          productName: this.joinSearchValues([
+            entry.productName,
+            planMeta.productName,
+            isOrderScheduling ? entry.name : '',
+            isOrderScheduling ? entry.text : ''
+          ]),
+          planCode: this.joinSearchValues([
             entry.productionOrderNumber ||
-            entry.planCode ||
-            entry.code ||
-            planMeta.code ||
-            planMeta.planCode ||
-            ''
+              entry.apsWorkOrderCode ||
+              entry.workOrderCode ||
+              entry.productionOrderCode,
+            entry.displayCode,
+            entry.planCode,
+            entry.orderCode,
+            entry.code,
+            planMeta.productionOrderNumber,
+            planMeta.apsWorkOrderCode,
+            planMeta.workOrderCode,
+            planMeta.code,
+            planMeta.planCode,
+            ...visibleTaskText
+          ])
         };
       },
       matchesPlanSearchFilters(entry, filters) {
@@ -960,6 +992,40 @@
       matchesCalendarFilters(entry) {
         return this.matchesPlanSearchFilters(entry, this.calendarFilters);
       },
+      buildFilteredGanttTasks() {
+        const resourceMatchedTasks = this.ganttTasks.filter((item) =>
+          this.matchesResourceFilter(item)
+        );
+        const directMatchedTasks = resourceMatchedTasks.filter((item) =>
+          this.matchesGanttFilters(item)
+        );
+        const matchedIds = new Set(directMatchedTasks.map((item) => item.id));
+        const shouldExpandMatchedParent =
+          (!this.ganttFilters.planCode &&
+            (this.ganttFilters.routingName || this.ganttFilters.productName)) ||
+          (this.resourceLabelMode !== 'order' && this.ganttFilters.planCode);
+        const matchedSplitParentIds = shouldExpandMatchedParent
+          ? new Set(
+              directMatchedTasks
+                .filter((item) => item.render === 'split' && !item.parent)
+                .map((item) => item.id)
+            )
+          : new Set();
+
+        directMatchedTasks.forEach((item) => {
+          if (item.parent) {
+            matchedIds.add(item.parent);
+          }
+        });
+
+        resourceMatchedTasks.forEach((item) => {
+          if (matchedSplitParentIds.has(item.parent)) {
+            matchedIds.add(item.id);
+          }
+        });
+
+        return resourceMatchedTasks.filter((item) => matchedIds.has(item.id));
+      },
       showCalendarTooltip(event, entries) {
         this.hoverTooltip = {
           visible: true,
@@ -1418,7 +1484,47 @@
   }
 
   /* 今日高亮 */
+  :deep(.gantt_layout_cell),
+  :deep(.gantt_task),
+  :deep(.gantt_data_area),
+  :deep(.gantt_task_bg),
+  :deep(.gantt_task_scale) {
+    background: #ffffff;
+  }
+
+  :deep(.gantt_task) {
+    border-left: none;
+  }
+
+  :deep(.gantt_ver_scroll),
+  :deep(.gantt_hor_scroll) {
+    background: #f8fafc;
+  }
+
+  :deep(.gantt_ver_scroll::-webkit-scrollbar),
+  :deep(.gantt_hor_scroll::-webkit-scrollbar),
+  :deep(.gantt_data_area::-webkit-scrollbar) {
+    width: 10px;
+    height: 10px;
+  }
+
+  :deep(.gantt_ver_scroll::-webkit-scrollbar-thumb),
+  :deep(.gantt_hor_scroll::-webkit-scrollbar-thumb),
+  :deep(.gantt_data_area::-webkit-scrollbar-thumb) {
+    border: 2px solid #f8fafc;
+    border-radius: 999px;
+    background: #c9d1dc;
+  }
+
+  :deep(.gantt_ver_scroll::-webkit-scrollbar-thumb:hover),
+  :deep(.gantt_hor_scroll::-webkit-scrollbar-thumb:hover),
+  :deep(.gantt_data_area::-webkit-scrollbar-thumb:hover) {
+    background: #aeb7c4;
+  }
+
   :deep(.gantt_task_scale) {
+    border-bottom: 1px solid #dcdfe6;
+
     .gantt_scale_line > .gantt_scale_cell {
       color: #333333;
       font-size: 11px;
@@ -1427,7 +1533,7 @@
 
       &.today {
         background: #dbeeff;
-        color: #ffffff;
+        color: #1677c8 !important;
       }
     }
   }
@@ -1517,15 +1623,23 @@
   :deep(.gantt_task_bg) {
     border-right: 1px solid #ebebeb;
   }
+  :deep(.gantt_task_bg .gantt_task_row),
+  :deep(.gantt_task_row) {
+    border-bottom: 1px solid #f3f5f7;
+  }
   :deep(.task-222) {
     height: 26px !important;
     line-height: 26px !important;
     border: none !important;
-    border-radius: 2px !important;
+    border-radius: 3px !important;
     box-shadow: none !important;
+    filter: saturate(0.88) brightness(0.99);
+    overflow: hidden;
+    transition: box-shadow 0.18s ease, filter 0.18s ease;
   }
   :deep(.task-222:hover) {
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.16) !important;
+    filter: saturate(0.94) brightness(1);
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.14) !important;
   }
   :deep(.gantt_task_line.task-parent-red),
   :deep(.gantt_task_line.task-parent-red .gantt_task_progress) {
@@ -1553,9 +1667,6 @@
     width: 100%;
     color: #fff;
   }
-  :deep(.gantt_task_row) {
-    border-bottom: none;
-  }
   :deep(.gantt-task-text) {
     display: block;
     width: 100%;
@@ -1564,11 +1675,12 @@
     box-sizing: border-box;
     color: #fff;
     font-size: 12px;
+    font-weight: 500;
     line-height: 26px;
     white-space: nowrap;
     text-overflow: ellipsis;
     text-align: center;
-    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.18);
+    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.16);
   }
   :deep(.month) {
     font-size: 18px;
@@ -1584,17 +1696,20 @@
   .gantt-tooltip-card {
     min-width: 320px;
     max-width: 420px;
-    padding: 10px 12px;
-    border-radius: 4px;
-    background: rgba(70, 70, 70, 0.9);
-    color: #ffffff;
-    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
+    padding: 12px 14px;
+    border: 1px solid rgba(226, 232, 240, 0.9);
+    border-radius: 6px;
+    background: rgba(255, 255, 255, 0.96);
+    color: #1f2937;
+    box-shadow: 0 12px 30px rgba(15, 23, 42, 0.18);
+    backdrop-filter: blur(8px);
   }
   .gantt-tooltip-card__title {
     margin-bottom: 8px;
     font-size: 13px;
     font-weight: 600;
     line-height: 20px;
+    color: #0f172a;
     word-break: break-all;
   }
   .gantt-tooltip-card__row {
@@ -1606,25 +1721,26 @@
   .gantt-tooltip-card__section + .gantt-tooltip-card__section {
     margin-top: 8px;
     padding-top: 8px;
-    border-top: 1px solid rgba(255, 255, 255, 0.12);
+    border-top: 1px solid #edf2f7;
   }
   .gantt-tooltip-card__section-title {
     margin-bottom: 4px;
     font-size: 12px;
     font-weight: 600;
-    color: rgba(255, 255, 255, 0.86);
+    color: #475569;
   }
   .gantt-tooltip-card__row + .gantt-tooltip-card__row {
     margin-top: 2px;
   }
   .gantt-tooltip-card__label {
     flex: 0 0 72px;
-    color: rgba(255, 255, 255, 0.78);
+    color: #64748b;
     white-space: nowrap;
   }
   .gantt-tooltip-card__value {
     flex: 1;
     min-width: 0;
+    color: #111827;
     white-space: nowrap;
     overflow: hidden;
     text-overflow: ellipsis;

+ 55 - 1
src/views/productionPlan/components/newFactoryProductionScheduling/TaskConfigPanel.vue

@@ -210,6 +210,7 @@
                   :value="row.quantity"
                   placeholder="请输入数量"
                   class="config-table-control"
+                  :disabled="isDispatchRowAssigned(row)"
                   @input="handleDispatchRowQuantityInput(row, $event)"
                 />
               </template>
@@ -227,6 +228,7 @@
                   placeholder="开始时间"
                   clearable
                   class="config-table-control"
+                  :disabled="isDispatchRowAssigned(row)"
                   @change="handleDispatchRowStartTimeChange(row)"
                 />
               </template>
@@ -254,6 +256,7 @@
                     placeholder="完成时间"
                     clearable
                     class="config-table-control"
+                    :disabled="isDispatchRowAssigned(row)"
                     @change="handleDispatchRowEndTimeChange(row)"
                   />
                 </div>
@@ -777,7 +780,8 @@
       }
     },
     watch: {
-      activeTaskKey() {
+      activeTaskKey(newKey, oldKey) {
+        this.clearDispatchSelectionsByTaskKey(oldKey);
         this.dispatchPage = 1;
         this.loadDispatchAssignData();
       },
@@ -1133,6 +1137,18 @@
         }
         return String(this.getAssignmentTypeCode(data.status)) !== '1';
       },
+      isDispatchRowAssigned(row) {
+        const data =
+          typeof this.getDispatchActionRowData === 'function'
+            ? this.getDispatchActionRowData(row)
+            : row || {};
+        const statusCode = this.getAssignmentTypeCode(data?.status);
+        if (String(statusCode) === '1') {
+          return true;
+        }
+        const statusText = this.getDispatchStatusText(data?.status);
+        return statusText === '已派单' || statusText === '派单';
+      },
       normalizeDispatchAssignment(item) {
         const assigneeId =
           item.assigneeId || item.workStationId || item.workstationId || '';
@@ -1284,6 +1300,35 @@
           this.optionMatchesDispatchObject(item.executionTeamId, row)
         );
       },
+      getDispatchTaskRowsByKey(groupKey) {
+        if (!groupKey) {
+          return [];
+        }
+        return (this.taskList || []).filter(
+          (item) => this.dispatchTaskGroupKey(item) === groupKey
+        );
+      },
+      clearDispatchSelectionsByTaskKey(groupKey) {
+        if (!this.orderDispatchStyle || !groupKey) {
+          return;
+        }
+        this.getDispatchTaskRowsByKey(groupKey).forEach((task) => {
+          if (!task?.executionTeamId || this.isDispatchRowAssigned(task)) {
+            return;
+          }
+          if (task._dispatchDraft) {
+            this.$emit('remove-task-row', task);
+            return;
+          }
+          this.$set(task, 'executionTeamId', '');
+          this.$set(task, 'rawExecutionTeamId', '');
+          this.$set(task, 'executionObjectType', '');
+          this.$set(task, 'executionObjectName', '');
+          this.$set(task, 'executionTeamName', '');
+          this.$set(task, 'executionTeamLeader', '');
+          this.$set(task, 'executionTeamLeaderId', '');
+        });
+      },
       createDispatchTaskRow(row) {
         const source = this.activeTask || {};
         const next = {
@@ -1367,6 +1412,9 @@
         return task;
       },
       handleDispatchRowQuantityInput(row, value) {
+        if (this.isDispatchRowAssigned(row)) {
+          return;
+        }
         this.$set(row, 'quantity', value);
         this.updateDispatchRowDraft(row, { quantity: value });
         const quantity = this.parseDispatchQuantity(value);
@@ -1513,6 +1561,9 @@
         this.$emit('time-change', row, 'executionEndTime');
       },
       handleDispatchRowStartTimeChange(row) {
+        if (this.isDispatchRowAssigned(row)) {
+          return;
+        }
         const task = this.ensureDispatchObjectSelected(row);
         if (!task) {
           return;
@@ -1528,6 +1579,9 @@
         });
       },
       handleDispatchRowEndTimeChange(row) {
+        if (this.isDispatchRowAssigned(row)) {
+          return;
+        }
         const task = this.ensureDispatchObjectSelected(row);
         if (!task) {
           return;