From 6361501810a76b6809162cac99b0d9c1faba3715 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期四, 16 四月 2026 15:10:02 +0800
Subject: [PATCH] fix: 对退料请求做限制

---
 src/views/productionManagement/productionOrder/index.vue |  385 +-----------------------------------------------------
 1 files changed, 10 insertions(+), 375 deletions(-)

diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index c66a0ec..cc0de4e 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -91,161 +91,16 @@
       </template>
     </el-dialog>
 
-    <el-dialog
+    <MaterialLedgerDialog
       v-model="materialDialogVisible"
-      title="棰嗘枡鍙拌处"
-      width="1200px"
-      @close="handleMaterialDialogClose"
-    >
-      <div class="material-toolbar">
-        <el-button type="primary" @click="handleAddMaterialRow">鏂板</el-button>
-      </div>
-      <el-table
-        v-loading="materialTableLoading"
-        :data="materialTableData"
-        border
-        row-key="tempId"
-      >
-        <el-table-column label="宸ュ簭鍚嶇О" min-width="180">
-          <template #default="{ row }">
-            <el-select
-              v-model="row.processId"
-              placeholder="璇烽�夋嫨宸ュ簭"
-              clearable
-              filterable
-              style="width: 100%;"
-              @change="val => handleProcessChange(row, val)"
-            >
-              <el-option
-                v-for="item in processOptions"
-                :key="item.id"
-                :label="item.name"
-                :value="item.id"
-              />
-            </el-select>
-          </template>
-        </el-table-column>
-        <el-table-column label="鍘熸枡鍚嶇О" min-width="160">
-          <template #default="{ row }">
-            <el-button type="primary" link @click="openMaterialProductSelect(row)">
-              {{ row.materialName || "閫夋嫨鍘熸枡" }}
-            </el-button>
-          </template>
-        </el-table-column>
-        <el-table-column label="鍘熸枡鍨嬪彿" min-width="180">
-          <template #default="{ row }">
-            {{ row.materialModel || "-" }}
-          </template>
-        </el-table-column>
-        <el-table-column label="闇�姹傛暟閲�" min-width="120">
-          <template #default="{ row }">
-            <el-input-number
-              v-model="row.requiredQty"
-              :min="0"
-              :precision="3"
-              :step="1"
-              controls-position="right"
-              style="width: 100%;"
-              @change="val => handleRequiredQtyChange(row, val)"
-            />
-          </template>
-        </el-table-column>
-        <el-table-column label="璁¢噺鍗曚綅" width="120">
-          <template #default="{ row }">
-            {{ row.unit || "-" }}
-          </template>
-        </el-table-column>
-        <el-table-column label="棰嗙敤鏁伴噺" min-width="120">
-          <template #default="{ row }">
-            <el-input-number
-              v-model="row.pickQty"
-              :min="0"
-              :precision="3"
-              :step="1"
-              controls-position="right"
-              style="width: 100%;"
-            />
-          </template>
-        </el-table-column>
-        <el-table-column label="鎿嶄綔" width="90" fixed="right">
-          <template #default="{ $index }">
-            <el-button type="danger" link @click="handleDeleteMaterialRow($index)">鍒犻櫎</el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button type="primary" :loading="materialSaving" @click="handleMaterialSave">淇濆瓨</el-button>
-          <el-button @click="materialDialogVisible = false">鍙栨秷</el-button>
-        </span>
-      </template>
-    </el-dialog>
-
-    <ProductSelectDialog
-      v-model="materialProductDialogVisible"
-      @confirm="handleMaterialProductConfirm"
-      single
+      :order-row="currentMaterialOrder"
+      @saved="getList"
     />
-
-    <el-dialog
+    <MaterialDetailDialog
       v-model="materialDetailDialogVisible"
