gongchunyi
2026-09-02 33889fd272af7d58870ebff56959184a3798ce31
feat: 领料台账添加库存余量列展示
已修改1个文件
47 ■■■■■ 文件已修改
src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
@@ -80,6 +80,13 @@
                             @change="val => handleRequiredQtyChange(row, val)" />
          </template>
        </el-table-column>
        <el-table-column label="库存余量"
                         min-width="90">
          <template #default="{ row }">
            <span v-if="row.stockQty === null">-</span>
            <span v-else>{{ stripTrailingZeros(row.stockQty) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="已领数量"
                         min-width="90">
          <template #default="{ row }">
@@ -145,6 +152,7 @@
  import { ElMessage } from "element-plus";
  import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
  import { findProductProcessRouteItemList } from "@/api/productionManagement/productProcessRoute.js";
  import { getStockInventoryByModelId } from "@/api/inventoryManagement/stockInventory.js";
  import {
    listMaterialPickingDetail,
    listMaterialPickingBom,
@@ -222,6 +230,7 @@
      returnedQty,
      remainingQty,
      pickQty: 0,
      stockQty: null,
      batchNo: [],
      batchNoList,
    };
@@ -349,6 +358,9 @@
          })
        );
      });
      // 先查出库存余量再入表,保证首次打开即展示(rows 尚未转为响应式代理,
      // 入表后再改原始对象不会触发视图更新)
      await loadStockQtyForRows(rows);
      materialTableData.value = rows;
    } finally {
      materialTableLoading.value = false;
@@ -367,6 +379,40 @@
  const handleClose = () => {
    materialTableData.value = [];
    currentMaterialSelectRowIndex.value = -1;
  };
  // 按型号汇总所有批次的原料可用库存余量
  const loadStockQtyForRows = async rows => {
    const modelIds = [
      ...new Set(rows.map(row => row.materialModelId).filter(Boolean)),
    ];
    const stockMap = new Map();
    await Promise.all(
      modelIds.map(async modelId => {
        try {
          const res = await getStockInventoryByModelId(modelId);
          const list = Array.isArray(res?.data)
            ? res.data
            : res?.data?.records || res?.data?.rows || [];
          const total = list.reduce(
            (sum, item) => sum + toNumber(item?.qualitity ?? item?.quantity),
            0
          );
          stockMap.set(modelId, roundQuantity(total));
        } catch (e) {
          stockMap.set(modelId, 0);
        }
      })
    );
    rows.forEach(row => {
      if (!row.materialModelId) {
        row.stockQty = null;
        return;
      }
      row.stockQty = stockMap.has(row.materialModelId)
        ? stockMap.get(row.materialModelId)
        : 0;
    });
  };
  const handleAddMaterialRow = () => {
@@ -416,6 +462,7 @@
    row.batchNo = [];
    currentMaterialSelectRowIndex.value = -1;
    materialProductDialogVisible.value = false;
    loadStockQtyForRows([row]);
  };
  const validateMaterialRows = () => {