From a387709376961b134da6fb35975663947519e5b2 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 19 八月 2026 17:42:04 +0800
Subject: [PATCH] 天津-阳光彩印 1.公出管理列表详情页「申请部门」当前只展示部门 ID,需替换为部门名称展示 2.同一机台排产多人、多班组生产时,报工支持拆分录入多人产量、分开记录各班组生产时长,生产核算自动汇总全部工时 3.生产工单列表删除「计划开始、计划结束」字段,移除进度条组件,简化页面展示 4.销售台账新增产品弹窗内含税单价小数位数调整为 5 位,匹配合同精准计价需求,避免金额尾差

---
 src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue |   13 ----
 src/api/productionManagement/workOrder.js                                  |    9 +++
 src/views/productionManagement/workOrder/index.vue                         |   91 +++++++++++++++++++++--------
 src/views/safeProduction/safeWorkApproval/index.vue                        |    7 ++
 src/views/productionManagement/productionCosting/index.vue                 |   13 ++++
 src/views/collaborativeApproval/approvalProcess/index.vue                  |    7 ++
 src/views/salesManagement/salesLedger/index.vue                            |   14 +++-
 7 files changed, 109 insertions(+), 45 deletions(-)

diff --git a/src/api/productionManagement/workOrder.js b/src/api/productionManagement/workOrder.js
index 84d344f..c5ea5bd 100644
--- a/src/api/productionManagement/workOrder.js
+++ b/src/api/productionManagement/workOrder.js
@@ -24,6 +24,15 @@
   });
 }
 
+// 鎶ュ伐寮圭獥鏁版嵁鏌ヨ锛堣繑鍥為粯璁ょ彮缁勬垚鍛� reportPersons锛�
+export function getProductWorkOrderById(id) {
+  return request({
+    url: "/productWorkOrder/getProductWorkOrderById",
+    method: "get",
+    params: { id },
+  });
+}
+
 // 涓嬭浇宸ュ崟娴佽浆鍗★紙杩斿洖鏂囦欢娴侊級
 export function downProductWorkOrder(id) {
   return request({
diff --git a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
index 425c3b6..3ad3310 100644
--- a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
+++ b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
@@ -17,18 +17,7 @@
 				<el-row>
 					<el-col :span="24">
 						<el-form-item label="鐢宠閮ㄩ棬锛�">
-							<el-select
-								disabled
-								v-model="form.approveDeptId"
-								placeholder="閫夋嫨閮ㄩ棬"
-							>
-								<el-option
-									v-for="user in productOptions"
-									:key="user.deptId"
-									:label="user.deptName"
-									:value="user.deptId"
-								/>
-							</el-select>
+							<el-input v-model="form.approveDeptName" placeholder="鐢宠閮ㄩ棬" disabled />
 						</el-form-item>
 					</el-col>
 				</el-row>
diff --git a/src/views/collaborativeApproval/approvalProcess/index.vue b/src/views/collaborativeApproval/approvalProcess/index.vue
index a15b121..f7e5834 100644
--- a/src/views/collaborativeApproval/approvalProcess/index.vue
+++ b/src/views/collaborativeApproval/approvalProcess/index.vue
@@ -144,6 +144,11 @@
 const userStore = useUserStore();
 const route = useRoute();
 
+// 绠$悊鍛樿处鍙凤紙瑙掕壊涓� 鏅��2 / admin / 鏈�楂�1锛夊彲瀹℃壒浠绘剰娴佺▼锛屼笉鍙楀鎵逛汉闄愬埗
+const isAdminUser = computed(() =>
+  ["admin", "鏅��2", "鏈�楂�1"].some(r => (userStore.roles || []).includes(r))
+);
+
 // 褰撳墠閫変腑鐨勬爣绛鹃〉锛岄粯璁や负鍏嚭绠$悊
 const activeTab = ref('1');
 
@@ -390,7 +395,7 @@
     tableData.value = (res.data.records || []).map(r => ({
       ...r,
       currentApproverNames: r.approveUserCurrentNames || r.approveUserCurrentName || '-',
-      _canApprove: String(r.approveUserCurrentIds ?? '').split(',').filter(Boolean).includes(String(userStore.id)) || r.approveUserCurrentId === userStore.id
+      _canApprove: isAdminUser.value || String(r.approveUserCurrentIds ?? '').split(',').filter(Boolean).includes(String(userStore.id)) || r.approveUserCurrentId === userStore.id
     }));
     page.total = res.data.total;
     // 鏇存柊褰撳墠绫诲瀷鏁伴噺
diff --git a/src/views/productionManagement/productionCosting/index.vue b/src/views/productionManagement/productionCosting/index.vue
index c437e78..fc6d4f7 100644
--- a/src/views/productionManagement/productionCosting/index.vue
+++ b/src/views/productionManagement/productionCosting/index.vue
@@ -67,7 +67,11 @@
               :tableLoading="tableLoading1"
               style="margin-right: 20px;"
               @pagination="pagination1"
-          ></PIMTable>
+          >
+            <template #personWorkMinutes="{ row }">
+              {{ row.personWorkMinutes ?? row.workMinutes ?? '-' }}
+            </template>
+          </PIMTable>
 				</div>
 			</el-col>
 		</el-row>
@@ -173,6 +177,13 @@
     prop: "workMinutes",
     width: 110,
   },
+  {
+    label: "浜哄憳宸ユ椂(鍒嗛挓)",
+    prop: "personWorkMinutes",
+    width: 120,
+    dataType: "slot",
+    slot: "personWorkMinutes",
+  },
 ]);
 
 // 宸︿晶姹囨�诲彴璐﹀垪锛堢敓浜т汉銆佷骇閲忋�佸伐璧勩�佸悎鏍肩巼锛�
