From eba558c9d91b6b2505a0e7fb0bc988bbbb080820 Mon Sep 17 00:00:00 2001 From: DXC Date: Tue, 21 Apr 2026 13:06:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(outbound):=20=E4=BC=98=E5=8C=96=E6=8C=89?= =?UTF-8?q?=20BOM=20=E6=B7=BB=E5=8A=A0=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E7=BC=BA=E4=BB=B6=E6=97=B6=E6=8C=89=E7=8E=B0=E6=9C=89?= =?UTF-8?q?=E5=BA=93=E5=AD=98=E9=83=A8=E5=88=86=E5=87=BA=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/outbound/Selection.vue | 74 +++++++++++-------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/inventory-web/src/views/outbound/Selection.vue b/inventory-web/src/views/outbound/Selection.vue index 706c739..ea83722 100644 --- a/inventory-web/src/views/outbound/Selection.vue +++ b/inventory-web/src/views/outbound/Selection.vue @@ -213,13 +213,12 @@ @@ -632,50 +631,65 @@ watch(selectedBomNo, async (newBomNo) => { }) const confirmBomAdd = async () => { - if(!selectedBomNo.value) return ElMessage.warning('请选择 BOM'); + if (!selectedBomNo.value) return ElMessage.warning('请选择 BOM') if (allStockData.value.length === 0) { - await openManualSelect() - manualDialogVisible.value = false + await ensureAllStockLoaded() } - try { - const detailRes = await getBomDetail(selectedBomNo.value) - const bomRows = detailRes.data?.children || [] + if (currentBomDetail.value.length === 0) { + try { + const detailRes = await getBomDetail(selectedBomNo.value) + currentBomDetail.value = detailRes.data?.children || [] + } catch (e) { + ElMessage.error('获取 BOM 详情失败') + return + } + } - let addedCount = 0; - bomRows.forEach((bomItem: any) => { - const needQty = (parseFloat(bomItem.dosage) || 0) * bomSets.value - // ★ BOM 添加时,匹配本地库存数据,带入库位信息 - const stockCandidate = allStockData.value.find(s => - (s.base_id && s.base_id == bomItem.child_id) - ) + const bomRows = currentBomDetail.value + let addedCount = 0 + let skippedCount = 0 - if (stockCandidate) { + bomRows.forEach((bomItem: any) => { + const dosage = parseFloat(bomItem.dosage) || 0 + const needQty = dosage * bomSets.value + + const stockCandidate = allStockData.value.find(s => + (s.base_id && s.base_id == bomItem.child_id) + ) + + if (stockCandidate) { + const availableQty = stockCandidate.availableCount || 0 + const actualAddQty = Math.min(needQty, availableQty) + + if (actualAddQty > 0) { const existing = selectedItems.value.find(e => e.uniqueKey === stockCandidate.uniqueKey) if (existing) { - existing.export_quantity += needQty + existing.export_quantity += actualAddQty } else { const newItem = JSON.parse(JSON.stringify(stockCandidate)) - // 如果后端 BomService 也返回了 warehouse_location (聚合的),这里优先使用 if (bomItem.warehouse_location) { newItem.warehouse_location = bomItem.warehouse_location } - newItem.export_quantity = needQty + newItem.export_quantity = actualAddQty selectedItems.value.push(newItem) } addedCount++ + } else { + skippedCount++ } - }) - - if(addedCount > 0) { - ElMessage.success(`成功添加 BOM 相关物料,共 ${addedCount} 类`) - bomSelectVisible.value = false } else { - ElMessage.warning('库存中未找到该 BOM 所需的任何原料') + skippedCount++ } - } catch(e) { - ElMessage.error('获取 BOM 详情失败') + }) + + if (addedCount > 0) { + const tip = skippedCount > 0 ? `(跳过 ${skippedCount} 种缺货物料)` : '' + ElMessage.success(`成功添加 ${addedCount} 类物料${tip}`) + bomSelectVisible.value = false + } else { + ElMessage.warning('该 BOM 所有物料库存均为 0') } }