fix: 充值履约幂等加固(会员/押金/积分),后台加会员club_id
This commit is contained in:
@@ -615,111 +615,13 @@ class YajinHuitiao(View):
|
||||
logger.error(f"金额不一致: 订单金额{order_amount_yuan}元, 支付金额{wechat_amount_yuan}元")
|
||||
return self.wechat_response('FAIL', '金额不一致')
|
||||
|
||||
# 7. 更新订单状态为已支付(3)
|
||||
order.zhuangtai = 3
|
||||
order.save(update_fields=['zhuangtai'])
|
||||
logger.info(f"订单状态更新成功: {order.dingdan_id} -> 3")
|
||||
|
||||
# 8. 更新打手押金
|
||||
from jituan.services.czjilu_fulfill import fulfill_yajin_recharge, CzjiluFulfillError
|
||||
try:
|
||||
# 通过用户ID查找打手(高效查询)
|
||||
dashou = UserDashou.query.get(user__UserUID=order.yonghuid)
|
||||
fulfill_yajin_recharge(out_trade_no, paid_amount_yuan=wechat_amount_yuan)
|
||||
except CzjiluFulfillError as exc:
|
||||
logger.error('押金回调履约失败 %s: %s', out_trade_no, exc)
|
||||
return self.wechat_response('FAIL', str(exc))
|
||||
|
||||
# 增加押金(使用Decimal确保精度)
|
||||
dashou.yajin += Decimal(str(order_amount_yuan))
|
||||
dashou.save(update_fields=['yajin'])
|
||||
|
||||
logger.info(f"打手押金更新成功: 用户{order.yonghuid}, 增加{order_amount_yuan}元, 新押金{dashou.yajin}")
|
||||
|
||||
# 8b. 押金分红(仅微信确认到账后;费率 CommissionRate Platform=12)
|
||||
try:
|
||||
|
||||
guanshi_id = dashou.yaoqingren
|
||||
if not guanshi_id:
|
||||
logger.info(f"押金分红跳过: 打手{order.yonghuid}无邀请管事")
|
||||
elif Gsfenhong.query.filter(dingdan_id=order.dingdan_id).exists():
|
||||
logger.info(f"押金分红已处理: 订单{order.dingdan_id}")
|
||||
else:
|
||||
lilu_obj = CommissionRate.query.filter(Platform='12').first()
|
||||
rate = lilu_obj.Rate if lilu_obj and lilu_obj.Rate is not None else Decimal('0')
|
||||
if rate <= 0:
|
||||
logger.info(f"押金分红跳过: 费率未配置或为0")
|
||||
else:
|
||||
recharge_amount = Decimal(str(order_amount_yuan))
|
||||
fenhong_jine = (recharge_amount * rate).quantize(Decimal('0.01'))
|
||||
if fenhong_jine > 0:
|
||||
with transaction.atomic():
|
||||
guanshi = UserGuanshi.objects.select_for_update().get(
|
||||
user__UserUID=guanshi_id
|
||||
)
|
||||
guanshi.yue += fenhong_jine
|
||||
guanshi.chongzhifenrun += fenhong_jine
|
||||
guanshi.save(update_fields=['yue', 'chongzhifenrun'])
|
||||
|
||||
user_main = dashou.user
|
||||
Gsfenhong.query.create(
|
||||
dingdan_id=order.dingdan_id,
|
||||
guanshi=guanshi_id,
|
||||
dashouid=order.yonghuid,
|
||||
shuoming='押金分红',
|
||||
fenhong=fenhong_jine,
|
||||
avatar=user_main.Avatar,
|
||||
nicheng=dashou.nicheng or '未知打手',
|
||||
fenhong_leixing=2,
|
||||
club_id=resolve_gsfenhong_club_id(
|
||||
dingdan_id=order.dingdan_id,
|
||||
dashouid=order.yonghuid,
|
||||
czjilu=order,
|
||||
),
|
||||
)
|
||||
logger.info(
|
||||
f"押金分红成功: 订单{order.dingdan_id}, 管事{guanshi_id}, "
|
||||
f"打手{order.yonghuid}, 金额{fenhong_jine}元"
|
||||
)
|
||||
try:
|
||||
update_guanshi_daily_by_action(
|
||||
yonghuid=guanshi_id,
|
||||
action=4,
|
||||
amount=fenhong_jine,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"押金分红管事日统计更新失败: {e}")
|
||||
except UserGuanshi.DoesNotExist:
|
||||
logger.warning(f"押金分红跳过: 管事{guanshi_id}不存在")
|
||||
except Exception as e:
|
||||
logger.error(f"押金分红处理失败: {str(e)}", exc_info=True)
|
||||
|
||||
except UserDashou.DoesNotExist:
|
||||
# 如果找不到打手,记录错误,但依然返回成功(避免微信重复回调)
|
||||
logger.error(f"打手信息不存在: 用户{order.yonghuid}")
|
||||
return self.wechat_response('SUCCESS', 'OK')
|
||||
except Exception as e:
|
||||
logger.error(f"更新打手押金失败: {str(e)}", exc_info=True)
|
||||
return self.wechat_response('FAIL', '更新押金失败')
|
||||
|
||||
# ==== 在返回成功响应之前添加这段代码 ====
|
||||
|
||||
# 更新收支记录表
|
||||
try:
|
||||
# 获取订单金额(确保是Decimal类型)
|
||||
jine_decimal = Decimal(str(order.jine)) if not isinstance(order.jine, Decimal) else order.jine
|
||||
|
||||
from jituan.services.szjilu_accounting import record_wechat_income_once
|
||||
record_wechat_income_once(
|
||||
jine_decimal,
|
||||
getattr(order, 'club_id', None),
|
||||
biz_ref=f'cz:{order.dingdan_id}',
|
||||
)
|
||||
|
||||
logger.info(f"收支记录更新成功: 订单{order.dingdan_id}, 金额{jine_decimal}元")
|
||||
|
||||
except Exception as e:
|
||||
# 收支记录更新失败不影响主流程,只记录日志
|
||||
logger.error(f"更新收支记录失败: {str(e)}", exc_info=True)
|
||||
|
||||
# ==== 添加结束 ====
|
||||
|
||||
# 9. 返回成功响应给微信
|
||||
logger.info(f"押金支付回调处理完成: {out_trade_no}")
|
||||
return self.wechat_response('SUCCESS', 'OK')
|
||||
|
||||
@@ -872,7 +774,19 @@ class YajinLunxun(APIView):
|
||||
'message': '订单不存在或不属于当前用户'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 3. 检查订单状态是否为已支付(3)
|
||||
# 3. 未支付则查微信并幂等履约
|
||||
if order.zhuangtai == 9:
|
||||
from jituan.services.czjilu_fulfill import confirm_czjilu_paid, CzjiluFulfillError
|
||||
try:
|
||||
confirm_czjilu_paid(dingdanid, request.user.UserUID, expected_leixing=2)
|
||||
order = Czjilu.query.get(dingdan_id=dingdanid, yonghuid=request.user.UserUID)
|
||||
except CzjiluFulfillError as exc:
|
||||
logger.info(f"押金确认未就绪 {dingdanid}: {exc}")
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': str(exc),
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
if order.zhuangtai != 3:
|
||||
logger.info(f"订单{dingdanid}尚未支付完成,当前状态: {order.zhuangtai}")
|
||||
return Response({
|
||||
@@ -1205,59 +1119,13 @@ class JifenHuitiao(View):
|
||||
logger.error(f"积分金额错误: 订单金额{order_amount_yuan}元, 支付金额{wechat_amount_yuan}元")
|
||||
return self.wechat_response('FAIL', '金额错误')
|
||||
|
||||
# ==== 在返回成功响应之前添加这段代码 ====
|
||||
|
||||
# 更新收支记录表
|
||||
from jituan.services.czjilu_fulfill import fulfill_jifen_recharge, CzjiluFulfillError
|
||||
try:
|
||||
jine_decimal = Decimal(str(order.jine)) if not isinstance(order.jine, Decimal) else order.jine
|
||||
from jituan.services.szjilu_accounting import record_wechat_income_once
|
||||
record_wechat_income_once(
|
||||
jine_decimal,
|
||||
getattr(order, 'club_id', None),
|
||||
biz_ref=f'cz:{order.dingdan_id}',
|
||||
)
|
||||
fulfill_jifen_recharge(out_trade_no, paid_amount_yuan=wechat_amount_yuan)
|
||||
except CzjiluFulfillError as exc:
|
||||
logger.error('积分回调履约失败 %s: %s', out_trade_no, exc)
|
||||
return self.wechat_response('FAIL', str(exc))
|
||||
|
||||
logger.info(f"收支记录更新成功: 订单{order.dingdan_id}, 金额{jine_decimal}元")
|
||||
|
||||
except Exception as e:
|
||||
# 收支记录更新失败不影响主流程,只记录日志
|
||||
logger.error(f"更新收支记录失败: {str(e)}", exc_info=True)
|
||||
|
||||
# ==== 添加结束 ====
|
||||
|
||||
# 7. 更新订单状态为已支付(3)
|
||||
order.zhuangtai = 3
|
||||
order.save(update_fields=['zhuangtai'])
|
||||
logger.info(f"积分订单状态更新成功: {order.dingdan_id} -> 3")
|
||||
|
||||
# 8. 更新打手积分
|
||||
try:
|
||||
# 通过用户ID查找打手
|
||||
dashou = UserDashou.query.get(user__UserUID=order.yonghuid)
|
||||
|
||||
# 检查积分是否小于10
|
||||
if dashou.jifen < 10:
|
||||
# 增加5积分,但不超过10
|
||||
new_jifen = dashou.jifen + 5
|
||||
dashou.jifen = min(new_jifen, 10) # 确保不超过10
|
||||
dashou.save(update_fields=['jifen'])
|
||||
|
||||
logger.info(f"打手积分更新成功: 用户{order.yonghuid}, 增加5积分, 新积分{dashou.jifen}")
|
||||
|
||||
|
||||
|
||||
|
||||
else:
|
||||
logger.warning(f"打手积分已满: 用户{order.yonghuid}, 当前积分{dashou.jifen}")
|
||||
|
||||
except UserDashou.DoesNotExist:
|
||||
logger.error(f"打手信息不存在: 用户{order.yonghuid}")
|
||||
return self.wechat_response('SUCCESS', 'OK')
|
||||
except Exception as e:
|
||||
logger.error(f"更新打手积分失败: {str(e)}", exc_info=True)
|
||||
return self.wechat_response('FAIL', '更新积分失败')
|
||||
|
||||
# 9. 返回成功响应给微信
|
||||
logger.info(f"积分支付回调处理完成: {out_trade_no}")
|
||||
return self.wechat_response('SUCCESS', 'OK')
|
||||
|
||||
@@ -1421,7 +1289,19 @@ class JifenLunxun(APIView):
|
||||
'message': '订单类型错误,不是积分订单'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 4. 检查订单状态是否为已支付(3)
|
||||
# 4. 未支付则查微信并幂等履约
|
||||
if order.zhuangtai == 9:
|
||||
from jituan.services.czjilu_fulfill import confirm_czjilu_paid, CzjiluFulfillError
|
||||
try:
|
||||
confirm_czjilu_paid(dingdanid, request.user.UserUID, expected_leixing=3)
|
||||
order = Czjilu.query.get(dingdan_id=dingdanid, yonghuid=request.user.UserUID)
|
||||
except CzjiluFulfillError as exc:
|
||||
logger.info(f"积分确认未就绪 {dingdanid}: {exc}")
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': str(exc),
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
if order.zhuangtai != 3:
|
||||
logger.info(f"积分订单{dingdanid}尚未支付完成,当前状态: {order.zhuangtai}")
|
||||
return Response({
|
||||
|
||||
Reference in New Issue
Block a user