diff --git a/src/views/productionManagement/workOrder/index.vue b/src/views/productionManagement/workOrder/index.vue
index 9c62a41..82ff04f 100644
--- a/src/views/productionManagement/workOrder/index.vue
+++ b/src/views/productionManagement/workOrder/index.vue
@@ -24,13 +24,7 @@
                 :tableData="tableData"
                 :page="page"
                 :tableLoading="tableLoading"
-                @pagination="pagination">
-        <template #completionStatus="{ row }">
-          <el-progress :percentage="toProgressPercentage(row?.completionStatus)"
-                       :color="progressColor(toProgressPercentage(row?.completionStatus))"
-                       :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
-        </template>
-      </PIMTable>
+                @pagination="pagination" />
     </div>
     <el-dialog v-model="editDialogVisible"
                title="缂栬緫鏃堕棿"
@@ -289,6 +283,19 @@
           <!--          </el-col>-->
         </el-row>
       </el-form>
+      <el-table :data="personList" border style="margin-top: 12px;">
+        <el-table-column label="鐢熶骇浜�" prop="userName" min-width="100" align="center" />
+        <el-table-column label="浜ч噺" min-width="120" align="center">
+          <template #default="scope">
+            <el-input-number v-model="scope.row.quantity" :min="0" :controls="false" placeholder="浜ч噺" style="width: 100%" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鐢熶骇鏃堕暱(鍒嗛挓)" min-width="140" align="center">
+          <template #default="scope">
+            <el-input-number v-model="scope.row.workHour" :min="0" :controls="false" placeholder="鏃堕暱(鍒嗛挓)" style="width: 100%" />
+          </template>
+        </el-table-column>
+      </el-table>
       <template #footer>
         <span class="dialog-footer">
           <el-button type="primary"
@@ -490,6 +497,7 @@
     productWorkOrderPage,
     updateProductWorkOrder,
     addProductMain,
+    getProductWorkOrderById,
     downProductWorkOrder,
     addProductionMachineRecord,
     productionMachineRecordListPage,
@@ -1075,25 +1083,13 @@
       width: "140",
     },
     {
+      label: "鍔犳斁鏁�",
+      prop: "processRouteAddNum",
+      width: "100",
+    },
+    {
       label: "瀹屾垚鏁伴噺",
       prop: "completeQuantity",
-      width: "140",
-    },
-    {
-      label: "瀹屾垚杩涘害",
-      prop: "completionStatus",
-      dataType: "slot",
-      slot: "completionStatus",
-      width: "140",
-    },
-    {
-      label: "璁″垝寮�濮嬫椂闂�",
-      prop: "planStartTime",
-      width: "140",
-    },
-    {
-      label: "璁″垝缁撴潫鏃堕棿",
-      prop: "planEndTime",
       width: "140",
     },
     {
@@ -1218,6 +1214,8 @@
     teamList: [],
     deviceId: null,
   });
+  // 鐝粍浜哄憳浜ч噺鏃堕暱鏄庣粏 [{ userId, userName, quantity, workHour }]
+  const personList = ref([]);
   const teamSelectOptions = computed(() => {
     const base =
       Array.isArray(reportForm.userIdsList) && reportForm.userIdsList.length > 0
@@ -1545,7 +1543,7 @@
       });
   };
 
-  const showReportDialog = row => {
+  const showReportDialog = async row => {
     currentReportRowData.value = row;
     reportForm.planQuantity = row.planQuantity - row.completeQuantity;
     reportForm.quantity = row.planQuantity - row.completeQuantity;
@@ -1558,7 +1556,7 @@
     reportForm.replenishQty = 0;
     reportForm.teamList = [];
     reportForm.scrapQty = 0;
-    reportForm.addQty = 0;
+    reportForm.addQty = row.processRouteAddNum ? Number(row.processRouteAddNum) : 0;
     reportForm.userIds = row.userIds || [];
 
     // 鍚堝苟宸ュ崟鎶ュ伐浜哄拰宸ュ簭鎶ュ伐浜猴紝鍘婚噸
@@ -1577,6 +1575,34 @@
         userId: item.userId,
         nickName: item.nickName,
       }));
