From de9108974398be5caae185d1106ef900975ddc56 Mon Sep 17 00:00:00 2001 From: XingQue Date: Sun, 28 Jun 2026 23:11:50 +0800 Subject: [PATCH] fix: clearer no-perm message with bound roles --- backend/view.py | 29 ++++++++++++++++++++++------- jituan/services/club_rbac.py | 25 +++++++++++++++++++++++++ jituan/services/kefu_menu.py | 2 ++ jituan/views.py | 1 + 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/backend/view.py b/backend/view.py index 88c49be..ac7be5a 100644 --- a/backend/view.py +++ b/backend/view.py @@ -640,10 +640,13 @@ class ModifyAdminUserView(APIView): role_codes = request.data.get('role_codes', []) if not role_codes: return Response({'code': 400, 'msg': '请选择角色'}) + from jituan.services.club_rbac import resolve_role_by_name + club_id = getattr(target_user, 'ClubID', '') or '' + added, missing = [], [] for rc in role_codes: - try: - role = Role.objects.get(RoleName=rc) - except Role.DoesNotExist: + role = resolve_role_by_name(rc, club_id) + if not role: + missing.append(rc) continue UserRole.objects.get_or_create( UserRoleUUID=uuid.uuid4().bytes, @@ -651,16 +654,28 @@ class ModifyAdminUserView(APIView): RoleUUID=role.RoleUUID, CompanyUUID=uuid.UUID('b0000000-0000-0000-0000-000000000001').bytes, ) + added.append(role.RoleName) + if not added: + return Response({ + 'code': 400, + 'msg': f'未找到可绑定的角色:{", ".join(missing or role_codes)}。请确认顶栏俱乐部与角色所属俱乐部一致', + }) + if missing: + return Response({ + 'code': 0, + 'msg': f'已绑定:{", ".join(added)};未找到:{", ".join(missing)}', + }) return Response({'code': 0, 'msg': '角色添加成功'}) elif action == 'remove_user_role': role_code = request.data.get('role_code') if not role_code: return Response({'code': 400, 'msg': '缺少角色编码'}) - try: - role = Role.objects.get(RoleName=role_code) - except Role.DoesNotExist: - return Response({'code': 404, 'msg': '角色不存在'}) + from jituan.services.club_rbac import resolve_role_by_name + club_id = getattr(target_user, 'ClubID', '') or '' + role = resolve_role_by_name(role_code, club_id) + if not role: + return Response({'code': 404, 'msg': '角色不存在或与用户俱乐部不匹配'}) UserRole.objects.filter(UserUUID=target_user.UserUUID, RoleUUID=role.RoleUUID).delete() return Response({'code': 0, 'msg': '角色移除成功'}) diff --git a/jituan/services/club_rbac.py b/jituan/services/club_rbac.py index 79ee728..6213118 100644 --- a/jituan/services/club_rbac.py +++ b/jituan/services/club_rbac.py @@ -60,3 +60,28 @@ def count_role_users_in_scope(role, request, kefu_user_uuids): def role_name_exists(role_name, club_id): return Role.objects.filter(RoleName=role_name, ClubID=club_id or '').exists() + + +def resolve_role_by_name(role_name, club_id=None): + """按角色名解析 Role;优先匹配用户俱乐部,其次集团全局角色(club_id 为空)。""" + name = (role_name or '').strip() + if not name: + return None + qs = Role.objects.filter(RoleName=name, RoleStatus=1) + cid = (club_id or '').strip() + if cid: + hit = qs.filter(ClubID=cid).first() + if hit: + return hit + return qs.filter(ClubID='').first() or qs.first() + + +def user_bound_role_names(user): + uuids = list( + UserRole.objects.filter(UserUUID=user.UserUUID).values_list('RoleUUID', flat=True) + ) + if not uuids: + return [] + return list( + Role.objects.filter(RoleUUID__in=uuids, RoleStatus=1).values_list('RoleName', flat=True) + ) diff --git a/jituan/services/kefu_menu.py b/jituan/services/kefu_menu.py index 277b55f..5f3ceeb 100644 --- a/jituan/services/kefu_menu.py +++ b/jituan/services/kefu_menu.py @@ -9,6 +9,7 @@ from jituan.services.admin_context import ( can_manage_admin_assignments, is_system_super_admin, ) +from jituan.services.club_rbac import user_bound_role_names from jituan.services.kefu_menu_definitions import KEFU_MENU_ROW_DEFS logger = logging.getLogger(__name__) @@ -132,6 +133,7 @@ def build_menu_access_payload(request, username=None): 'visible_page_ids': sorted(set(visible_ids)), 'visible_paths': visible_paths, 'permission_codes': _permission_codes_list(permissions), + 'role_names': user_bound_role_names(request.user), 'can_switch_club': bool(club_ctx.get('can_switch_club')), 'is_group_admin': bool(club_ctx.get('is_group_admin')), 'menu_ready': True, diff --git a/jituan/views.py b/jituan/views.py index a9ff4a1..74076ae 100644 --- a/jituan/views.py +++ b/jituan/views.py @@ -170,6 +170,7 @@ class ClubKefuLoginView(APIView): 'visible_page_ids': [], 'visible_paths': [], 'permission_codes': [], + 'role_names': [], 'can_switch_club': False, 'is_group_admin': False, 'menu_ready': False,