695593266@qq.com 2 săptămâni în urmă
părinte
comite
4bdb7f628d

+ 87 - 34
src/views/productionPlan/components/gantt/components/CalendarTable.vue

@@ -120,9 +120,10 @@
     min-width: 0;
     min-height: 0;
     background: #fff;
-    border: 1px solid #dfe6ec;
-    border-radius: 4px;
+    border: 1px solid #e6edf5;
+    border-radius: 8px;
     overflow: hidden;
+    box-shadow: 0 4px 14px rgba(31, 45, 61, 0.06);
   }
 
   .calendar-empty {
@@ -133,6 +134,7 @@
     justify-content: center;
     color: #909399;
     font-size: 16px;
+    background: #fbfdff;
   }
 
   .calendar-table-wrapper {
@@ -141,6 +143,22 @@
     height: 100%;
     overflow-x: auto;
     overflow-y: auto;
+    background: #fff;
+  }
+
+  .calendar-table-wrapper::-webkit-scrollbar {
+    width: 8px;
+    height: 8px;
+  }
+
+  .calendar-table-wrapper::-webkit-scrollbar-thumb {
+    border: 2px solid #fff;
+    border-radius: 999px;
+    background: #c9d4e2;
+  }
+
+  .calendar-table-wrapper::-webkit-scrollbar-thumb:hover {
+    background: #aeb9c8;
   }
 
   .calendar-table {
@@ -152,85 +170,100 @@
 
   .calendar-th,
   .calendar-td {
-    border: 1px solid #dcdfe6;
+    border: 1px solid #e6edf5;
     text-align: center;
     padding: 0;
   }
 
   .calendar-th {
     height: 36px;
-    background: #f8f8f8;
-    color: #303133;
-    font-weight: 500;
+    background: #f7fafc;
+    color: #263445;
+    font-weight: 600;
     font-size: 14px;
   }
 
   .calendar-th--month {
-    height: 40px;
-    font-size: 22px;
-    background: #efefef;
+    height: 42px;
+    font-size: 18px;
+    letter-spacing: 0;
+    background: linear-gradient(180deg, #f8fbff 0%, #eef5fb 100%);
+    color: #1f2d3d;
   }
 
   .calendar-th--group,
   .calendar-td--group {
-    width: 108px;
-    min-width: 108px;
+    width: 124px;
+    min-width: 124px;
   }
 
   .calendar-th--task,
   .calendar-td--task {
-    width: 184px;
-    min-width: 184px;
+    width: 160px;
+    min-width: 160px;
   }
 
   .calendar-th--day {
-    width: 48px;
-    min-width: 48px;
+    width: 64px;
+    min-width: 64px;
     font-size: 14px;
   }
 
   .calendar-th--day.is-weekend {
-    background: #f4f4f4;
+    background: #f5f8fb;
+    color: #7a8794;
   }
 
   .calendar-th--day.is-today {
-    background: #d9ecff;
-    color: #409eff;
+    background: #e5f2ff;
+    color: #1683d8;
+    box-shadow: inset 0 -2px 0 #1f8ceb;
   }
 
   .calendar-td--group,
   .calendar-td--task {
-    padding: 6px 8px;
+    padding: 8px 10px;
     background: #fff;
-    color: #303133;
-    font-size: 15px;
+    color: #364152;
+    font-size: 14px;
     word-break: break-all;
     text-align: left;
     vertical-align: middle;
   }
 
   .calendar-td--group {
-    font-weight: 500;
+    background: #fbfdff;
+    color: #243447;
+    font-weight: 600;
   }
 
   .calendar-td--day {
-    height: 56px;
+    height: 62px;
     background: #fff;
     vertical-align: top;
-    padding: 3px 5px;
+    padding: 6px;
+    transition: background 0.18s ease;
+  }
+
+  tbody tr:nth-child(odd) .calendar-td--day {
+    background: #fcfdff;
+  }
+
+  tbody tr:hover .calendar-td {
+    background: #f7fbff;
   }
 
   .calendar-td--day.is-weekend {
-    background: #fafafa;
+    background: #f8fafc;
   }
 
   .calendar-td--day.is-today {
-    background: #edf6ff;
+    background: #edf7ff;
   }
 
   .calendar-day-content {
     width: 100%;
-    min-height: 48px;
+    min-height: 50px;
     overflow: hidden;
   }
 
@@ -238,28 +271,48 @@
     display: flex;
     align-items: center;
     justify-content: space-between;
-    gap: 4px;
-    font-size: 14px;
-    line-height: 17px;
-    color: #666;
+    gap: 6px;
+    min-height: 24px;
+    padding: 2px 6px;
+    box-sizing: border-box;
+    border: 1px solid #f1d7b1;
+    border-radius: 4px;
+    background: #fff8ed;
+    color: #7a4b12;
+    font-size: 13px;
+    line-height: 18px;
     white-space: nowrap;
     overflow: hidden;
+    box-shadow: 0 1px 3px rgba(143, 91, 23, 0.08);
+    transition: all 0.18s ease;
+  }
+
+  .calendar-day-entry:hover {
+    border-color: #edbd77;
+    background: #fff3dc;
+    box-shadow: 0 3px 8px rgba(143, 91, 23, 0.13);
   }
 
   .calendar-day-entry + .calendar-day-entry {
-    margin-top: 1px;
+    margin-top: 4px;
   }
 
   .calendar-day-entry__code {
     flex: 1;
     min-width: 0;
-    color: #a86a19;
+    color: #a4610b;
+    font-weight: 600;
     overflow: hidden;
     text-overflow: ellipsis;
   }
 
   .calendar-day-entry__qty {
     flex-shrink: 0;
-    color: #555;
+    min-width: 20px;
+    padding-left: 6px;
+    border-left: 1px solid #f0d2a2;
+    color: #8a5b20;
+    font-weight: 600;
+    text-align: right;
   }
 </style>

+ 20 - 0
src/views/productionPlan/components/gantt/components/ResourcePanel.vue

@@ -166,9 +166,15 @@
       color: #364152;
     }
 
