From 9696cd7b0754672889dcab70cb5a30fab69d326a Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期三, 03 六月 2026 15:02:53 +0800
Subject: [PATCH] 生产报工班组信息可支持手动输入,若系统中无对应人员,也能输入

---
 src/views/productionManagement/workOrder/index.vue | 2978 ++++++++++++++++++++++++++++++-----------------------------
 1 files changed, 1,518 insertions(+), 1,460 deletions(-)

diff --git a/src/views/productionManagement/workOrder/index.vue b/src/views/productionManagement/workOrder/index.vue
index 3c9f23f..18ece60 100644
--- a/src/views/productionManagement/workOrder/index.vue
+++ b/src/views/productionManagement/workOrder/index.vue
@@ -9,7 +9,7 @@
                     placeholder="璇疯緭鍏�"
                     @change="handleQuery"
                     clearable
-                    prefix-icon="Search"/>
+                    prefix-icon="Search" />
         </div>
         <div class="search-item">
           <el-button type="primary"
@@ -28,7 +28,7 @@
         <template #completionStatus="{ row }">
           <el-progress :percentage="toProgressPercentage(row?.completionStatus)"
                        :color="progressColor(toProgressPercentage(row?.completionStatus))"
-                       :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''"/>
+                       :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
         </template>
       </PIMTable>
     </div>
@@ -43,7 +43,7 @@
                           placeholder="璇烽�夋嫨"
                           value-format="YYYY-MM-DD HH:mm"
                           format="YYYY-MM-DD HH:mm"
-                          style="width: 300px"/>
+                          style="width: 300px" />
         </el-form-item>
         <el-form-item label="璁″垝缁撴潫鏃堕棿">
           <el-date-picker v-model="editrow.planEndTime"
@@ -51,7 +51,7 @@
                           placeholder="璇烽�夋嫨"
                           value-format="YYYY-MM-DD HH:mm"
                           format="YYYY-MM-DD HH:mm"
-                          style="width: 300px"/>
+                          style="width: 300px" />
         </el-form-item>
         <el-form-item label="瀹為檯寮�濮嬫椂闂�">
           <el-date-picker v-model="editrow.actualStartTime"
@@ -59,7 +59,7 @@
                           placeholder="璇烽�夋嫨"
                           value-format="YYYY-MM-DD HH:mm"
                           format="YYYY-MM-DD HH:mm"
-                          style="width: 300px"/>
+                          style="width: 300px" />
         </el-form-item>
         <el-form-item label="瀹為檯缁撴潫鏃堕棿">
           <el-date-picker v-model="editrow.actualEndTime"
@@ -67,7 +67,7 @@
                           placeholder="璇烽�夋嫨"
                           value-format="YYYY-MM-DD HH:mm"
                           format="YYYY-MM-DD HH:mm"
-                          style="width: 300px"/>
+                          style="width: 300px" />
         </el-form-item>
       </el-form>
       <template #footer>
@@ -155,7 +155,7 @@
           <div class="qr-container">
             <img :src="transferCardQrUrl"
                  alt="娴佽浆鍗′簩缁寸爜"
-                 style="width: 200px; height: 200px;"/>
+                 style="width: 200px; height: 200px;" />
             <!-- <div class="qr-tip"
                  style="margin-top: 10px; text-align: center;">娴佽浆鍗′簩缁寸爜</div> -->
           </div>
@@ -173,132 +173,119 @@
     <el-dialog v-model="reportDialogVisible"
                :title="`鎶ュ伐(宸ュ崟缂栧彿:${currentReportRowData?.workOrderNo || '-'})`"
                width="1000px">
-      <el-form
-          ref="reportFormRef"
-          :model="reportForm"
-          :rules="reportFormRules"
-          label-width="120px"
-      >
+      <el-form ref="reportFormRef"
+               :model="reportForm"
+               :rules="reportFormRules"
+               label-width="120px">
         <el-row :gutter="20">
-
           <el-col :span="12">
             <el-form-item label="寰呯敓浜ф暟閲�">
-              <el-input v-model="reportForm.planQuantity" readonly disabled/>
+              <el-input v-model="reportForm.planQuantity"
+                        readonly
+                        disabled />
             </el-form-item>
           </el-col>
-
           <el-col :span="12">
-            <el-form-item label="鏈鐢熶骇鏁伴噺" prop="quantity">
-              <el-input
-                  v-model.number="reportForm.quantity"
-                  type="number"
-                  min="1"
-                  step="1"
-                  placeholder="璇疯緭鍏ユ湰娆$敓浜ф暟閲�"
-                  style="width: 100%"
-                  :class="{ 'over-limit': reportForm.quantity > reportForm.planQuantity }"
-                  @input="handleQuantityInput"
-              />
+            <el-form-item label="鏈鐢熶骇鏁伴噺"
+                          prop="quantity">
+              <el-input v-model.number="reportForm.quantity"
+                        type="number"
+                        min="1"
+                        step="1"
+                        placeholder="璇疯緭鍏ユ湰娆$敓浜ф暟閲�"
+                        style="width: 100%"
+                        :class="{ 'over-limit': reportForm.quantity > reportForm.planQuantity }"
+                        @input="handleQuantityInput" />
             </el-form-item>
           </el-col>
-
           <el-col :span="12">
-            <el-form-item label="琛ヤ骇鏁伴噺" prop="replenishQty">
-              <el-input
-                  v-model.number="reportForm.replenishQty"
-                  type="number"
-                  min="0"
-                  step="1"
-                  placeholder="璇疯緭鍏ヨˉ浜ф暟閲�"
-              />
+            <el-form-item label="琛ヤ骇鏁伴噺"
+                          prop="replenishQty">
+              <el-input v-model.number="reportForm.replenishQty"
+                        type="number"
+                        min="0"
+                        step="1"
+                        placeholder="璇疯緭鍏ヨˉ浜ф暟閲�" />
             </el-form-item>
           </el-col>
-
           <el-col :span="12">
-            <el-form-item label="鎶ュ簾鏁伴噺" prop="scrapQty">
-              <el-input
-                  v-model.number="reportForm.scrapQty"
-                  type="number"
-                  min="0"
-                  step="1"
-                  placeholder="璇疯緭鍏ユ姤搴熸暟閲�"
-                  @input="handleScrapQtyInput"
-              />
+            <el-form-item label="鎶ュ簾鏁伴噺"
+                          prop="scrapQty">
+              <el-input v-model.number="reportForm.scrapQty"
+                        type="number"
+                        min="0"
+                        step="1"
+                        placeholder="璇疯緭鍏ユ姤搴熸暟閲�"
+                        @input="handleScrapQtyInput" />
             </el-form-item>
           </el-col>
-
           <el-col :span="12">
-            <el-form-item label="鍔犳斁鏁�" prop="addQty">
-              <el-input
-                  v-model.number="reportForm.addQty"
-                  type="number"
-                  min="0"
-                  step="1"
-                  placeholder="璇疯緭鍏ュ姞鏀炬暟"
-              />
+            <el-form-item label="鍔犳斁鏁�"
+                          prop="addQty">
+              <el-input v-model.number="reportForm.addQty"
+                        type="number"
+                        min="0"
+                        step="1"
+                        placeholder="璇疯緭鍏ュ姞鏀炬暟" />
             </el-form-item>
           </el-col>
-
           <el-col :span="12">
-            <el-form-item label="鐝粍淇℃伅" prop="teamList">
-              <el-select
-                  v-model="reportForm.teamList"
-                  multiple
-                  filterable
-                  clearable
-                  collapse-tags
-                  value-key="userId"
-                  placeholder="璇烽�夋嫨鐝粍鎴愬憳"
-              >
-                <el-option
-                    v-for="user in reportForm.userIdsList"
-                    :key="user.userId"
-                    :label="user.nickName"
-                    :value="{ userId: user.userId, userName: user.nickName }"
-                />
+            <el-form-item label="鐝粍淇℃伅"
+                          prop="teamList">
+              <el-select v-model="reportForm.teamList"
+                         multiple
+                         filterable
+                         allow-create
+                         default-first-option
+                         clearable
+                         collapse-tags
+                         value-key="userName"
+                         placeholder="璇烽�夋嫨鎴栬緭鍏ョ彮缁勬垚鍛�"
+                         @change="handleTeamListChange">
+                <el-option v-for="user in reportForm.userIdsList"
+                           :key="user.userId"
+                           :label="user.nickName"
+                           :value="{ userId: user.userId, userName: user.nickName }" />
               </el-select>
             </el-form-item>
           </el-col>
-
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="鏈哄彴" prop="deviceId">-->
-<!--              <el-select-->
-<!--                  v-model="reportForm.deviceId"-->
-<!--                  placeholder="璇烽�夋嫨鏈哄彴"-->
-<!--                  filterable-->
-<!--                  clearable-->
-<!--                  @change="(val) => handleDeviceChange(val)"-->
-<!--                  :disabled="isDetail"-->
-<!--              >-->
-<!--                <el-option-->
-<!--                    v-for="item in deviceOptions"-->
-<!--                    :key="item.id"-->
-<!--                    :label="item.deviceName"-->
-<!--                    :value="item.id"-->
-<!--                />-->
-<!--              </el-select>-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="瀹℃牳浜�" prop="auditUserId">-->
-<!--              <el-select-->
-<!--                  v-model="reportForm.auditUserId"-->
-<!--                  placeholder="璇烽�夋嫨瀹℃牳浜�"-->
-<!--                  clearable-->
-<!--                  filterable-->
-<!--                  @change="handleReviewerIdChange"-->
-<!--              >-->
-<!--                <el-option-->
-<!--                    v-for="user in userOptions"-->
-<!--                    :key="user.userId"-->
-<!--                    :label="user.nickName"-->
-<!--                    :value="user.userId"-->
-<!--                />-->
-<!--              </el-select>-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-
+          <!--          <el-col :span="12">-->
+          <!--            <el-form-item label="鏈哄彴" prop="deviceId">-->
+          <!--              <el-select-->
+          <!--                  v-model="reportForm.deviceId"-->
+          <!--                  placeholder="璇烽�夋嫨鏈哄彴"-->
+          <!--                  filterable-->
+          <!--                  clearable-->
+          <!--                  @change="(val) => handleDeviceChange(val)"-->
+          <!--                  :disabled="isDetail"-->
+          <!--              >-->
+          <!--                <el-option-->
+          <!--                    v-for="item in deviceOptions"-->
+          <!--                    :key="item.id"-->
+          <!--                    :label="item.deviceName"-->
+          <!--                    :value="item.id"-->
+          <!--                />-->
+          <!--              </el-select>-->
+          <!--            </el-form-item>-->
+          <!--          </el-col>-->
+          <!--          <el-col :span="12">-->
+          <!--            <el-form-item label="瀹℃牳浜�" prop="auditUserId">-->
+          <!--              <el-select-->
+          <!--                  v-model="reportForm.auditUserId"-->
+          <!--                  placeholder="璇烽�夋嫨瀹℃牳浜�"-->
+          <!--                  clearable-->
+          <!--                  filterable-->
+          <!--                  @change="handleReviewerIdChange"-->
+          <!--              >-->
+          <!--                <el-option-->
+          <!--                    v-for="user in userOptions"-->
+          <!--                    :key="user.userId"-->
+          <!--                    :label="user.nickName"-->
+          <!--                    :value="user.userId"-->
+          <!--                />-->
+          <!--              </el-select>-->
+          <!--            </el-form-item>-->
+          <!--          </el-col>-->
         </el-row>
       </el-form>
       <template #footer>
@@ -309,36 +296,61 @@
         </span>
       </template>
     </el-dialog>
-    <el-dialog
-        v-model="auditDialogVisible"
-        title="瀹℃牳"
-        width="1000px"
-        :close-on-click-modal="false"
-    >
-      <el-table :data="auditTableData" border style="width: 100%" v-loading="auditLoading">
-        <el-table-column label="浜у搧鍚嶇О" prop="productName" min-width="140" show-overflow-tooltip/>
-        <el-table-column label="瑙勬牸" prop="model" min-width="120" show-overflow-tooltip/>
-        <el-table-column label="鍗曚綅" prop="unit" width="80"/>
-        <el-table-column label="宸ュ簭鍚嶇О" prop="processName" min-width="120" show-overflow-tooltip/>
-        <el-table-column label="闇�姹傛暟閲�" prop="planQuantity" width="110"/>
-        <el-table-column label="瀹屾垚鏁伴噺" prop="completeQuantity" width="110"/>
-        <el-table-column label="瀹屾垚杩涘害" prop="completionStatus" width="140">
+    <el-dialog v-model="auditDialogVisible"
+               title="瀹℃牳"
+               width="1000px"
+               :close-on-click-modal="false">
+      <el-table :data="auditTableData"
+                border
+                style="width: 100%"
+                v-loading="auditLoading">
+        <el-table-column label="浜у搧鍚嶇О"
+                         prop="productName"
+                         min-width="140"
+                         show-overflow-tooltip />
+        <el-table-column label="瑙勬牸"
+                         prop="model"
+                         min-width="120"
+                         show-overflow-tooltip />
+        <el-table-column label="鍗曚綅"
+                         prop="unit"
+                         width="80" />
+        <el-table-column label="宸ュ簭鍚嶇О"
+                         prop="processName"
+                         min-width="120"
+                         show-overflow-tooltip />
+        <el-table-column label="闇�姹傛暟閲�"
+                         prop="planQuantity"
+                         width="110" />
+        <el-table-column label="瀹屾垚鏁伴噺"
+                         prop="completeQuantity"
+                         width="110" />
+        <el-table-column label="瀹屾垚杩涘害"
+                         prop="completionStatus"
+                         width="140">
           <template #default="{ row }">
