fix: 待收款驳回按业务单号查打款记录,避免 pk 误查导致 400
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user