From 1ffd92758d634e6b1374ca1ab3eb7425c042d6fb Mon Sep 17 00:00:00 2001 From: XingQue Date: Wed, 8 Jul 2026 21:06:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=8A=BC=E9=87=91=E6=8F=90=E7=8E=B0?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E5=B0=81=E5=8F=B7=EF=BC=8C=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E5=8A=A0=E5=BC=BA=E6=89=93=E6=89=8B/=E6=94=B6=E6=AC=BE?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- users/tixian_shenhe_services.py | 78 +++++++++++++++++++++++---------- users/views/tixian.py | 56 ++++++++++------------- 2 files changed, 78 insertions(+), 56 deletions(-) diff --git a/users/tixian_shenhe_services.py b/users/tixian_shenhe_services.py index e55cb80..9f977ae 100644 --- a/users/tixian_shenhe_services.py +++ b/users/tixian_shenhe_services.py @@ -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) diff --git a/users/views/tixian.py b/users/views/tixian.py index 7d42ad4..a9484dd 100644 --- a/users/views/tixian.py +++ b/users/views/tixian.py @@ -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}'}