Files
Django/jituan/services/admin_assignments.py
2026-07-29 06:46:14 +08:00

197 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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)