TransService.get_records: 追加 material_name 字段 + SKU 兜底查询解决数据孤岛问题
This commit is contained in:
@ -7,6 +7,7 @@ from app.models.inbound.semi import StockSemi
|
|||||||
from app.models.inbound.product import StockProduct
|
from app.models.inbound.product import StockProduct
|
||||||
from app.models.base import MaterialBase
|
from app.models.base import MaterialBase
|
||||||
from sqlalchemy import desc, func, nullslast, asc, or_, and_
|
from sqlalchemy import desc, func, nullslast, asc, or_, and_
|
||||||
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
|
|
||||||
class TransService:
|
class TransService:
|
||||||
@ -396,8 +397,75 @@ class TransService:
|
|||||||
q = q.order_by(nullslast(asc(TransBorrow.expected_return_time)))
|
q = q.order_by(nullslast(asc(TransBorrow.expected_return_time)))
|
||||||
pagination = q.paginate(page=page, per_page=limit, error_out=False)
|
pagination = q.paginate(page=page, per_page=limit, error_out=False)
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# ★ 批量预加载物料名称(两步:收集ID → 批量 JOIN → 内存拼装)
|
||||||
|
# ============================================================
|
||||||
|
items_with_names = []
|
||||||
|
items = pagination.items
|
||||||
|
if items:
|
||||||
|
# 步骤 1:收集所有 (source_table, stock_id) 对
|
||||||
|
stock_ids_by_table = {'stock_buy': set(), 'stock_semi': set(), 'stock_product': set()}
|
||||||
|
for item in items:
|
||||||
|
if item.source_table in stock_ids_by_table and item.stock_id:
|
||||||
|
stock_ids_by_table[item.source_table].add(item.stock_id)
|
||||||
|
|
||||||
|
# 步骤 2:批量查询库存表并 JOIN MaterialBase
|
||||||
|
stock_map = {} # { ('stock_buy', 101): '物料名称', ... }
|
||||||
|
model_map = {
|
||||||
|
'stock_buy': StockBuy,
|
||||||
|
'stock_semi': StockSemi,
|
||||||
|
'stock_product': StockProduct
|
||||||
|
}
|
||||||
|
for table_name, ids in stock_ids_by_table.items():
|
||||||
|
if not ids:
|
||||||
|
continue
|
||||||
|
ModelClass = model_map.get(table_name)
|
||||||
|
if not ModelClass:
|
||||||
|
continue
|
||||||
|
stocks = ModelClass.query.options(
|
||||||
|
joinedload(ModelClass.base)
|
||||||
|
).filter(ModelClass.id.in_(ids)).all()
|
||||||
|
for stock in stocks:
|
||||||
|
name = stock.base.name if stock.base else ''
|
||||||
|
stock_map[(table_name, stock.id)] = name
|
||||||
|
|
||||||
|
# 步骤 3(前置):收集 SKU 兜底候选集
|
||||||
|
empty_sku_set = set()
|
||||||
|
for item in items:
|
||||||
|
name = stock_map.get((item.source_table, item.stock_id), '')
|
||||||
|
if not name and item.sku:
|
||||||
|
empty_sku_set.add(item.sku)
|
||||||
|
|
||||||
|
# 步骤 3(前置):SKU 兜底批量查询
|
||||||
|
# 场景:库存记录被跨表转移(删旧建新)时,trans_borrow.stock_id 指向孤立记录
|
||||||
|
# 通过 sku 在三张库存表中查找任意匹配,再通过 base_id 获取 MaterialBase.name
|
||||||
|
sku_name_map = {}
|
||||||
|
if empty_sku_set:
|
||||||
|
for ModelClass in [StockProduct, StockSemi, StockBuy]:
|
||||||
|
stocks = ModelClass.query.options(
|
||||||
|
joinedload(ModelClass.base)
|
||||||
|
).filter(
|
||||||
|
ModelClass.sku.in_(empty_sku_set)
|
||||||
|
).all()
|
||||||
|
for stock in stocks:
|
||||||
|
if stock.sku not in sku_name_map and stock.base:
|
||||||
|
sku_name_map[stock.sku] = stock.base.name
|
||||||
|
|
||||||
|
# 步骤 3:为每条记录注入 material_name(含 SKU 兜底)
|
||||||
|
for item in items:
|
||||||
|
item_dict = item.to_dict()
|
||||||
|
material_name = stock_map.get((item.source_table, item.stock_id), '')
|
||||||
|
if not material_name and item.sku:
|
||||||
|
material_name = sku_name_map.get(item.sku, '')
|
||||||
|
item_dict['material_name'] = material_name
|
||||||
|
items_with_names.append(item_dict)
|
||||||
|
|
||||||
|
items_data = items_with_names
|
||||||
|
else:
|
||||||
|
items_data = []
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'items': [r.to_dict() for r in pagination.items],
|
'items': items_data,
|
||||||
'total': pagination.total,
|
'total': pagination.total,
|
||||||
'page': page,
|
'page': page,
|
||||||
'limit': limit
|
'limit': limit
|
||||||
|
|||||||
Reference in New Issue
Block a user