| | |
| | | @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 }"> |
| | |
| | | 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, |
| | |
| | | returnedQty, |
| | | remainingQty, |
| | | pickQty: 0, |
| | | stockQty: null, |
| | | batchNo: [], |
| | | batchNoList, |
| | | }; |
| | |
| | | }) |
| | | ); |
| | | }); |
| | | // 先查出库存余量再入表,保证首次打开即展示(rows 尚未转为响应式代理, |
| | | // 入表后再改原始对象不会触发视图更新) |
| | | await loadStockQtyForRows(rows); |
| | | materialTableData.value = rows; |
| | | } finally { |
| | | materialTableLoading.value = false; |
| | |
| | | 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 = () => { |
| | |
| | | row.batchNo = []; |
| | | currentMaterialSelectRowIndex.value = -1; |
| | | materialProductDialogVisible.value = false; |
| | | loadStockQtyForRows([row]); |
| | | }; |
| | | |
| | | const validateMaterialRows = () => { |