fix: 押金提现不再封号,统一加强打手/收款校验

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-08 21:06:28 +08:00
parent ad33ee6c86
commit 1ffd92758d
2 changed files with 78 additions and 56 deletions

View File

@@ -225,6 +225,34 @@ def check_dashou_trial_blocks_commission_withdraw(yonghuid):
return True, ''
def _dashou_has_unfinished_orders(yonghuid):
return Order.query.filter(
PlayerID=yonghuid,
).exclude(
Status__in=[ORDER_STATUS_COMPLETED, ORDER_STATUS_REFUNDED],
).exists()
def _dashou_has_open_penalties(yonghuid):
return Penalty.query.filter(
PenalizedUserID=yonghuid,
).exclude(
Status__in=[2, 4],
).exists()
def validate_payment_info_for_withdraw(user_main):
"""申请/收款前:须已绑定手机号,且收款账号与收款码至少一项。"""
phone = (getattr(user_main, 'Phone', None) or '').strip()
account = (getattr(user_main, 'PaymentAccount', None) or '').strip()
qr = (getattr(user_main, 'PaymentQRCode', None) or '').strip()
if not phone:
return False, '请先完善收款手机号后再提现'
if not account and not qr:
return False, '请先设置收款账号或上传收款码后再提现'
return True, ''
def validate_withdraw_eligibility(user_main, leixing, jine):
"""
提现申请资格校验(完整基本条件;仅放宽「不限制并行申请笔数」)。
@@ -245,7 +273,7 @@ def validate_withdraw_eligibility(user_main, leixing, jine):
return False, '打手账号已被封禁,无法提现', {}
if dashou.zhuangtai != 1:
return False, '有订单进行中,请完成后提现', {}
if dashou.jifen != 10:
if dashou.jifen < 10:
return False, '积分不足10分请补充积分后提现', {}
huiyuan_ok, huiyuan_msg = check_dashou_has_formal_huiyuan_for_withdraw(yonghuid)
if not huiyuan_ok:
@@ -253,6 +281,10 @@ def validate_withdraw_eligibility(user_main, leixing, jine):
trial_ok, trial_msg = check_dashou_trial_blocks_commission_withdraw(yonghuid)
if not trial_ok:
return False, trial_msg, {}
if _dashou_has_unfinished_orders(yonghuid):
return False, '您还有未完成或未退款的订单,请先处理完毕再提现', {}
if _dashou_has_open_penalties(yonghuid):
return False, '您有未处理完毕的自身罚单(待缴纳/申诉中),请先处理', {}
if dashou.yue < jine:
return False, f'余额不足,当前余额: {dashou.yue}', {}
return True, '', {'nicheng': dashou.nicheng or ''}
@@ -299,20 +331,16 @@ def validate_withdraw_eligibility(user_main, leixing, jine):
return False, '打手账号已禁用,无法提取押金', {}
if dashou.zhuangtai != 1:
return False, '您有订单进行中,请完成后提取押金', {}
if dashou.jifen != 10:
if dashou.jifen < 10:
return False, '积分不足10分请补充积分后提取押金', {}
huiyuan_ok, huiyuan_msg = check_dashou_has_valid_huiyuan(yonghuid)
huiyuan_ok, huiyuan_msg = check_dashou_has_formal_huiyuan_for_withdraw(yonghuid)
if not huiyuan_ok:
return False, huiyuan_msg, {}
if dashou.yajin < jine:
return False, f'押金余额不足,当前押金: {dashou.yajin}', {}
unfinished = Order.query.filter(
PlayerID=yonghuid,
).exclude(Status__in=[ORDER_STATUS_COMPLETED, ORDER_STATUS_REFUNDED]).exists()
if unfinished:
if _dashou_has_unfinished_orders(yonghuid):
return False, '您还有未完成或未退款的订单,请先处理完毕再提取押金', {}
self_fadan = Penalty.query.filter(PenalizedUserID=yonghuid).exclude(Status__in=[2, 4]).exists()
if self_fadan:
if _dashou_has_open_penalties(yonghuid):
return False, '您有未处理完毕的自身罚单(待缴纳/申诉中),请先处理', {}
return True, '', {'nicheng': dashou.nicheng or ''}
@@ -359,6 +387,10 @@ def validate_collect_eligibility(user_main, leixing):
打手佣金/押金:罚单、封禁、接单中、积分、会员、订单等;
其他身份:账号状态、罚单/订单等。
"""
pay_ok, pay_msg = validate_payment_info_for_withdraw(user_main)
if not pay_ok:
return False, pay_msg
yonghuid = user_main.UserUID
fadan_ok, fadan_msg = check_fadan_qiangdan_eligible(yonghuid, 2)
@@ -374,7 +406,7 @@ def validate_collect_eligibility(user_main, leixing):
return False, '打手账号已被封禁,无法收款'
if dashou.zhuangtai != 1:
return False, '您有订单进行中,请完成后再收款'
if dashou.jifen != 10:
if dashou.jifen < 10:
return False, '积分不足10分无法收款'
huiyuan_ok, huiyuan_msg = check_dashou_has_formal_huiyuan_for_withdraw(yonghuid)
if not huiyuan_ok:
@@ -382,6 +414,10 @@ def validate_collect_eligibility(user_main, leixing):
trial_ok, trial_msg = check_dashou_trial_blocks_commission_withdraw(yonghuid)
if not trial_ok:
return False, trial_msg
if _dashou_has_unfinished_orders(yonghuid):
return False, '您还有未完成或未退款的订单,无法收款'
if _dashou_has_open_penalties(yonghuid):
return False, '您有未处理完毕的自身罚单,无法收款'
return True, ''
if leixing == 5:
@@ -393,18 +429,14 @@ def validate_collect_eligibility(user_main, leixing):
return False, '打手账号已禁用,无法收款'
if dashou.zhuangtai != 1:
return False, '您有订单进行中,请完成后再收款'
if dashou.jifen != 10:
if dashou.jifen < 10:
return False, '积分不足10分无法收款'
huiyuan_ok, huiyuan_msg = check_dashou_has_valid_huiyuan(yonghuid)
huiyuan_ok, huiyuan_msg = check_dashou_has_formal_huiyuan_for_withdraw(yonghuid)
if not huiyuan_ok:
return False, huiyuan_msg
unfinished = Order.query.filter(
PlayerID=yonghuid,
).exclude(Status__in=[ORDER_STATUS_COMPLETED, ORDER_STATUS_REFUNDED]).exists()
if unfinished:
if _dashou_has_unfinished_orders(yonghuid):
return False, '您还有未完成或未退款的订单,无法收款'
self_fadan = Penalty.query.filter(PenalizedUserID=yonghuid).exclude(Status__in=[2, 4]).exists()
if self_fadan:
if _dashou_has_open_penalties(yonghuid):
return False, '您有未处理完毕的自身罚单,无法收款'
return True, ''
@@ -831,8 +863,7 @@ def refund_balance(user_main, leixing, jine):
elif leixing == 5:
dashou = UserDashou.objects.select_for_update().get(user=user_main)
dashou.yajin += jine
dashou.zhanghaozhuangtai = 1
dashou.save()
dashou.save(update_fields=['yajin'])
elif leixing == 6:
shangjia = UserShangjia.objects.select_for_update().get(user=user_main)
shangjia.yue += jine
@@ -876,8 +907,7 @@ def deduct_balance(user_main, leixing, jine):
if dashou.yajin < jine:
raise ValueError('押金余额不足')
dashou.yajin -= jine
dashou.zhanghaozhuangtai = 0
dashou.save()
dashou.save(update_fields=['yajin'])
return dashou.nicheng or ''
if leixing == 6:
shangjia = UserShangjia.objects.select_for_update().get(user=user_main)
@@ -1384,6 +1414,10 @@ def create_audit_application(user_main, leixing, jine):
"""
yonghuid = user_main.UserUID
pay_ok, pay_msg = validate_payment_info_for_withdraw(user_main)
if not pay_ok:
raise ValueError(pay_msg)
ok, msg, extra = validate_withdraw_eligibility(user_main, leixing, jine)
if not ok:
raise ValueError(msg)

View File

@@ -73,6 +73,8 @@ from ..tixian_shenhe_services import (
check_shijidaozhang_within_limit,
check_dashou_has_formal_huiyuan_for_withdraw,
check_dashou_trial_blocks_commission_withdraw,
validate_withdraw_eligibility,
validate_payment_info_for_withdraw,
WX_STATE_FAIL, WX_STATE_SUCCESS, WX_STATE_WAIT, WX_STATE_CANCELING,
)
from ..tixian_shenhe_views import process_audit_collect
@@ -392,14 +394,19 @@ class TixianShenqingView(APIView):
return Response({'code': 6, 'msg': '提现金额过低,扣除手续费后无实际到账'},
status=status.HTTP_400_BAD_REQUEST)
# 3. 根据提现类型执行校验和扣款
nicheng = ''
pay_ok, pay_msg = validate_payment_info_for_withdraw(user_main)
if not pay_ok:
return Response({'code': 7, 'msg': pay_msg},
status=status.HTTP_400_BAD_REQUEST)
ok, elig_msg, extra = validate_withdraw_eligibility(user_main, leixing, jine)
if not ok:
return Response({'code': 8, 'msg': elig_msg},
status=status.HTTP_400_BAD_REQUEST)
# 3. 根据提现类型扣款(资格已在 validate_withdraw_eligibility 校验)
nicheng = extra.get('nicheng', '')
if leixing == 1:
result = self._check_dashou_commission_withdraw(user_main, jine)
if result['code'] != 0:
return Response(result, status=status.HTTP_400_BAD_REQUEST)
nicheng = result['data']['nicheng']
# 扣款(佣金)
with transaction.atomic():
profile = UserDashou.objects.select_for_update().get(user=user_main)
if profile.yue < jine:
@@ -407,65 +414,46 @@ class TixianShenqingView(APIView):
profile.yue = F('yue') - jine
profile.save()
elif leixing == 2:
result = self._check_guanshi_dividend_withdraw(user_main, jine)
if result['code'] != 0:
return Response(result, status=status.HTTP_400_BAD_REQUEST)
with transaction.atomic():
profile = UserGuanshi.objects.select_for_update().get(user=user_main)
if profile.yue < jine:
return Response({'code': 22, 'msg': '余额不足'})
profile.yue = F('yue') - jine
profile.save()
nicheng = "管事用户"
nicheng = extra.get('nicheng') or '管事用户'
elif leixing == 3:
result = self._check_zuzhang_withdraw(user_main, jine)
if result['code'] != 0:
return Response(result, status=status.HTTP_400_BAD_REQUEST)
with transaction.atomic():
profile = UserZuzhang.objects.select_for_update().get(user=user_main)
if profile.ketixian_jine < jine:
return Response({'code': 32, 'msg': '可提现金额不足'})
profile.ketixian_jine = F('ketixian_jine') - jine
profile.save()
nicheng = user_main.nicheng if hasattr(user_main, 'nicheng') else ''
nicheng = extra.get('nicheng') or ''
elif leixing == 4:
result = self._check_shenheguan_withdraw(user_main, jine)
if result['code'] != 0:
return Response(result, status=status.HTTP_400_BAD_REQUEST)
with transaction.atomic():
profile = UserShenheguan.objects.select_for_update().get(user=user_main)
if profile.yue < jine:
return Response({'code': 42, 'msg': '可提现金额不足'})
profile.yue = F('yue') - jine
profile.save()
nicheng = "审核官"
nicheng = extra.get('nicheng') or '审核官'
elif leixing == 5:
# 打手押金提现(退出)
result = self._check_dashou_yajin_withdraw(user_main, jine)
if result['code'] != 0:
return Response(result, status=status.HTTP_400_BAD_REQUEST)
# 打手押金提现:仅扣押金,走审核流程,不再封禁账号
with transaction.atomic():
profile = UserDashou.objects.select_for_update().get(user=user_main)
if profile.yajin < jine:
return Response({'code': 53, 'msg': '押金余额不足'})
profile.yajin = F('yajin') - jine
# 押金提现后封禁打手账号
profile.zhanghaozhuangtai = 0 # 0表示禁用
profile.save()
nicheng = profile.nicheng or ''
profile.save(update_fields=['yajin'])
nicheng = extra.get('nicheng') or profile.nicheng or ''
elif leixing == 6:
# 商家余额提现(退出)
result = self._check_shangjia_withdraw(user_main, jine)
if result['code'] != 0:
return Response(result, status=status.HTTP_400_BAD_REQUEST)
with transaction.atomic():
profile = UserShangjia.objects.select_for_update().get(user=user_main)
if profile.yue < jine:
return Response({'code': 63, 'msg': '商家余额不足'})
profile.yue = F('yue') - jine
# 注意:是否封禁商家账号?根据需求,用户未明确要求封禁,暂时只扣款,可后续扩展。
profile.save()
nicheng = profile.nicheng or ''
nicheng = extra.get('nicheng') or profile.nicheng or ''
# 4. 创建提现记录(先扣款后创建,确保资金安全)
try:
@@ -529,7 +517,7 @@ class TixianShenqingView(APIView):
return {'code': 11, 'msg': '打手账号已被封禁,无法提现'}
if dashou.zhuangtai != 1:
return {'code': 12, 'msg': '您有订单进行中,请完成后提现'}
if dashou.jifen != 10:
if dashou.jifen < 10:
return {'code': 15, 'msg': '积分不足10分请补充积分后提现'}
if dashou.yue < jine:
return {'code': 13, 'msg': f'余额不足,当前余额: {dashou.yue}'}