diff --git a/inventory-backend/app/services/bom_service.py b/inventory-backend/app/services/bom_service.py index c61e73d..726d17b 100644 --- a/inventory-backend/app/services/bom_service.py +++ b/inventory-backend/app/services/bom_service.py @@ -267,14 +267,35 @@ class BomService: elif status == 'archived': query = query.filter(BomTable.is_archived == True) - # 关键词搜索 + # 关键词搜索:与 get_bom_list 保持同一口径——子查询匹配 (bom_no, version), + # 同时覆盖 bom_no、父件名/规格、子件名/规格,保证任意关键字下 summary 计数与 list 明细绝对一致 if keyword: kw = f'%{keyword.strip()}%' - query = query.filter(or_( - BomTable.bom_no.ilike(kw), - MaterialBase.name.ilike(kw), - MaterialBase.spec_model.ilike(kw) - )) + kw_child_alias = db.aliased(MaterialBase) + match_subq = db.session.query( + BomTable.bom_no, + BomTable.version + ).join( + MaterialBase, BomTable.parent_id == MaterialBase.id + ).outerjoin( + kw_child_alias, BomTable.child_id == kw_child_alias.id + ).filter( + or_( + BomTable.bom_no.ilike(kw), + MaterialBase.name.ilike(kw), + MaterialBase.spec_model.ilike(kw), + kw_child_alias.name.ilike(kw), + kw_child_alias.spec_model.ilike(kw) + ) + ).distinct().subquery() + + query = query.join( + match_subq, + db.and_( + BomTable.bom_no == match_subq.c.bom_no, + BomTable.version == match_subq.c.version + ) + ) query = query.group_by(MaterialBase.category) \ .order_by(MaterialBase.category) @@ -525,10 +546,16 @@ class BomService: """ 仅更新某 BOM 版本(整组行)的启用状态,供列表/只读视图"启用/停用"开关使用。 不触碰子件结构;成功后清除该 bom_no 的缓存。 + 注意:只按 bom_no+version 精确匹配,不加 is_enabled/is_archived 等多余过滤—— + 停用/归档中的版本只要记录存在即可继续改状态。 """ + bom_no = (bom_no or '').strip() + version = (version or '').strip() + if not bom_no or not version: + raise ValueError('BOM编号/版本不能为空') rows = BomTable.query.filter_by(bom_no=bom_no, version=version).all() if not rows: - raise ValueError('BOM 不存在') + raise ValueError(f'BOM不存在(bom_no={bom_no}, version={version})') for rec in rows: rec.is_enabled = bool(is_enabled) db.session.commit() @@ -542,9 +569,13 @@ class BomService: 仅更新某 BOM 版本(整组行)的归档标记。 归档=仍启用可查看/编辑,但不再作为其它 BOM 子件的引用候选;取消归档即恢复正常引用。 """ + bom_no = (bom_no or '').strip() + version = (version or '').strip() + if not bom_no or not version: + raise ValueError('BOM编号/版本不能为空') rows = BomTable.query.filter_by(bom_no=bom_no, version=version).all() if not rows: - raise ValueError('BOM 不存在') + raise ValueError(f'BOM不存在(bom_no={bom_no}, version={version})') for rec in rows: rec.is_archived = bool(archived) db.session.commit()