diff --git a/backend/utils.py b/backend/utils.py index b1fe88f..e99de71 100644 --- a/backend/utils.py +++ b/backend/utils.py @@ -1,7 +1,9 @@ # houtai/utils.py import logging import json +from functools import lru_cache from django.core.exceptions import ObjectDoesNotExist +from django.db.models import Q from rest_framework.response import Response from .models import AbnormalUserLog, UserRole, Permission, DashouRiTongji, ShangjiaRiTongji, \ GuanshiXufeiRiTongji, GuanshiRiTongji, ZuzhangRiTongji, TixianRiTongji @@ -419,4 +421,94 @@ def update_tixian_daily_stat(leixing, amount): if not created: TixianRiTongji.objects.filter(id=stat.id).update( total_amount=F('total_amount') + amount - ) \ No newline at end of file + ) + + +# 罚款权限(与 permission 表一致) +# 66693a/b/c + 66694c:按身份管理罚款;99933abs:罚款申请(通用,可查看列表并操作各身份) +_DEFAULT_FADAN_PERM_TO_SHENFEN = { + '66693a': 1, # 罚款管理-打手 + '66693c': 2, # 罚款管理-管事 + '66693b': 3, # 罚款管理-商家 + '66694c': 4, # 罚款管理-组长 +} + +_FADAN_GENERIC_PERMS = ( + '99933abs', # 罚款申请权限 +) + +_SHENFEN_KEYWORDS = { + '打手': 1, + '管事': 2, + '商家': 3, + '组长': 4, +} + +SHENFEN_PROFILE_MAP = { + 1: 'dashou_profile', + 2: 'guanshi_profile', + 3: 'shop_profile', + 4: 'zuzhang_profile', +} + + +@lru_cache(maxsize=1) +def _get_fadan_permission_config(): + """ + 加载罚款相关权限码(硬编码 + permission 表按 perm_name 补充)。 + 仅匹配 perm_name 含「罚款/罚单」,避免 qtczcaiwu 等描述里带「罚款」的财务权限误入。 + """ + perm_map = dict(_DEFAULT_FADAN_PERM_TO_SHENFEN) + generic_codes = list(_FADAN_GENERIC_PERMS) + try: + rows = Permission.objects.filter( + Q(perm_name__icontains='罚款') | Q(perm_name__icontains='罚单') + ).values('perm_code', 'perm_name') + for row in rows: + code = row['perm_code'] + name = row['perm_name'] or '' + matched_sf = None + for kw, sf in _SHENFEN_KEYWORDS.items(): + if kw in name: + matched_sf = sf + break + if matched_sf is not None: + perm_map[code] = matched_sf + elif code not in generic_codes: + generic_codes.append(code) + except Exception as e: + logger.warning(f"从 permission 表加载罚款权限失败,使用硬编码映射: {e}") + return perm_map, tuple(generic_codes) + + +# 兼容旧引用 +PERMISSION_TO_SHENFEN = _DEFAULT_FADAN_PERM_TO_SHENFEN + + +def has_fadan_view_permission(permissions, account_id=''): + """列表/统计:拥有任一罚款权限或超级管理员权限即可查看。""" + if '000001' in permissions: + return True + perm_map, generic_codes = _get_fadan_permission_config() + all_codes = set(perm_map.keys()) | set(generic_codes) + if any(p in permissions for p in all_codes): + return True + logger.warning( + f"罚款查看权限不足 account={account_id} " + f"user_perms={permissions} need_any={sorted(all_codes)}" + ) + return False + + +def check_fadan_permission(permissions, shenfen): + """创建/处理:需拥有对应身份的罚款权限,或通用罚款权限,或超级管理员权限。""" + if '000001' in permissions: + return True + if any(p in permissions for p in _get_fadan_permission_config()[1]): + return True + shenfen = int(shenfen) + perm_map, _ = _get_fadan_permission_config() + for perm, sf in perm_map.items(): + if sf == shenfen and perm in permissions: + return True + return False \ No newline at end of file diff --git a/backend/view.py b/backend/view.py index cb063e3..87cc5f9 100644 --- a/backend/view.py +++ b/backend/view.py @@ -41,7 +41,13 @@ from orders.utils import update_daily_payout from shop.utils import update_dianpu_daily_stat from products.utils import update_shangpin_daily_stat from orders.notice_tasks import dingdan_guangbo -from .utils import verify_kefu_permission +from .utils import ( + verify_kefu_permission, + PERMISSION_TO_SHENFEN, + SHENFEN_PROFILE_MAP, + has_fadan_view_permission, + check_fadan_permission, +) # models 集中导入 ## backend @@ -5698,8 +5704,7 @@ class FaKuanTongJiView(APIView): if kefu is None: return permissions - # 至少有一个罚款管理权限 - if not any(p in permissions for p in PERMISSION_TO_SHENFEN.keys()): + if not has_fadan_view_permission(permissions, username): return Response({'code': 403, 'msg': '无权限查看罚款统计'}) stats = Fadan.objects.aggregate( @@ -5733,7 +5738,7 @@ class FaKuanLieBiaoView(APIView): kefu, permissions = verify_kefu_permission(request, username) if kefu is None: return permissions - if not any(p in permissions for p in PERMISSION_TO_SHENFEN.keys()): + if not has_fadan_view_permission(permissions, username): return Response({'code': 403, 'msg': '无权限查看罚款列表'}) page = int(request.data.get('page', 1))