feat: gate withdraw audit and add-balance to group executives only

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-06-29 01:30:56 +08:00
parent dd9e4afa49
commit dc71c4f1cb
3 changed files with 85 additions and 5 deletions

View File

@@ -1117,6 +1117,10 @@ class KefuUpdateDashouView(APIView):
elif caozuo == 'jia_yue':
if '001bb' not in permissions:
return Response({'code': 403, 'msg': '无权限加打手余额'})
from jituan.services.group_finance_gate import deny_group_finance_exec
deny = deny_group_finance_exec(request.user, request)
if deny:
return deny
amount = Decimal(str(value))
dashou_profile.yue += amount
dashou_profile.save()
@@ -1637,6 +1641,10 @@ class KefuUpdateShangjiaView(APIView):
# 增加余额
if action == 'add_balance':
from jituan.services.group_finance_gate import deny_group_finance_exec
deny = deny_group_finance_exec(request.user, request)
if deny:
return deny
amount_str = request.data.get('amount')
try:
amount = Decimal(str(amount_str))
@@ -3527,6 +3535,10 @@ class UpdateGuanliView(APIView):
if new_yue > old_yue:
if '4400c' not in permissions:
return Response({'code': 403, 'msg': '无权限增加余额需要4400c'})
from jituan.services.group_finance_gate import deny_group_finance_exec
deny = deny_group_finance_exec(request.user, request)
if deny:
return deny
action_desc = f'增加{new_yue - old_yue}'
elif new_yue < old_yue:
if '4400b' not in permissions:
@@ -4147,6 +4159,10 @@ class UpdateZuzhangView(APIView):
if new_val > old_ketixian_jine:
if '6600a' not in permissions:
return Response({'code': 403, 'msg': '无权限增加可提现金额需要6600a'})
from jituan.services.group_finance_gate import deny_group_finance_exec
deny = deny_group_finance_exec(request.user, request)
if deny:
return deny
action_desc = f'增加{new_val - old_ketixian_jine}'
elif new_val < old_ketixian_jine:
if '6600b' not in permissions:

View File

@@ -0,0 +1,50 @@
"""集团级资金处置权限:提现审核、加余额等。俱乐部 000001 超级管理不能绕过。"""
from django.db.models import Q
from jituan.constants import DATA_SCOPE_ALL
from jituan.models import AdminAssignment
from jituan.services.admin_context import GROUP_MANAGE_ROLES, build_admin_club_context, is_system_super_admin
MSG_GROUP_FINANCE_REQUIRED = '该操作仅集团高管可执行(需在数据范围配置中为集团级任职)'
def has_group_finance_exec(user, request=None):
"""系统超管 / 集团任职GROUP_OWNER、GROUP_SUPER_ADMIN"""
if is_system_super_admin(user):
return True
ctx = build_admin_club_context(user)
if ctx.get('is_group_admin') and ctx.get('role_code') in GROUP_MANAGE_ROLES:
return True
uid = getattr(user, 'UserUID', None)
if not uid:
return False
return AdminAssignment.query.filter(
yonghuid=uid,
status=1,
role_code__in=GROUP_MANAGE_ROLES,
).filter(
Q(club_id__isnull=True) | Q(data_scope=DATA_SCOPE_ALL),
).exists()
def deny_group_finance_exec(user, request=None):
from rest_framework.response import Response
if has_group_finance_exec(user, request):
return None
return Response({'code': 403, 'msg': MSG_GROUP_FINANCE_REQUIRED})
def require_withdraw_audit_access(request, phone):
"""提现审核:须 005bb 且集团资金处置权。"""
from backend.utils import verify_kefu_permission
from rest_framework.response import Response
kefu, permissions = verify_kefu_permission(request, phone)
if kefu is None:
return None, permissions
if '005bb' not in permissions:
return None, Response({'code': 403, 'msg': '您无权操作提现审核'})
deny = deny_group_finance_exec(request.user, request)
if deny:
return None, deny
return kefu, None

View File

@@ -8793,6 +8793,10 @@ class KefuUpdateDashouView(APIView):
elif caozuo == 'jia_yue':
if '001bb' not in permissions:
return Response({'code': 403, 'msg': '无权限加打手余额'})
from jituan.services.group_finance_gate import deny_group_finance_exec
deny = deny_group_finance_exec(request.user, request)
if deny:
return deny
amount = Decimal(str(value))
dashou_profile.yue += amount
dashou_profile.save()
@@ -9776,6 +9780,8 @@ class KefuWithdrawListView(APIView):
return 1
def post(self, request):
from jituan.services.group_finance_gate import require_withdraw_audit_access
dakuan_mode_filter = request.data.get('dakuan_mode')
req_params = self._safe_request_params(request)
kefu_txsh_list_logger.info('kefu_txsh_list 请求开始 params=%s', req_params)
@@ -9804,11 +9810,9 @@ class KefuWithdrawListView(APIView):
if not phone:
return Response({'code': 401, 'msg': '缺少客服手机号'}, status=status.HTTP_401_UNAUTHORIZED)
kefu, permissions = verify_kefu_permission(request, phone)
if kefu is None:
return permissions
if '005bb' not in permissions:
return Response({'code': 403, 'msg': '您无权查看提现审核列表'})
kefu, err_resp = require_withdraw_audit_access(request, phone)
if err_resp:
return err_resp
q = Q()
@@ -10029,6 +10033,11 @@ class KefuWithdrawDetailView(APIView):
logger.warning(f"客服账号已禁用: {current_user.UserUID}")
return Response({'code': 401, 'msg': '认证失败'}, status=status.HTTP_401_UNAUTHORIZED)
from jituan.services.group_finance_gate import require_withdraw_audit_access
_, err_resp = require_withdraw_audit_access(request, phone)
if err_resp:
return err_resp
# 查询提现记录
try:
record = Tixianjilu.query.get(id=tixian_id)
@@ -10327,6 +10336,11 @@ class KefuWithdrawActionView(APIView):
if err_resp:
return err_resp
from jituan.services.group_finance_gate import require_withdraw_audit_access
_, audit_err = require_withdraw_audit_access(request, phone)
if audit_err:
return audit_err
items, err_resp = self._parse_items(request)
if err_resp:
return err_resp