193 lines
5.5 KiB
Python
193 lines
5.5 KiB
Python
"""admin_assignment 任职 CRUD。
|
|
|
|
集团任职用 club_id=''(禁止 NULL):MySQL 对 NULL 唯一约束失效,会无限复制,
|
|
导致「停一条冒出五六条」。停用改为硬删除。
|
|
"""
|
|
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 normalize_club_id(club_id):
|
|
"""集团级统一成空串,禁止 NULL(避免唯一索引失效)。"""
|
|
if club_id is None:
|
|
return ''
|
|
s = str(club_id).strip()
|
|
return s
|
|
|
|
|
|
def _club_filter(qs, club_id):
|
|
cid = normalize_club_id(club_id)
|
|
if not cid:
|
|
return qs.filter(Q(club_id__isnull=True) | Q(club_id=''))
|
|
return qs.filter(club_id=cid)
|
|
|
|
|
|
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 _strip_system_super_if_needed(yonghuid):
|
|
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 or user.IsStaff:
|
|
user.IsSuperuser = False
|
|
user.IsStaff = False
|
|
user.save(update_fields=['IsSuperuser', 'IsStaff'])
|
|
|
|
|
|
def create_or_reactivate_assignment(
|
|
yonghuid,
|
|
club_id,
|
|
role_code,
|
|
data_scope,
|
|
is_primary,
|
|
granted_by,
|
|
):
|
|
club_id = normalize_club_id(club_id)
|
|
if not club_id:
|
|
data_scope = DATA_SCOPE_ALL
|
|
|
|
# 创建前先清同键垃圾(含 NULL/空串/status=0 重复)
|
|
junk = _club_filter(
|
|
AdminAssignment.objects.filter(yonghuid=yonghuid, role_code=role_code),
|
|
club_id,
|
|
)
|
|
active = junk.filter(status=1).order_by('-id')
|
|
if active.exists():
|
|
keep = active.first()
|
|
junk.exclude(pk=keep.pk).delete()
|
|
return None, '该任职记录已存在且有效'
|
|
|
|
junk.delete()
|
|
|
|
if is_primary:
|
|
_clear_other_primary(yonghuid)
|
|
|
|
row = AdminAssignment.objects.create(
|
|
yonghuid=yonghuid,
|
|
club_id=club_id,
|
|
role_code=role_code,
|
|
data_scope=data_scope,
|
|
is_primary=is_primary,
|
|
granted_by=granted_by or '',
|
|
status=1,
|
|
)
|
|
return row.id, None
|
|
|
|
|
|
def _is_group_level(row):
|
|
return (
|
|
not normalize_club_id(row.club_id)
|
|
or (row.data_scope or '') == DATA_SCOPE_ALL
|
|
or (row.role_code or '') in GROUP_ROLE_CODES
|
|
)
|
|
|
|
|
|
def deactivate_assignment(assignment_id):
|
|
"""停用=硬删除。集团级则删光该人全部集团任职并摘 IsSuperuser。"""
|
|
try:
|
|
pk = int(assignment_id)
|
|
except (TypeError, ValueError):
|
|
return False, '任职 id 无效'
|
|
|
|
row = AdminAssignment.objects.filter(pk=pk).first()
|
|
if not row:
|
|
# 可能已被删,幂等成功
|
|
return True, None
|
|
|
|
yonghuid = row.yonghuid
|
|
role_code = row.role_code
|
|
club_id = row.club_id
|
|
group_level = _is_group_level(row)
|
|
|
|
# 同人同角色同俱乐部(含 NULL/'')全部硬删
|
|
_club_filter(
|
|
AdminAssignment.objects.filter(yonghuid=yonghuid, role_code=role_code),
|
|
club_id,
|
|
).delete()
|
|
|
|
if group_level:
|
|
AdminAssignment.objects.filter(yonghuid=yonghuid).filter(
|
|
Q(club_id__isnull=True)
|
|
| Q(club_id='')
|
|
| Q(data_scope=DATA_SCOPE_ALL)
|
|
| Q(role_code__in=list(GROUP_ROLE_CODES))
|
|
).delete()
|
|
_strip_system_super_if_needed(yonghuid)
|
|
|
|
return True, None
|
|
|
|
|
|
def deactivate_all_assignments_for_user(yonghuid):
|
|
"""账号禁用:硬删全部任职 + 摘超管。"""
|
|
yonghuid = (yonghuid or '').strip()
|
|
if not yonghuid:
|
|
return 0
|
|
deleted, _ = AdminAssignment.objects.filter(yonghuid=yonghuid).delete()
|
|
_strip_system_super_if_needed(yonghuid)
|
|
return deleted
|
|
|
|
|
|
def dedupe_active_assignments():
|
|
"""硬删重复任职;并把 club_id=NULL 归一成 ''。"""
|
|
# 归一 NULL -> ''
|
|
AdminAssignment.objects.filter(club_id__isnull=True).update(club_id='')
|
|
|
|
rows = list(
|
|
AdminAssignment.objects.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).delete()
|
|
return len(dup_ids)
|