-            <el-progress
-                :percentage="toProgressPercentage(row?.completionStatus)"
-                :color="progressColor(toProgressPercentage(row?.completionStatus))"
-                :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''"
-            />
+            <el-progress :percentage="toProgressPercentage(row?.completionStatus)"
+                         :color="progressColor(toProgressPercentage(row?.completionStatus))"
+                         :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
           </template>
         </el-table-column>
-        <el-table-column label="璁″垝寮�濮嬫椂闂�" prop="planStartTime" width="140"/>
-        <el-table-column label="璁″垝缁撴潫鏃堕棿" prop="planEndTime" width="140"/>
+        <el-table-column label="璁″垝寮�濮嬫椂闂�"
+                         prop="planStartTime"
+                         width="140" />
+        <el-table-column label="璁″垝缁撴潫鏃堕棿"
+                         prop="planEndTime"
+                         width="140" />
       </el-table>
       <template #footer>
         <span class="dialog-footer">
-          <el-button type="primary" :loading="auditLoading" @click="submitAudit(1)">閫氳繃</el-button>
-          <el-button type="danger" :loading="auditLoading" @click="submitAudit(2)">涓嶉�氳繃</el-button>
-          <el-button :disabled="auditLoading" @click="auditDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary"
+                     :loading="auditLoading"
+                     @click="submitAudit(1)">閫氳繃</el-button>
+          <el-button type="danger"
+                     :loading="auditLoading"
+                     @click="submitAudit(2)">涓嶉�氳繃</el-button>
+          <el-button :disabled="auditLoading"
+                     @click="auditDialogVisible = false">鍙栨秷</el-button>
         </span>
       </template>
     </el-dialog>
@@ -347,1118 +359,1155 @@
                width="1000px"
                :close-on-click-modal="false">
       <div class="schedule-panel">
-        <el-row v-if="!isScheduleHistoryMode" style="margin-bottom: 12px;">
+        <el-row v-if="!isScheduleHistoryMode"
+                style="margin-bottom: 12px;">
           <el-col>
-            <el-button type="primary" plain :disabled="scheduleLoading || scheduleSaving" @click="addScheduleRow">
+            <el-button type="primary"
+                       plain
+                       :disabled="scheduleLoading || scheduleSaving"
+                       @click="addScheduleRow">
               鏂板涓�琛�
             </el-button>
           </el-col>
         </el-row>
-        <el-table :data="scheduleRows" border style="width: 100%" v-loading="scheduleLoading">
-          <el-table-column type="index" label="搴忓彿" width="70" align="center" :index="indexMethod" />
-          <el-table-column label="鏈涓婃満鏈哄彴" min-width="220">
-            <template #default="{ row }">
-              <el-select
-                  v-model="row.deviceId"
-                  placeholder="璇烽�夋嫨鏈哄彴"
-                  filterable
-                  clearable
+        <el-table :data="scheduleRows"
+                  border
                   style="width: 100%"
-                  :disabled="scheduleSaving || isScheduleHistoryMode"
-                  @change="val => handleScheduleDeviceChange(val, row)"
-              >
-                <el-option
-                    v-for="item in deviceOptions"
-                    :key="item.id"
-                    :label="item.deviceName"
-                    :value="String(item.id)"
-                />
+                  v-loading="scheduleLoading">
+          <el-table-column type="index"
+                           label="搴忓彿"
+                           width="70"
+                           align="center"
+                           :index="indexMethod" />
+          <el-table-column label="鏈涓婃満鏈哄彴"
+                           min-width="220">
+            <template #default="{ row }">
+              <el-select v-model="row.deviceId"
+                         placeholder="璇烽�夋嫨鏈哄彴"
+                         filterable
+                         clearable
+                         style="width: 100%"
+                         :disabled="scheduleSaving || isScheduleHistoryMode"
+                         @change="val => handleScheduleDeviceChange(val, row)">
+                <el-option v-for="item in deviceOptions"
+                           :key="item.id"
+                           :label="item.deviceName"
+                           :value="String(item.id)" />
               </el-select>
             </template>
           </el-table-column>
-
-          <el-table-column label="鏈涓婃満浜�" min-width="220">
+          <el-table-column label="鏈涓婃満浜�"
+                           min-width="220">
             <template #default="{ row }">
-              <div v-if="isScheduleHistoryMode" class="schedule-user-tags">
-                <el-tag
-                    v-for="(userId, index) in row.userIds"
-                    :key="`${userId}-${index}`"
-                    type="primary"
-                >
+              <div v-if="isScheduleHistoryMode"
+                   class="schedule-user-tags">
+                <el-tag v-for="(userId, index) in row.userIds"
+                        :key="`${userId}-${index}`"
+                        type="primary">
                   {{ resolveScheduleUserName(userId) }}
                 </el-tag>
                 <span v-if="!row.userIds?.length">-</span>
               </div>
-              <el-select
-                  v-else
-                  v-model="row.userIds"
-                  placeholder="璇烽�夋嫨涓婃満浜�"
-                  filterable
-                  multiple
-                  clearable
-                  collapse-tags
-                  style="width: 100%"
-                  :disabled="scheduleSaving"
-                  @change="val => handleScheduleUserChange(val, row)"
-              >
-                <el-option
-                    v-for="user in row.userOptions"
-                    :key="user.userId"
-                    :label="user.nickName"
-                    :value="String(user.userId)"
-                />
+              <el-select v-else
+                         v-model="row.userIds"
+                         placeholder="璇烽�夋嫨涓婃満浜�"
+                         filterable
+                         multiple
+                         clearable
+                         collapse-tags
+                         style="width: 100%"
+                         :disabled="scheduleSaving"
+                         @change="val => handleScheduleUserChange(val, row)">
+                <el-option v-for="user in row.userOptions"
+                           :key="user.userId"
+                           :label="user.nickName"
+                           :value="String(user.userId)" />
               </el-select>
             </template>
           </el-table-column>
-
-          <el-table-column label="鏈涓婃満鏃堕棿" min-width="240">
+          <el-table-column label="鏈涓婃満鏃堕棿"
+                           min-width="240">
             <template #default="{ row }">
-              <el-date-picker
-                  v-model="row.startTime"
-                  type="datetime"
-                  value-format="YYYY-MM-DD HH:mm:ss"
-                  format="YYYY-MM-DD HH:mm:ss"
-                  placeholder="璇烽�夋嫨涓婃満鏃堕棿"
-                  style="width: 100%"
-                  :disabled="scheduleSaving || isScheduleHistoryMode"
-              />
+              <el-date-picker v-model="row.startTime"
+                              type="datetime"
+                              value-format="YYYY-MM-DD HH:mm:ss"
+                              format="YYYY-MM-DD HH:mm:ss"
+                              placeholder="璇烽�夋嫨涓婃満鏃堕棿"
+                              style="width: 100%"
+                              :disabled="scheduleSaving || isScheduleHistoryMode" />
             </template>
           </el-table-column>
-
-          <el-table-column v-if="!isScheduleHistoryMode" label="鎿嶄綔" width="110" align="center">
+          <el-table-column v-if="!isScheduleHistoryMode"
+                           label="鎿嶄綔"
+                           width="110"
+                           align="center">
             <template #default="{ row }">
-              <el-button
-                  link
-                  type="danger"
-                  :loading="row.deleting"
-                  :disabled="scheduleSaving"
-                  @click="removeScheduleRow(row)"
-              >
+              <el-button link
+                         type="danger"
+                         :loading="row.deleting"
+                         :disabled="scheduleSaving"
+                         @click="removeScheduleRow(row)">
                 鍒犻櫎
               </el-button>
             </template>
           </el-table-column>
         </el-table>
-
-        <Pagination
-            v-show="isScheduleHistoryMode && schedulePage.total > 0"
-            style="margin-top: 12px"
-            :total="schedulePage.total"
-            :page="schedulePage.current"
-            :limit="schedulePage.size"
-            @pagination="handleSchedulePagination"
-        />
+        <Pagination v-show="isScheduleHistoryMode && schedulePage.total > 0"
+                    style="margin-top: 12px"
+                    :total="schedulePage.total"
+                    :page="schedulePage.current"
+                    :limit="schedulePage.size"
+                    @pagination="handleSchedulePagination" />
       </div>
-
       <template #footer>
         <span class="dialog-footer">
           <template v-if="isScheduleHistoryMode">
             <el-button @click="scheduleDialogVisible = false">鍏抽棴</el-button>
           </template>
           <template v-else>
-            <el-button type="primary" :loading="scheduleSaving" @click="handleSaveSchedule">淇濆瓨鎺掍骇</el-button>
-            <el-button :disabled="scheduleSaving" @click="scheduleDialogVisible = false">鍙栨秷</el-button>
+            <el-button type="primary"
+                       :loading="scheduleSaving"
+                       @click="handleSaveSchedule">淇濆瓨鎺掍骇</el-button>
+            <el-button :disabled="scheduleSaving"
+                       @click="scheduleDialogVisible = false">鍙栨秷</el-button>
           </template>
         </span>
       </template>
     </el-dialog>
-    <FilesDia ref="workOrderFilesRef"/>
+    <FilesDia ref="workOrderFilesRef" />
   </div>
 </template>
 
 <script setup>
-import {onMounted, ref, nextTick, computed} from "vue";
-import {deepClone} from "@/utils/index.js"
-import {ElMessageBox, ElMessage} from "element-plus";
-import Pagination from "@/components/PIMTable/Pagination.vue";
-import dayjs from "dayjs";
-import { processList } from '@/api/productionManagement/productionProcess.js'
-import {
-  productWorkOrderPage,
-  updateProductWorkOrder,
-  addProductMain,
-  downProductWorkOrder,
-  addProductionMachineRecord,
-  productionMachineRecordListPage,
-  deleteProductionMachineRecord
-} from "@/api/productionManagement/workOrder.js";
-import {getUserProfile, userListNoPageByTenantId} from "@/api/system/user.js";
-import QRCode from "qrcode";
-import {getCurrentInstance, reactive, toRefs} from "vue";
-import FilesDia from "./components/filesDia.vue";
-import {getDeviceLedger} from "@/api/equipmentManagement/ledger.js";
+  import { onMounted, ref, nextTick, computed } from "vue";
+  import { deepClone } from "@/utils/index.js";
+  import { ElMessageBox, ElMessage } from "element-plus";
+  import Pagination from "@/components/PIMTable/Pagination.vue";
+  import dayjs from "dayjs";
+  import { processList } from "@/api/productionManagement/productionProcess.js";
+  import {
+    productWorkOrderPage,
+    updateProductWorkOrder,
+    addProductMain,
+    downProductWorkOrder,
+    addProductionMachineRecord,
+    productionMachineRecordListPage,
+    deleteProductionMachineRecord,
+  } from "@/api/productionManagement/workOrder.js";
+  import { getUserProfile, userListNoPageByTenantId } from "@/api/system/user.js";
+  import QRCode from "qrcode";
+  import { getCurrentInstance, reactive, toRefs } from "vue";
+  import FilesDia from "./components/filesDia.vue";
+  import { getDeviceLedger } from "@/api/equipmentManagement/ledger.js";
 
-const {proxy} = getCurrentInstance();
+  const { proxy } = getCurrentInstance();
 
-const currentUserId = ref("");
-const deviceOptions = ref([])
-const currentUserName = ref("");
+  const currentUserId = ref("");
+  const deviceOptions = ref([]);
+  const currentUserName = ref("");
 
