fix: 会员充值先开通再分红防回滚,补开通与注册时间字段
This commit is contained in:
@@ -911,6 +911,7 @@ class KefuGetDashouDetailView(APIView):
|
||||
'wechat': '',
|
||||
'phone': user_main.Phone or '',
|
||||
'CreateTime': user_main.UserCreateTime,
|
||||
'create_time': user_main.UserCreateTime.strftime('%Y-%m-%d %H:%M:%S') if getattr(user_main, 'UserCreateTime', None) else '',
|
||||
'ip': user_main.IP or '',
|
||||
'jiedanzongliang': 0,
|
||||
'chengjiaozongliang': 0,
|
||||
@@ -951,6 +952,7 @@ class KefuGetDashouDetailView(APIView):
|
||||
'wechat': dashou.wechat or '',
|
||||
'phone': user_main.Phone or '',
|
||||
'CreateTime': user_main.UserCreateTime,
|
||||
'create_time': user_main.UserCreateTime.strftime('%Y-%m-%d %H:%M:%S') if getattr(user_main, 'UserCreateTime', None) else '',
|
||||
'ip': user_main.IP or '',
|
||||
'jiedanzongliang': dashou.jiedanzongliang,
|
||||
'chengjiaozongliang': dashou.chengjiaozongliang,
|
||||
@@ -1554,6 +1556,7 @@ class KefuGetShangjiaDetailView(APIView):
|
||||
'jinyuedingdan': shangjia.jinyuedingdan,
|
||||
'jinyueliushui': str(shangjia.jinyueliushui),
|
||||
'CreateTime': shangjia.CreateTime.isoformat() if shangjia.CreateTime else None,
|
||||
'create_time': user.UserCreateTime.strftime('%Y-%m-%d %H:%M:%S') if getattr(user, 'UserCreateTime', None) else '',
|
||||
}
|
||||
|
||||
return Response({'code': 0, 'data': data})
|
||||
@@ -3824,6 +3827,7 @@ class GetZuzhangDetailView(APIView):
|
||||
'jinyue_fenyong': str(zuzhang.jinyue_fenyong),
|
||||
'fenyong_zonge': str(zuzhang.fenyong_zonge),
|
||||
'CreateTime': zuzhang.CreateTime.isoformat() if zuzhang.CreateTime else None,
|
||||
'create_time': user.UserCreateTime.strftime('%Y-%m-%d %H:%M:%S') if getattr(user, 'UserCreateTime', None) else '',
|
||||
}
|
||||
|
||||
# 余额提现相关
|
||||
|
||||
@@ -127,7 +127,12 @@ def _apply_member_fenhong(order, huiyuan, purchase_cishu):
|
||||
logger.info('会员分红已处理,跳过: %s', order.dingdan_id)
|
||||
return
|
||||
|
||||
dashou = UserDashou.query.get(user__UserUID=order.yonghuid)
|
||||
try:
|
||||
dashou = UserDashou.query.get(user__UserUID=order.yonghuid)
|
||||
except UserDashou.DoesNotExist:
|
||||
logger.warning('打手不存在,跳过会员分红: %s', order.yonghuid)
|
||||
return
|
||||
|
||||
guanshi_id = dashou.yaoqingren
|
||||
if not guanshi_id:
|
||||
logger.info('打手%s无邀请管事,跳过会员分红', order.yonghuid)
|
||||
@@ -282,6 +287,35 @@ def _add_first_buy_jifen(yonghuid):
|
||||
logger.warning('首次购会员加积分失败,打手不存在: %s', yonghuid)
|
||||
|
||||
|
||||
def repair_member_entitlement_if_paid(dingdan_id):
|
||||
"""
|
||||
订单已标为已支付(zhuangtai=3)但 huiyuangoumai 缺失时补开通会员。
|
||||
用于修复历史脏数据或履约中断。
|
||||
"""
|
||||
order = Czjilu.query.filter(dingdan_id=dingdan_id, leixing=1).first()
|
||||
if not order or order.zhuangtai != 3 or not order.huiyuan_id:
|
||||
return False
|
||||
|
||||
exists = Huiyuangoumai.query.filter(
|
||||
yonghu_id=order.yonghuid,
|
||||
huiyuan_id=order.huiyuan_id,
|
||||
).exists()
|
||||
if exists:
|
||||
return True
|
||||
|
||||
try:
|
||||
huiyuan = Huiyuan.query.get(huiyuan_id=order.huiyuan_id)
|
||||
except Huiyuan.DoesNotExist:
|
||||
logger.error('补开通会员失败,会员不存在 dingdan=%s huiyuan=%s', dingdan_id, order.huiyuan_id)
|
||||
return False
|
||||
|
||||
club_id = getattr(order, 'club_id', None) or CLUB_ID_DEFAULT
|
||||
with transaction.atomic():
|
||||
_apply_huiyuan_goumai(order.yonghuid, order.huiyuan_id, huiyuan, club_id)
|
||||
logger.warning('已补开通会员 dingdan=%s yonghu=%s huiyuan=%s', dingdan_id, order.yonghuid, order.huiyuan_id)
|
||||
return True
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def fulfill_member_recharge(dingdan_id, paid_amount_yuan=None, source='callback'):
|
||||
"""
|
||||
@@ -315,7 +349,10 @@ def fulfill_member_recharge(dingdan_id, paid_amount_yuan=None, source='callback'
|
||||
f'支付金额{paid}与订单{order_amt}不一致', 'amount_mismatch',
|
||||
)
|
||||
|
||||
huiyuan = Huiyuan.query.get(huiyuan_id=order.huiyuan_id)
|
||||
huiyuan = Huiyuan.query.filter(huiyuan_id=order.huiyuan_id).first()
|
||||
if not huiyuan:
|
||||
raise MemberRechargeError(f'会员不存在: {order.huiyuan_id}', 'huiyuan_not_found')
|
||||
|
||||
club_id = getattr(order, 'club_id', None) or CLUB_ID_DEFAULT
|
||||
|
||||
is_first_purchase_of_member = not Huiyuangoumai.query.filter(
|
||||
@@ -328,12 +365,12 @@ def fulfill_member_recharge(dingdan_id, paid_amount_yuan=None, source='callback'
|
||||
order.yonghuid, order.huiyuan_id, order.dingdan_id, club_id,
|
||||
)
|
||||
|
||||
jine_decimal = Decimal(str(order.jine))
|
||||
try:
|
||||
from jituan.services.szjilu_accounting import record_wechat_income_once
|
||||
record_wechat_income_once(jine_decimal, club_id, biz_ref=f'cz:{dingdan_id}')
|
||||
except Exception as exc:
|
||||
logger.error('会员收支统计更新失败: %s', exc, exc_info=True)
|
||||
# 先开通会员,再记账;分红失败不得回滚会员
|
||||
goumai_record, _, is_first_buy_any = _apply_huiyuan_goumai(
|
||||
order.yonghuid, order.huiyuan_id, huiyuan, club_id,
|
||||
)
|
||||
if is_first_buy_any:
|
||||
_add_first_buy_jifen(order.yonghuid)
|
||||
|
||||
order.zhuangtai = 3
|
||||
order.save(update_fields=['zhuangtai'])
|
||||
@@ -341,13 +378,20 @@ def fulfill_member_recharge(dingdan_id, paid_amount_yuan=None, source='callback'
|
||||
huiyuan.goumai_cishu = (huiyuan.goumai_cishu or 0) + 1
|
||||
huiyuan.save(update_fields=['goumai_cishu'])
|
||||
|
||||
goumai_record, _, is_first_buy_any = _apply_huiyuan_goumai(
|
||||
order.yonghuid, order.huiyuan_id, huiyuan, club_id,
|
||||
)
|
||||
if is_first_buy_any:
|
||||
_add_first_buy_jifen(order.yonghuid)
|
||||
jine_decimal = Decimal(str(order.jine))
|
||||
try:
|
||||
from jituan.services.szjilu_accounting import record_wechat_income_once
|
||||
record_wechat_income_once(jine_decimal, club_id, biz_ref=f'cz:{dingdan_id}')
|
||||
except Exception as exc:
|
||||
logger.error('会员收支统计更新失败: %s', exc, exc_info=True)
|
||||
|
||||
_apply_member_fenhong(order, huiyuan, purchase_cishu)
|
||||
try:
|
||||
_apply_member_fenhong(order, huiyuan, purchase_cishu)
|
||||
except Exception as exc:
|
||||
logger.error(
|
||||
'会员分红失败但会员已开通 dingdan=%s err=%s',
|
||||
dingdan_id, exc, exc_info=True,
|
||||
)
|
||||
|
||||
logger.info(
|
||||
'会员充值履约完成 dingdan=%s source=%s club=%s purchase_cishu=%s first_member=%s',
|
||||
@@ -419,6 +463,11 @@ def confirm_member_recharge_paid(dingdan_id, yonghuid):
|
||||
goumai = Huiyuangoumai.query.filter(
|
||||
yonghu_id=yonghuid, huiyuan_id=order.huiyuan_id,
|
||||
).first()
|
||||
if not goumai:
|
||||
repair_member_entitlement_if_paid(dingdan_id)
|
||||
goumai = Huiyuangoumai.query.filter(
|
||||
yonghu_id=yonghuid, huiyuan_id=order.huiyuan_id,
|
||||
).first()
|
||||
if not goumai:
|
||||
raise MemberRechargeError('订单已付但会员记录缺失,请联系客服', 'data_error')
|
||||
return {
|
||||
|
||||
@@ -1767,6 +1767,9 @@ class HuiyuanHuitiao(View):
|
||||
|
||||
if order.zhuangtai != 9:
|
||||
logger.warning(f"会员订单状态不是未支付: {order.dingdan_id}, 当前状态: {order.zhuangtai}")
|
||||
if order.zhuangtai == 3:
|
||||
from jituan.services.member_recharge import repair_member_entitlement_if_paid
|
||||
repair_member_entitlement_if_paid(out_trade_no)
|
||||
return self.wechat_response('SUCCESS', 'OK')
|
||||
|
||||
wechat_amount_yuan = total_fee / 100
|
||||
@@ -1968,6 +1971,9 @@ class HuiyuanLunxun(APIView):
|
||||
'message': '会员订单尚未支付完成'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
from jituan.services.member_recharge import repair_member_entitlement_if_paid
|
||||
repair_member_entitlement_if_paid(dingdanid)
|
||||
|
||||
# 5. 查询会员信息
|
||||
try:
|
||||
huiyuan = Huiyuan.query.get(huiyuan_id=order.huiyuan_id)
|
||||
|
||||
@@ -8585,6 +8585,7 @@ class KefuGetDashouDetailView(APIView):
|
||||
'wechat': '',
|
||||
'phone': user_main.Phone or '',
|
||||
'CreateTime': user_main.UserCreateTime,
|
||||
'create_time': user_main.UserCreateTime.strftime('%Y-%m-%d %H:%M:%S') if getattr(user_main, 'UserCreateTime', None) else '',
|
||||
'ip': user_main.IP or '',
|
||||
'jiedanzongliang': 0,
|
||||
'chengjiaozongliang': 0,
|
||||
@@ -8621,6 +8622,7 @@ class KefuGetDashouDetailView(APIView):
|
||||
'wechat': dashou.wechat or '',
|
||||
'phone': user_main.Phone or '',
|
||||
'CreateTime': user_main.UserCreateTime,
|
||||
'create_time': user_main.UserCreateTime.strftime('%Y-%m-%d %H:%M:%S') if getattr(user_main, 'UserCreateTime', None) else '',
|
||||
'ip': user_main.IP or '',
|
||||
'jiedanzongliang': dashou.jiedanzongliang,
|
||||
'chengjiaozongliang': dashou.chengjiaozongliang,
|
||||
|
||||
Reference in New Issue
Block a user