更新代码管事分红问题

This commit is contained in:
XingQue
2026-06-16 01:56:14 +08:00
parent 790f397893
commit 58b2bdf215
4 changed files with 110 additions and 32 deletions

View File

@@ -336,9 +336,23 @@ def update_daily_payout(amount):
from decimal import Decimal
from django.db import IntegrityError
from dingdan.models import Lilubiao
def _normalize_lilu_rate(raw):
"""Lilubiao 存小数比例;若后台误填 15 表示 15%,自动除以 100"""
if raw is None:
return Decimal('0')
rate = Decimal(str(raw))
if rate <= 0:
return Decimal('0')
if rate > 1:
rate = (rate / Decimal('100')).quantize(Decimal('0.0001'))
return rate
def calc_shangjia_order_fencheng(jine):
"""
商家发单时计算打手/管事分成。
@@ -350,22 +364,20 @@ def calc_shangjia_order_fencheng(jine):
jine = Decimal(str(jine))
try:
lilu_obj = Lilubiao.objects.get(fadanpingtai='3')
rate_dashou = Decimal(str(lilu_obj.lilu)) if lilu_obj.lilu and lilu_obj.lilu > 0 else Decimal('1')
rate_dashou = _normalize_lilu_rate(lilu_obj.lilu) if lilu_obj.lilu else Decimal('1')
if rate_dashou <= 0:
rate_dashou = Decimal('1')
except Lilubiao.DoesNotExist:
rate_dashou = Decimal('1')
lilu_guanshi_dashou_obj = Lilubiao.objects.filter(fadanpingtai='13').first()
rate_guanshi_dashou = (
Decimal(str(lilu_guanshi_dashou_obj.lilu))
if lilu_guanshi_dashou_obj and lilu_guanshi_dashou_obj.lilu is not None
else Decimal('0')
rate_guanshi_dashou = _normalize_lilu_rate(
lilu_guanshi_dashou_obj.lilu if lilu_guanshi_dashou_obj else None
)
lilu_guanshi_shangjia_obj = Lilubiao.objects.filter(fadanpingtai='15').first()
rate_guanshi_shangjia = (
Decimal(str(lilu_guanshi_shangjia_obj.lilu))
if lilu_guanshi_shangjia_obj and lilu_guanshi_shangjia_obj.lilu is not None
else Decimal('0')
rate_guanshi_shangjia = _normalize_lilu_rate(
lilu_guanshi_shangjia_obj.lilu if lilu_guanshi_shangjia_obj else None
)
dashou_fencheng = min(
@@ -401,6 +413,17 @@ def _pay_guanshi_order_fenhong(order, guanshi_id, amount, related_user_id, niche
logger.info(f"管事分红已处理: 订单{order.dingdan_id}, 类型{fenhong_leixing}")
return False
# 旧表结构 dingdan_id 全局唯一时,第二笔分红会插入失败
legacy_conflict = Gsfenhong.objects.filter(dingdan_id=order.dingdan_id).exclude(
fenhong_leixing=fenhong_leixing
).exists()
if legacy_conflict:
logger.error(
f"管事分红写入失败: 订单{order.dingdan_id} 已有其他类型分红记录,"
f"请执行 python manage.py migrate shangpin 0010 更新 gsfenhong 表唯一约束"
)
return False
try:
with transaction.atomic():
guanshi = UserGuanshi.objects.select_for_update().get(user__yonghuid=guanshi_id)
@@ -425,6 +448,14 @@ def _pay_guanshi_order_fenhong(order, guanshi_id, amount, related_user_id, niche
except UserGuanshi.DoesNotExist:
logger.warning(f"管事分红跳过: 管事{guanshi_id}不存在")
return False
except IntegrityError as e:
logger.error(
f"管事分红写入失败(数据库约束): 订单{order.dingdan_id}, 类型{fenhong_leixing}, "
f"关联用户{related_user_id}, 错误={e}. "
f"请确认已执行 migrate shangpin 0010 与 migrate dingdan 0017",
exc_info=True,
)
return False
except Exception as e:
logger.error(f"管事分红失败: {e}", exc_info=True)
return False
@@ -441,6 +472,11 @@ def _pay_guanshi_order_fenhong(order, guanshi_id, amount, related_user_id, niche
return True
def _resolve_dashou_inviter_guanshi(dashou_profile):
guanshi_id = (dashou_profile.yaoqingren or '').strip()
return guanshi_id or None
def settle_shangjia_order_guanshi_fenhong(order, dashou_id):
"""
商家订单结单时结算管事分红(幂等,失败不抛异常阻断主流程)。
@@ -448,14 +484,34 @@ def settle_shangjia_order_guanshi_fenhong(order, dashou_id):
- 管事商家派单分红派单商家打手身份的邀请管事guanshi_shangjia_fencheng
同一管事可同时获得两笔分红。
"""
from dingdan.models import DingdanShangjia
from dingdan.models import Dingdan, DingdanShangjia
from yonghu.models import UserDashou
if getattr(order, 'fadan_pingtai', None) != 2:
return
# 1. 接单打手邀请管事分红
# 重新读订单,确保拿到发单时写入的分红金额
try:
order = Dingdan.objects.get(dingdan_id=order.dingdan_id)
except Dingdan.DoesNotExist:
logger.warning(f"管事分红跳过: 订单{order.dingdan_id}不存在")
return
guanshi_fencheng = order.guanshi_fencheng or Decimal('0')
guanshi_shangjia_fencheng = order.guanshi_shangjia_fencheng or Decimal('0')
logger.info(
f"商家订单管事分红结算: 订单{order.dingdan_id}, 打手{dashou_id}, "
f"打手接单分红={guanshi_fencheng}, 商家派单分红={guanshi_shangjia_fencheng}"
)
if guanshi_fencheng <= 0 and guanshi_shangjia_fencheng <= 0:
logger.info(
f"管事分红跳过: 订单{order.dingdan_id} 两项分红均为0 "
f"(请检查 Lilubiao 13/15 费率及打手分成是否占满订单金额)"
)
return
# 1. 接单打手邀请管事分红
if guanshi_fencheng > 0 and dashou_id:
try:
dashou = UserDashou.objects.select_related('user').get(user__yonghuid=dashou_id)
@@ -463,11 +519,12 @@ def settle_shangjia_order_guanshi_fenhong(order, dashou_id):
logger.info(f"管事打手分红跳过: 打手{dashou_id}不存在")
dashou = None
if dashou and dashou.yaoqingren:
guanshi_id = _resolve_dashou_inviter_guanshi(dashou) if dashou else None
if dashou and guanshi_id:
user_main = dashou.user
_pay_guanshi_order_fenhong(
order=order,
guanshi_id=dashou.yaoqingren,
guanshi_id=guanshi_id,
amount=guanshi_fencheng,
related_user_id=dashou_id,
nicheng=dashou.nicheng,
@@ -476,13 +533,14 @@ def settle_shangjia_order_guanshi_fenhong(order, dashou_id):
shuoming='商家订单打手分红',
)
else:
logger.info(f"管事打手分红跳过: 打手{dashou_id}无邀请管事")
logger.info(f"管事打手分红跳过: 打手{dashou_id}无邀请管事(yaoqingren为空)")
# 2. 派单商家邀请管事分红
guanshi_shangjia_fencheng = order.guanshi_shangjia_fencheng or Decimal('0')
if guanshi_shangjia_fencheng > 0:
try:
shangjia_ext = DingdanShangjia.objects.select_related('dingdan').get(dingdan__dingdan_id=order.dingdan_id)
shangjia_ext = DingdanShangjia.objects.select_related('dingdan').get(
dingdan__dingdan_id=order.dingdan_id
)
shangjia_id = shangjia_ext.shangjia_id
except DingdanShangjia.DoesNotExist:
logger.info(f"管事商家分红跳过: 订单{order.dingdan_id}无商家扩展")
@@ -495,11 +553,12 @@ def settle_shangjia_order_guanshi_fenhong(order, dashou_id):
logger.info(f"管事商家分红跳过: 商家{shangjia_id}无打手扩展")
merchant_dashou = None
if merchant_dashou and merchant_dashou.yaoqingren:
guanshi_id = _resolve_dashou_inviter_guanshi(merchant_dashou) if merchant_dashou else None
if merchant_dashou and guanshi_id:
user_main = merchant_dashou.user
_pay_guanshi_order_fenhong(
order=order,
guanshi_id=merchant_dashou.yaoqingren,
guanshi_id=guanshi_id,
amount=guanshi_shangjia_fencheng,
related_user_id=shangjia_id,
nicheng=shangjia_ext.sjnicheng or merchant_dashou.nicheng,
@@ -508,4 +567,6 @@ def settle_shangjia_order_guanshi_fenhong(order, dashou_id):
shuoming='商家派单管事分红',
)
else:
logger.info(f"管事商家分红跳过: 商家{shangjia_id}打手身份无邀请管事")
logger.info(
f"管事商家分红跳过: 商家{shangjia_id}打手身份无邀请管事(yaoqingren为空)"
)