From bfa9cabc4fe74da05c3d1eb5148929551c4d87c2 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 28 五月 2026 09:13:01 +0800
Subject: [PATCH] 中兴实强new 1.生产订单领料时如果库存不足可以提交采购申请单 2.采购申请单通知点击跳转是根据合同号直接进行查询

---
 src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue |   87 ++++++++++++++++++++++++++++++++++---------
 1 files changed, 68 insertions(+), 19 deletions(-)

diff --git a/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue b/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
index 09e7421..85fbe35 100644
--- a/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
+++ b/src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
@@ -2,7 +2,7 @@
   <div>
     <el-dialog v-model="dialogVisible"
                title="棰嗘枡鍙拌处"
-               width="1200px"
+               width="1400px"
                @close="handleClose">
       <div class="material-toolbar">
         <el-button type="primary"
@@ -65,10 +65,18 @@
             </el-select>
           </template>
         </el-table-column>
+        <el-table-column label="搴撳瓨鏁伴噺"
+                         min-width="120">
+          <template #default="{ row }">
+            <span :class="{ 'text-danger': isStockInsufficient(row) }">
+              {{ row.stockQuantity ?? '-' }}
+            </span>
+          </template>
+        </el-table-column>
         <el-table-column label="闇�姹傛暟閲�"
                          min-width="120">
           <template #default="{ row }">
-            <span v-if="row.bom === true">{{ row.demandedQuantity ?? "-" }}</span>
+            <span v-if="row.bom === true" :class="{ 'text-danger': isStockInsufficient(row) }">{{ row.demandedQuantity ?? "-" }}</span>
             <el-input-number v-else
                              v-model="row.demandedQuantity"
                              :min="0"
@@ -76,6 +84,7 @@
                              :step="1"
                              controls-position="right"
                              style="width: 100%;"
+                             :class="{ 'is-stock-insufficient': isStockInsufficient(row) }"
                              @change="val => handleRequiredQtyChange(row, val)" />
           </template>
         </el-table-column>
@@ -109,6 +118,9 @@
       </el-table>
       <template #footer>
         <span class="dialog-footer">
+          <el-button v-if="hasInsufficientStock"
+                     type="warning"
+                     @click="openPurchaseRequestDialog">閲囪喘鐢宠</el-button>
           <el-button type="primary"
                      :loading="materialSaving"
                      :disabled="isSaveDisabled"
@@ -120,6 +132,10 @@
     <ProductSelectDialog v-model="materialProductDialogVisible"
                          @confirm="handleMaterialProductConfirm"
                          single />
+    <PurchaseRequestDialog v-model="purchaseRequestDialogVisible"
+                           :insufficient-items="insufficientStockItems"
+                           :order-row="props.orderRow"
+                           @saved="handlePurchaseRequestSaved" />
     <!-- request-url="/stockInventory/rawMaterials" -->
   </div>
 </template>
@@ -128,18 +144,18 @@
   import { computed, ref, watch } from "vue";
   import { ElMessage } from "element-plus";
   import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+  import PurchaseRequestDialog from "./PurchaseRequestDialog.vue";
   import {
     findProductProcessRouteItemList,
     listMain,
   } from "@/api/productionManagement/productProcessRoute.js";
   import {
-    listMaterialPickingDetail,
     listMaterialPickingBom,
-    listMaterialPickingLedger,
     saveMaterialPickingLedger,
     updateMaterialPickingLedger,
   } from "@/api/productionManagement/productionOrder.js";
   import { queryList2 } from "@/api/productionManagement/productStructure.js";
+
 
   const props = defineProps({
     modelValue: { type: Boolean, default: false },
@@ -156,6 +172,7 @@
   const materialTableLoading = ref(false);
   const materialSaving = ref(false);
   const materialTableData = ref([]);
+  const purchaseRequestDialogVisible = ref(false);
 
   const isSaveDisabled = computed(() => {
     if (materialTableData.value.length === 0) return true;
@@ -183,6 +200,23 @@
     });
   });
 
+  // 鍒ゆ柇搴撳瓨鏄惁涓嶈冻
+  const isStockInsufficient = (row) => {
+    const stockQuantity = Number(row.stockQuantity ?? 0);
+    const demandedQty = Number(row.demandedQuantity ?? 0);
+    return demandedQty > 0 && stockQuantity > 0 && demandedQty > stockQuantity;
+  };
+
+  // 搴撳瓨涓嶈冻鐨勮
+  const insufficientStockItems = computed(() => {
+    return materialTableData.value.filter(row => isStockInsufficient(row));
+  });
+
+  // 鏄惁鏈夊簱瀛樹笉瓒�
+  const hasInsufficientStock = computed(() => {
+    return insufficientStockItems.value.length > 0;
+  });
+
   const processOptions = ref([]);
   const currentMaterialSelectRowIndex = ref(-1);
   let materialTempId = 0;
@@ -206,6 +240,7 @@
         : row.batchNo
       : [],
     batchNoList: row.batchNoList || [],
+    stockQuantity: row.stockQuantity ?? row.stockQty ?? null,
   });
 
   const getProcessOptions = async () => {
@@ -239,22 +274,14 @@
     materialTableData.value = [];
     await getProcessOptions();
     try {
-      const detailRes = await listMaterialPickingDetail(props.orderRow.id);
-      const detailList = Array.isArray(detailRes?.data)
-        ? detailRes.data
-        : detailRes?.data?.records || [];
-      if (detailList.length > 0) {
-        isDetail.value = true;
-        materialTableData.value = detailList.map(item => createMaterialRow(item));
-        return;
-      } else {
+      // 鐩存帴璋冪敤listMaterialPickingBom鎺ュ彛鑾峰彇搴撳瓨鏁伴噺
+      const bomRes = await listMaterialPickingBom(props.orderRow.id);
+      const bomList = Array.isArray(bomRes?.data)
+        ? bomRes.data
+        : bomRes?.data?.records || [];
+      if (bomList.length > 0) {
         isDetail.value = false;
-        const bomRes = await listMaterialPickingBom(props.orderRow.id);
-        const bomList = Array.isArray(bomRes?.data)
-          ? bomRes.data
-          : bomRes?.data?.records || [];
         materialTableData.value = bomList.map(item => createMaterialRow(item));
-        return;
       }
     } finally {
       materialTableLoading.value = false;
@@ -305,7 +332,7 @@
     materialProductDialogVisible.value = true;
   };
 
-  const handleMaterialProductConfirm = products => {
+  const handleMaterialProductConfirm = async (products) => {
     console.log(products, "products");
 
     if (!products || products.length === 0) return;
@@ -417,6 +444,17 @@
       materialSaving.value = false;
     }
   };
+
+  // 鎵撳紑閲囪喘鐢宠瀵硅瘽妗�
+  const openPurchaseRequestDialog = () => {
+    purchaseRequestDialogVisible.value = true;
+  };
+
+  // 閲囪喘鐢宠淇濆瓨鍥炶皟
+  const handlePurchaseRequestSaved = () => {
+    // 閲囪喘鐢宠淇濆瓨鎴愬姛鍚庡埛鏂版暟鎹�
+    loadMaterialData();
+  };
 </script>
 
 <style scoped lang="scss">
@@ -424,4 +462,15 @@
     margin-bottom: 12px;
     text-align: right;
   }
+
+  .text-danger {
+    color: #f56c6c;
+    font-weight: bold;
+  }
+
+  :deep(.is-stock-insufficient) {
+    .el-input__wrapper {
+      box-shadow: 0 0 0 1px #f56c6c inset;
+    }
+  }
 </style>

--
Gitblit v1.9.3