فهرست منبع

修改样式的bug

695593266@qq.com 2 ماه پیش
والد
کامیت
3f81b9db97

+ 87 - 10
src/views/productionPlan/components/detail/planDotLineDetail.vue

@@ -1,5 +1,20 @@
 <template>
   <div v-loading="loading" class="pane-box plan-dot-line-detail">
+    <div class="plan-time-bar">
+      <span class="plan-time-item">
+        <span class="plan-time-label">计划开始时间:</span>
+        <span class="plan-time-value">{{ planStartDisplay }}</span>
+      </span>
+      <span class="plan-time-item">
+        <span class="plan-time-label">计划结束时间:</span>
+        <span class="plan-time-value">{{ planEndDisplay }}</span>
+      </span>
+
+      <span class="plan-time-item">
+        <span class="plan-time-label">计划数量:</span>
+        <span class="plan-time-value">{{ planNumDisplay }}</span>
+      </span>
+    </div>
     <div class="plan-dot-line">
       <div class="top-route">
         <div class="panel-title">工艺路线</div>
@@ -43,7 +58,7 @@
               label="序号"
               width="60"
               align="center"
-              class-name="process-name-cell"
+              class-name="config-index-cell"
               label-class-name="config-execution-team-header"
             />
             <el-table-column
@@ -110,6 +125,18 @@
   /** 与 planDotLine.vue 一致:0 自制、1 请托、2 委外 */
   const EXEC_TYPE = Object.freeze({ HOMEMADE: 0, ENTRUST: 1, OUTSOURCE: 2 });
 
+  function formatDateTime(val) {
+    if (val == null || val === '') return '';
+    const str = String(val).trim();
+    if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(str)) return str;
+    const d = new Date(val);
+    if (Number.isNaN(d.getTime())) return '';
+    const p = (n) => String(n).padStart(2, '0');
+    return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(
+      d.getHours()
+    )}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
+  }
+
   export default {
     name: 'PlanDotLineDetail',
     props: {
@@ -117,6 +144,10 @@
       planId: {
         type: [Number, String],
         default: null
+      },
+      infoData: {
+        type: Object,
+        default: () => {}
       }
     },
     data() {
@@ -139,6 +170,20 @@
         if (!list.length) return -1;
         const a = this.routeStepsActive;
         return a >= list.length ? list.length - 1 : a;
+      },
+      planStartDisplay() {
+        const t = this.infoData?.productionPlan?.startTime;
+        return t ? formatDateTime(t) || String(t) : '—';
+      },
+      planEndDisplay() {
+        const t = this.infoData?.productionPlan?.endTime;
+        return t ? formatDateTime(t) || String(t) : '—';
+      },
+      planNumDisplay() {
+        const t =
+          this.infoData?.productionPlan?.productNum +
+          this.infoData?.productionPlan?.measuringUnit;
+        return t ? t : '—';
       }
     },
     watch: {
@@ -268,6 +313,35 @@
     box-sizing: content-box;
   }
 