-const ensureCurrentUser = async () => {
-  if (currentUserId.value) return;
-  try {
-    const res = await getUserProfile();
-    if (res?.code === 200) {
-      currentUserId.value = String(res?.data?.userId ?? "");
-      currentUserName.value = String(res?.data?.nickName ?? "");
+  const ensureCurrentUser = async () => {
+    if (currentUserId.value) return;
+    try {
+      const res = await getUserProfile();
+      if (res?.code === 200) {
+        currentUserId.value = String(res?.data?.userId ?? "");
+        currentUserName.value = String(res?.data?.nickName ?? "");
+      }
+    } catch (err) {
+      console.error("鑾峰彇鐢ㄦ埛淇℃伅澶辫触", err);
     }
-  } catch (err) {
-    console.error("鑾峰彇鐢ㄦ埛淇℃伅澶辫触", err);
-  }
-};
-
-// 鏈哄彴鑾峰彇
-const getDeviceList = () => {
-  getDeviceLedger().then(res => {
-    deviceOptions.value = Array.isArray(res?.data) ? res.data : []
-  })
-}
-
-const handleDeviceChange = (val) => {
-  const device = deviceOptions.value.find(item => item.id === val)
-  reportForm.deviceName = device?.deviceName || ""
-  reportForm.deviceId = val || ""
-}
-
-const normalizeArray = (val) => {
-  if (val === null || val === undefined) return [];
-  if (Array.isArray(val)) return val;
-  if (typeof val === "string") {
-    return val
-        .split(/[,锛�;锛沑s]+/g)
-        .map((s) => s.trim())
-        .filter(Boolean);
-  }
-  return [val];
-};
-
-const isCurrentUserInUserIds = (row) => {
-  const uid = String(currentUserId.value || "");
-  if (!uid) return false;
-
-  const ids = normalizeArray(row?.userIds)
-      .map(id => String(id))
-      .filter(Boolean);
-
-  return ids.includes(uid);
-};
-
-// 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁鍦ㄥ伐搴忔姤宸ヤ汉涓�
-const isCurrentUserInProcessUserIds = (row) => {
-  const uid = String(currentUserId.value || "");
-  if (!uid) return false;
-
-  const ids = normalizeArray(row?.processUserIds)
-      .map(id => String(id))
-      .filter(Boolean);
-
-  return ids.includes(uid);
-};
-
-// 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁鍙互鎶ュ伐锛堝伐鍗曟姤宸ヤ汉 鎴� 宸ュ簭鎶ュ伐浜猴級
-const canCurrentUserReport = (row) => {
-  return isCurrentUserInUserIds(row) || isCurrentUserInProcessUserIds(row);
-};
-
-const canOperateByReportWorker = computed(() => {
-  return (row) => isCurrentUserReportWorker(row);
-});
-
-const isRowScheduled = (row) => {
-  const ids = normalizeArray(row?.userIds)
-    .map((val) => String(val))
-    .filter(Boolean);
-  if (!ids.length) return false;
-  return ids.some((val) => val !== "0");
-};
-
-const buildBaseScheduleUsersByRow = (row) => {
-  if (!row) return [];
-
-  if (Array.isArray(row?.reportWorkerList) && row.reportWorkerList.length > 0) {
-    const mapped = row.reportWorkerList
-      .map((item) => {
-        const userId = String(item?.userId ?? item?.id ?? "").trim();
-        const nickName = String(item?.userName ?? item?.nickName ?? "").trim();
-        return { userId, nickName: nickName || userId };
-      })
-      .filter((item) => item.userId);
-    const uniq = new Map();
-    mapped.forEach((item) => uniq.set(String(item.userId), item));
-    return Array.from(uniq.values());
-  }
-
-  const configuredIds = [
-    row.reportUserIds,
-    row.reportWorkerIds,
-    row.userIdList,
-    row.reportUserId,
-    row.userId,
-  ]
-    .flatMap((v) => normalizeArray(v))
-    .map((v) => String(v).trim())
-    .filter(Boolean);
-
-  if (configuredIds.length > 0) {
-    const uniqIds = Array.from(new Set(configuredIds));
-    return uniqIds.map((id) => {
-      const user = userTeamOptions.value.find((u) => String(u.userId) === String(id));
-      return { userId: String(id), nickName: user?.nickName || String(id) };
-    });
-  }
-
-  return userTeamOptions.value.map((u) => ({
-    userId: String(u.userId),
-    nickName: u.nickName,
-  }));
-};
-
-const resolveScheduleUserName = (userId) => {
-  const uid = String(userId ?? "").trim();
-  if (!uid) return "";
-  const inBase = baseScheduleUsers.value.find((u) => String(u.userId) === uid);
-  if (inBase?.nickName) return inBase.nickName;
-  const inTeam = userTeamOptions.value.find((u) => String(u.userId) === uid);
-  return inTeam?.nickName || uid;
-};
-
-const buildScheduleUserOptionsByDeviceId = (deviceId) => {
-  const device = deviceOptions.value.find((item) => String(item.id) === String(deviceId));
-
-  const operatorIds = device?.operatorId
-    ? String(device.operatorId)
-      .split(/[,锛�;锛沑s]+/g)
-      .map((id) => id.trim())
-      .filter(Boolean)
-    : [];
-
-  if (!operatorIds.length) {
-    return [...baseScheduleUsers.value];
-  }
-
-  return baseScheduleUsers.value.filter((user) =>
-    operatorIds.includes(String(user.userId))
-  );
-};
-
-const createScheduleRow = (preset = {}) => {
-  const deviceId =
-    preset?.deviceId === null || preset?.deviceId === undefined
-      ? ""
-      : String(preset.deviceId);
-
-  const userOptions = deviceId
-    ? buildScheduleUserOptionsByDeviceId(deviceId)
-    : [...baseScheduleUsers.value];
-
-  const userIds = normalizeArray(preset?.userIds)
-    .map((val) => String(val))
-    .filter(Boolean)
-    .filter((uid) => userOptions.some((user) => String(user.userId) === String(uid)));
-
-  return {
-    id: preset?.id ?? "",
-    deviceId,
-    deviceName: preset?.deviceName ?? "",
-    userIds,
-    userOptions,
-    startTime: preset?.startTime ?? dayjs().format("YYYY-MM-DD HH:mm:ss"),
-    deleting: false,
   };
-};
 
-const addScheduleRow = (preset) => {
-  if (preset) {
-    scheduleRows.value.push(createScheduleRow(preset));
-    return;
-  }
+  // 鏈哄彴鑾峰彇
+  const getDeviceList = () => {
+    getDeviceLedger().then(res => {
+      deviceOptions.value = Array.isArray(res?.data) ? res.data : [];
+    });
+  };
 
-  scheduleRows.value.push(
-    createScheduleRow({
-      id: "",
-      deviceId:"",
-      deviceName:"",
-      userIds: [],
-      startTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
-    })
+  const handleDeviceChange = val => {
+    const device = deviceOptions.value.find(item => item.id === val);
+    reportForm.deviceName = device?.deviceName || "";
+    reportForm.deviceId = val || "";
+  };
+
+  const normalizeArray = val => {
+    if (val === null || val === undefined) return [];
+    if (Array.isArray(val)) return val;
+    if (typeof val === "string") {
+      return val
+        .split(/[,锛�;锛沑s]+/g)
+        .map(s => s.trim())
+        .filter(Boolean);
+    }
+    return [val];
+  };
+
+  const isCurrentUserInUserIds = row => {
+    const uid = String(currentUserId.value || "");
+    if (!uid) return false;
+
+    const ids = normalizeArray(row?.userIds)
+      .map(id => String(id))
+      .filter(Boolean);
+
+    return ids.includes(uid);
+  };
+
+  // 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁鍦ㄥ伐搴忔姤宸ヤ汉涓�
+  const isCurrentUserInProcessUserIds = row => {
+    const uid = String(currentUserId.value || "");
+    if (!uid) return false;
+
+    const ids = normalizeArray(row?.processUserIds)
+      .map(id => String(id))
+      .filter(Boolean);
+
+    return ids.includes(uid);
+  };
+
+  // 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁鍙互鎶ュ伐锛堝伐鍗曟姤宸ヤ汉 鎴� 宸ュ簭鎶ュ伐浜猴級
+  const canCurrentUserReport = row => {
+    return isCurrentUserInUserIds(row) || isCurrentUserInProcessUserIds(row);
+  };
+
+  const canOperateByReportWorker = computed(() => {
+    return row => isCurrentUserReportWorker(row);
+  });
+
+  const isRowScheduled = row => {
+    const ids = normalizeArray(row?.userIds)
+      .map(val => String(val))
+      .filter(Boolean);
+    if (!ids.length) return false;
+    return ids.some(val => val !== "0");
+  };
+
+  const buildBaseScheduleUsersByRow = row => {
+    if (!row) return [];
+
+    if (Array.isArray(row?.reportWorkerList) && row.reportWorkerList.length > 0) {
+      const mapped = row.reportWorkerList
+        .map(item => {
+          const userId = String(item?.userId ?? item?.id ?? "").trim();
+          const nickName = String(item?.userName ?? item?.nickName ?? "").trim();
+          return { userId, nickName: nickName || userId };
+        })
+        .filter(item => item.userId);
+      const uniq = new Map();
+      mapped.forEach(item => uniq.set(String(item.userId), item));
+      return Array.from(uniq.values());
+    }
+
+    const configuredIds = [
+      row.reportUserIds,
+      row.reportWorkerIds,
+      row.userIdList,
+      row.reportUserId,
+      row.userId,
+    ]
+      .flatMap(v => normalizeArray(v))
+      .map(v => String(v).trim())
+      .filter(Boolean);
+
+    if (configuredIds.length > 0) {
+      const uniqIds = Array.from(new Set(configuredIds));
+      return uniqIds.map(id => {
+        const user = userTeamOptions.value.find(
+          u => String(u.userId) === String(id)
+        );
+        return { userId: String(id), nickName: user?.nickName || String(id) };
+      });
+    }
+
+    return userTeamOptions.value.map(u => ({
+      userId: String(u.userId),
+      nickName: u.nickName,
+    }));
+  };
+
+  const resolveScheduleUserName = userId => {
+    const uid = String(userId ?? "").trim();
+    if (!uid) return "";
+    const inBase = baseScheduleUsers.value.find(u => String(u.userId) === uid);
+    if (inBase?.nickName) return inBase.nickName;
+    const inTeam = userTeamOptions.value.find(u => String(u.userId) === uid);
+    return inTeam?.nickName || uid;
+  };
+
+  const buildScheduleUserOptionsByDeviceId = deviceId => {
+    const device = deviceOptions.value.find(
+      item => String(item.id) === String(deviceId)
+    );
+
+    const operatorIds = device?.operatorId
+      ? String(device.operatorId)
+          .split(/[,锛�;锛沑s]+/g)
+          .map(id => id.trim())
+          .filter(Boolean)
+      : [];
+
+    if (!operatorIds.length) {
+      return [...baseScheduleUsers.value];
+    }
+
+    return baseScheduleUsers.value.filter(user =>
+      operatorIds.includes(String(user.userId))
+    );
+  };
+
+  const createScheduleRow = (preset = {}) => {
+    const deviceId =
+      preset?.deviceId === null || preset?.deviceId === undefined
+        ? ""
+        : String(preset.deviceId);
+
+    const userOptions = deviceId
+      ? buildScheduleUserOptionsByDeviceId(deviceId)
+      : [...baseScheduleUsers.value];
+
+    const userIds = normalizeArray(preset?.userIds)
+      .map(val => String(val))
+      .filter(Boolean)
+      .filter(uid =>
+        userOptions.some(user => String(user.userId) === String(uid))
+      );
+
+    return {
+      id: preset?.id ?? "",
+      deviceId,
+      deviceName: preset?.deviceName ?? "",
+      userIds,
+      userOptions,
+      startTime: preset?.startTime ?? dayjs().format("YYYY-MM-DD HH:mm:ss"),
+      deleting: false,
+    };
+  };
+
+  const addScheduleRow = preset => {
+    if (preset) {
+      scheduleRows.value.push(createScheduleRow(preset));
+      return;
+    }
+
+    scheduleRows.value.push(
+      createScheduleRow({
+        id: "",
+        deviceId: "",
+        deviceName: "",
+        userIds: [],
+        startTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
+      })
+    );
+  };
+
+  const refreshScheduleRows = async () => {
+    const workOrderRow = currentReportRowData.value;
+
+    if (!workOrderRow?.id) {
+      schedulePage.current = 1;
+      schedulePage.total = 0;
+      scheduleRows.value = [];
+      return;
+    }
+
+    scheduleLoading.value = true;
+    try {
+      const res = await productionMachineRecordListPage({
+        workOrderId: workOrderRow.id,
+        current: schedulePage.current,
+        size: schedulePage.size,
+      });
+
+      const records = Array.isArray(res?.data?.records) ? res.data.records : [];
+      const apiTotal = Number(res?.data?.total);
+      schedulePage.total =
+        Number.isFinite(apiTotal) && apiTotal > 0 ? apiTotal : records.length;
+
+      const lastPage = Math.max(
+        1,
+        Math.ceil((schedulePage.total || 0) / schedulePage.size)
+      );
+      if (schedulePage.current > lastPage) {
+        schedulePage.current = lastPage;
+        await refreshScheduleRows();
+        return;
+      }
+
+      const rows = records.map(record => mapMachineRecordToScheduleRow(record));
+      scheduleRows.value = rows;
+    } catch (error) {
+      console.error("鑾峰彇鎺掍骇璁板綍澶辫触", error);
+      schedulePage.total = 0;
+      scheduleRows.value = [];
+      ElMessage.error("鑾峰彇鎺掍骇璁板綍澶辫触");
+    } finally {
+      scheduleLoading.value = false;
+    }
+  };
+
+  const removeScheduleRow = async row => {
+    if (!row || isScheduleHistoryMode.value) return;
+
+    if (!row.id) {
+      scheduleRows.value = scheduleRows.value.filter(item => item !== row);
+      if (!scheduleRows.value.length) {
+        addScheduleRow();
+      }
+      return;
+    }
+
+    try {
+      await ElMessageBox.confirm("纭畾鍒犻櫎杩欐潯鎺掍骇璁板綍鍚楋紵", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning",
+      });
+    } catch {
+      return;
+    }
+
+    row.deleting = true;
+    try {
+      const res = await deleteProductionMachineRecord([row.id]);
+      if (res?.code !== undefined && res.code !== 200) {
+        ElMessage.error(res?.msg || "鍒犻櫎澶辫触");
+        return;
+      }
+
+      ElMessage.success("鍒犻櫎鎴愬姛");
+      await refreshScheduleRows();
+      getList();
+    } catch (error) {
+      console.error("鍒犻櫎鎺掍骇璁板綍澶辫触", error);
+      ElMessage.error("鍒犻櫎澶辫触锛岃閲嶈瘯");
+    } finally {
+      row.deleting = false;
+    }
+  };
+
+  const handleScheduleUserChange = (userIds, row) => {
+    row.userIds = normalizeArray(userIds)
+      .map(val => String(val))
+      .filter(Boolean);
+  };
+
+  const handleScheduleDeviceChange = (deviceId, row) => {
+    const device = deviceOptions.value.find(
+      item => String(item.id) === String(deviceId)
+    );
+
+    row.deviceId =
+      deviceId === null || deviceId === undefined ? "" : String(deviceId);
+    row.deviceName = device?.deviceName || "";
+    row.userOptions = row.deviceId
+      ? buildScheduleUserOptionsByDeviceId(row.deviceId)
+      : [...baseScheduleUsers.value];
+
+    row.userIds = normalizeArray(row.userIds)
+      .map(uid => String(uid))
+      .filter(uid =>
+        row.userOptions.some(user => String(user.userId) === String(uid))
+      );
+  };
+
+  const handleSchedulePagination = ({ page, limit }) => {
+    if (!isScheduleHistoryMode.value) return;
+    schedulePage.current = page;
+    schedulePage.size = limit;
+    refreshScheduleRows();
+  };
+
+  const validateScheduleRows = () => {
+    if (!scheduleRows.value.length) {
+      ElMessage.warning("璇疯嚦灏戞坊鍔犱竴鏉′笂鏈轰俊鎭�");
+      return false;
+    }
+
+    for (let index = 0; index < scheduleRows.value.length; index += 1) {
+      const row = scheduleRows.value[index];
+
+      if (!row.deviceId) {
+        ElMessage.warning(`绗�${index + 1}琛岃閫夋嫨鏈哄彴`);
+        return false;
+      }
+
+      if (!Array.isArray(row.userIds) || row.userIds.length === 0) {
+        ElMessage.warning(`绗�${index + 1}琛岃閫夋嫨涓婃満浜篳);
+        return false;
+      }
+
+      if (!row.startTime) {
+        ElMessage.warning(`绗�${index + 1}琛岃閫夋嫨涓婃満鏃堕棿`);
+        return false;
+      }
+
+      if (!dayjs(row.startTime).isValid()) {
+        ElMessage.warning(`绗�${index + 1}琛屼笂鏈烘椂闂存牸寮忎笉姝g‘`);
+        return false;
+      }
+    }
+
+    return true;
+  };
+
+  const buildMachineRecordPayload = (
+    workOrderRow,
+    scheduleRow,
+    sortIndex = 0
+  ) => {
+    const processId =
+      workOrderRow?.processId ??
+      workOrderRow?.productProcessRouteItemId ??
+      reportForm.productProcessRouteItemId;
+
+    const operatorIds = normalizeArray(scheduleRow?.userIds)
+      .map(val => String(val).trim())
+      .filter(Boolean)
+      .join(",");
+
+    const nickName = normalizeArray(scheduleRow?.userIds)
+      .map(uid => resolveScheduleUserName(uid))
+      .filter(Boolean)
+      .join(",");
+
+    const payload = {
+      workOrderId: workOrderRow?.id,
+      processId,
+      machineId: scheduleRow.deviceId ? Number(scheduleRow.deviceId) : undefined,
+      deviceName: scheduleRow.deviceName,
+      operatorId: operatorIds || undefined,
+      nickName: nickName || "",
+      machineStartTime: scheduleRow.startTime,
+      reportStatus: false,
+      remark: `鎺掍骇搴忓彿:${sortIndex + 1}`,
+    };
+
+    if (scheduleRow.id) {
+      payload.id = scheduleRow.id;
+    }
+
+    return payload;
+  };
+
+  const indexMethod = index => {
+    return (schedulePage.current - 1) * schedulePage.size + index + 1;
+  };
+
+  const scheduleDialogMode = ref("create");
+  const isScheduleHistoryMode = computed(
+    () => scheduleDialogMode.value === "history"
   );
-};
+  const scheduleDialogTitle = computed(
+    () =>
+      `${isScheduleHistoryMode.value ? "鎺掍骇璁板綍" : "鐢熶骇鎺掍骇"}(宸ュ崟缂栧彿:${
+        currentReportRowData.value?.workOrderNo || "-"
+      })`
+  );
 
-const refreshScheduleRows = async () => {
-  const workOrderRow = currentReportRowData.value;
+  const mapMachineRecordToScheduleRow = record => {
+    const id = record?.id ?? "";
+    const deviceId = record?.machineId ?? record?.deviceId ?? "";
+    const deviceName = record?.deviceName ?? record?.machineName ?? "";
+    const startTime = record?.machineStartTime ?? record?.startTime ?? "";
+    const userIds = normalizeArray(
+      record?.operatorId ?? record?.operatorIds ?? record?.userId
+    )
+      .map(val => String(val))
+      .filter(Boolean);
 
-  if (!workOrderRow?.id) {
+    return createScheduleRow({
+      id,
+      deviceId:
+        deviceId === null || deviceId === undefined ? "" : String(deviceId),
+      deviceName,
+      userIds,
+      startTime,
+    });
+  };
+
+  const buildScheduleRowsFromRecords = records => {
+    const list = Array.isArray(records) ? records : [];
+    const grouped = new Map();
+
+    list.forEach(record => {
+      const row = mapMachineRecordToScheduleRow(record);
+      const key = `${row.deviceId}__${row.startTime}__${row.deviceName}`;
+
+      if (!grouped.has(key)) {
+        grouped.set(key, row);
+        return;
+      }
+
+      const existing = grouped.get(key);
+      existing.ids = Array.from(new Set([existing.id, row.id].filter(Boolean)));
+      existing.userIds = Array.from(
+        new Set(
+          [...(existing?.userIds || []), ...(row?.userIds || [])].map(v =>
+            String(v)
+          )
+        )
+      ).filter(Boolean);
+
+      if (!existing.deviceName && row.deviceName)
+        existing.deviceName = row.deviceName;
+    });
+
+    return Array.from(grouped.values()).sort(
+      (a, b) => dayjs(a.startTime).valueOf() - dayjs(b.startTime).valueOf()
+    );
+  };
+
+  const resetCreateScheduleRows = () => {
     schedulePage.current = 1;
     schedulePage.total = 0;
     scheduleRows.value = [];
-    return;
-  }
-
-  scheduleLoading.value = true;
-  try {
-    const res = await productionMachineRecordListPage({
-      workOrderId: workOrderRow.id,
-      current: schedulePage.current,
-      size: schedulePage.size,
-    });
-
-    const records = Array.isArray(res?.data?.records) ? res.data.records : [];
-    const apiTotal = Number(res?.data?.total);
-    schedulePage.total =
-      Number.isFinite(apiTotal) && apiTotal > 0
-        ? apiTotal
-        : records.length;
-
-    const lastPage = Math.max(1, Math.ceil((schedulePage.total || 0) / schedulePage.size));
-    if (schedulePage.current > lastPage) {
-      schedulePage.current = lastPage;
-      await refreshScheduleRows();
-      return;
-    }
-
-    const rows = records.map(record => mapMachineRecordToScheduleRow(record));
-    scheduleRows.value = rows;
-  } catch (error) {
-    console.error("鑾峰彇鎺掍骇璁板綍澶辫触", error);
-    schedulePage.total = 0;
-    scheduleRows.value = [];
-    ElMessage.error("鑾峰彇鎺掍骇璁板綍澶辫触");
-  } finally {
-    scheduleLoading.value = false;
-  }
-};
-
-const removeScheduleRow = async (row) => {
-  if (!row || isScheduleHistoryMode.value) return;
-
-  if (!row.id) {
-    scheduleRows.value = scheduleRows.value.filter((item) => item !== row);
-    if (!scheduleRows.value.length) {
-      addScheduleRow();
-    }
-    return;
-  }
-
-  try {
-    await ElMessageBox.confirm("纭畾鍒犻櫎杩欐潯鎺掍骇璁板綍鍚楋紵", "鎻愮ず", {
-      confirmButtonText: "纭畾",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    });
-  } catch {
-    return;
-  }
-
-  row.deleting = true;
-  try {
-    const res = await deleteProductionMachineRecord([row.id]);
-    if (res?.code !== undefined && res.code !== 200) {
-      ElMessage.error(res?.msg || "鍒犻櫎澶辫触");
-      return;
-    }
-
-    ElMessage.success("鍒犻櫎鎴愬姛");
-    await refreshScheduleRows();
-    getList();
-  } catch (error) {
-    console.error("鍒犻櫎鎺掍骇璁板綍澶辫触", error);
-    ElMessage.error("鍒犻櫎澶辫触锛岃閲嶈瘯");
-  } finally {
-    row.deleting = false;
-  }
-};
-
-const handleScheduleUserChange = (userIds, row) => {
-  row.userIds = normalizeArray(userIds).map((val) => String(val)).filter(Boolean);
-};
-
-const handleScheduleDeviceChange = (deviceId, row) => {
-  const device = deviceOptions.value.find((item) => String(item.id) === String(deviceId));
-
-  row.deviceId = deviceId === null || deviceId === undefined ? "" : String(deviceId);
-  row.deviceName = device?.deviceName || "";
-  row.userOptions = row.deviceId ? buildScheduleUserOptionsByDeviceId(row.deviceId) : [...baseScheduleUsers.value];
-
-  row.userIds = normalizeArray(row.userIds)
-    .map((uid) => String(uid))
-    .filter((uid) => row.userOptions.some((user) => String(user.userId) === String(uid)));
-};
-
-const handleSchedulePagination = ({page, limit}) => {
-  if (!isScheduleHistoryMode.value) return;
-  schedulePage.current = page;
-  schedulePage.size = limit;
-  refreshScheduleRows();
-};
-
-const validateScheduleRows = () => {
-  if (!scheduleRows.value.length) {
-    ElMessage.warning("璇疯嚦灏戞坊鍔犱竴鏉′笂鏈轰俊鎭�");
-    return false;
-  }
-
-  for (let index = 0; index < scheduleRows.value.length; index += 1) {
-    const row = scheduleRows.value[index];
-
-    if (!row.deviceId) {
-      ElMessage.warning(`绗�${index + 1}琛岃閫夋嫨鏈哄彴`);
-      return false;
-    }
-
-    if (!Array.isArray(row.userIds) || row.userIds.length === 0) {
-      ElMessage.warning(`绗�${index + 1}琛岃閫夋嫨涓婃満浜篳);
-      return false;
-    }
-
-    if (!row.startTime) {
-      ElMessage.warning(`绗�${index + 1}琛岃閫夋嫨涓婃満鏃堕棿`);
-      return false;
-    }
-
-    if (!dayjs(row.startTime).isValid()) {
-      ElMessage.warning(`绗�${index + 1}琛屼笂鏈烘椂闂存牸寮忎笉姝g‘`);
-      return false;
-    }
-  }
-
-
-  return true;
-};
-
-const buildMachineRecordPayload = (workOrderRow, scheduleRow, sortIndex = 0) => {
-  const processId =
-    workOrderRow?.processId ??
-    workOrderRow?.productProcessRouteItemId ??
-    reportForm.productProcessRouteItemId;
-
-  const operatorIds = normalizeArray(scheduleRow?.userIds)
-    .map((val) => String(val).trim())
-    .filter(Boolean)
-    .join(",");
-
-  const nickName = normalizeArray(scheduleRow?.userIds)
-    .map((uid) => resolveScheduleUserName(uid))
-    .filter(Boolean)
-    .join(",");
-
-  const payload = {
-    workOrderId: workOrderRow?.id,
-    processId,
-    machineId: scheduleRow.deviceId ? Number(scheduleRow.deviceId) : undefined,
-    deviceName: scheduleRow.deviceName,
-    operatorId: operatorIds || undefined,
-    nickName: nickName || "",
-    machineStartTime: scheduleRow.startTime,
-    reportStatus: false,
-    remark: `鎺掍骇搴忓彿:${sortIndex + 1}`,
+    addScheduleRow();
   };
 
-  if (scheduleRow.id) {
-    payload.id = scheduleRow.id;
-  }
+  const openScheduleDialog = async row => {
+    scheduleDialogMode.value = "create";
+    currentReportRowData.value = row;
+    baseScheduleUsers.value = buildBaseScheduleUsersByRow(row);
+    userTemp.value = [...baseScheduleUsers.value];
+    scheduleDialogVisible.value = true;
+    resetCreateScheduleRows();
+  };
 
-  return payload;
-};
+  const openHistoryTimelineDialog = async row => {
+    scheduleDialogMode.value = "history";
+    currentReportRowData.value = row;
+    baseScheduleUsers.value = buildBaseScheduleUsersByRow(row);
+    userTemp.value = [...baseScheduleUsers.value];
+    schedulePage.current = 1;
+    schedulePage.total = 0;
+    scheduleRows.value = [];
+    scheduleDialogVisible.value = true;
 
-const indexMethod = (index) => {
-  return (schedulePage.current - 1) * schedulePage.size + index + 1;
-};
+    await refreshScheduleRows();
+  };
 
-const scheduleDialogMode = ref("create");
-const isScheduleHistoryMode = computed(() => scheduleDialogMode.value === "history");
-const scheduleDialogTitle = computed(() =>
-  `${isScheduleHistoryMode.value ? "鎺掍骇璁板綍" : "鐢熶骇鎺掍骇"}(宸ュ崟缂栧彿:${currentReportRowData.value?.workOrderNo || "-"})`
-);
+  const handleSaveSchedule = async () => {
+    if (isScheduleHistoryMode.value) return;
+    if (scheduleSaving.value) return;
+    if (!validateScheduleRows()) return;
 
-const mapMachineRecordToScheduleRow = (record) => {
-  const id = record?.id ?? "";
-  const deviceId = record?.machineId ?? record?.deviceId ?? "";
-  const deviceName = record?.deviceName ?? record?.machineName ?? "";
-  const startTime = record?.machineStartTime ?? record?.startTime ?? "";
-  const userIds = normalizeArray(record?.operatorId ?? record?.operatorIds ?? record?.userId)
-    .map((val) => String(val))
-    .filter(Boolean);
-
-  return createScheduleRow({
-    id,
-    deviceId: deviceId === null || deviceId === undefined ? "" : String(deviceId),
-    deviceName,
-    userIds,
-    startTime,
-  });
-};
-
-const buildScheduleRowsFromRecords = (records) => {
-  const list = Array.isArray(records) ? records : [];
-  const grouped = new Map();
-
-  list.forEach((record) => {
-    const row = mapMachineRecordToScheduleRow(record);
-    const key = `${row.deviceId}__${row.startTime}__${row.deviceName}`;
-
-    if (!grouped.has(key)) {
-      grouped.set(key, row);
+    const workOrderRow = currentReportRowData.value;
+    if (!workOrderRow?.id) {
+      ElMessage.warning("缂哄皯宸ュ崟淇℃伅锛屾棤娉曚繚瀛樻帓浜�");
       return;
     }
 
-    const existing = grouped.get(key);
-    existing.ids = Array.from(new Set([existing.id, row.id].filter(Boolean)));
-    existing.userIds = Array.from(
-      new Set([...(existing?.userIds || []), ...(row?.userIds || [])].map((v) => String(v)))
-    ).filter(Boolean);
-
-    if (!existing.deviceName && row.deviceName) existing.deviceName = row.deviceName;
-  });
-
-  return Array.from(grouped.values()).sort(
-    (a, b) => dayjs(a.startTime).valueOf() - dayjs(b.startTime).valueOf()
-  );
-};
-
-const resetCreateScheduleRows = () => {
-  schedulePage.current = 1;
-  schedulePage.total = 0;
-  scheduleRows.value = [];
-  addScheduleRow();
-};
-
-const openScheduleDialog = async (row) => {
-  scheduleDialogMode.value = "create";
-  currentReportRowData.value = row;
-  baseScheduleUsers.value = buildBaseScheduleUsersByRow(row);
-  userTemp.value = [...baseScheduleUsers.value];
-  scheduleDialogVisible.value = true;
-  resetCreateScheduleRows();
-};
-
-const openHistoryTimelineDialog = async (row) => {
-  scheduleDialogMode.value = "history";
-  currentReportRowData.value = row;
-  baseScheduleUsers.value = buildBaseScheduleUsersByRow(row);
-  userTemp.value = [...baseScheduleUsers.value];
-  schedulePage.current = 1;
-  schedulePage.total = 0;
-  scheduleRows.value = [];
-  scheduleDialogVisible.value = true;
-
-  await refreshScheduleRows();
-};
-
-const handleSaveSchedule = async () => {
-  if (isScheduleHistoryMode.value) return;
-  if (scheduleSaving.value) return;
-  if (!validateScheduleRows()) return;
-
-  const workOrderRow = currentReportRowData.value;
-  if (!workOrderRow?.id) {
-    ElMessage.warning("缂哄皯宸ュ崟淇℃伅锛屾棤娉曚繚瀛樻帓浜�");
-    return;
-  }
-
-  const sortedRows = [...scheduleRows.value].sort((a, b) => dayjs(a.startTime).valueOf() - dayjs(b.startTime).valueOf());
-
-  scheduleSaving.value = true;
-  try {
-    const productionMachineRecord = sortedRows.map((scheduleRow, index) =>
-      buildMachineRecordPayload(workOrderRow, scheduleRow, index)
+    const sortedRows = [...scheduleRows.value].sort(
+      (a, b) => dayjs(a.startTime).valueOf() - dayjs(b.startTime).valueOf()
     );
 
-    const res = await addProductionMachineRecord({productionMachineRecord});
-    if (res?.code !== undefined && res.code !== 200) {
-      ElMessage.error(res?.msg || "淇濆瓨鎺掍骇澶辫触");
+    scheduleSaving.value = true;
+    try {
+      const productionMachineRecord = sortedRows.map((scheduleRow, index) =>
+        buildMachineRecordPayload(workOrderRow, scheduleRow, index)
+      );
+
+      const res = await addProductionMachineRecord({ productionMachineRecord });
+      if (res?.code !== undefined && res.code !== 200) {
+        ElMessage.error(res?.msg || "淇濆瓨鎺掍骇澶辫触");
+        return;
+      }
+
+      proxy.$modal.msgSuccess("鎺掍骇宸蹭繚瀛�");
+      scheduleDialogVisible.value = false;
+      resetCreateScheduleRows();
+      await getList();
+    } catch (error) {
+      console.error("淇濆瓨鎺掍骇澶辫触", error);
+      ElMessage.error("淇濆瓨鎺掍骇澶辫触锛岃閲嶈瘯");
+    } finally {
+      scheduleSaving.value = false;
+    }
+  };
+
+  const tableColumn = ref([
+    {
+      label: "宸ュ崟绫诲瀷",
+      prop: "workOrderType",
+      width: "80",
+    },
+    {
+      label: "宸ュ崟缂栧彿",
+      prop: "workOrderNo",
+      width: "140",
+    },
+    {
+      label: "鐢熶骇璁㈠崟鍙�",
+      prop: "productOrderNpsNo",
+      width: "140",
+      formatData: val => (val && val.length > 4 ? val.slice(0, -4) : val || ""),
+    },
+    {
+      label: "鎴愬搧鍚嶇О",
+      prop: "finalProductModel",
+      minWidth: 200,
+      overHidden: false,
+    },
+    // {
+    //   label: "鍔犲伐鍝佸悕绉�",
+    //   prop: "productName",
+    //   width: "140",
+    // },
+    // {
+    //   label: "鍔犲伐鍝佽鏍�",
+    //   prop: "model",
+    // },
+    // {
+    //   label: "鍔犲伐鍝佸崟浣�",
+    //   prop: "unit",
+    // },
+    {
+      label: "宸ュ簭鍚嶇О",
+      prop: "processName",
+    },
+    {
+      label: "闇�姹傛暟閲�",
+      prop: "planQuantity",
+      width: "140",
+    },
+    {
+      label: "瀹屾垚鏁伴噺",
+      prop: "completeQuantity",
+      width: "140",
+    },
+    {
+      label: "瀹屾垚杩涘害",
+      prop: "completionStatus",
+      dataType: "slot",
+      slot: "completionStatus",
+      width: "140",
+    },
+    {
+      label: "璁″垝寮�濮嬫椂闂�",
+      prop: "planStartTime",
+      width: "140",
+    },
+    {
+      label: "璁″垝缁撴潫鏃堕棿",
+      prop: "planEndTime",
+      width: "140",
+    },
+    {
+      label: "瀹為檯寮�濮嬫椂闂�",
+      prop: "actualStartTime",
+      width: "140",
+    },
+    {
+      label: "瀹為檯缁撴潫鏃堕棿",
+      prop: "actualEndTime",
+      width: "140",
+    },
+    {
+      label: "鎿嶄綔",
+      width: "220",
+      align: "center",
+      dataType: "action",
+      fixed: "right",
+      operation: [
+        {
+          name: "缂栬緫",
+          clickFun: row => {
+            handleEdit(row);
+          },
+        },
+        {
+          name: "娴佽浆鍗�",
+          clickFun: row => {
+            downloadAndPrintWorkOrder(row);
+          },
+        },
+        {
+          name: "闄勪欢",
+          clickFun: row => {
+            openWorkOrderFiles(row);
+          },
+        },
+        {
+          name: "鎶ュ伐",
+          clickFun: row => {
+            showReportDialog(row);
+          },
+          // 鐢ㄦ埛褰撳墠id鍦ㄥ伐鍗曟姤宸ヤ汉鎴栧伐搴忔姤宸ヤ汉涓�
+          disabled: row =>
+            row.completeQuantity >= row.planQuantity ||
+            !canCurrentUserReport(row) ||
+            row.hasUnreportedMachine,
+        },
+        {
+          name: "鐢熶骇鎺掍骇",
+          clickFun: row => {
+            if (!row.canSchedule) {
+              ElMessage.warning("褰撳墠鐢ㄦ埛涓嶅湪璇ュ伐搴忎汉鍛樹腑锛屼笉鑳界敓浜ф帓浜�");
+              return;
+            }
+            openScheduleDialog(row);
+          },
+          disabled: row =>
+            !row.canSchedule || row.completeQuantity >= row.planQuantity,
+        },
+        {
+          name: "鎺掍骇璁板綍",
+          clickFun: row => {
+            if (!row.canSchedule) {
+              ElMessage.warning("褰撳墠鐢ㄦ埛涓嶅湪璇ュ伐搴忎汉鍛樹腑锛屼笉鑳芥煡鐪嬫帓浜ц褰�");
+              return;
+            }
+            openHistoryTimelineDialog(row);
+          },
+          disabled: row => !row.canSchedule,
+        },
+        // {
+        //   name:"瀹℃牳",
+        //   color: "#f56c6c",
+        //   clickFun: row => {
+        //     handleAudit(row);
+        //   },
+        //   disabled: row => Number(row?.auditStatus) === 1,
+        // }
+      ],
+    },
+  ]);
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+  const scheduleRows = ref([]);
+  const scheduleLoading = ref(false);
+  const scheduleSaving = ref(false);
+  const schedulePage = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+  const editDialogVisible = ref(false);
+  const transferCardVisible = ref(false);
+  const transferCardQrUrl = ref("");
+  const scheduleDialogVisible = ref(false);
+  const transferCardRowData = ref(null);
+  const baseScheduleUsers = ref([]);
+  const userTemp = ref([]);
+  const reportDialogVisible = ref(false);
+  const auditDialogVisible = ref(false);
+  const auditRowData = ref(null);
+  const auditTableData = ref([]);
+  const auditLoading = ref(false);
+  const workOrderFilesRef = ref(null);
+  const reportFormRef = ref(null);
+  const userOptions = ref([]);
+  const userTeamOptions = ref([]);
+  const reportForm = reactive({
+    planQuantity: 0,
+    quantity: null,
+    scrapQty: null,
+    addQty: 0,
+    startTime: "",
+    endTime: "",
+    userName: "",
+    workOrderId: "",
+    reportWork: "",
+    productProcessRouteItemId: "",
+    userId: "",
+    productMainId: null,
+    teamList: [],
+    deviceId: null,
+  });
+  function removeLastFour(str) {
+    if (!str) return ""; // 绌哄�间繚鎶�
+    return str.toString().slice(0, -4); // 鏍稿績锛氭埅鍙� 0 鍒� 鍊掓暟绗�4浣�
+  }
+  // 鏈鐢熶骇鏁伴噺楠岃瘉瑙勫垯
+  const validateQuantity = (rule, value, callback) => {
+    if (value === null || value === undefined || value === "") {
+      callback(new Error("璇疯緭鍏ユ湰娆$敓浜ф暟閲�"));
+      return;
+    }
+    const num = Number(value);
+    // 鏁存暟涓斿ぇ浜庣瓑浜�1
+    if (isNaN(num) || !Number.isInteger(num) || num < 1) {
+      callback(new Error("鏈鐢熶骇鏁伴噺蹇呴』澶т簬绛変簬1"));
+      return;
+    }
+    callback();
+  };
+
+  // 鎶ュ簾鏁伴噺楠岃瘉瑙勫垯
+  const validateScrapQty = (rule, value, callback) => {
+    if (value === null || value === undefined || value === "") {
+      callback();
+      return;
+    }
+    const num = Number(value);
+    // 鏁存暟涓斿ぇ浜庣瓑浜�0
+    if (isNaN(num) || !Number.isInteger(num) || num < 0) {
+      callback(new Error("鎶ュ簾鏁伴噺蹇呴』澶т簬绛変簬0"));
+      return;
+    }
+    callback();
+  };
+
+  // 瀹℃牳
+  const handleAudit = row => {
+    if (Number(row?.auditStatus) === 1) {
+      ElMessage.warning("璇ュ伐鍗曞凡瀹℃牳");
+      return;
+    }
+    auditRowData.value = row;
+    const workOrderNo = row?.workOrderNo;
+    const related = workOrderNo
+      ? tableData.value.filter(r => r?.workOrderNo === workOrderNo)
+      : [];
+    auditTableData.value = related.length > 0 ? related : [row];
+    auditDialogVisible.value = true;
+  };
+
+  const submitAudit = async result => {
+    const current = auditRowData.value;
+    if (!current) return;
+    if (auditLoading.value) return;
+
+    const confirmText = result === 1 ? "纭畾瀹℃牳閫氳繃鍚楋紵" : "纭畾瀹℃牳涓嶉�氳繃鍚楋紵";
+    try {
+      await ElMessageBox.confirm(confirmText, "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning",
+      });
+    } catch {
       return;
     }
 
-    proxy.$modal.msgSuccess("鎺掍骇宸蹭繚瀛�");
-    scheduleDialogVisible.value = false;
-    resetCreateScheduleRows();
-    await getList();
-  } catch (error) {
-    console.error("淇濆瓨鎺掍骇澶辫触", error);
-    ElMessage.error("淇濆瓨鎺掍骇澶辫触锛岃閲嶈瘯");
-  } finally {
-    scheduleSaving.value = false;
-  }
-};
+    auditLoading.value = true;
+    try {
+      const updates = auditTableData.value.map(item => {
+        const id = item?.id;
+        if (!id) return Promise.resolve();
+        return updateProductWorkOrder({ id, auditStatus: result });
+      });
+      await Promise.all(updates);
+      ElMessage.success("瀹℃牳鎴愬姛");
+      auditDialogVisible.value = false;
+      await getList();
+    } finally {
+      auditLoading.value = false;
+    }
+  };
 
-const tableColumn = ref([
-  {
-    label: "宸ュ崟绫诲瀷",
-    prop: "workOrderType",
-    width: "80",
-  },
-  {
-    label: "宸ュ崟缂栧彿",
-    prop: "workOrderNo",
-    width: "140",
-  },
-  {
-    label: "鐢熶骇璁㈠崟鍙�",
-    prop: "productOrderNpsNo",
-    width: "140",
-    formatData: val => (val && val.length > 4 ? val.slice(0, -4) : val || ""),
-  },
-  {
-    label: "鎴愬搧鍚嶇О",
-    prop: "finalProductModel",
-    minWidth: 200,
-    overHidden: false
-  },
-  // {
-  //   label: "鍔犲伐鍝佸悕绉�",
-  //   prop: "productName",
-  //   width: "140",
-  // },
-  // {
-  //   label: "鍔犲伐鍝佽鏍�",
-  //   prop: "model",
-  // },
-  // {
-  //   label: "鍔犲伐鍝佸崟浣�",
-  //   prop: "unit",
-  // },
-  {
-    label: "宸ュ簭鍚嶇О",
-    prop: "processName",
-  },
-  {
-    label: "闇�姹傛暟閲�",
-    prop: "planQuantity",
-    width: "140",
-  },
-  {
-    label: "瀹屾垚鏁伴噺",
-    prop: "completeQuantity",
-    width: "140",
-  },
-  {
-    label: "瀹屾垚杩涘害",
-    prop: "completionStatus",
-    dataType: "slot",
-    slot: "completionStatus",
-    width: "140",
-  },
-  {
-    label: "璁″垝寮�濮嬫椂闂�",
-    prop: "planStartTime",
-    width: "140",
-  },
-  {
-    label: "璁″垝缁撴潫鏃堕棿",
-    prop: "planEndTime",
-    width: "140",
-  },
-  {
-    label: "瀹為檯寮�濮嬫椂闂�",
-    prop: "actualStartTime",
-    width: "140",
-  },
-  {
-    label: "瀹為檯缁撴潫鏃堕棿",
-    prop: "actualEndTime",
-    width: "140",
-  },
-  {
-    label: "鎿嶄綔",
-    width: "220",
-    align: "center",
-    dataType: "action",
-    fixed: "right",
-    operation: [
-      {
-        name: "缂栬緫",
-        clickFun: row => {
-          handleEdit(row);
-        },
-      },
-      {
-        name: "娴佽浆鍗�",
-        clickFun: row => {
-          downloadAndPrintWorkOrder(row);
-        },
-      },
-      {
-        name: "闄勪欢",
-        clickFun: row => {
-          openWorkOrderFiles(row);
-        },
-      },
-      {
-        name: "鎶ュ伐",
-        clickFun: row => {
-          showReportDialog(row);
-        },
-        // 鐢ㄦ埛褰撳墠id鍦ㄥ伐鍗曟姤宸ヤ汉鎴栧伐搴忔姤宸ヤ汉涓�
-        disabled: row => row.completeQuantity >= row.planQuantity ||
-            !canCurrentUserReport(row) || row.hasUnreportedMachine
-      },
-      {
-        name: "鐢熶骇鎺掍骇",
-        clickFun: row => {
-          if (!row.canSchedule) {
-            ElMessage.warning("褰撳墠鐢ㄦ埛涓嶅湪璇ュ伐搴忎汉鍛樹腑锛屼笉鑳界敓浜ф帓浜�");
-            return;
-          }
-          openScheduleDialog(row);
-        },
-        disabled: row => !row.canSchedule || row.completeQuantity >= row.planQuantity
-      },
-      {
-        name: "鎺掍骇璁板綍",
-        clickFun: row => {
-          if (!row.canSchedule) {
-            ElMessage.warning("褰撳墠鐢ㄦ埛涓嶅湪璇ュ伐搴忎汉鍛樹腑锛屼笉鑳芥煡鐪嬫帓浜ц褰�");
-            return;
-          }
-          openHistoryTimelineDialog(row);
-        },
-        disabled: row => !row.canSchedule
-      }
-      // {
-      //   name:"瀹℃牳",
-      //   color: "#f56c6c",
-      //   clickFun: row => {
-      //     handleAudit(row);
-      //   },
-      //   disabled: row => Number(row?.auditStatus) === 1,
-      // }
-    ],
-  },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const scheduleRows = ref([]);
-const scheduleLoading = ref(false);
-const scheduleSaving = ref(false);
-const schedulePage = reactive({
-  current: 1,
-  size: 10,
-  total: 0,
-});
-const editDialogVisible = ref(false);
-const transferCardVisible = ref(false);
-const transferCardQrUrl = ref("");
-const scheduleDialogVisible = ref(false);
-const transferCardRowData = ref(null);
-const baseScheduleUsers = ref([]);
-const userTemp = ref([]);
-const reportDialogVisible = ref(false);
-const auditDialogVisible = ref(false);
-const auditRowData = ref(null);
-const auditTableData = ref([]);
-const auditLoading = ref(false);
-const workOrderFilesRef = ref(null);
-const reportFormRef = ref(null);
-const userOptions = ref([]);
-const userTeamOptions = ref([]);
-const reportForm = reactive({
-  planQuantity: 0,
-  quantity: null,
-  scrapQty: null,
-  addQty: 0,
-  startTime: "",
-  endTime: "",
-  userName: "",
-  workOrderId: "",
-  reportWork: "",
-  productProcessRouteItemId: "",
-  userId: "",
-  productMainId: null,
-  teamList: [],
-  deviceId: null,
-});
-function removeLastFour(str) {
-  if (!str) return ''; // 绌哄�间繚鎶�
-  return str.toString().slice(0, -4); // 鏍稿績锛氭埅鍙� 0 鍒� 鍊掓暟绗�4浣�
-}
-// 鏈鐢熶骇鏁伴噺楠岃瘉瑙勫垯
-const validateQuantity = (rule, value, callback) => {
-  if (value === null || value === undefined || value === "") {
-    callback(new Error("璇疯緭鍏ユ湰娆$敓浜ф暟閲�"));
-    return;
-  }
-  const num = Number(value);
-  // 鏁存暟涓斿ぇ浜庣瓑浜�1
-  if (isNaN(num) || !Number.isInteger(num) || num < 1) {
-    callback(new Error("鏈鐢熶骇鏁伴噺蹇呴』澶т簬绛変簬1"));
-    return;
-  }
-  callback();
-};
-
-// 鎶ュ簾鏁伴噺楠岃瘉瑙勫垯
-const validateScrapQty = (rule, value, callback) => {
-  if (value === null || value === undefined || value === "") {
-    callback();
-    return;
-  }
-  const num = Number(value);
-  // 鏁存暟涓斿ぇ浜庣瓑浜�0
-  if (isNaN(num) || !Number.isInteger(num) || num < 0) {
-    callback(new Error("鎶ュ簾鏁伴噺蹇呴』澶т簬绛変簬0"));
-    return;
-  }
-  callback();
-};
-
-// 瀹℃牳
-const handleAudit = (row) => {
-  if (Number(row?.auditStatus) === 1) {
-    ElMessage.warning("璇ュ伐鍗曞凡瀹℃牳");
-    return;
-  }
-  auditRowData.value = row;
-  const workOrderNo = row?.workOrderNo;
-  const related = workOrderNo
-      ? tableData.value.filter(r => r?.workOrderNo === workOrderNo)
-      : [];
-  auditTableData.value = related.length > 0 ? related : [row];
-  auditDialogVisible.value = true;
-};
-
-const submitAudit = async (result) => {
-  const current = auditRowData.value;
-  if (!current) return;
-  if (auditLoading.value) return;
-
-  const confirmText = result === 1 ? "纭畾瀹℃牳閫氳繃鍚楋紵" : "纭畾瀹℃牳涓嶉�氳繃鍚楋紵";
-  try {
-    await ElMessageBox.confirm(confirmText, "鎻愮ず", {
-      confirmButtonText: "纭畾",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
+  // 鏌ョ湅璇︽儏
+  const handleView = row => {
+    const { workOrderId } = row;
+    router.push({
+      path: "/productionManagement/workOrderDetail",
+      query: { workOrderId },
     });
-  } catch {
-    return;
-  }
+  };
 
-  auditLoading.value = true;
-  try {
-    const updates = auditTableData.value.map(item => {
-      const id = item?.id;
-      if (!id) return Promise.resolve();
-      return updateProductWorkOrder({id, auditStatus: result});
-    });
-    await Promise.all(updates);
-    ElMessage.success("瀹℃牳鎴愬姛");
-    auditDialogVisible.value = false;
-    await getList();
-  } finally {
-    auditLoading.value = false;
-  }
-};
+  // 楠岃瘉瑙勫垯
+  const reportFormRules = {
+    quantity: [{ required: true, validator: validateQuantity, trigger: "blur" }],
+    scrapQty: [{ validator: validateScrapQty, trigger: "blur" }],
+    startTime: [{ required: true, message: "璇烽�夋嫨寮�濮嬫椂闂�", trigger: "change" }],
+    endTime: [{ required: true, message: "璇烽�夋嫨缁撴潫鏃堕棿", trigger: "change" }],
+    // auditUserId: [{required: true, message: "璇烽�夋嫨瀹℃牳浜�", trigger: "change"}],
+    teamList: [{ required: true, message: "璇烽�夋嫨鐝粍", trigger: "change" }],
+    deviceId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" }],
+  };
 
-// 鏌ョ湅璇︽儏
-const handleView = (row) => {
-  const {workOrderId} = row;
-  router.push({
-    path: "/productionManagement/workOrderDetail",
-    query: {workOrderId},
-  });
-}
-
-// 楠岃瘉瑙勫垯
-const reportFormRules = {
-  quantity: [{required: true, validator: validateQuantity, trigger: "blur"}],
-  scrapQty: [{validator: validateScrapQty, trigger: "blur"}],
-  startTime: [{required: true, message: "璇烽�夋嫨寮�濮嬫椂闂�", trigger: "change"}],
-  endTime: [{required: true, message: "璇烽�夋嫨缁撴潫鏃堕棿", trigger: "change"}],
-  // auditUserId: [{required: true, message: "璇烽�夋嫨瀹℃牳浜�", trigger: "change"}],
-  teamList: [{required: true, message: "璇烽�夋嫨鐝粍", trigger: "change"}],
-  deviceId: [{required: true, message: "璇烽�夋嫨璁惧", trigger: "change"}],
-};
-
-// 澶勭悊鏈鐢熶骇鏁伴噺杈撳叆锛岄檺鍒跺繀椤诲ぇ浜庣瓑浜�1
-const handleQuantityInput = value => {
-  if (value === "" || value === null || value === undefined) {
-    reportForm.quantity = null;
-    return;
-  }
-  const num = Number(value);
-  if (isNaN(num)) {
-    return;
-  }
-  // 濡傛灉灏忎簬1锛屾竻闄�
-  if (num < 1) {
-    reportForm.quantity = null;
-    return;
-  }
-  // 濡傛灉鏄皬鏁板彇鏁存暟閮ㄥ垎
-  if (!Number.isInteger(num)) {
-    const intValue = Math.floor(num);
-    // 濡傛灉鍙栨暣鍚庡皬浜�1锛屾竻闄�
-    if (intValue < 1) {
+  // 澶勭悊鏈鐢熶骇鏁伴噺杈撳叆锛岄檺鍒跺繀椤诲ぇ浜庣瓑浜�1
+  const handleQuantityInput = value => {
+    if (value === "" || value === null || value === undefined) {
       reportForm.quantity = null;
       return;
     }
-    reportForm.quantity = intValue;
-    return;
-  }
-  reportForm.quantity = num;
-};
-
-// 澶勭悊鎶ュ簾鏁伴噺
-const handleScrapQtyInput = value => {
-  if (value === "" || value === null || value === undefined) {
-    reportForm.scrapQty = null;
-    return;
-  }
-  const num = Number(value);
-  // 濡傛灉鏄疦aN锛屼繚鎸佸師鍊�
-  if (isNaN(num)) {
-    return;
-  }
-  // 濡傛灉鏄礋鏁帮紝娓呴櫎杈撳叆
-  if (num < 0) {
-    reportForm.scrapQty = null;
-    return;
-  }
-  // 濡傛灉鏄皬鏁帮紝鍙栨暣鏁伴儴鍒�
-  if (!Number.isInteger(num)) {
-    reportForm.scrapQty = Math.floor(num);
-    return;
-  }
-  // 鏈夋晥鐨勯潪璐熸暣鏁帮紙鍖呮嫭0锛�
-  reportForm.scrapQty = num;
-};
-const currentReportRowData = ref(null);
-const page = reactive({
-  current: 1,
-  size: 100,
-  total: 0,
-});
-
-const data = reactive({
-  searchForm: {
-    workOrderNo: "",
-  },
-});
-const {searchForm} = toRefs(data);
-const toProgressPercentage = val => {
-  const n = Number(val);
-  if (!Number.isFinite(n)) return 0;
-  if (n <= 0) return 0;
-  if (n >= 100) return 100;
-  return Math.round(n);
-};
-const progressColor = percentage => {
-  const p = toProgressPercentage(percentage);
-  if (p < 30) return "#f56c6c";
-  if (p < 50) return "#e6a23c";
-  if (p < 80) return "#409eff";
-  return "#67c23a";
-};
-let editrow = ref(null);
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-  page.current = 1;
-   getList();
-};
-const pagination = obj => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = async () => {
-  tableLoading.value = true;
-
-  try {
-    await ensureCurrentUser();
-    await processLists();
-
-    const params = { ...searchForm.value, ...page };
-    const res = await productWorkOrderPage(params);
-
-    const records = Array.isArray(res?.data?.records) ? res.data.records : [];
-
-    tableData.value = records.map(row => ({
-      ...row,
-      canSchedule: canScheduleByWorkOrderNo(row)
-    }));
-
-    page.total = res?.data?.total || 0;
-  } finally {
-    tableLoading.value = false;
-  }
-};
-
-// 涓嬭浇骞舵墦鍗板伐鍗曟祦杞崱锛堟枃浠舵祦锛�
-const downloadAndPrintWorkOrder = async row => {
-  if (!row || !row.id) {
-    proxy.$modal.msgError("缂哄皯宸ュ崟ID锛屾棤娉曚笅杞芥祦杞崱");
-    return;
-  }
-  const fileName = row.workOrderNo
-      ? `宸ュ崟娴佽浆鍗${row.workOrderNo}.xlsx`
-      : "宸ュ崟娴佽浆鍗�.xlsx";
-  try {
-    // 璋冪敤鎺ュ彛锛屼互 responseType: 'blob' 鑾峰彇鏂囦欢娴�
-    const blob = await downProductWorkOrder(row.id);
-
-    if (!blob) {
-      proxy.$modal.msgError("鏈幏鍙栧埌娴佽浆鍗℃枃浠�");
+    const num = Number(value);
+    if (isNaN(num)) {
       return;
     }
-
-    // 鍒涘缓 Blob URL
-    const fileBlob =
-        blob instanceof Blob
-            ? blob
-            : new Blob([blob], {type: blob.type || "application/octet-stream"});
-    const url = window.URL.createObjectURL(fileBlob);
-
-    // 鍒涘缓闅愯棌 iframe锛岀敤浜庤Е鍙戞祻瑙堝櫒鎵撳嵃
-    const iframe = document.createElement("iframe");
-    iframe.style.position = "fixed";
-    iframe.style.right = "0";
-    iframe.style.bottom = "0";
-    iframe.style.width = "0";
-    iframe.style.height = "0";
-    iframe.style.border = "0";
-    iframe.src = url;
-    document.body.appendChild(iframe);
-
-    iframe.onload = () => {
-      try {
-        iframe.contentWindow?.focus();
-        iframe.contentWindow?.print();
-      } catch (e) {
-        console.error("鑷姩璋冪敤鎵撳嵃澶辫触", e);
-        // 閫�鑰屾眰鍏舵锛屾墦寮�鏂扮獥鍙g敱鐢ㄦ埛鎵嬪姩鎵撳嵃
-        window.open(url);
+    // 濡傛灉灏忎簬1锛屾竻闄�
+    if (num < 1) {
+      reportForm.quantity = null;
+      return;
+    }
+    // 濡傛灉鏄皬鏁板彇鏁存暟閮ㄥ垎
+    if (!Number.isInteger(num)) {
+      const intValue = Math.floor(num);
+      // 濡傛灉鍙栨暣鍚庡皬浜�1锛屾竻闄�
+      if (intValue < 1) {
+        reportForm.quantity = null;
+        return;
       }
-    };
-  } catch (e) {
-    console.error("涓嬭浇宸ュ崟娴佽浆鍗″け璐�", e);
-    proxy.$modal.msgError("涓嬭浇宸ュ崟娴佽浆鍗″け璐�");
-  }
-};
+      reportForm.quantity = intValue;
+      return;
+    }
+    reportForm.quantity = num;
+  };
 
-const showTransferCard = async row => {
-  transferCardRowData.value = row;
-  const qrContent = String(row.id);
+  // 澶勭悊鎶ュ簾鏁伴噺
+  const handleScrapQtyInput = value => {
+    if (value === "" || value === null || value === undefined) {
+      reportForm.scrapQty = null;
+      return;
+    }
+    const num = Number(value);
+    // 濡傛灉鏄疦aN锛屼繚鎸佸師鍊�
+    if (isNaN(num)) {
+      return;
+    }
+    // 濡傛灉鏄礋鏁帮紝娓呴櫎杈撳叆
+    if (num < 0) {
+      reportForm.scrapQty = null;
+      return;
+    }
+    // 濡傛灉鏄皬鏁帮紝鍙栨暣鏁伴儴鍒�
+    if (!Number.isInteger(num)) {
+      reportForm.scrapQty = Math.floor(num);
+      return;
+    }
+    // 鏈夋晥鐨勯潪璐熸暣鏁帮紙鍖呮嫭0锛�
+    reportForm.scrapQty = num;
+  };
+  const currentReportRowData = ref(null);
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
+  });
 
-  transferCardQrUrl.value = await QRCode.toDataURL(qrContent);
-  transferCardVisible.value = true;
-};
+  const data = reactive({
+    searchForm: {
+      workOrderNo: "",
+    },
+  });
+  const { searchForm } = toRefs(data);
+  const toProgressPercentage = val => {
+    const n = Number(val);
+    if (!Number.isFinite(n)) return 0;
+    if (n <= 0) return 0;
+    if (n >= 100) return 100;
+    return Math.round(n);
+  };
+  const progressColor = percentage => {
+    const p = toProgressPercentage(percentage);
+    if (p < 30) return "#f56c6c";
+    if (p < 50) return "#e6a23c";
+    if (p < 80) return "#409eff";
+    return "#67c23a";
+  };
+  let editrow = ref(null);
 
-const printTransferCard = () => {
-  window.print();
-};
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+  const pagination = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+  const getList = async () => {
+    tableLoading.value = true;
 
-const handleEdit = row => {
-  // if (!isCurrentUserReportWorker(row)) {
-  //   ElMessage.warning("褰撳墠鐢ㄦ埛涓嶆槸璇ュ伐鍗曠殑鎶ュ伐浜猴紝鏃犳硶缂栬緫");
-  //   return;
-  // }
-  editrow.value = JSON.parse(JSON.stringify(row));
-  editDialogVisible.value = true;
-};
+    try {
+      await ensureCurrentUser();
+      await processLists();
 
-const handleUpdate = () => {
-  updateProductWorkOrder(editrow.value)
+      const params = { ...searchForm.value, ...page };
+      const res = await productWorkOrderPage(params);
+
+      const records = Array.isArray(res?.data?.records) ? res.data.records : [];
+
+      tableData.value = records.map(row => ({
+        ...row,
+        canSchedule: canScheduleByWorkOrderNo(row),
+      }));
+
+      page.total = res?.data?.total || 0;
+    } finally {
+      tableLoading.value = false;
+    }
+  };
+
+  // 涓嬭浇骞舵墦鍗板伐鍗曟祦杞崱锛堟枃浠舵祦锛�
+  const downloadAndPrintWorkOrder = async row => {
+    if (!row || !row.id) {
+      proxy.$modal.msgError("缂哄皯宸ュ崟ID锛屾棤娉曚笅杞芥祦杞崱");
+      return;
+    }
+    const fileName = row.workOrderNo
+      ? `宸ュ崟娴佽浆鍗${row.workOrderNo}.xlsx`
+      : "宸ュ崟娴佽浆鍗�.xlsx";
+    try {
+      // 璋冪敤鎺ュ彛锛屼互 responseType: 'blob' 鑾峰彇鏂囦欢娴�
+      const blob = await downProductWorkOrder(row.id);
+
+      if (!blob) {
+        proxy.$modal.msgError("鏈幏鍙栧埌娴佽浆鍗℃枃浠�");
+        return;
+      }
+
+      // 鍒涘缓 Blob URL
+      const fileBlob =
+        blob instanceof Blob
+          ? blob
+          : new Blob([blob], { type: blob.type || "application/octet-stream" });
+      const url = window.URL.createObjectURL(fileBlob);
+
+      // 鍒涘缓闅愯棌 iframe锛岀敤浜庤Е鍙戞祻瑙堝櫒鎵撳嵃
+      const iframe = document.createElement("iframe");
+      iframe.style.position = "fixed";
+      iframe.style.right = "0";
+      iframe.style.bottom = "0";
+      iframe.style.width = "0";
+      iframe.style.height = "0";
+      iframe.style.border = "0";
+      iframe.src = url;
+      document.body.appendChild(iframe);
+
+      iframe.onload = () => {
+        try {
+          iframe.contentWindow?.focus();
+          iframe.contentWindow?.print();
+        } catch (e) {
+          console.error("鑷姩璋冪敤鎵撳嵃澶辫触", e);
+          // 閫�鑰屾眰鍏舵锛屾墦寮�鏂扮獥鍙g敱鐢ㄦ埛鎵嬪姩鎵撳嵃
+          window.open(url);
+        }
+      };
+    } catch (e) {
+      console.error("涓嬭浇宸ュ崟娴佽浆鍗″け璐�", e);
+      proxy.$modal.msgError("涓嬭浇宸ュ崟娴佽浆鍗″け璐�");
+    }
+  };
+
+  const showTransferCard = async row => {
+    transferCardRowData.value = row;
+    const qrContent = String(row.id);
+
+    transferCardQrUrl.value = await QRCode.toDataURL(qrContent);
+    transferCardVisible.value = true;
+  };
+
+  const printTransferCard = () => {
+    window.print();
+  };
+
+  const handleEdit = row => {
+    // if (!isCurrentUserReportWorker(row)) {
+    //   ElMessage.warning("褰撳墠鐢ㄦ埛涓嶆槸璇ュ伐鍗曠殑鎶ュ伐浜猴紝鏃犳硶缂栬緫");
+    //   return;
+    // }
+    editrow.value = JSON.parse(JSON.stringify(row));
+    editDialogVisible.value = true;
+  };
+
+  const handleUpdate = () => {
+    updateProductWorkOrder(editrow.value)
       .then(res => {
         proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
         editDialogVisible.value = false;
@@ -1469,379 +1518,388 @@
           confirmButtonText: "纭畾",
         });
       });
-};
+  };
 
-const showReportDialog = row => {
+  const showReportDialog = row => {
+    currentReportRowData.value = row;
+    reportForm.planQuantity = row.planQuantity - row.completeQuantity;
+    reportForm.quantity = row.planQuantity - row.completeQuantity;
+    reportForm.productProcessRouteItemId = row.productProcessRouteItemId;
+    reportForm.workOrderId = row.id;
+    reportForm.reportWork = row.reportWork;
+    reportForm.productMainId = row.productMainId;
+    reportForm.startTime = "";
+    reportForm.endTime = "";
+    reportForm.replenishQty = 0;
+    reportForm.teamList = [];
+    reportForm.scrapQty = 0;
+    reportForm.addQty = 0;
+    reportForm.userIds = row.userIds || [];
 
-  currentReportRowData.value = row;
-  reportForm.planQuantity = row.planQuantity - row.completeQuantity;
-  reportForm.quantity = row.planQuantity - row.completeQuantity;
-  reportForm.productProcessRouteItemId = row.productProcessRouteItemId;
-  reportForm.workOrderId = row.id;
-  reportForm.reportWork = row.reportWork;
-  reportForm.productMainId = row.productMainId;
-  reportForm.startTime = "";
-  reportForm.endTime = "";
-  reportForm.replenishQty = 0;
-  reportForm.teamList = [];
-  reportForm.scrapQty = 0;
-  reportForm.addQty = 0;
-  reportForm.userIds = row.userIds || [];
-
-  // 鍚堝苟宸ュ崟鎶ュ伐浜哄拰宸ュ簭鎶ュ伐浜猴紝鍘婚噸
-  const workOrderUserIds = normalizeArray(row.userIds)
+    // 鍚堝苟宸ュ崟鎶ュ伐浜哄拰宸ュ簭鎶ュ伐浜猴紝鍘婚噸
+    const workOrderUserIds = normalizeArray(row.userIds)
       .map(id => String(id).trim())
       .filter(Boolean);
-  const processUserIds = normalizeArray(row.processUserIds)
+    const processUserIds = normalizeArray(row.processUserIds)
       .map(id => String(id).trim())
       .filter(Boolean);
-  const allowedUserIds = [...new Set([...workOrderUserIds, ...processUserIds])];
+    const allowedUserIds = [...new Set([...workOrderUserIds, ...processUserIds])];
 
-  // 鍙厑璁搁�夋嫨宸ュ崟鎶ュ伐浜哄拰宸ュ簭鎶ュ伐浜�
-  reportForm.userIdsList = userTeamOptions.value
+    // 鍙厑璁搁�夋嫨宸ュ崟鎶ュ伐浜哄拰宸ュ簭鎶ュ伐浜�
+    reportForm.userIdsList = userTeamOptions.value
       .filter(item => allowedUserIds.includes(String(item.userId)))
       .map(item => ({
         userId: item.userId,
-        nickName: item.nickName
+        nickName: item.nickName,
       }));
 
+    nextTick(() => {
+      reportFormRef.value?.clearValidate();
+    });
+    ensureCurrentUser().then(() => {
+      reportForm.userId = currentUserId.value;
+      reportForm.userName = currentUserName.value;
+    });
 
-  nextTick(() => {
-    reportFormRef.value?.clearValidate();
-  });
-  ensureCurrentUser().then(() => {
-    reportForm.userId = currentUserId.value;
-    reportForm.userName = currentUserName.value;
-  });
+    reportDialogVisible.value = true;
+  };
 
-  reportDialogVisible.value = true;
-};
+  const openWorkOrderFiles = row => {
+    workOrderFilesRef.value?.openDialog(row);
+  };
 
-const openWorkOrderFiles = row => {
-  workOrderFilesRef.value?.openDialog(row);
-};
+  const handleReport = () => {
+    reportFormRef.value?.validate(valid => {
+      if (!valid) {
+        return false;
+      }
 
-const handleReport = () => {
-  reportFormRef.value?.validate(valid => {
-    if (!valid) {
-      return false;
-    }
+      if (reportForm.planQuantity <= 0) {
+        ElMessageBox.alert("寰呯敓浜ф暟閲忎负0锛屾棤娉曟姤宸�", "鎻愮ず", {
+          confirmButtonText: "纭畾",
+        });
+        return;
+      }
 
-    if (reportForm.planQuantity <= 0) {
-      ElMessageBox.alert("寰呯敓浜ф暟閲忎负0锛屾棤娉曟姤宸�", "鎻愮ず", {
-        confirmButtonText: "纭畾",
-      });
-      return;
-    }
-
-    // 楠岃瘉鏈鐢熶骇鏁伴噺
-    if (
+      // 楠岃瘉鏈鐢熶骇鏁伴噺
+      if (
         reportForm.quantity === null ||
         reportForm.quantity === undefined ||
         reportForm.quantity === ""
-    ) {
-      ElMessageBox.alert("璇疯緭鍏ユ湰娆$敓浜ф暟閲�", "鎻愮ず", {
-        confirmButtonText: "纭畾",
-      });
-      return;
-    }
+      ) {
+        ElMessageBox.alert("璇疯緭鍏ユ湰娆$敓浜ф暟閲�", "鎻愮ず", {
+          confirmButtonText: "纭畾",
+        });
+        return;
+      }
 
-    const quantity = Number(reportForm.quantity);
-    const scrapQty =
+      const quantity = Number(reportForm.quantity);
+      const scrapQty =
         reportForm.scrapQty === null ||
         reportForm.scrapQty === undefined ||
         reportForm.scrapQty === ""
-            ? 0
-            : Number(reportForm.scrapQty);
+          ? 0
+          : Number(reportForm.scrapQty);
 
-    // 鏈鐢熶骇鏁伴噺
-    if (isNaN(quantity) || !Number.isInteger(quantity) || quantity < 1) {
-      ElMessageBox.alert("鏈鐢熶骇鏁伴噺蹇呴』澶т簬绛変簬1", "鎻愮ず", {
-        confirmButtonText: "纭畾",
-      });
-      return;
-    }
-
-    // 鎶ュ簾鏁伴噺蹇呴』鏄暣鏁颁笖澶т簬绛変簬0
-    if (isNaN(scrapQty) || !Number.isInteger(scrapQty) || scrapQty < 0) {
-      ElMessageBox.alert("鎶ュ簾鏁伴噺蹇呴』澶т簬绛変簬0", "鎻愮ず", {
-        confirmButtonText: "纭畾",
-      });
-      return;
-    }
-
-    // if (quantity > reportForm.planQuantity) {
-    //   ElMessageBox.alert("鏈鐢熶骇鏁伴噺涓嶈兘瓒呰繃寰呯敓浜ф暟閲�", "鎻愮ず", {
-    //     confirmButtonText: "纭畾",
-    //   });
-    //   return;
-    // }
-
-    const submitData = {
-      ...reportForm,
-      quantity: quantity,
-      scrapQty: scrapQty,
-    };
-    addProductMain(submitData).then(res => {
-      if (res.code === 200) {
-        proxy.$modal.msgSuccess("鎶ュ伐鎴愬姛");
-        reportDialogVisible.value = false;
-        getList();
-      } else {
-        ElMessageBox.alert(res.msg || "鎶ュ伐澶辫触", "鎻愮ず", {
+      // 鏈鐢熶骇鏁伴噺
+      if (isNaN(quantity) || !Number.isInteger(quantity) || quantity < 1) {
+        ElMessageBox.alert("鏈鐢熶骇鏁伴噺蹇呴』澶т簬绛変簬1", "鎻愮ず", {
           confirmButtonText: "纭畾",
         });
+        return;
       }
-    });
-  });
-};
 
-// 鑾峰彇鐢ㄦ埛鍒楄〃
-const getUserList = () => {
-  userListNoPageByTenantId()
+      // 鎶ュ簾鏁伴噺蹇呴』鏄暣鏁颁笖澶т簬绛変簬0
+      if (isNaN(scrapQty) || !Number.isInteger(scrapQty) || scrapQty < 0) {
+        ElMessageBox.alert("鎶ュ簾鏁伴噺蹇呴』澶т簬绛変簬0", "鎻愮ず", {
+          confirmButtonText: "纭畾",
+        });
+        return;
+      }
+
+      // if (quantity > reportForm.planQuantity) {
+      //   ElMessageBox.alert("鏈鐢熶骇鏁伴噺涓嶈兘瓒呰繃寰呯敓浜ф暟閲�", "鎻愮ず", {
+      //     confirmButtonText: "纭畾",
+      //   });
+      //   return;
+      // }
+
+      const submitData = {
+        ...reportForm,
+        quantity: quantity,
+        scrapQty: scrapQty,
+      };
+      addProductMain(submitData).then(res => {
+        if (res.code === 200) {
+          proxy.$modal.msgSuccess("鎶ュ伐鎴愬姛");
+          reportDialogVisible.value = false;
+          getList();
+        } else {
+          ElMessageBox.alert(res.msg || "鎶ュ伐澶辫触", "鎻愮ず", {
+            confirmButtonText: "纭畾",
+          });
+        }
+      });
+    });
+  };
+
+  // 鑾峰彇鐢ㄦ埛鍒楄〃
+  const getUserList = () => {
+    userListNoPageByTenantId()
       .then(res => {
         if (res.code === 200) {
-          const list = Array.isArray(res.data) ? res.data : []
+          const list = Array.isArray(res.data) ? res.data : [];
           userOptions.value = [
-            {nickName: "浠绘剰鐢ㄦ埛", userId: "-1"},
-            ...deepClone(list)
-          ]
-          userTeamOptions.value = deepClone(list)
+            { nickName: "浠绘剰鐢ㄦ埛", userId: "-1" },
+            ...deepClone(list),
+          ];
+          userTeamOptions.value = deepClone(list);
         }
       })
       .catch(err => {
         console.error("鑾峰彇鐢ㄦ埛鍒楄〃澶辫触", err);
       });
-};
+  };
 
-// 鐢ㄦ埛閫夋嫨鍙樺寲鏃舵洿鏂� userName
-const handleUserChange = userId => {
-  if (userId) {
-    const selectedUser = userOptions.value.find(user => user.userId === userId);
-    if (selectedUser) {
-      reportForm.userName = selectedUser.nickName;
+  // 鐢ㄦ埛閫夋嫨鍙樺寲鏃舵洿鏂� userName
+  const handleUserChange = userId => {
+    if (userId) {
+      const selectedUser = userOptions.value.find(user => user.userId === userId);
+      if (selectedUser) {
+        reportForm.userName = selectedUser.nickName;
+      }
+    } else {
+      reportForm.userName = "";
     }
-  } else {
-    reportForm.userName = "";
-  }
-};
-// 瀹℃牳浜�
-const handleReviewerIdChange = userId => {
-  if (userId) {
-    const selectedUser = userOptions.value.find(user => user.userId === userId);
-    if (selectedUser) {
-      reportForm.auditUserName = selectedUser.nickName;
+  };
+
+  const handleTeamListChange = val => {
+    if (!Array.isArray(val)) return;
+    if (!val.some(item => typeof item === "string")) return;
+    reportForm.teamList = val.map(item => {
+      if (typeof item === "string") {
+        return { userName: item };
+      }
+      return item;
+    });
+  };
+  // 瀹℃牳浜�
+  const handleReviewerIdChange = userId => {
+    if (userId) {
+      const selectedUser = userOptions.value.find(user => user.userId === userId);
+      if (selectedUser) {
+        reportForm.auditUserName = selectedUser.nickName;
+      }
+    } else {
+      reportForm.auditUserName = "";
     }
-  } else {
-    reportForm.auditUserName = "";
-  }
-}
+  };
 
-const processData = ref([]);
+  const processData = ref([]);
 
-// 鏌ヨ鎵�鏈夊伐搴�
-const processLists = async () => {
-  console.log(processData.value)
-  if (processData.value.length > 0) {
+  // 鏌ヨ鎵�鏈夊伐搴�
+  const processLists = async () => {
+    console.log(processData.value);
+    if (processData.value.length > 0) {
+      return processData.value;
+    }
+    const res = await processList();
+
+    processData.value = Array.isArray(res?.data) ? res.data : [];
     return processData.value;
-  }
-  const res = await processList();
+  };
 
-  processData.value = Array.isArray(res?.data) ? res.data : [];
-  return processData.value;
-};
+  // 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁鑳芥帓浜�
+  const canScheduleByWorkOrderNo = row => {
+    if (!row) return false;
 
-// 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁鑳芥帓浜�
-const canScheduleByWorkOrderNo = (row) => {
-  if (!row) return false;
+    const uid = String(currentUserId.value || "");
+    if (!uid) return false;
 
-  const uid = String(currentUserId.value || "");
-  if (!uid) return false;
+    const currentProcess = processData.value.find(
+      item => String(item.id) === String(row.processId)
+    );
 
-  const currentProcess = processData.value.find(item =>
-      String(item.id) === String(row.processId)
-  );
+    if (!currentProcess) return false;
 
-  if (!currentProcess) return false;
-
-  const ids = normalizeArray(currentProcess.userIds)
+    const ids = normalizeArray(currentProcess.userIds)
       .map(id => String(id).trim())
       .filter(Boolean);
 
-  return ids.includes(uid);
-};
+    return ids.includes(uid);
+  };
 
-onMounted(async () => {
-  await ensureCurrentUser();
-  await processLists();
-  await getList();
-  getUserList();
-  getDeviceList();
-});
+  onMounted(async () => {
+    await ensureCurrentUser();
+    await processLists();
+    await getList();
+    getUserList();
+    getDeviceList();
+  });
 </script>
 
 <style scoped lang="scss">
-.search_form {
-  margin-bottom: 20px;
+  .search_form {
+    margin-bottom: 20px;
 
-  .search-row {
+    .search-row {
+      display: flex;
+      gap: 20px;
+      align-items: center;
+
+      .search-item {
+        display: flex;
+        align-items: center;
+        gap: 10px;
+      }
+    }
+  }
+
+  .transfer-card-title {
+    font-size: 24px;
+    font-weight: bold;
+    text-align: center;
+    margin-bottom: 20px;
+  }
+
+  .transfer-card-container {
     display: flex;
     gap: 20px;
-    align-items: center;
+    height: 350px;
 
-    .search-item {
+    .transfer-card-info {
+      flex: 1;
+      overflow: auto;
+
+      .info-group {
+        width: 50%;
+        float: left;
+      }
+
+      .info-item {
+        display: flex;
+        margin-bottom: 15px;
+
+        .info-label {
+          width: 120px;
+          font-weight: bold;
+          margin-right: 20px;
+        }
+
+        .info-value {
+          flex: 1;
+        }
+      }
+    }
+
+    .transfer-card-qr {
+      width: 240px;
       display: flex;
+      flex-direction: column;
       align-items: center;
-      gap: 10px;
-    }
-  }
-}
-
-.transfer-card-title {
-  font-size: 24px;
-  font-weight: bold;
-  text-align: center;
-  margin-bottom: 20px;
-}
-
-.transfer-card-container {
-  display: flex;
-  gap: 20px;
-  height: 350px;
-
-  .transfer-card-info {
-    flex: 1;
-    overflow: auto;
-
-    .info-group {
-      width: 50%;
-      float: left;
-    }
-
-    .info-item {
-      display: flex;
-      margin-bottom: 15px;
-
-      .info-label {
-        width: 120px;
-        font-weight: bold;
-        margin-right: 20px;
-      }
-
-      .info-value {
-        flex: 1;
-      }
+      justify-content: flex-start;
     }
   }
 
-  .transfer-card-qr {
-    width: 240px;
+  .schedule-user-tags {
     display: flex;
-    flex-direction: column;
+    flex-wrap: wrap;
+    gap: 8px;
+    min-height: 32px;
     align-items: center;
-    justify-content: flex-start;
   }
-}
-
-.schedule-user-tags {
-  display: flex;
-  flex-wrap: wrap;
-  gap: 8px;
-  min-height: 32px;
-  align-items: center;
-}
 </style>
 
 <style lang="scss">
-@media print {
-  @page {
-    size: landscape;
-  }
-  body * {
-    visibility: hidden;
-  }
-  .el-dialog__wrapper,
-  .el-dialog,
-  .el-dialog__body,
-  .transfer-card-title,
-  .transfer-card-container,
-  .transfer-card-container *,
-  .info-item,
-  .info-label,
-  .info-value {
-    visibility: visible;
-  }
-  .print-button-container {
-    visibility: hidden;
-  }
-  .el-dialog__wrapper {
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    margin: 0;
-  }
-  .el-dialog {
-    width: 100% !important;
-    max-width: 800px;
-    margin: 0 auto !important;
-  }
-  .el-dialog__header,
-  .el-dialog__footer {
-    display: none;
-  }
-  .el-dialog__body {
-    padding: 20px;
-  }
-  .transfer-card-container {
-    height: auto;
-    display: flex;
-    gap: 20px;
-  }
-  .transfer-card-info {
-    flex: 1;
-
-    .info-group {
-      width: 100%;
-      float: none;
-      margin-bottom: 20px;
+  @media print {
+    @page {
+      size: landscape;
     }
-
-    .info-item {
+    body * {
+      visibility: hidden;
+    }
+    .el-dialog__wrapper,
+    .el-dialog,
+    .el-dialog__body,
+    .transfer-card-title,
+    .transfer-card-container,
+    .transfer-card-container *,
+    .info-item,
+    .info-label,
+    .info-value {
+      visibility: visible;
+    }
+    .print-button-container {
+      visibility: hidden;
+    }
+    .el-dialog__wrapper {
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      margin: 0;
+    }
+    .el-dialog {
+      width: 100% !important;
+      max-width: 800px;
+      margin: 0 auto !important;
+    }
+    .el-dialog__header,
+    .el-dialog__footer {
+      display: none;
+    }
+    .el-dialog__body {
+      padding: 20px;
+    }
+    .transfer-card-container {
+      height: auto;
       display: flex;
-      margin-bottom: 10px;
+      gap: 20px;
+    }
+    .transfer-card-info {
+      flex: 1;
 
-      .info-label {
-        width: 100px;
-        font-weight: bold;
-        margin-right: 15px;
-        white-space: nowrap;
+      .info-group {
+        width: 100%;
+        float: none;
+        margin-bottom: 20px;
       }
 
-      .info-value {
-        flex: 1;
-        word-break: break-word;
+      .info-item {
+        display: flex;
+        margin-bottom: 10px;
+
+        .info-label {
+          width: 100px;
+          font-weight: bold;
+          margin-right: 15px;
+          white-space: nowrap;
+        }
+
+        .info-value {
+          flex: 1;
+          word-break: break-word;
+        }
       }
     }
+    .transfer-card-qr {
+      width: 160px;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: flex-start;
+    }
+    .qr-container img {
+      width: 140px !important;
+      height: 140px !important;
+    }
   }
-  .transfer-card-qr {
-    width: 160px;
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    justify-content: flex-start;
+  .el-table .cell {
+    white-space: normal !important;
+    word-break: break-all;
   }
-  .qr-container img {
-    width: 140px !important;
-    height: 140px !important;
-  }
-}
-.el-table .cell {
-  white-space: normal !important;
-  word-break: break-all;
-}
 
-.over-limit .el-input__inner {
-  color: #f56c6c !important;
-}
+  .over-limit .el-input__inner {
+    color: #f56c6c !important;
+  }
 </style>

--
Gitblit v1.9.3