+    :deep(.el-input__inner:focus) {
+      border-color: #1f8ceb;
+      box-shadow: 0 0 0 2px rgba(31, 140, 235, 0.08);
+    }
+
     :deep(.el-button) {
       margin-left: 0;
       border-radius: 4px;
+      font-weight: 600;
     }
   }
 
@@ -179,6 +185,20 @@
     background: #fff;
   }
 
+  .resource-list::-webkit-scrollbar {
+    width: 8px;
+  }
+
+  .resource-list::-webkit-scrollbar-thumb {
+    border: 2px solid #fff;
+    border-radius: 999px;
+    background: #c9d4e2;
+  }
+
+  .resource-list::-webkit-scrollbar-thumb:hover {
+    background: #aeb9c8;
+  }
+
   .resource-item,
   .resource-empty {
     min-height: 34px;

+ 12 - 1
src/views/productionPlan/components/gantt/project-gantt.vue

@@ -1451,10 +1451,17 @@
   .view-switch ::v-deep .el-button {
     border-radius: 4px;
     font-weight: 600;
+    transition: all 0.18s ease;
+  }
+  .view-switch ::v-deep .el-button:not(.el-button--primary):hover {
+    color: #1683d8;
+    border-color: #bfdcf5;
+    background: #f4f9ff;
   }
   .view-switch ::v-deep .el-button--primary {
     border-color: #1f8ceb;
     background: #1f8ceb;
+    box-shadow: 0 3px 8px rgba(31, 140, 235, 0.22);
   }
   .calendar-view {
     flex: 1;
@@ -1654,6 +1661,9 @@
   :deep(.gantt_task_bg .gantt_task_row:nth-child(odd)) {
     background: #fcfdff;
   }
+  :deep(.gantt_task_bg .gantt_task_row:hover) {
+    background: #f7fbff;
+  }
   :deep(.task-222) {
     height: 28px !important;
     line-height: 28px !important;
@@ -1663,6 +1673,7 @@
     filter: saturate(0.88) brightness(0.99);
     overflow: hidden;
     transition: box-shadow 0.18s ease, filter 0.18s ease;
+    backdrop-filter: saturate(1.05);
   }
   :deep(.task-222:hover) {
     filter: saturate(0.94) brightness(1);
@@ -1702,7 +1713,7 @@
     box-sizing: border-box;
     color: #fff;
     font-size: 12px;
-    font-weight: 500;
+    font-weight: 600;
     line-height: 28px;
     white-space: nowrap;
     text-overflow: ellipsis;

+ 37 - 0
src/views/productionPlan/components/newFactoryProductionScheduling.vue

@@ -2524,14 +2524,51 @@
   }
 
   .form-wrapper ::v-deep .el-link {
+    display: inline-flex;
+    align-items: center;
+    justify-content: center;
+    min-width: 42px;
+    height: 24px;
+    padding: 0 8px;
+    border-radius: 999px;
+    background: #eef7ff;
     color: #1683d8;
     font-weight: 600;
+    line-height: 24px;
+    transition: all 0.18s ease;
+  }
+
+  .form-wrapper ::v-deep .el-link:hover {
+    background: #dff0ff;
+    color: #0f75bd;
   }
 
   .form-wrapper ::v-deep .el-checkbox__inner {
     border-color: #d8e1eb;
   }
 
+  .form-wrapper ::v-deep .el-table__body-wrapper::-webkit-scrollbar,
+  .form-wrapper ::v-deep .el-table__fixed-body-wrapper::-webkit-scrollbar {
+    width: 8px;
+    height: 8px;
+  }
+
+  .form-wrapper ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb,
+  .form-wrapper
+    ::v-deep
+    .el-table__fixed-body-wrapper::-webkit-scrollbar-thumb {
+    border: 2px solid #fff;
+    border-radius: 999px;
+    background: #c9d4e2;
+  }
+
+  .form-wrapper ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover,
+  .form-wrapper
+    ::v-deep
+    .el-table__fixed-body-wrapper::-webkit-scrollbar-thumb:hover {
+    background: #aeb9c8;
+  }
+
   .form-wrapper.is-plan-scheduling ::v-deep .ele-pro-table {
     display: flex;
     flex-direction: column;

+ 193 - 6
src/views/productionPlan/components/newFactoryProductionScheduling/TaskConfigPanel.vue

@@ -94,15 +94,41 @@
           </div>
           <div class="dispatch-toolbar-icons">
             <el-tooltip content="刷新" placement="top">
-              <el-button square size="mini">
+              <el-button
+                square
+                size="mini"
+                :loading="dispatchRefreshLoading"
+                @click="handleDispatchRefresh"
+              >
                 <i class="el-icon-refresh"></i>
               </el-button>
             </el-tooltip>
-            <el-tooltip content="列设置" placement="top">
-              <el-button square size="mini">
+            <el-popover
+              placement="bottom-end"
+              width="220"
+              trigger="click"
+              popper-class="dispatch-column-popover"
+            >
+              <div class="dispatch-column-settings">
+                <div class="dispatch-column-settings__title">列设置</div>
+                <el-checkbox-group
+                  v-model="dispatchVisibleColumns"
+                  class="dispatch-column-settings__list"
+                  @change="handleDispatchColumnVisibleChange"
+                >
+                  <el-checkbox
+                    v-for="column in dispatchColumnOptions"
+                    :key="column.key"
+                    :label="column.key"
+                  >
+                    {{ column.label }}
+                  </el-checkbox>
+                </el-checkbox-group>
+              </div>
+              <el-button slot="reference" square size="mini">
                 <i class="el-icon-s-operation"></i>
               </el-button>
-            </el-tooltip>
+            </el-popover>
             <el-tooltip
               :content="dotLineFullscreen ? '退出全屏' : '全屏展示'"
               placement="top"
@@ -122,6 +148,7 @@
 
         <div class="dispatch-table-wrap">
           <el-table
+            ref="dispatchTable"
             :data="pagedDispatchObjectRows"
             border
             size="small"
@@ -153,6 +180,7 @@
               </template>
             </el-table-column>
             <el-table-column
+              v-if="isDispatchColumnVisible('displayName')"
               prop="displayName"
               label="工位名称"
               align="center"
@@ -160,6 +188,7 @@
               show-overflow-tooltip
             />
             <el-table-column
+              v-if="isDispatchColumnVisible('code')"
               prop="code"
               label="编码"
               align="center"
@@ -167,6 +196,7 @@
               show-overflow-tooltip
             />
             <el-table-column
+              v-if="isDispatchColumnVisible('assetCode')"
               prop="assetCode"
               label="设备编码"
               align="center"
@@ -174,6 +204,7 @@
               show-overflow-tooltip
             />
             <el-table-column
+              v-if="isDispatchColumnVisible('assetName')"
               prop="assetName"
               label="设备名称"
               align="center"
@@ -181,6 +212,7 @@
               show-overflow-tooltip
             />
             <el-table-column
+              v-if="isDispatchColumnVisible('assetModelType')"
               prop="assetModelType"
               label="设备型号"
               align="center"
@@ -188,6 +220,7 @@
               show-overflow-tooltip
             />
             <el-table-column
+              v-if="isDispatchColumnVisible('assetCategoryLevelPath')"
               prop="assetCategoryLevelPath"
               label="设备类型"
               align="center"
@@ -195,6 +228,7 @@
               show-overflow-tooltip
             />
             <el-table-column
+              v-if="isDispatchColumnVisible('status')"
               prop="status"
               label="状态"
               align="center"
@@ -204,7 +238,12 @@
                 {{ getDispatchStatusText(row.status) }}
               </template>
             </el-table-column>
-            <el-table-column label="数量" align="center" width="140">
+            <el-table-column
+              v-if="isDispatchColumnVisible('quantity')"
+              label="数量"
+              align="center"
+              width="140"
+            >
               <template slot-scope="{ row }">
                 <el-input
                   :value="row.quantity"
@@ -216,6 +255,7 @@
               </template>
             </el-table-column>
             <el-table-column
+              v-if="isDispatchColumnVisible('startTime')"
               label="计划开始时间"
               align="center"
               min-width="220"
@@ -234,6 +274,7 @@
               </template>
             </el-table-column>
             <el-table-column
+              v-if="isDispatchColumnVisible('endTime')"
               label="计划完成时间"
               align="center"
               min-width="220"
@@ -262,7 +303,12 @@
                 </div>
               </template>
             </el-table-column>
-            <el-table-column label="操作" width="88" align="center">
+            <el-table-column
+              v-if="isDispatchColumnVisible('action')"
+              label="操作"
+              width="88"
+              align="center"
+            >
               <template slot-scope="{ row }">
                 <el-popconfirm
                   v-if="canResetDispatchRow(row)"
@@ -626,11 +672,55 @@
         dispatchRowDraftMap: {},
         dispatchAssignmentMap: {},
         dispatchToolbarLoading: false,
+        dispatchRefreshLoading: false,
         dispatchReportType: 1,
+        dispatchColumnOptions: [
+          { key: 'displayName', label: '工位名称' },
+          { key: 'code', label: '编码' },
+          { key: 'assetCode', label: '设备编码' },
+          { key: 'assetName', label: '设备名称' },
+          { key: 'assetModelType', label: '设备型号' },
+          { key: 'assetCategoryLevelPath', label: '设备类型' },
+          { key: 'status', label: '状态' },
+          { key: 'quantity', label: '数量' },
+          { key: 'startTime', label: '计划开始时间' },
+          { key: 'endTime', label: '计划完成时间' },
+          { key: 'action', label: '操作' }
+        ],
+        dispatchColumnVisible: {
+          displayName: true,
+          code: true,
+          assetCode: true,
+          assetName: true,
+          assetModelType: true,
+          assetCategoryLevelPath: true,
+          status: true,
+          quantity: true,
+          startTime: true,
+          endTime: true,
+          action: true
+        },
         suppressTaskListAssignReloadUntil: 0
       };
     },
     computed: {
+      dispatchVisibleColumns: {
+        get() {
+          return this.dispatchColumnOptions
+            .filter((item) => this.dispatchColumnVisible[item.key] !== false)
+            .map((item) => item.key);
+        },
+        set(keys) {
+          const visibleKeys = new Set(keys);
+          this.dispatchColumnOptions.forEach((item) => {
+            this.$set(
+              this.dispatchColumnVisible,
+              item.key,
+              visibleKeys.has(item.key)
+            );
+          });
+        }
+      },
       dispatchTaskTabs() {
         const groupMap = new Map();
         (this.taskList || []).forEach((item) => {
@@ -844,6 +934,18 @@
           this.currentPlan?.workOrderSingleReport;
         return this.normalizeDispatchReportType(value);
       },
+      isDispatchColumnVisible(key) {
+        return this.dispatchColumnVisible[key] !== false;
+      },
+      handleDispatchColumnVisibleChange(keys) {
+        if (!keys.length) {
+          this.dispatchVisibleColumns = ['displayName'];
+          this.$message.warning('至少保留一列');
+        }
+        this.$nextTick(() => {
+          this.$refs.dispatchTable?.doLayout?.();
+        });
+      },
       parseDispatchQuantity(value) {
         if (value === null || value === undefined || value === '') {
           return null;
@@ -1256,6 +1358,20 @@
           this.$message.warning(e.message || '获取派单数据失败');
         }
       },
+      async handleDispatchRefresh() {
+        if (this.dispatchRefreshLoading) {
+          return;
+        }
+        this.dispatchRefreshLoading = true;
+        try {
+          await this.loadDispatchAssignData();
+          this.$nextTick(() => {
+            this.$refs.dispatchTable?.doLayout?.();
+          });
+        } finally {
+          this.dispatchRefreshLoading = false;
+        }
+      },
       isEmptyDispatchQuantity(value) {
         if (value === null || value === undefined || value === '') {
           return true;
@@ -2063,6 +2179,12 @@
       font-weight: 500;
       color: #909399;
       text-align: center;
+      transition: all 0.18s ease;
+    }
+
+    .el-tabs__item:not(.is-active):hover {
+      color: #1683d8;
+      background: #f4f9ff;
     }
 
     .el-tabs__item.is-active {
@@ -2131,6 +2253,13 @@
   .dispatch-toolbar ::v-deep .el-button {
     border-radius: 4px;
     font-weight: 600;
+    transition: all 0.18s ease;
+  }
+
+  .dispatch-toolbar ::v-deep .el-button:not(.el-button--primary):hover {
+    color: #1683d8;
+    border-color: #bfdcf5;
+    background: #f4f9ff;
   }
 
   .dispatch-toolbar-left ::v-deep .el-button--primary {
@@ -2342,6 +2471,21 @@
       background: #eef7ff;
     }
 
+    .el-table__body-wrapper::-webkit-scrollbar {
+      width: 8px;
+      height: 8px;
+    }
+
+    .el-table__body-wrapper::-webkit-scrollbar-thumb {
+      border: 2px solid #fff;
+      border-radius: 999px;
+      background: #c9d4e2;
+    }
+
+    .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
+      background: #aeb9c8;
+    }
+
     .el-table td,
     .el-table th {
       padding-top: 6px;
@@ -2355,6 +2499,16 @@
     .el-table__fixed-right {
       box-shadow: -4px 0 8px rgba(0, 0, 0, 0.04);
     }
+
+    .config-table-control .el-input__inner {
+      border-color: #e1e8f0;
+      background: #fbfdff;
+    }
+
+    .config-table-control .el-input__inner:focus {
+      border-color: #1f8ceb;
+      box-shadow: 0 0 0 2px rgba(31, 140, 235, 0.08);
+    }
   }
 
   @media (max-width: 576px) {
@@ -2393,3 +2547,36 @@
     }
   }
 </style>
+
+<style lang="scss">
+  .dispatch-column-popover {
+    padding: 12px 14px;
+    border: 1px solid #e6edf5;
+    border-radius: 8px;
+    box-shadow: 0 8px 24px rgba(31, 45, 61, 0.12);
+
+    .dispatch-column-settings__title {
+      margin-bottom: 10px;
+      color: #263445;
+      font-size: 14px;
+      font-weight: 600;
+    }
+
+    .dispatch-column-settings__list {
+      display: grid;
+      grid-template-columns: repeat(2, minmax(0, 1fr));
+      gap: 8px 10px;
+    }
+
+    .el-checkbox {
+      margin-right: 0;
+      color: #4b5563;
+      line-height: 22px;
+    }
+
+    .el-checkbox__label {
+      padding-left: 6px;
+      font-size: 13px;
+    }
+  }
+</style>