+  .plan-time-bar {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+    gap: 12px 28px;
+    margin-bottom: 12px;
+    padding: 10px 12px;
+    border: 1px solid #ebeef5;
+    border-radius: 4px;
+    background: #fafafa;
+    font-size: 14px;
+  }
+
+  .plan-time-item {
+    display: inline-flex;
+    align-items: baseline;
+    gap: 4px;
+  }
+
+  .plan-time-label {
+    color: #606266;
+    white-space: nowrap;
+  }
+
+  .plan-time-value {
+    color: #303133;
+    font-weight: 500;
+  }
+
   .plan-dot-line-detail .route-steps ::v-deep {
     .el-steps {
       display: flex;
@@ -287,30 +361,30 @@
       word-break: break-all;
     }
     .el-step.active .el-step__title {
-      color: #409eff;
+      color: #157a2c;
       font-weight: 600;
     }
     .el-step__line {
       top: 14px;
     }
     .el-step__head.is-success {
-      color: #0c7741;
-      border-color: #0c7741;
+      color: #157a2c;
+      border-color: #157a2c;
     }
     .el-step__head.is-success .el-step__line {
-      background-color: #0c7741;
+      background-color: #157a2c;
     }
     .el-step__head.is-success .el-step__icon {
-      color: #0c7741;
-      border-color: #0c7741;
+      color: #157a2c;
+      border-color: #157a2c;
     }
     .el-step__head.is-success .el-step__line-inner {
-      background-color: #0c7741;
-      border-color: #0c7741;
+      background-color: #157a2c;
+      border-color: #157a2c;
     }
     .el-step__title.is-success,
     .el-step__description.is-success {
-      color: #0c7741;
+      color: #157a2c;
     }
     .el-step__icon {
       width: 30px;
@@ -349,6 +423,9 @@
       font-weight: 500;
       line-height: 1.4;
     }
+    td.config-index-cell > .cell {
+      font-size: 14px;
+    }
     .el-table__body .cell {
       padding-left: 6px;
       padding-right: 6px;

+ 151 - 71
src/views/productionPlan/components/planDotLine.vue

@@ -24,6 +24,11 @@
           <span class="plan-time-label">计划结束时间:</span>
           <span class="plan-time-value">{{ planEndDisplay }}</span>
         </span>
+
+        <span class="plan-time-item">
+          <span class="plan-time-label">计划数量:</span>
+          <span class="plan-time-value">{{ planNumDisplay }}</span>
+        </span>
       </div>
       <div class="top-route">
         <div class="panel-title">工艺路线</div>
@@ -71,6 +76,7 @@
               label="序号"
               width="60"
               align="center"
+              class-name="config-table-index-col"
             />
             <el-table-column
               label="工序名称"
@@ -90,6 +96,7 @@
                 <el-select
                   v-model="row.executionType"
                   placeholder="执行模式"
+                  clearable
                   class="config-table-control"
                   @change="onExecutionTypeChange(row)"
                 >
@@ -137,12 +144,19 @@
                   />
                 </el-select>
                 <el-select
-                  v-else
+                  v-else-if="execTypeNum(row) === EXEC_TYPE.OUTSOURCE"
                   :value="''"
                   placeholder="委外无需选择"
                   disabled
                   class="config-table-control"
                 />
+                <el-select
+                  v-else
+                  :value="''"
+                  placeholder="请先选择执行模式"
+                  disabled
+                  class="config-table-control"
+                />
               </template>
             </el-table-column>
             <el-table-column
@@ -156,6 +170,7 @@
                   type="datetime"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="执行开始时间"
+                  clearable
                   class="config-table-control"
                   @change="handleTimeChange(row, 'executionStartTime')"
                 />
@@ -166,10 +181,11 @@
               min-width="168"
               align="center"
             >
-              <template slot-scope="{ row, $index }">
+              <template slot-scope="{ row }">
                 <div
                   :class="{
-                    'last-end-over-plan-wrap': isLastRowEndAfterPlanEnd($index)
+                    'last-end-over-plan-wrap': isExecutionEndOverPlanEnd(row),
+                    'end-over-delivery-wrap': isExecutionEndOverDelivery(row)
                   }"
                 >
                   <el-date-picker
@@ -177,6 +193,7 @@
                     type="datetime"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="执行结束时间"
+                    clearable
                     class="config-table-control"
                     @change="handleTimeChange(row, 'executionEndTime')"
                   />
@@ -299,6 +316,11 @@
         const t = this.currentPlan?.endTime;
         return t ? formatDateTime(t) || String(t) : '—';
       },
