feat(outbound): 库存列表按规格+库位聚合 + BOM明细类型修复
This commit is contained in:
@ -266,8 +266,37 @@ def get_stock_list():
|
||||
d['available_quantity'] = d.get('qty_available', d.get('available_quantity', 0))
|
||||
all_items.append(d)
|
||||
|
||||
total = len(all_items)
|
||||
# ── 按规格+库位聚合(出库选单合并同类项)───────────────────────
|
||||
is_aggregated = request.args.get('is_aggregated', 'false').lower() == 'true'
|
||||
|
||||
if is_aggregated:
|
||||
grouped_dict = {}
|
||||
for item in all_items:
|
||||
# 核心聚合键:类型 + 规格型号 + 库位
|
||||
group_key = f"{item.get('type')}_{item.get('standard')}_{item.get('warehouse_location', '')}"
|
||||
|
||||
if group_key in grouped_dict:
|
||||
# 累加数量
|
||||
existing = grouped_dict[group_key]
|
||||
existing['available_quantity'] = float(existing.get('available_quantity', 0)) + float(item.get('available_quantity', 0))
|
||||
existing['stock_quantity'] = float(existing.get('stock_quantity', 0)) + float(item.get('stock_quantity', 0))
|
||||
# 保留 id 列表(出库提交时需用到)
|
||||
existing_ids = existing.get('_ids', [])
|
||||
existing_ids.append(item.get('id'))
|
||||
existing['_ids'] = existing_ids
|
||||
else:
|
||||
# 存入代表项
|
||||
grouped_dict[group_key] = item.copy()
|
||||
# 强制统一数据类型以便前端处理
|
||||
grouped_dict[group_key]['available_quantity'] = float(item.get('available_quantity', 0))
|
||||
grouped_dict[group_key]['stock_quantity'] = float(item.get('stock_quantity', 0))
|
||||
grouped_dict[group_key]['_ids'] = [item.get('id')]
|
||||
|
||||
# 替换原列表为聚合后的列表
|
||||
all_items = list(grouped_dict.values())
|
||||
|
||||
# ── 手动切片分页 ────────────────────────────────────────────
|
||||
total = len(all_items)
|
||||
start = (page - 1) * pageSize
|
||||
end = start + pageSize
|
||||
paged = all_items[start:end]
|
||||
|
||||
@ -326,7 +326,7 @@
|
||||
|
||||
<el-dialog
|
||||
v-model="dialog.visible"
|
||||
width="700px"
|
||||
width="1200px"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
@close="cancel"
|
||||
|
||||
@ -511,7 +511,8 @@ const loadStockList = async () => {
|
||||
const res: any = await getStockList({
|
||||
page: stockPage.value,
|
||||
pageSize: stockPageSize.value,
|
||||
keyword: searchKeyword.value.trim()
|
||||
keyword: searchKeyword.value.trim(),
|
||||
is_aggregated: true // ★ 触发后端按规格+库位合并
|
||||
})
|
||||
// 为每个item添加uniqueKey和确保warehouse_location字段正确映射
|
||||
stockList.value = (res.data?.list || []).map((item: any) => ({
|
||||
@ -649,7 +650,7 @@ watch(selectedBomNo, async (newBomNo) => {
|
||||
return
|
||||
}
|
||||
try {
|
||||
const detailRes = await getBomDetail(newBomNo)
|
||||
const detailRes: any = await getBomDetail(newBomNo)
|
||||
currentBomDetail.value = detailRes.data?.children || []
|
||||
} catch (e) {
|
||||
ElMessage.error('加载 BOM 明细失败')
|
||||
@ -666,7 +667,7 @@ const confirmBomAdd = async () => {
|
||||
|
||||
if (currentBomDetail.value.length === 0) {
|
||||
try {
|
||||
const detailRes = await getBomDetail(selectedBomNo.value)
|
||||
const detailRes: any = await getBomDetail(selectedBomNo.value)
|
||||
currentBomDetail.value = detailRes.data?.children || []
|
||||
} catch (e) {
|
||||
ElMessage.error('获取 BOM 详情失败')
|
||||
|
||||
Reference in New Issue
Block a user