-      title="棰嗘枡璇︽儏"
-      width="1400px"
-      @close="handleMaterialDetailDialogClose"
-    >
-      <el-table
-        v-loading="materialDetailLoading"
-        :data="materialDetailTableData"
-        border
-        row-key="id"
-      >
-        <el-table-column label="宸ュ簭鍚嶇О" prop="processName" min-width="180" />
-        <el-table-column label="鍘熸枡鍚嶇О" prop="materialName" min-width="160" />
-        <el-table-column label="鍘熸枡鍨嬪彿" prop="materialModel" min-width="180" />
-        <el-table-column label="闇�姹傛暟閲�" prop="requiredQty" min-width="110" />
-        <el-table-column label="璁¢噺鍗曚綅" prop="unit" width="100" />
-        <el-table-column label="棰嗙敤鏁伴噺" prop="pickQty" min-width="110" />
-        <el-table-column label="琛ユ枡鏁伴噺" min-width="120">
-          <template #default="{ row }">
-            <el-button type="primary" link @click="handleViewSupplementRecord(row)">
-              {{ row.supplementQty ?? 0 }}
-            </el-button>
-          </template>
-        </el-table-column>
-        <el-table-column label="閫�鏂欐暟閲�" prop="returnQty" min-width="110" />
-        <el-table-column label="瀹為檯鏁伴噺" prop="actualQty" min-width="110" />
-      </el-table>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button type="warning" :loading="materialReturnConfirming" @click="handleReturnConfirm">
-            閫�鏂欑‘璁�
-          </el-button>
-          <el-button @click="materialDetailDialogVisible = false">鍙栨秷</el-button>
-        </span>
-      </template>
-    </el-dialog>
-
-    <el-dialog
-      v-model="supplementRecordDialogVisible"
-      title="琛ユ枡璁板綍"
-      width="800px"
-    >
-      <el-table
-        v-loading="supplementRecordLoading"
-        :data="supplementRecordTableData"
-        border
-        row-key="id"
-      >
-        <el-table-column label="琛ユ枡鏁伴噺" prop="supplementQty" min-width="120" />
-        <el-table-column label="琛ユ枡鏃堕棿" prop="supplementTime" min-width="180" />
-        <el-table-column label="澶囨敞" prop="remark" min-width="200" />
-      </el-table>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="supplementRecordDialogVisible = false">鍏抽棴</el-button>
-        </span>
-      </template>
-    </el-dialog>
+      :order-row="currentMaterialDetailOrder"
+      @confirmed="getList"
+    />
 
     <new-product-order v-if="isShowNewModal"
                          v-model:visible="isShowNewModal"
@@ -258,20 +113,15 @@
   import { ElMessageBox } from "element-plus";
   import dayjs from "dayjs";
   import { useRouter } from "vue-router";
-  import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
   import {
     productOrderListPage,
     listProcessRoute,
     bindingRoute,
     listProcessBom, delProductOrder,
-    listMaterialPickingLedger,
-    saveMaterialPickingLedger,
-    listMaterialPickingDetail,
-    listMaterialSupplementRecord,
-    confirmMaterialReturn,
   } from "@/api/productionManagement/productionOrder.js";
   import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
-  import { processList } from "@/api/productionManagement/productionProcess.js";
+  import MaterialLedgerDialog from "@/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue";
+  import MaterialDetailDialog from "@/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue";
   import PIMTable from "@/components/PIMTable/PIMTable.vue";
   const NewProductOrder = defineAsyncComponent(() => import("@/views/productionManagement/productionOrder/New.vue"));
 
@@ -454,35 +304,9 @@
     routeId: null,
   });
   const materialDialogVisible = ref(false);
-  const materialProductDialogVisible = ref(false);
-  const materialTableLoading = ref(false);
-  const materialSaving = ref(false);
-  const materialTableData = ref([]);
-  const processOptions = ref([]);
   const currentMaterialOrder = ref(null);
-  const currentMaterialSelectRowIndex = ref(-1);
   const materialDetailDialogVisible = ref(false);
-  const materialDetailLoading = ref(false);
-  const materialDetailTableData = ref([]);
-  const materialReturnConfirming = ref(false);
   const currentMaterialDetailOrder = ref(null);
-  const supplementRecordDialogVisible = ref(false);
-  const supplementRecordLoading = ref(false);
-  const supplementRecordTableData = ref([]);
-  let materialTempId = 0;
-
-  const createMaterialRow = (row = {}) => ({
-    tempId: row.id || `temp_${++materialTempId}`,
-    id: row.id,
-    processId: row.processId,
-    processName: row.processName || "",
-    materialModelId: row.materialModelId,
-    materialName: row.materialName || "",
-    materialModel: row.materialModel || "",
-    requiredQty: Number(row.requiredQty ?? 0),
-    unit: row.unit || "",
-    pickQty: Number(row.pickQty ?? row.requiredQty ?? 0),
-  });
 
   const openBindRouteDialog = async row => {
     bindForm.orderId = row.id;
@@ -528,199 +352,14 @@
     }
   };
 
-  const getProcessOptions = async () => {
-    if (processOptions.value.length > 0) return;
-    try {
-      const res = await processList({});
-      processOptions.value = res.data || [];
-    } catch (e) {
-      console.error("鑾峰彇宸ュ簭鍒楄〃澶辫触锛�", e);
-      proxy.$modal.msgError("鑾峰彇宸ュ簭鍒楄〃澶辫触");
-    }
-  };
-
-  const openMaterialDialog = async row => {
+  const openMaterialDialog = row => {
     currentMaterialOrder.value = row;
     materialDialogVisible.value = true;
-    materialTableLoading.value = true;
-    materialTableData.value = [];
-    await getProcessOptions();
-    try {
-      const res = await listMaterialPickingLedger({ orderId: row.id });
-      const list = res.data || [];
-      materialTableData.value = list.map(item => createMaterialRow(item));
-    } catch (e) {
-      console.error("鑾峰彇棰嗘枡鍙拌处澶辫触锛�", e);
-      proxy.$modal.msgError("鑾峰彇棰嗘枡鍙拌处澶辫触");
-    } finally {
-      materialTableLoading.value = false;
-    }
-  };
-
-  const handleMaterialDialogClose = () => {
-    materialTableData.value = [];
-    currentMaterialOrder.value = null;
-    currentMaterialSelectRowIndex.value = -1;
-  };
-
-  const handleAddMaterialRow = () => {
-    materialTableData.value.push(createMaterialRow());
-  };
-
-  const handleDeleteMaterialRow = index => {
-    materialTableData.value.splice(index, 1);
-  };
-
-  const handleProcessChange = (row, processId) => {
-    const process = processOptions.value.find(item => item.id === processId);
-    row.processName = process?.name || "";
-  };
-
-  const handleRequiredQtyChange = (row, val) => {
-    const required = Number(val ?? 0);
-    row.requiredQty = required;
-    if (!row.pickQty || Number(row.pickQty) === 0) {
-      row.pickQty = required;
-    }
-  };
-
-  const openMaterialProductSelect = row => {
-    currentMaterialSelectRowIndex.value = materialTableData.value.findIndex(item => item.tempId === row.tempId);
-    materialProductDialogVisible.value = true;
-  };
-
-  const handleMaterialProductConfirm = products => {
-    if (!products || products.length === 0) return;
-    const index = currentMaterialSelectRowIndex.value;
-    if (index < 0 || !materialTableData.value[index]) return;
-    const product = products[0];
-    const row = materialTableData.value[index];
-    row.materialModelId = product.id;
-    row.materialName = product.productName || "";
-    row.materialModel = product.model || "";
-    row.unit = product.unit || "";
-    currentMaterialSelectRowIndex.value = -1;
-    materialProductDialogVisible.value = false;
-  };
-
-  const validateMaterialRows = () => {
-    if (materialTableData.value.length === 0) {
-      proxy.$modal.msgWarning("璇疯嚦灏戞柊澧炰竴鏉¢鏂欒褰�");
-      return false;
-    }
-    const invalidRow = materialTableData.value.find(
-      item =>
-        !item.processId ||
-        !item.materialModelId ||
-        item.requiredQty === null ||
-        item.requiredQty === undefined ||
-        item.pickQty === null ||
-        item.pickQty === undefined
-    );
-    if (invalidRow) {
-      proxy.$modal.msgWarning("璇峰畬鍠勯鏂欏彴璐﹀繀濉瓧娈�");
-      return false;
-    }
-    return true;
-  };
-
-  const handleMaterialSave = async () => {
-    if (!currentMaterialOrder.value?.id) {
-      proxy.$modal.msgWarning("鏈幏鍙栧埌褰撳墠鐢熶骇璁㈠崟");
-      return;
-    }
-    if (!validateMaterialRows()) return;
-    materialSaving.value = true;
-    try {
-      await saveMaterialPickingLedger({
-        orderId: currentMaterialOrder.value.id,
-        items: materialTableData.value.map(item => ({
-          id: item.id,
-          processId: item.processId,
-          processName: item.processName,
-          materialModelId: item.materialModelId,
-          materialName: item.materialName,
-          materialModel: item.materialModel,
-          requiredQty: item.requiredQty,
-          unit: item.unit,
-          pickQty: item.pickQty,
-        })),
-      });
-      proxy.$modal.msgSuccess("淇濆瓨鎴愬姛");
-      materialDialogVisible.value = false;
-    } catch (e) {
-      console.error("淇濆瓨棰嗘枡鍙拌处澶辫触锛�", e);
-      proxy.$modal.msgError("淇濆瓨棰嗘枡鍙拌处澶辫触");
-    } finally {
-      materialSaving.value = false;
-    }
   };
 
   const openMaterialDetailDialog = async row => {
     currentMaterialDetailOrder.value = row;
     materialDetailDialogVisible.value = true;
-    materialDetailLoading.value = true;
-    materialDetailTableData.value = [];
-    try {
-      const res = await listMaterialPickingDetail({ orderId: row.id });
-      materialDetailTableData.value = res.data || [];
-    } catch (e) {
-      console.error("鑾峰彇棰嗘枡璇︽儏澶辫触锛�", e);
-      proxy.$modal.msgError("鑾峰彇棰嗘枡璇︽儏澶辫触");
-    } finally {
-      materialDetailLoading.value = false;
-    }
-  };
-
-  const handleMaterialDetailDialogClose = () => {
-    materialDetailTableData.value = [];
-    currentMaterialDetailOrder.value = null;
-  };
-
-  const handleViewSupplementRecord = async row => {
-    if (!row?.id) {
-      proxy.$modal.msgWarning("缂哄皯棰嗘枡鏄庣粏ID锛屾棤娉曟煡鐪嬭ˉ鏂欒褰�");
-      return;
-    }
-    supplementRecordDialogVisible.value = true;
-    supplementRecordLoading.value = true;
-    supplementRecordTableData.value = [];
-    try {
-      const res = await listMaterialSupplementRecord({ materialDetailId: row.id });
-      supplementRecordTableData.value = res.data || [];
-    } catch (e) {
-      console.error("鑾峰彇琛ユ枡璁板綍澶辫触锛�", e);
-      proxy.$modal.msgError("鑾峰彇琛ユ枡璁板綍澶辫触");
-    } finally {
-      supplementRecordLoading.value = false;
-    }
-  };
-
-  const handleReturnConfirm = async () => {
-    if (!currentMaterialDetailOrder.value?.id) {
-      proxy.$modal.msgWarning("鏈幏鍙栧埌褰撳墠鐢熶骇璁㈠崟");
-      return;
-    }
-    try {
-      await ElMessageBox.confirm("纭鎵ц閫�鏂欑‘璁わ紵", "鎻愮ず", {
-        confirmButtonText: "纭",
-        cancelButtonText: "鍙栨秷",
-        type: "warning",
-      });
-    } catch (e) {
-      return;
-    }
-    materialReturnConfirming.value = true;
-    try {
-      await confirmMaterialReturn({ orderId: currentMaterialDetailOrder.value.id });
-      proxy.$modal.msgSuccess("閫�鏂欑‘璁ゆ垚鍔�");
-      openMaterialDetailDialog(currentMaterialDetailOrder.value);
-    } catch (e) {
-      console.error("閫�鏂欑‘璁ゅけ璐ワ細", e);
-      proxy.$modal.msgError("閫�鏂欑‘璁ゅけ璐�");
-    } finally {
-      materialReturnConfirming.value = false;
-    }
   };
 
   // 鏌ヨ鍒楄〃
@@ -875,8 +514,4 @@
 	margin-top: unset;
 }
 
-.material-toolbar {
-  margin-bottom: 12px;
-  text-align: right;
-}
 </style>

--
Gitblit v1.9.3