+      planNumDisplay() {
+        const t =
+          this.currentPlan?.productNum + this.currentPlan?.measuringUnit;
+        return t ? t : '—';
+      },
       /** 最后一道工序执行结束时间是否晚于计划结束时间 */
       lastProcessEndAfterPlanEnd() {
         const list = this.taskList;
@@ -439,25 +461,19 @@
           executionStartTime: formatDateTime(item.executionStartTime),
           executionEndTime: formatDateTime(item.executionEndTime),
           executionType: execType,
-          executionFactoryId:
-            entrust
-              ? item.executionFactoryId ?? item.executionTeamId ?? ''
-              : '',
-          executionFactoryName:
-            entrust
-              ? item.executionFactoryName ??
-                item.executionTeamName ??
-                ''
-              : '',
+          executionFactoryId: entrust
+            ? item.executionFactoryId ?? item.executionTeamId ?? ''
+            : '',
+          executionFactoryName: entrust
+            ? item.executionFactoryName ?? item.executionTeamName ?? ''
+            : '',
           executionTeamId: homemade ? item.executionTeamId ?? '' : '',
           executionTeamLeader:
             outsource || entrust ? '' : item.executionTeamLeader ?? '',
           executionTeamLeaderId:
             outsource || entrust ? '' : item.executionTeamLeaderId ?? '',
           executionTeamName:
-            outsource || entrust
-              ? ''
-              : item.executionTeamName ?? ''
+            outsource || entrust ? '' : item.executionTeamName ?? ''
         };
       },
 
@@ -491,7 +507,7 @@
       },
 
       execTypeNum(row) {
-        return toSafeNumber(row.executionType) ?? EXEC_TYPE.HOMEMADE;
+        return toSafeNumber(row.executionType);
       },
 
       clearExecutionTeamFields(row) {
@@ -574,37 +590,56 @@
           return;
         }
         const deadline = this.currentPlan?.planDeliveryTime;
-        if (deadline && row[changeKey]) {
+        if (
+          changeKey === 'executionStartTime' &&
+          deadline &&
+          row.executionStartTime
+        ) {
           const d = new Date(deadline).getTime();
-          const v = new Date(row[changeKey]).getTime();
+          const v = new Date(row.executionStartTime).getTime();
           if (!Number.isNaN(d) && !Number.isNaN(v) && v > d) {
             this.$message.warning('时间不能大于计划交付时间');
             this.$set(row, changeKey, '');
             return;
           }
         }
-        const planEnd = this.currentPlan?.endTime;
-        if (
-          changeKey === 'executionEndTime' &&
-          planEnd &&
-          row.executionEndTime &&
-          isEndAfterPlanEnd(row.executionEndTime, planEnd)
-        ) {
-          this.$message.warning('执行结束时间不能超过计划结束时间');
-          this.$set(row, 'executionEndTime', '');
-          return;
+        if (changeKey === 'executionEndTime' && row.executionEndTime) {
+          const planEnd = this.currentPlan?.endTime;
+          const overDelivery =
+            !!deadline && isEndAfterPlanEnd(row.executionEndTime, deadline);
+          const overPlanEnd =
+            !!planEnd && isEndAfterPlanEnd(row.executionEndTime, planEnd);
+          if (overDelivery && overPlanEnd) {
+            this.$message.warning(
+              '执行结束时间晚于计划交付时间及计划结束时间,已保留填写内容,请留意核对'
+            );
+          } else if (overDelivery) {
+            this.$message.warning(
+              '执行结束时间晚于计划交付时间,已保留填写内容,请留意核对'
+            );
+          } else if (overPlanEnd) {
+            this.$message.warning(
+              '执行结束时间晚于计划结束时间,已保留填写内容,请留意核对'
+            );
+          }
         }
       },
 
-      /** 最后一行「执行结束时间」单元格是否标红(晚于计划结束时间) */
-      isLastRowEndAfterPlanEnd(index) {
-        const list = this.taskList;
+      /** 执行结束时间晚于计划交付时间(选择框标红,可保存) */
+      isExecutionEndOverDelivery(row) {
+        const deadline = this.currentPlan?.planDeliveryTime;
+        return (
+          !!deadline &&
+          !!row?.executionEndTime &&
+          isEndAfterPlanEnd(row.executionEndTime, deadline)
+        );
+      },
+
+      /** 执行结束时间晚于计划结束时间(任意工序行标红,可保存) */
+      isExecutionEndOverPlanEnd(row) {
         const planEnd = this.currentPlan?.endTime;
-        if (!list.length || index !== list.length - 1 || !planEnd) {
-          return false;
-        }
-        const row = list[index];
         return (
+          !!planEnd &&
           !!row?.executionEndTime &&
           isEndAfterPlanEnd(row.executionEndTime, planEnd)
         );
@@ -667,22 +702,11 @@
             );
             return false;
           }
-          const planEnd = this.currentPlan?.endTime;
-          if (
-            planEnd &&
-            item.executionEndTime &&
-            isEndAfterPlanEnd(item.executionEndTime, planEnd)
-          ) {
-            this.$message.warning(
-              `${label(item)}执行结束时间不能超过计划结束时间`
-            );
-            return false;
-          }
 
           const deadline = this.currentPlan?.planDeliveryTime;
           if (deadline) {
             const d = new Date(deadline).getTime();
-            const checkTime = (val, name) => {
+            const checkStart = (val, name) => {
               if (!val) return true;
               const t = new Date(val).getTime();
               return Number.isNaN(d) || Number.isNaN(t) || t <= d
@@ -692,9 +716,8 @@
                   ),
                   false);
             };
-            if (!checkTime(item.executionStartTime, '执行开始时间'))
+            if (!checkStart(item.executionStartTime, '执行开始时间'))
               return false;
-            if (!checkTime(item.executionEndTime, '执行结束时间')) return false;
           }
         }
         return true;
