revert: restore gvsdsdk role/permission APIs; keep KefuProfile login fix

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-06-29 00:02:40 +08:00
parent 42cb117a8a
commit dd9e4afa49
4 changed files with 203 additions and 165 deletions

View File

@@ -148,62 +148,46 @@ class GetRolePermissionView(APIView):
if '000001' not in permissions:
return Response({'code': 403, 'msg': '您无权访问此页面'})
from backend.models import (
Role as BackendRole,
Permission as BackendPermission,
UserRole as LegacyUserRole,
# 3. 获取所有权限
all_perms = Permission.objects.filter(PermStatus=1).values('PermCode', 'PermName', 'PermDesc')
permissions_list = [_serialize_permission_row(p) for p in all_perms]
from jituan.services.club_rbac import count_role_users_in_scope, filter_roles_for_request
kefu_user_uuids = list(
User.objects.filter(KefuProfile__isnull=False).values_list('UserUUID', flat=True)
)
all_perms = BackendPermission.objects.all().values('perm_code', 'perm_name', 'description')
permissions_list = [
{
'perm_code': p['perm_code'],
'perm_name': p['perm_name'],
'perm_desc': p.get('description') or '',
}
for p in all_perms
]
roles = filter_roles_for_request(request)
roles_data = []
for role in BackendRole.objects.all().order_by('role_id'):
user_count = LegacyUserRole.objects.filter(role=role).count()
perms_of_role = BackendPermission.objects.filter(rolepermission__role=role).distinct()
for role in roles:
user_count = count_role_users_in_scope(role, request, kefu_user_uuids)
role_perm_uuids = RolePermission.objects.filter(
RoleUUID=role.RoleUUID
).values_list('PermUUID', flat=True)
perms_of_role = [
_serialize_permission_row(p)
for p in Permission.objects.filter(
PermUUID__in=list(role_perm_uuids)
).values('PermCode', 'PermName', 'PermDesc')
]
roles_data.append({
'role_code': role.role_name,
'role_name': role.role_name,
'description': role.description or '',
'club_id': '',
'role_code': role.RoleName,
'role_name': role.RoleName,
'description': role.RoleDesc or '',
'club_id': getattr(role, 'ClubID', '') or '',
'user_count': user_count,
'permissions': [
{
'perm_code': p.perm_code,
'perm_name': p.perm_name,
'perm_desc': p.description or '',
}
for p in perms_of_role
],
'permissions': perms_of_role
})
return Response({
'code': 0,
'data': {
'roles': roles_data,
'permissions': permissions_list,
},
'permissions': permissions_list
}
})
def _resolve_backend_role(role_code):
from backend.models import Role as BackendRole
rc = (role_code or '').strip()
if not rc:
return None
return (
BackendRole.objects.filter(role_name=rc).first()
or BackendRole.objects.filter(role_code=rc).first()
)
class ModifyRolePermissionView(APIView):
"""
通用接口:支持删除角色、为角色添加权限、移除角色权限
@@ -229,26 +213,22 @@ class ModifyRolePermissionView(APIView):
if not role_code:
return Response({'code': 400, 'msg': '缺少角色编码'})
from backend.models import (
Permission as BackendPermission,
RolePermission as LegacyRolePermission,
UserRole as LegacyUserRole,
)
role = _resolve_backend_role(role_code)
if not role:
try:
role = Role.objects.get(RoleName=role_code)
except Role.DoesNotExist:
return Response({'code': 404, 'msg': '角色不存在'})
# 超级管理员角色的特殊限制
if role.role_name == '管理员':
if role.RoleName == '管理员':
if action in ['delete_role']:
return Response({'code': 403, 'msg': '超级管理员角色不能删除'})
# 根据 action 处理
if action == 'delete_role':
# 删除角色:同时删除角色权限关联、用户角色关联
with transaction.atomic():
LegacyRolePermission.objects.filter(role=role).delete()
LegacyUserRole.objects.filter(role=role).delete()
RolePermission.objects.filter(RoleUUID=role.RoleUUID).delete()
UserRole.objects.filter(RoleUUID=role.RoleUUID).delete()
role.delete()
return Response({'code': 0, 'msg': '角色删除成功'})
@@ -256,26 +236,34 @@ class ModifyRolePermissionView(APIView):
perm_code = request.data.get('perm_code')
if not perm_code:
return Response({'code': 400, 'msg': '缺少权限编码'})
if role.role_name == '管理员' and perm_code == '000001':
if role.RoleName == '管理员' and perm_code == '000001':
return Response({'code': 403, 'msg': '此权限已存在,不能重复添加'})
perm = BackendPermission.objects.filter(perm_code=perm_code).first()
if not perm:
try:
perm = Permission.objects.get(PermCode=perm_code)
except Permission.DoesNotExist:
return Response({'code': 404, 'msg': '权限不存在'})
if LegacyRolePermission.objects.filter(role=role, permission=perm).exists():
# 检查是否已存在
if RolePermission.objects.filter(RoleUUID=role.RoleUUID, PermUUID=perm.PermUUID).exists():
return Response({'code': 400, 'msg': '该角色已拥有此权限'})
LegacyRolePermission.objects.create(role=role, permission=perm)
RolePermission.objects.create(
RolePermUUID=uuid.uuid4().bytes,
RoleUUID=role.RoleUUID,
PermUUID=perm.PermUUID,
CreateTime=timezone.now(),
)
return Response({'code': 0, 'msg': '权限添加成功'})
elif action == 'remove_permission':
perm_code = request.data.get('perm_code')
if not perm_code:
return Response({'code': 400, 'msg': '缺少权限编码'})
if role.role_name == '管理员' and perm_code == '000001':
if role.RoleName == '管理员' and perm_code == '000001':
return Response({'code': 403, 'msg': '不能移除超级管理员的此权限'})
perm = BackendPermission.objects.filter(perm_code=perm_code).first()
if not perm:
try:
perm = Permission.objects.get(PermCode=perm_code)
except Permission.DoesNotExist:
return Response({'code': 404, 'msg': '权限不存在'})
deleted, _ = LegacyRolePermission.objects.filter(role=role, permission=perm).delete()
deleted, _ = RolePermission.objects.filter(RoleUUID=role.RoleUUID, PermUUID=perm.PermUUID).delete()
if deleted == 0:
return Response({'code': 400, 'msg': '该角色未拥有此权限'})
return Response({'code': 0, 'msg': '权限移除成功'})
@@ -284,32 +272,45 @@ class ModifyRolePermissionView(APIView):
role_name = (request.data.get('role_name') or '').strip()
description = (request.data.get('description') or '').strip()
perm_codes = request.data.get('perm_codes') or []
from backend.models import Role as BackendRole
if role.role_name == '管理员':
role_name = role.role_name
elif role_name and role_name != role.role_name:
if BackendRole.objects.filter(role_name=role_name).exclude(role_id=role.role_id).exists():
if role.RoleName == '管理员':
role_name = role.RoleName
elif role_name and role_name != role.RoleName:
if Role.objects.filter(RoleName=role_name).exclude(RoleUUID=role.RoleUUID).exists():
return Response({'code': 400, 'msg': '角色名称已存在'})
with transaction.atomic():
if role.role_name != '管理员':
if role.RoleName != '管理员':
if role_name:
role.role_name = role_name
role.description = description
role.save(update_fields=['role_name', 'description'])
LegacyRolePermission.objects.filter(role=role).delete()
role.RoleName = role_name
role.RoleDesc = description
role.save(update_fields=['RoleName', 'RoleDesc'])
RolePermission.objects.filter(RoleUUID=role.RoleUUID).delete()
for pc in perm_codes:
if pc == '000001' and role.role_name != '管理员':
if pc == '000001' and role.RoleName != '管理员':
continue
perm = BackendPermission.objects.filter(perm_code=pc).first()
if not perm:
try:
perm = Permission.objects.get(PermCode=pc, PermStatus=1)
except Permission.DoesNotExist:
continue
LegacyRolePermission.objects.create(role=role, permission=perm)
if role.role_name == '管理员':
super_perm = BackendPermission.objects.filter(perm_code='000001').first()
if super_perm and not LegacyRolePermission.objects.filter(
role=role, permission=super_perm,
).exists():
LegacyRolePermission.objects.create(role=role, permission=super_perm)
RolePermission.objects.create(
RolePermUUID=uuid.uuid4().bytes,
RoleUUID=role.RoleUUID,
PermUUID=perm.PermUUID,
CreateTime=timezone.now(),
)
if role.RoleName == '管理员':
try:
super_perm = Permission.objects.get(PermCode='000001', PermStatus=1)
if not RolePermission.objects.filter(
RoleUUID=role.RoleUUID, PermUUID=super_perm.PermUUID,
).exists():
RolePermission.objects.create(
RolePermUUID=uuid.uuid4().bytes,
RoleUUID=role.RoleUUID,
PermUUID=super_perm.PermUUID,
CreateTime=timezone.now(),
)
except Permission.DoesNotExist:
pass
return Response({'code': 0, 'msg': '角色保存成功'})
else:
@@ -338,33 +339,47 @@ class AddRoleView(APIView):
if '000001' not in permissions:
return Response({'code': 403, 'msg': '您无权进行此操作'})
from backend.models import (
Role as BackendRole,
Permission as BackendPermission,
RolePermission as LegacyRolePermission,
# 检查角色名称是否已存在(同俱乐部内唯一)
from jituan.services.club_rbac import resolve_role_club_id, role_name_exists
target_club_id = resolve_role_club_id(
request, (request.data.get('target_club_id') or '').strip() or None,
)
if role_name_exists(role_name, target_club_id):
return Response({'code': 400, 'msg': '该俱乐部下角色名称已存在'})
if BackendRole.objects.filter(role_name=role_name).exists():
return Response({'code': 400, 'msg': '角色名称已存在'})
# 生成唯一角色编码格式ROLE_ + 8位随机字母数字
role_code = f"ROLE_{''.join(random.choices(string.ascii_uppercase + string.digits, k=8))}"
# 创建角色
with transaction.atomic():
role = BackendRole.objects.create(
role_code=role_code,
role_name=role_name,
description=description,
role = Role.objects.create(
RoleUUID=uuid.uuid4().bytes,
TenantUUID=b'\x00' * 16,
RoleName=role_name,
RoleType=2,
RoleStatus=1,
AssignScope=0,
RoleDesc=description,
ClubID=target_club_id,
CreateTime=timezone.now(),
)
# 绑定权限(过滤掉不存在的权限编码)
for pc in perm_codes:
# 不允许添加 000001 权限(此权限仅供超级管理员)
if pc == '000001':
continue
perm = BackendPermission.objects.filter(perm_code=pc).first()
if not perm:
try:
perm = Permission.objects.get(PermCode=pc)
RolePermission.objects.create(
RolePermUUID=uuid.uuid4().bytes,
RoleUUID=role.RoleUUID,
PermUUID=perm.PermUUID,
CreateTime=timezone.now(),
)
except Permission.DoesNotExist:
logger.warning(f"添加角色时忽略不存在的权限编码: {pc}")
continue
LegacyRolePermission.objects.create(role=role, permission=perm)
return Response({'code': 0, 'msg': '角色添加成功', 'data': {'role_code': role_name}})
return Response({'code': 0, 'msg': '角色添加成功', 'data': {'role_code': role_code}})
@@ -403,14 +418,15 @@ class GetAdminUserListView(APIView):
if nicheng:
users = users.filter(KefuProfile__nicheng__icontains=nicheng)
# 关键修正:先求值为列表,再传入 phone__in
if role_code:
from backend.models import Role as BackendRole, UserRole as LegacyUserRole
target_role = _resolve_backend_role(role_code)
target_role = Role.objects.filter(RoleName=role_code).first()
if target_role:
account_ids = list(
LegacyUserRole.objects.filter(role=target_role).values_list('account_id', flat=True)
user_uuids = list(
UserRole.objects.filter(RoleUUID=target_role.RoleUUID)
.values_list('UserUUID', flat=True)
)
users = users.filter(Phone__in=account_ids)
users = users.filter(UserUUID__in=user_uuids)
else:
users = users.none()
@@ -419,12 +435,16 @@ class GetAdminUserListView(APIView):
page_obj = paginator.get_page(page)
data_list = []
from backend.models import UserRole as LegacyUserRole
for user in page_obj:
user_roles = LegacyUserRole.objects.filter(account_id=user.Phone).select_related('role')
# 通过 gvsdsdk UserRole 获取用户角色
user_role_uuids = list(
UserRole.objects.filter(UserUUID=user.UserUUID)
.values_list('RoleUUID', flat=True)
)
user_roles = Role.objects.filter(RoleUUID__in=user_role_uuids)
roles_data = [
{'role_code': ur.role.role_name, 'role_name': ur.role.role_name}
for ur in user_roles
{'role_code': r.RoleName, 'role_name': r.RoleName}
for r in user_roles
]
data_list.append({
'phone': user.Phone or '',
@@ -470,16 +490,16 @@ class GetAdminRolesView(APIView):
if '000001' not in permissions:
return Response({'code': 403, 'msg': '您无权访问此页面'})
from backend.models import Role as BackendRole
roles = BackendRole.objects.all().order_by('role_id')
from jituan.services.club_rbac import filter_roles_for_request
roles = filter_roles_for_request(request).values('RoleName', 'ClubID')
return Response({
'code': 0,
'data': {
'roles': [
{
'role_code': r.role_name,
'role_name': r.role_name,
'club_id': '',
'role_code': r['RoleName'],
'role_name': r['RoleName'],
'club_id': r.get('ClubID') or '',
}
for r in roles
]
@@ -618,22 +638,25 @@ class ModifyAdminUserView(APIView):
role_codes = request.data.get('role_codes', [])
if not role_codes:
return Response({'code': 400, 'msg': '请选择角色'})
from backend.models import Role as BackendRole, UserRole as LegacyUserRole
from jituan.services.club_rbac import resolve_role_by_name
club_id = getattr(target_user, 'ClubID', '') or ''
added, missing = [], []
for rc in role_codes:
role = _resolve_backend_role(rc)
role = resolve_role_by_name(rc, club_id)
if not role:
missing.append(rc)
continue
LegacyUserRole.objects.get_or_create(
account_id=target_user.Phone,
role=role,
UserRole.objects.get_or_create(
UserRoleUUID=uuid.uuid4().bytes,
UserUUID=target_user.UserUUID,
RoleUUID=role.RoleUUID,
CompanyUUID=uuid.UUID('b0000000-0000-0000-0000-000000000001').bytes,
)
added.append(role.role_name)
added.append(role.RoleName)
if not added:
return Response({
'code': 400,
'msg': f'未找到可绑定的角色:{", ".join(missing or role_codes)}',
'msg': f'未找到可绑定的角色:{", ".join(missing or role_codes)}。请确认顶栏俱乐部与角色所属俱乐部一致',
})
if missing:
return Response({
@@ -646,11 +669,12 @@ class ModifyAdminUserView(APIView):
role_code = request.data.get('role_code')
if not role_code:
return Response({'code': 400, 'msg': '缺少角色编码'})
from backend.models import UserRole as LegacyUserRole
role = _resolve_backend_role(role_code)
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': '角色不存在'})
LegacyUserRole.objects.filter(account_id=target_user.Phone, role=role).delete()
return Response({'code': 404, 'msg': '角色不存在或与用户俱乐部不匹配'})
UserRole.objects.filter(UserUUID=target_user.UserUUID, RoleUUID=role.RoleUUID).delete()
return Response({'code': 0, 'msg': '角色移除成功'})
else: