fix: 待收款驳回按业务单号查打款记录,避免 pk 误查导致 400

This commit is contained in:
XingQue
2026-07-30 19:06:38 +08:00
parent 9df450b278
commit 6f4e458871
2 changed files with 60 additions and 33 deletions

View File

@@ -1314,6 +1314,36 @@ def mark_transfer_success(auto_record, *, wechat_transfer_no=None, with_accounti
return True
def _lock_auto_record_by_audit(audit):
"""
按审核单锁定关联打款记录。
audit.tixian_auto_id 存的是 TixianAutoRecord.tixian_id业务单号不是自增 pk。
"""
auto = None
auto_id = (getattr(audit, 'tixian_auto_id', None) or '').strip()
if auto_id:
auto = (
TixianAutoRecord.objects.select_for_update()
.filter(tixian_id=auto_id)
.first()
)
# 兼容极少数历史数据误存自增 id
if auto is None and auto_id.isdigit():
auto = (
TixianAutoRecord.objects.select_for_update()
.filter(pk=int(auto_id))
.first()
)
if auto is None and getattr(audit, 'shenhe_danhao', None):
auto = (
TixianAutoRecord.objects.select_for_update()
.filter(shenhe_danhao=audit.shenhe_danhao)
.order_by('-CreateTime')
.first()
)
return auto
def admin_mark_pending_collect_success(audit, tixian, kefu_uid, *, with_accounting=True):
"""
客服强制:待收款(6) → 提现成功(2)。
@@ -1323,25 +1353,18 @@ def admin_mark_pending_collect_success(audit, tixian, kefu_uid, *, with_accounti
audit = TixianShenheJilu.objects.select_for_update().get(pk=audit.pk)
tixian = Tixianjilu.objects.select_for_update().get(pk=tixian.pk)
if int(audit.zhuangtai) != 6 or int(tixian.zhuangtai) != 6:
raise ValueError('仅待收款状态可标记为已收款')
raise ValueError(
f'仅待收款状态可标记为已收款'
f'(当前提现单={tixian.zhuangtai},审核单={audit.zhuangtai})'
)
# 1) 先改状态
sync_audit_and_jilu_status(audit, 2, shenhe_ren_id=kefu_uid or '')
tixian.shenheid = kefu_uid or tixian.shenheid or ''
sync_audit_and_jilu_status(audit, 2, shenhe_ren_id=(kefu_uid or '')[:11])
tixian.shenheid = (kefu_uid or tixian.shenheid or '')[:11]
tixian.save(update_fields=['shenheid', 'UpdateTime'])
# 2) 关联打款单:处理中→成功;无打款单则直接按审核金额记账
auto = None
auto_id = (getattr(audit, 'tixian_auto_id', None) or '').strip()
if auto_id:
auto = TixianAutoRecord.objects.select_for_update().filter(pk=auto_id).first()
if auto is None and audit.shenhe_danhao:
auto = (
TixianAutoRecord.objects.select_for_update()
.filter(shenhe_danhao=audit.shenhe_danhao)
.order_by('-CreateTime')
.first()
)
auto = _lock_auto_record_by_audit(audit)
if auto is not None:
if int(auto.zhuangtai) == 0:
@@ -1392,26 +1415,26 @@ def admin_reject_pending_or_auditing(
"""
audit = TixianShenheJilu.objects.select_for_update().get(pk=audit.pk)
tixian = Tixianjilu.objects.select_for_update().get(pk=tixian.pk)
cur = int(audit.zhuangtai)
if cur not in (1, 6):
raise ValueError('仅审核中/待收款可驳回')
if int(tixian.zhuangtai) != cur:
raise ValueError('提现单与审核单状态不一致')
jt = int(tixian.zhuangtai)
at = int(audit.zhuangtai)
if jt not in (1, 6) or at not in (1, 6):
raise ValueError(
f'仅审核中/待收款可驳回(当前提现单={jt},审核单={at})'
)
# 两边都可驳回但不同步时,以审核单为准对齐提现单后再驳回
if jt != at:
logger.warning(
'驳回前状态不一致,对齐提现单→审核单 tixian=%s jt=%s at=%s',
tixian.id, jt, at,
)
tixian.zhuangtai = at
tixian.save(update_fields=['zhuangtai', 'UpdateTime'])
reason = (reason or '').strip()[:500] or '客服驳回'
kefu_uid = (kefu_uid or '')[:11]
# 待收款可能已有打款单:先失败释放限额,避免用户还能收款
auto_id = (getattr(audit, 'tixian_auto_id', None) or '').strip()
auto = None
if auto_id:
auto = TixianAutoRecord.objects.select_for_update().filter(pk=auto_id).first()
if auto is None and audit.shenhe_danhao:
auto = (
TixianAutoRecord.objects.select_for_update()
.filter(shenhe_danhao=audit.shenhe_danhao, zhuangtai=0)
.order_by('-CreateTime')
.first()
)
auto = _lock_auto_record_by_audit(audit)
if auto is not None and int(auto.zhuangtai) == 0:
_close_auto_record_failed(auto, reason)
@@ -1419,7 +1442,7 @@ def admin_reject_pending_or_auditing(
sync_audit_and_jilu_status(
audit, 5,
bhliyou=reason,
bo_hui_ren_id=kefu_uid or '',
bo_hui_ren_id=kefu_uid or None,
tixian_auto_id=None,
)
tixian.shenheid = kefu_uid or tixian.shenheid or ''
@@ -1437,7 +1460,7 @@ def admin_reject_pending_or_auditing(
shouxufei=audit.shouxufei,
refund_fee=bool(refund_fee),
apply_entry_freeze=bool(apply_entry_freeze),
biz_id=f'withdraw_reject:admin:{tixian.id}:{cur}',
biz_id=f'withdraw_reject:admin:{tixian.id}:{at}',
freeze_reason=f'提现驳回退款 #{tixian.id}',
)
return refund_result

View File

@@ -728,7 +728,10 @@ class KefuWithdrawActionView(APIView):
# action=2审核中/待收款 → 驳回
if action == 2:
if cur not in (1, 6) or int(audit.zhuangtai) not in (1, 6):
raise ValueError(f'提现记录{tixian_id}:仅审核中/待收款可驳回')
raise ValueError(
f'提现记录{tixian_id}:仅审核中/待收款可驳回'
f'(当前提现单={cur},审核单={audit.zhuangtai})'
)
admin_reject_pending_or_auditing(
audit, tixian, user, kefu_uid, reason,
refund_principal=refund_principal,
@@ -902,6 +905,7 @@ class KefuWithdrawActionView(APIView):
)
except ValueError as e:
logger.warning('kefu_txsh_action 业务拒绝: %s data=%s', e, request.data)
return Response({'code': 400, 'msg': str(e)}, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
logger.error(f'处理提现事务失败: {e}', exc_info=True)