@@ -855,16 +878,19 @@
     font-weight: 500;
   }
 
-  .last-end-over-plan-wrap {
+  .last-end-over-plan-wrap,
+  .end-over-delivery-wrap {
     width: 100%;
   }
 
-  .last-end-over-plan-wrap ::v-deep .el-input__inner {
+  .last-end-over-plan-wrap ::v-deep .el-input__inner,
+  .end-over-delivery-wrap ::v-deep .el-input__inner {
     color: #f56c6c;
     border-color: #f56c6c;
   }
 
-  .last-end-over-plan-wrap ::v-deep .el-input__inner:focus {
+  .last-end-over-plan-wrap ::v-deep .el-input__inner:focus,
+  .end-over-delivery-wrap ::v-deep .el-input__inner:focus {
     border-color: #f56c6c;
   }
 
@@ -917,8 +943,10 @@
       white-space: normal;
       word-break: break-all;
     }
-    .el-step.active .el-step__title {
-      color: #409eff;
+    .el-step__title:not(.is-error) {
+      color: #157a2c;
+    }
+    .el-step.active .el-step__title:not(.is-error) {
       font-weight: 600;
     }
     .el-step__line {
@@ -926,19 +954,39 @@
     }
     /* 已完成步骤 success 色(默认绿)改为品牌绿 */
     .el-step__head.is-success {
-      color: #0c7741;
-      border-color: #0c7741;
+      color: #157a2c;
+      border-color: #157a2c;
     }
     .el-step__head.is-success .el-step__line {
-      background-color: #0c7741;
+      background-color: #157a2c;
     }
     .el-step__head.is-success .el-step__icon {
-      color: #0c7741;
-      border-color: #0c7741;
+      color: #157a2c;
+      border-color: #157a2c;
     }
     .el-step__head.is-success .el-step__line-inner {
-      background-color: #0c7741;
-      border-color: #0c7741;
+      background-color: #157a2c;
+      border-color: #157a2c;
+    }
+    /* 当前步骤 process:ele-admin 对 .is-text 使用主题色实心圆,需覆盖 background */
+    .el-step__head.is-process {
+      color: #157a2c;
+      border-color: #157a2c;
+    }
+    .el-step__head.is-process .el-step__icon {
+      color: #157a2c;
+      border-color: #157a2c;
+    }
+    .el-step__head.is-process .el-step__icon.is-text {
+      color: #fff;
+      border-color: #157a2c;
+      background: #157a2c;
+    }
+    .el-step__head.is-process .el-step__icon.is-text .el-step__icon-inner {
+      color: #fff;
+    }
+    .el-step__description.is-process {
+      color: #157a2c;
     }
     .el-step__icon {
       width: 30px;
@@ -966,6 +1014,10 @@
   }
 
   .config-table ::v-deep {
+    /* 序号列:column 上的 style 无效,需 class-name + td 内 .cell */
+    td.config-table-index-col .cell {
+      font-size: 14px !important;
+    }
     .el-table td > .cell {
       font-size: 14px;
       text-align: center;
@@ -976,9 +1028,12 @@
     }
     td.task-name-cell .task-name-text {
       font-size: 14px;
-      font-weight: 500;
       line-height: 1.4;
     }
+    /* 与工序名称一致:覆盖 el-select / date-editor 的 small 字号 */
+    .config-table-control .el-input__inner {
+      font-size: 14px;
+    }
     .config-table-control {
       width: 100% !important;
     }
@@ -996,7 +1051,6 @@
       th.el-table__cell
       > .cell {
       font-size: 15px !important;
-      font-weight: 600 !important;
       line-height: 1.4 !important;
     }
 
@@ -1006,19 +1060,45 @@
     }
 
     .route-steps .el-step__head.is-success {
-      color: #0c7741;
-      border-color: #0c7741;
+      color: #157a2c;
+      border-color: #157a2c;
     }
     .route-steps .el-step__head.is-success .el-step__line {
-      background-color: #0c7741;
+      background-color: #157a2c;
     }
     .route-steps .el-step__head.is-success .el-step__icon {
-      color: #0c7741;
-      border-color: #0c7741;
+      color: #157a2c;
+      border-color: #157a2c;
     }
     .route-steps .el-step__head.is-success .el-step__line-inner {
-      background-color: #0c7741;
-      border-color: #0c7741;
+      background-color: #157a2c;
+      border-color: #157a2c;
+    }
+
+    .route-steps .el-step__head.is-process {
+      color: #157a2c;
+      border-color: #157a2c;
+    }
+    .route-steps .el-step__head.is-process .el-step__icon {
+      color: #157a2c;
+      border-color: #157a2c;
+    }
+    .route-steps .el-step__head.is-process .el-step__icon.is-text {
+      color: #fff;
+      border-color: #157a2c;
+      background: #157a2c;
+    }
+    .route-steps
+      .el-step__head.is-process
+      .el-step__icon.is-text
+      .el-step__icon-inner {
+      color: #fff;
+    }
+    .route-steps .el-step__title:not(.is-error) {
+      color: #157a2c;
+    }
+    .route-steps .el-step__description.is-process {
+      color: #157a2c;
     }
   }
 </style>

+ 8 - 1
src/views/productionPlan/detail.vue

@@ -13,6 +13,7 @@
           <planDotLineDetail
             ref="planDotLineDetailRef"
             :plan-id="dotLinePlanId"
+            :infoData="infoData"
           />
         </el-tab-pane>
         <!-- <el-tab-pane label="物料信息表" name="material">
@@ -51,7 +52,13 @@
   import { getProductPlanDetail } from '@/api/productionPlan/index';
 
   export default {
-    components: { plan, material, productionDetail, bpmDetail, planDotLineDetail },
+    components: {
+      plan,
+      material,
+      productionDetail,
+      bpmDetail,
+      planDotLineDetail
+    },
     data() {
       return {
         activeName: 'plan',

+ 76 - 5
src/views/workOrder/components/details.vue

@@ -380,6 +380,21 @@
           v-if="hasDotLineDetail"
         >
           <div class="plan-dot-line">
+            <div class="plan-time-bar">
+              <span class="plan-time-item">
+                <span class="plan-time-label">计划开始时间:</span>
+                <span class="plan-time-value">{{ planStartDisplay }}</span>
+              </span>
+              <span class="plan-time-item">
+                <span class="plan-time-label">计划结束时间:</span>
+                <span class="plan-time-value">{{ planEndDisplay }}</span>
+              </span>
+
+              <span class="plan-time-item">
+                <span class="plan-time-label">计划数量:</span>
+                <span class="plan-time-value">{{ planNumDisplay }}</span>
+              </span>
+            </div>
             <div class="top-route">
               <div class="panel-title">工艺路线</div>
               <el-empty
@@ -422,7 +437,7 @@
                     label="序号"
                     width="60"
                     align="center"
-                    class-name="process-name-cell"
+                    class-name="config-index-cell"
                     label-class-name="config-execution-team-header"
                   />
                   <el-table-column
@@ -502,6 +517,18 @@
     ENTRUST: 1,
     OUTSOURCE: 2
   });
+
+  function formatDateTime(val) {
+    if (val == null || val === '') return '';
+    const str = String(val).trim();
+    if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(str)) return str;
+    const d = new Date(val);
+    if (Number.isNaN(d.getTime())) return '';
+    const p = (n) => String(n).padStart(2, '0');
+    return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(
+      d.getHours()
+    )}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
+  }
   export default {
     components: {},
     props: {
@@ -757,6 +784,18 @@
             slot: 'action'
           }
         ];
+      },
+      planStartDisplay() {
+        const t = this.current?.planStartTime;
+        return t ? formatDateTime(t) || String(t) : '—';
+      },
+      planEndDisplay() {
+        const t = this.current?.planCompleteTime;
+        return t ? formatDateTime(t) || String(t) : '—';
+      },
+      planNumDisplay() {
+        const t = this.current?.formingNum + this.current?.measuringUnit;
+        return t ? t : '—';
       }
     },
     watch: {},
