From 7e4524ae42f0156bffbe3df9f07f0494dffcf60a Mon Sep 17 00:00:00 2001 From: yueli Date: Tue, 11 Aug 2026 13:28:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(warning):=20=E9=A2=84=E8=AD=A6=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E8=A2=AB=20field=5Fpermissions=20Default=20Deny=20?= =?UTF-8?q?=E8=A7=84=E5=88=99=E9=94=99=E8=AF=AF=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MaterialBase 映射中新增 warningStatus/warningEnabled/warningRed/warningYellow/warningRedEmails/warningYellowEmails 字段 - 新增 _permits() 函数支持通配符权限匹配 (material_list:* 覆盖所有 material_list:xxx) - 修复 apply_strict_rbac 使用 _permits 替代直接 in 检查 根因: field_permissions.py 的 STOCK_FIELD_RBAC_MAPPING 中没有预警字段映射, apply_strict_rbac 的 Default Deny 规则会删除所有不在映射中的字段,导致前端永远收不到预警数据。 --- .../app/utils/field_permissions.py | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/inventory-backend/app/utils/field_permissions.py b/inventory-backend/app/utils/field_permissions.py index 62a30a3..f0267eb 100644 --- a/inventory-backend/app/utils/field_permissions.py +++ b/inventory-backend/app/utils/field_permissions.py @@ -20,6 +20,12 @@ STOCK_FIELD_RBAC_MAPPING = { "referencePrice": "material_list:referencePrice", "inventoryCount": "material_list:inventoryCount", "availableCount": "material_list:availableCount", + "warningStatus": "material_list:view_warning", + "warningEnabled": "material_list:view_warning", + "warningRed": "material_list:view_warning", + "warningYellow": "material_list:view_warning", + "warningRedEmails": "material_list:view_warning", + "warningYellowEmails": "material_list:view_warning", }, "StockBuy": { "id": None, "request_id": None, "request_no": None, @@ -89,6 +95,21 @@ def _is_super_admin(user_permissions: list) -> bool: return '*' in user_permissions or any(p.endswith(':*') for p in user_permissions) +def _permits(perm_code: str, user_permissions: list) -> bool: + """检查用户权限列表是否覆盖指定的权限码(支持通配符匹配)""" + if perm_code is None: + return True # None = 公开字段 + if perm_code in user_permissions: + return True # 精确匹配 + # 通配符匹配: material_list:* 覆盖所有 material_list:xxx + for p in user_permissions: + if p.endswith(':*') and perm_code.startswith(p[:-2] + ':'): + return True + if '*' in user_permissions: + return True + return False + + def apply_strict_rbac(item_dict: dict, table_name: str, user_permissions: list) -> dict: """ Default Deny 字段过滤器: @@ -112,7 +133,7 @@ def apply_strict_rbac(item_dict: dict, table_name: str, user_permissions: list) del item_dict[key] # Default Deny else: perm_code = mapping[key] - if perm_code is not None and perm_code not in user_permissions: + if not _permits(perm_code, user_permissions): if isinstance(item_dict[key], (int, float)): item_dict[key] = 0 elif isinstance(item_dict[key], bool):