197 lines
5.9 KiB
Python
197 lines
5.9 KiB
Python
"""admin_assignment 任职 CRUD(修复停用不生效、重复插入、IsSuperuser 绕过)。"""
|
||
from django.db.models import Q
|
||
from django.utils import timezone
|
||
|
||
from jituan.constants import DATA_SCOPE_ALL, DATA_SCOPE_SINGLE, SUPER_ADMIN_PHONES
|
||
from jituan.models import AdminAssignment
|
||
|
||
GROUP_ROLE_CODES = frozenset({
|
||
'GROUP_OWNER',
|
||
'GROUP_SUPER_ADMIN',
|
||
'GROUP_AFTER_SALES',
|
||
'GROUP_FINANCE',
|
||
'GROUP_CONFIG',
|
||
})
|
||
|
||
|
||
def _club_filter(qs, club_id):
|
||
if club_id is None or club_id == '':
|
||
return qs.filter(Q(club_id__isnull=True) | Q(club_id=''))
|
||
return qs.filter(club_id=club_id)
|
||
|
||
|
||
def find_assignment(yonghuid, club_id, role_code):
|
||
qs = AdminAssignment.query.filter(yonghuid=yonghuid, role_code=role_code)
|
||
return _club_filter(qs, club_id).order_by('-id').first()
|
||
|
||
|
||
def find_active_assignment(yonghuid, club_id, role_code):
|
||
qs = AdminAssignment.query.filter(yonghuid=yonghuid, role_code=role_code, status=1)
|
||
return _club_filter(qs, club_id).order_by('-id').first()
|
||
|
||
|
||
def clear_other_primary_assignments(yonghuid, except_id=None):
|
||
qs = AdminAssignment.query.filter(yonghuid=yonghuid, status=1, is_primary=True)
|
||
if except_id:
|
||
qs = qs.exclude(id=except_id)
|
||
ids = list(qs.values_list('id', flat=True))
|
||
if ids:
|
||
AdminAssignment.objects.filter(pk__in=ids).update(
|
||
is_primary=False,
|
||
UpdateTime=timezone.now(),
|
||
)
|
||
|
||
|
||
def _clear_other_primary(yonghuid, except_id=None):
|
||
clear_other_primary_assignments(yonghuid, except_id=except_id)
|
||
|
||
|
||
def create_or_reactivate_assignment(
|
||
yonghuid,
|
||
club_id,
|
||
role_code,
|
||
data_scope,
|
||
is_primary,
|
||
granted_by,
|
||
):
|
||
active = find_active_assignment(yonghuid, club_id, role_code)
|
||
if active:
|
||
return None, '该任职记录已存在且有效'
|
||
|
||
if is_primary:
|
||
_clear_other_primary(yonghuid)
|
||
|
||
inactive_qs = _club_filter(
|
||
AdminAssignment.objects.filter(yonghuid=yonghuid, role_code=role_code).exclude(status=1),
|
||
club_id,
|
||
).order_by('-id')
|
||
inactive = inactive_qs.first()
|
||
if inactive:
|
||
if is_primary:
|
||
_clear_other_primary(yonghuid)
|
||
inactive_qs.exclude(pk=inactive.pk).update(status=0, UpdateTime=timezone.now())
|
||
AdminAssignment.objects.filter(pk=inactive.id).update(
|
||
status=1,
|
||
data_scope=data_scope,
|
||
is_primary=is_primary,
|
||
granted_by=granted_by,
|
||
UpdateTime=timezone.now(),
|
||
)
|
||
return inactive.id, None
|
||
|
||
row = AdminAssignment.query.create(
|
||
yonghuid=yonghuid,
|
||
club_id=club_id,
|
||
role_code=role_code,
|
||
data_scope=data_scope,
|
||
is_primary=is_primary,
|
||
granted_by=granted_by,
|
||
status=1,
|
||
)
|
||
return row.id, None
|
||
|
||
|
||
def _strip_system_super_if_needed(yonghuid):
|
||
"""
|
||
停用集团权限后:非白名单账号必须摘掉 IsSuperuser。
|
||
否则 build_admin_club_context 仍把 is_group_admin=True,停用等于没停。
|
||
"""
|
||
yonghuid = (yonghuid or '').strip()
|
||
if not yonghuid:
|
||
return
|
||
try:
|
||
from users.business_models import User
|
||
except Exception:
|
||
return
|
||
user = User.objects.filter(UserUID=yonghuid).first()
|
||
if not user:
|
||
return
|
||
if (user.Phone or '') in SUPER_ADMIN_PHONES:
|
||
return
|
||
if user.IsSuperuser:
|
||
user.IsSuperuser = False
|
||
user.save(update_fields=['IsSuperuser'])
|
||
|
||
|
||
def deactivate_all_group_assignments_for_user(yonghuid):
|
||
"""停用该用户全部集团级任职(空俱乐部 / ALL_CLUBS / GROUP_* 角色)。"""
|
||
yonghuid = (yonghuid or '').strip()
|
||
if not yonghuid:
|
||
return 0
|
||
qs = AdminAssignment.objects.filter(yonghuid=yonghuid, status=1).filter(
|
||
Q(club_id__isnull=True)
|
||
| Q(club_id='')
|
||
| Q(data_scope=DATA_SCOPE_ALL)
|
||
| Q(role_code__in=list(GROUP_ROLE_CODES))
|
||
)
|
||
return qs.update(status=0, UpdateTime=timezone.now())
|
||
|
||
|
||
def deactivate_assignment(assignment_id):
|
||
"""
|
||
停用任职。
|
||
- 同人同角色同俱乐部(含 NULL 重复行)全部停
|
||
- 若是集团级任职:再停掉该人全部集团任职,并摘掉非白名单 IsSuperuser
|
||
"""
|
||
try:
|
||
pk = int(assignment_id)
|
||
except (TypeError, ValueError):
|
||
return False, '任职 id 无效'
|
||
|
||
row = AdminAssignment.objects.filter(pk=pk).first()
|
||
if not row:
|
||
return False, '任职记录不存在'
|
||
|
||
qs = AdminAssignment.objects.filter(
|
||
yonghuid=row.yonghuid,
|
||
role_code=row.role_code,
|
||
status=1,
|
||
)
|
||
qs = _club_filter(qs, row.club_id)
|
||
qs.update(status=0, UpdateTime=timezone.now())
|
||
|
||
is_group_level = (
|
||
not (row.club_id or '').strip()
|
||
or (row.data_scope or '') == DATA_SCOPE_ALL
|
||
or (row.role_code or '') in GROUP_ROLE_CODES
|
||
)
|
||
if is_group_level:
|
||
deactivate_all_group_assignments_for_user(row.yonghuid)
|
||
_strip_system_super_if_needed(row.yonghuid)
|
||
|
||
return True, None
|
||
|
||
|
||
def deactivate_all_assignments_for_user(yonghuid):
|
||
"""账号禁用时:停用该用户全部有效任职,并摘掉非白名单 IsSuperuser。"""
|
||
yonghuid = (yonghuid or '').strip()
|
||
if not yonghuid:
|
||
return 0
|
||
n = AdminAssignment.objects.filter(yonghuid=yonghuid, status=1).update(
|
||
status=0,
|
||
UpdateTime=timezone.now(),
|
||
)
|
||
_strip_system_super_if_needed(yonghuid)
|
||
return n
|
||
|
||
|
||
def dedupe_active_assignments():
|
||
"""停用重复的有效任职,每组 (yonghuid, club_id, role_code) 只保留一条。"""
|
||
rows = list(
|
||
AdminAssignment.query.filter(status=1).order_by('yonghuid', 'club_id', 'role_code', 'id')
|
||
)
|
||
seen = {}
|
||
dup_ids = []
|
||
for row in rows:
|
||
key = (row.yonghuid, row.club_id or '', row.role_code)
|
||
if key in seen:
|
||
dup_ids.append(row.id)
|
||
else:
|
||
seen[key] = row.id
|
||
if dup_ids:
|
||
AdminAssignment.objects.filter(pk__in=dup_ids).update(
|
||
status=0,
|
||
UpdateTime=timezone.now(),
|
||
)
|
||
return len(dup_ids)
|