From 22229c67d87f0fae4c4bc90db106b8a1e2c49b53 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 20 八月 2026 15:50:11 +0800
Subject: [PATCH] feat(permission): 为多个模块添加管理员权限控制功能

---
 src/views/productionManagement/workOrder/index.vue |  111 ++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 80 insertions(+), 31 deletions(-)

diff --git a/src/views/productionManagement/workOrder/index.vue b/src/views/productionManagement/workOrder/index.vue
index 9c62a41..d8cc499 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,
@@ -500,8 +508,13 @@
   import { getCurrentInstance, reactive, toRefs } from "vue";
   import FilesDia from "./components/filesDia.vue";
   import { getDeviceLedger } from "@/api/equipmentManagement/ledger.js";
+  import useUserStore from "@/store/modules/user";
 
   const { proxy } = getCurrentInstance();
+  const userStore = useUserStore();
+  const isAdminUser = computed(() =>
+    ["admin", "鏅��2", "鏈�楂�1"].some(r => (userStore.roles || []).includes(r))
+  );
 
   const currentUserId = ref("");
   const deviceOptions = ref([]);
@@ -569,9 +582,13 @@
     return ids.includes(uid);
   };
 
-  // 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁鍙互鎶ュ伐锛堝伐鍗曟姤宸ヤ汉 鎴� 宸ュ簭鎶ュ伐浜猴級
+  // 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁鍙互鎶ュ伐锛堝伐鍗曟姤宸ヤ汉 鎴� 宸ュ簭鎶ュ伐浜猴紝绠$悊鍛樹笉鍙楅檺锛�
   const canCurrentUserReport = row => {
-    return isCurrentUserInUserIds(row) || isCurrentUserInProcessUserIds(row);
+    return (
+      isAdminUser.value ||
+      isCurrentUserInUserIds(row) ||
+      isCurrentUserInProcessUserIds(row)
+    );
   };
 
   const canOperateByReportWorker = computed(() => {
@@ -1075,25 +1092,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",
     },
     {
@@ -1136,11 +1141,10 @@
           clickFun: row => {
             showReportDialog(row);
           },
-          // 鐢ㄦ埛褰撳墠id鍦ㄥ伐鍗曟姤宸ヤ汉鎴栧伐搴忔姤宸ヤ汉涓�
+          // 鐢ㄦ埛褰撳墠id鍦ㄥ伐鍗曟姤宸ヤ汉鎴栧伐搴忔姤宸ヤ汉涓紝涓斿畬鎴愭暟閲忔湭杈捐鍒掓暟閲忔椂鍙户缁垎鎵规姤宸�
           disabled: row =>
             row.completeQuantity >= row.planQuantity ||
-            !canCurrentUserReport(row) ||
-            row.hasUnreportedMachine,
+            !canCurrentUserReport(row),
         },
         {
           name: "鐢熶骇鎺掍骇",
@@ -1218,6 +1222,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 +1551,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 +1564,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 +1583,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 +1683,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) {
@@ -1762,6 +1809,8 @@
 
   // 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁鑳芥帓浜�
   const canScheduleByWorkOrderNo = row => {
+    // 绠$悊鍛樺彲鎺掍骇
+    if (isAdminUser.value) return true;
     if (!row) return false;
 
     const uid = String(currentUserId.value || "");

--
Gitblit v1.9.3