diff --git a/inventory-backend/app/services/outbound_service.py b/inventory-backend/app/services/outbound_service.py index 5da6ad6..8c69769 100644 --- a/inventory-backend/app/services/outbound_service.py +++ b/inventory-backend/app/services/outbound_service.py @@ -195,25 +195,48 @@ class OutboundService: def get_grouped_list(page=1, per_page=10, keyword=None, start_date=None, end_date=None): """ 查询出库记录(按出库单号分组),包含详细物品信息 + 支持跨表搜索:单号、领用人、SKU、物料名称、规格型号 """ # 1. 查询分页单号 + # 如果有关键词,需要联表搜索物料名称和规格型号 + if keyword: + # 子查询:关联 material_base 表获取物料名称和规格型号 + material_join = db.session.query( + TransOutbound.outbound_no + ).join( + MaterialBase, + TransOutbound.sku == MaterialBase.sku + ).filter(or_( + MaterialBase.name.ilike(f'%{keyword}%'), + MaterialBase.spec_model.ilike(f'%{keyword}%') + )).subquery() + + # 主搜索条件:单号、领用人、SKU + 物料名称、规格型号 + keyword_conditions = or_( + TransOutbound.outbound_no.ilike(f'%{keyword}%'), + TransOutbound.consumer_name.ilike(f'%{keyword}%'), + TransOutbound.sku.ilike(f'%{keyword}%'), + TransOutbound.outbound_no.in_(material_join) # 匹配物料名称/规格型号的单号 + ) + else: + keyword_conditions = None + stmt = db.session.query( TransOutbound.outbound_no, func.max(TransOutbound.outbound_time).label('max_time') ).group_by(TransOutbound.outbound_no) - if keyword: - stmt = stmt.filter(or_( - TransOutbound.outbound_no.ilike(f'%{keyword}%'), - TransOutbound.consumer_name.ilike(f'%{keyword}%'), - TransOutbound.sku.ilike(f'%{keyword}%') - )) + if keyword_conditions is not None: + stmt = stmt.filter(keyword_conditions) if start_date and end_date: stmt = stmt.filter(TransOutbound.outbound_time.between(start_date, end_date)) stmt = stmt.order_by(desc('max_time')) + # 使用 distinct 确保跨表查询不重复 + stmt = stmt.distinct() + pagination = stmt.paginate(page=page, per_page=per_page, error_out=False) outbound_nos = [row.outbound_no for row in pagination.items] diff --git a/inventory-backend/app/services/permission_service.py b/inventory-backend/app/services/permission_service.py index 805dea3..2b168ea 100644 --- a/inventory-backend/app/services/permission_service.py +++ b/inventory-backend/app/services/permission_service.py @@ -447,6 +447,18 @@ class PermissionService: ('system_audit', '审计日志', '/system/audit', 'system_mgmt', 3), ] + # 第一步:清理根级别的冗余子菜单(这些本应是子节点,但可能之前被错误地创建为根节点) + child_codes = [m[0] for m in menu_defs if m[3] is not None] # 所有子菜单的code + orphaned_menus = SysMenu.query.filter( + SysMenu.code.in_(child_codes), + (SysMenu.parent_id == 0) | (SysMenu.parent_id.is_(None)) + ).all() + for menu in orphaned_menus: + print(f"🗑️ 清理根级别冗余菜单: {menu.code} ({menu.name})") + # 删除关联的权限 + SysRolePermission.query.filter_by(target_code=menu.code).delete() + db.session.delete(menu) + # 创建或更新菜单 menu_map = {} # code -> menu obj diff --git a/inventory-web/src/views/outbound/index.vue b/inventory-web/src/views/outbound/index.vue index 3340411..3e3db28 100644 --- a/inventory-web/src/views/outbound/index.vue +++ b/inventory-web/src/views/outbound/index.vue @@ -3,7 +3,7 @@