+
+    // 鑾峰彇鎶ュ伐寮圭獥鏁版嵁锛屽甫鍑洪粯璁ょ彮缁勬垚鍛橈紙鍚堝苟鎺掍骇浜哄憳涓庢満鍙版搷浣滃憳锛屽幓閲嶏級
+    personList.value = [];
+    try {
+      const res = await getProductWorkOrderById(row.id);
+      const reportPersons = (Array.isArray(res?.data?.reportPersons)
+        ? res.data.reportPersons
+        : []
+      )
+        .filter(p => p && typeof p === "object")
+        .map(p => ({
+          userId: p.userId ?? p.id ?? "",
+          userName: String(p.userName || p.nickName || "").trim(),
+        }))
+        .filter(p => p.userName !== "");
+      personList.value = reportPersons.map(p => ({
+        userId: p.userId,
+        userName: p.userName,
+        quantity: null,
+        workHour: null,
+      }));
+      reportForm.teamList = reportPersons.map(p => ({
+        userId: p.userId,
+        userName: p.userName,
+      }));
+    } catch (err) {
+      console.error("鑾峰彇鎶ュ伐寮圭獥鏁版嵁澶辫触", err);
+    }
 
     nextTick(() => {
       reportFormRef.value?.clearValidate();
@@ -1649,10 +1675,23 @@
       //   return;
       // }
 
+      // 鏍¢獙鍚勭彮缁勪骇閲忎箣鍜岀瓑浜庢姤宸ユ�讳骇閲�
+      const personQuantityTotal = personList.value.reduce(
+        (sum, p) => sum + (Number(p.quantity) || 0),
+        0
+      );
+      if (personQuantityTotal !== quantity) {
+        ElMessageBox.alert("鍚勭彮缁勪骇閲忎箣鍜屽繀椤荤瓑浜庢姤宸ユ�讳骇閲�", "鎻愮ず", {
+          confirmButtonText: "纭畾",
+        });
+        return;
+      }
+
       const submitData = {
         ...reportForm,
         quantity: quantity,
         scrapQty: scrapQty,
+        personList: personList.value,
       };
       addProductMain(submitData).then(res => {
         if (res.code === 200) {
diff --git a/src/views/safeProduction/safeWorkApproval/index.vue b/src/views/safeProduction/safeWorkApproval/index.vue
index 1d40ab3..1fdd4a9 100644
--- a/src/views/safeProduction/safeWorkApproval/index.vue
+++ b/src/views/safeProduction/safeWorkApproval/index.vue
@@ -85,6 +85,11 @@
   const userStore = useUserStore();
   const route = useRoute();
 
+  // 绠$悊鍛樿处鍙凤紙瑙掕壊涓� 鏅��2 / admin / 鏈�楂�1锛夊彲瀹℃壒浠绘剰娴佺▼锛屼笉鍙楀鎵逛汉闄愬埗
+  const isAdminUser = computed(() =>
+    ["admin", "鏅��2", "鏈�楂�1"].some(r => (userStore.roles || []).includes(r))
+  );
+
   // 褰撳墠瀹℃壒绫诲瀷锛屾牴鎹�変腑鐨勬爣绛鹃〉璁$畻
   const currentApproveType = computed(() => {
     return Number(8);
@@ -276,7 +281,7 @@
         tableData.value = (res.data.records || []).map(r => ({
           ...r,
           currentApproverNames: r.approveUserCurrentNames || r.approveUserCurrentName || '-',
-          _canApprove: String(r.approveUserCurrentIds ?? '').split(',').filter(Boolean).includes(String(userStore.id)) || r.approveUserCurrentId === userStore.id
+          _canApprove: isAdminUser.value || String(r.approveUserCurrentIds ?? '').split(',').filter(Boolean).includes(String(userStore.id)) || r.approveUserCurrentId === userStore.id
         }));
         page.total = res.data.total;
       })
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 1e5a0fe..7bb01c6 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -647,7 +647,7 @@
                                :min="0"
                                v-model="productForm.taxInclusiveUnitPrice"
                                style="width: 100%"
-                               :precision="4"
+                               :precision="5"
                                placeholder="璇疯緭鍏�"
                                clearable
                                @change="calculateFromQuantity" />
@@ -1179,6 +1179,12 @@
     if (Number.isNaN(num)) return "0.0000";
     return num.toFixed(4);
   };
+  const formatAmount5 = value => {
+    if (value === undefined || value === null || value === "") return "0.00000";
+    const num = Number(value);
+    if (Number.isNaN(num)) return "0.00000";
+    return num.toFixed(5);
+  };
   const findLedgerRecordByRow = row => {
     if (!row) return null;
     if (
@@ -1663,7 +1669,7 @@
           productForm.value.taxInclusiveUnitPrice !== null &&
           productForm.value.taxInclusiveUnitPrice !== ""
         ) {
-          productForm.value.taxInclusiveUnitPrice = formatAmount4(
+          productForm.value.taxInclusiveUnitPrice = formatAmount5(
             productForm.value.taxInclusiveUnitPrice
           );
         }
@@ -2298,7 +2304,7 @@
     productForm.value.taxInclusiveTotalPrice = totalPrice.toFixed(4);
 
     // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
-    productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(4);
+    productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(5);
 
     // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
     if (productForm.value.taxRate) {
@@ -2342,7 +2348,7 @@
     // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
     productForm.value.taxInclusiveUnitPrice = (
       inclusiveTotalPrice / quantity
-    ).toFixed(4);
+    ).toFixed(5);
 
     isCalculating.value = false;
   };

--
Gitblit v1.9.3