@@ -919,6 +958,35 @@
     min-height: 360px;
   }
 
+  .plan-time-bar {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+    gap: 12px 28px;
+    margin-bottom: 12px;
+    padding: 10px 12px;
+    border: 1px solid #ebeef5;
+    border-radius: 4px;
+    background: #fafafa;
+    font-size: 14px;
+  }
+
+  .plan-time-item {
+    display: inline-flex;
+    align-items: baseline;
+    gap: 4px;
+  }
+
+  .plan-time-label {
+    color: #606266;
+    white-space: nowrap;
+  }
+
+  .plan-time-value {
+    color: #303133;
+    font-weight: 500;
+  }
+
   .top-route,
   .config-panel {
     border: 1px solid #ebeef5;
@@ -968,16 +1036,16 @@
       word-break: break-all;
     }
     .el-step.active .el-step__title {
-      color: #409eff;
+      color: #157a2c;
       font-weight: 600;
     }
     .el-step__head.is-success {
-      color: #0c7741;
-      border-color: #0c7741;
+      color: #157a2c;
+      border-color: #157a2c;
     }
     .el-step__title.is-success,
     .el-step__description.is-success {
-      color: #0c7741;
+      color: #157a2c;
     }
     .el-step__line {
       top: 14px;
@@ -1019,6 +1087,9 @@
       font-weight: 500;
       line-height: 1.4;
     }
+    td.config-index-cell > .cell {
+      font-size: 14px;
+    }
     .el-table__body .cell {
       padding-left: 6px;
       padding-right: 6px;

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

@@ -184,7 +184,7 @@
             :underline="false"
             @click="productionPreparations(row)"
           >
-            生产准备
+            生产准备
           </el-link>
           <el-popconfirm
             class="ele-action"