fix: 切换俱乐部仅算本俱乐部角色权限,统一权限解析

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-06 19:00:18 +08:00
parent 553d2d5707
commit 45a4dde034
4 changed files with 57 additions and 54 deletions

View File

@@ -135,34 +135,44 @@ def resolve_roles_for_binding(role_names, club_id=None):
def filter_role_uuids_for_club_scope(role_uuids, club_id, scope, allowed_club_ids=None):
"""
按当前俱乐部上下文过滤 UserRole 绑定的 RoleUUID。
SINGLE_CLUB本俱乐部角色 + 全局角色ClubID 为空)
ALL_CLUBS全局角色 + 各已授权俱乐部的角色(并集)。
SINGLE_CLUB本俱乐部角色Role.ClubID=当前俱乐部),不含其他俱乐部/全局
ALL_CLUBS已授权俱乐部角色 + 全局角色club_id 为空)。
"""
if not role_uuids:
return []
qs = Role.objects.filter(RoleUUID__in=role_uuids, RoleStatus=1)
wanted = {role_uuid_bytes(u) for u in role_uuids}
if scope == DATA_SCOPE_ALL:
club_ids = [c for c in (allowed_club_ids or []) if c]
if club_ids:
return list(
qs.filter(Q(ClubID='') | Q(ClubID__in=club_ids)).values_list('RoleUUID', flat=True)
)
return list(qs.filter(ClubID='').values_list('RoleUUID', flat=True))
club_ids = {c for c in (allowed_club_ids or []) if c}
matched = []
for role in Role.objects.filter(RoleStatus=1):
key = role_uuid_bytes(role.RoleUUID)
if key not in wanted:
continue
rcid = (getattr(role, 'ClubID', None) or '').strip()
if rcid == '' or rcid in club_ids:
matched.append(role.RoleUUID)
return matched
cid = (club_id or CLUB_ID_DEFAULT).strip()
# 本俱乐部专属角色 + 全局角色权限取并集002ac 等常在全局角色上)
return list(qs.filter(Q(ClubID=cid) | Q(ClubID='')).values_list('RoleUUID', flat=True))
matched = []
for role in Role.objects.filter(RoleStatus=1, ClubID=cid):
if role_uuid_bytes(role.RoleUUID) in wanted:
matched.append(role.RoleUUID)
return matched
def resolve_permission_codes_for_club(user, club_id, allowed_club_ids=None):
"""指定俱乐部 SINGLE 视图下用户的 gvsdsdk 权限码"""
def resolve_permission_codes_for_club(user, club_id, allowed_club_ids=None, scope=None):
"""当前俱乐部上下文下的 gvsdsdk 权限码(与 verify_kefu_permission / 菜单共用)"""
from jituan.constants import DATA_SCOPE_SINGLE
from gvsdsdk.models import Permission as SdkPermission, RolePermission as SdkRolePermission, UserRole as SdkUserRole
eff_scope = scope or DATA_SCOPE_SINGLE
role_uuids = list(SdkUserRole.objects.filter(
UserUUID=user.UserUUID,
).values_list('RoleUUID', flat=True))
role_uuids = filter_role_uuids_for_club_scope(
role_uuids, club_id, DATA_SCOPE_SINGLE, allowed_club_ids,
role_uuids, club_id, eff_scope, allowed_club_ids,
)
if not role_uuids:
return []
@@ -176,6 +186,13 @@ def resolve_permission_codes_for_club(user, club_id, allowed_club_ids=None):
)
def resolve_effective_permission_codes(user, club_id, scope, allowed_club_ids=None):
"""菜单与各业务接口统一权限码:仅当前俱乐部 gvsdsdk 角色,不串其他俱乐部。"""
return resolve_permission_codes_for_club(
user, club_id, allowed_club_ids, scope=scope,
)
def user_bound_role_names(user, club_id=None, scope=None, allowed_club_ids=None):
from backend.utils import _legacy_backend_role_permissions

View File

@@ -132,8 +132,8 @@ def build_menu_access_payload(request, username=None):
visible_ids.append(page.page_id)
club_ctx = build_admin_club_context(request.user)
club_id = resolve_club_id_from_request(request)
scope = resolve_club_scope(request)
club_id = getattr(request, 'club_id', None) or resolve_club_id_from_request(request)
scope = getattr(request, 'club_scope', None) or resolve_club_scope(request)
allowed = list(get_allowed_club_ids(request.user))
path_by_id = {p.page_id: p.path for p in pages if p.path}
visible_paths = [path_by_id[pid] for pid in visible_ids if pid in path_by_id]