修复了已知的生产环境问题

This commit is contained in:
2026-06-17 21:25:45 +08:00
parent d00f0d08e5
commit 4aca437d2b
25 changed files with 13547 additions and 13423 deletions

View File

@@ -1,4 +1,4 @@
# Generated by Django 4.2.27 on 2026-06-17 16:31
# Generated by Django 4.2.27 on 2026-06-17 21:18
from django.db import migrations, models
import django.db.models.deletion

View File

@@ -1,208 +1,208 @@
"""
阿龙电竞 - 订单定时任务
处理订单超时自动确认等逻辑
完整版本,包含所有必要的异常处理
"""
from celery import shared_task
from django.db import transaction
from django.db.models import F, Q
from django.conf import settings
from django.utils import timezone
from datetime import timedelta
from decimal import Decimal
import logging
# 导入模型 - 确保路径正确
from orders.models import Dingdan
from users.models import UserDashou, UserShangjia
from gvsdsdk.models import User
from utils.celery_utils import safe_decimal_operation, log_task_execution, rollback_on_failure
from gvsdsdk.fluent import db, func, FQ
logger = logging.getLogger(__name__)
@shared_task(bind=True, max_retries=3, default_retry_delay=60)
def process_expired_order(self, dingdan_id):
"""
处理单个超时订单(订单状态=8超过48小时未处理
【已禁用】ORDER_AUTO_SETTLEMENT_ENABLED=False 且已从 Celery autodiscover 移除
"""
if not getattr(settings, 'ORDER_AUTO_SETTLEMENT_ENABLED', False):
logger.warning('订单%s自动结算已关闭(ORDER_AUTO_SETTLEMENT_ENABLED=False),拒绝执行', dingdan_id)
return f"订单{dingdan_id}自动结算已禁用,跳过"
# --- 以下原结算逻辑保留备查 ---
try:
# 使用select_for_update锁定记录防止并发修改
with transaction.atomic():
# 获取订单,同时锁定记录
order = Dingdan.objects.select_for_update().get(
dingdan_id=dingdan_id
)
# 再次检查订单状态是否为8
if order.zhuangtai != 8:
logger.info(f"订单{dingdan_id}状态已不是8当前:{order.zhuangtai}),跳过处理")
return f"订单{dingdan_id}状态已变更,跳过处理"
# 获取发单平台类型
fadan_pingtai = order.fadan_pingtai
# 获取打手ID和分成金额
dashou_id = order.jiedan_dashou_id
dashou_fencheng = safe_decimal_operation(order.dashou_fencheng)
# 1. 更新订单状态为3已完成
order.zhuangtai = 3
order.save(update_fields=['zhuangtai'])
# 2. 更新打手信息(如果存在)
updated_dashou = False
if dashou_id:
try:
# 查询打手用户主表
dashou_user = User.query.filter(yonghuid=dashou_id).first()
if dashou_user:
# 获取打手扩展表
dashou_profile = getattr(dashou_user, 'dashou_profile', None)
if dashou_profile:
# 使用F表达式原子更新
UserDashou.query.filter(pk=dashou_profile.pk).update(
chengjiaozongliang=F('chengjiaozongliang') + 1,
yue=F('yue') + dashou_fencheng,
zonge=F('zonge') + dashou_fencheng,
jinrishouyi=F('jinrishouyi') + dashou_fencheng,
jinyueshouyi=F('jinyueshouyi') + dashou_fencheng
)
updated_dashou = True
logger.info(f"更新打手{dashou_id}信息成功")
except Exception as e:
logger.error(f"更新打手信息失败打手ID: {dashou_id}, 错误: {str(e)}")
# 继续执行,不中断流程
# 3. 如果是商家发单,更新商家信息
updated_shangjia = False
if fadan_pingtai == 2: # 商家发单
try:
# 获取商家扩展信息
shangjia_kuozhan = getattr(order, 'shangjia_kuozhan', None)
if shangjia_kuozhan:
shangjia_id = shangjia_kuozhan.shangjia_id
if shangjia_id:
# 查询商家用户
shangjia_user = User.query.filter(yonghuid=shangjia_id).first()
if shangjia_user:
shangjia_profile = getattr(shangjia_user, 'shop_profile', None)
if shangjia_profile:
# 更新商家成交订单数量
UserShangjia.query.filter(pk=shangjia_profile.pk).update(
chengjiao=F('chengjiao') + 1
)
updated_shangjia = True
logger.info(f"更新商家{shangjia_id}信息成功")
except Exception as e:
logger.error(f"更新商家信息失败订单ID: {dingdan_id}, 错误: {str(e)}")
# 继续执行,不中断流程
# 记录任务执行结果
result_msg = f"订单{dingdan_id}自动结算完成"
if updated_dashou:
result_msg += ",打手信息已更新"
if updated_shangjia:
result_msg += ",商家信息已更新"
if fadan_pingtai == 1:
pass # 平台收益更新逻辑待完善
log_task_execution(f"自动结算订单 {dingdan_id}", True, result_msg)
return result_msg
except Dingdan.DoesNotExist:
error_msg = f"订单{dingdan_id}不存在"
logger.warning(error_msg)
return error_msg
except Exception as e:
error_msg = f"处理订单{dingdan_id}时发生错误: {str(e)}"
logger.error(error_msg)
# 重试机制
if self.request.retries < self.max_retries:
logger.info(f"订单{dingdan_id}处理失败,准备第{self.request.retries + 1}次重试")
raise self.retry(exc=e)
log_task_execution(f"自动结算订单 {dingdan_id}", False, error_msg)
return error_msg
@shared_task
@rollback_on_failure("批量检查超时订单")
def check_order_expire_task():
"""
批量检查超时订单(补偿机制)
【已禁用】ORDER_AUTO_SETTLEMENT_ENABLED=False
"""
if not getattr(settings, 'ORDER_AUTO_SETTLEMENT_ENABLED', False):
logger.warning('订单自动结算补偿检查已关闭(ORDER_AUTO_SETTLEMENT_ENABLED=False),拒绝执行')
return {"success": True, "message": "自动结算已禁用", "count": 0}
# --- 以下原补偿逻辑保留备查 ---
try:
# 计算更宽松的时间点当前时间减去72小时48+24小时
# 这样避免误处理刚变为状态8的订单
check_time = timezone.now() - timedelta(seconds=settings.ORDER_EXPIRE_SECONDS + 86400) # 48+24=72小时
# 查询状态为8且创建时间早于检查时间的订单
expired_orders = Dingdan.query.filter(
zhuangtai=8,
create_time__lt=check_time
).values_list('dingdan_id', flat=True)
expired_count = expired_orders.count()
if expired_count == 0:
logger.info("补偿检查:无超时订单")
return {"success": True, "message": "无超时订单", "count": 0}
# 分批处理超时订单(避免一次处理太多)
batch_size = 10
processed_count = 0
for i in range(0, expired_count, batch_size):
batch = expired_orders[i:i+batch_size]
# 异步处理每个超时订单
for dingdan_id in batch:
process_expired_order.apply_async(
args=[dingdan_id],
queue='order_tasks',
priority=8 # 补偿任务的优先级低一些
)
processed_count += 1
result_msg = f"补偿检查:发现{expired_count}个可能超时的订单,已提交处理{processed_count}"
log_task_execution("批量检查超时订单", True, result_msg)
return {
"success": True,
"message": result_msg,
"total_count": expired_count,
"processed_count": processed_count
}
except Exception as e:
error_msg = f"批量检查超时订单失败: {str(e)}"
logger.error(error_msg)
log_task_execution("批量检查超时订单", False, error_msg)
return {
"success": False,
"message": error_msg,
"error": str(e)
}
"""
阿龙电竞 - 订单定时任务
处理订单超时自动确认等逻辑
完整版本,包含所有必要的异常处理
"""
from celery import shared_task
from django.db import transaction
from django.db.models import F, Q
from django.conf import settings
from django.utils import timezone
from datetime import timedelta
from decimal import Decimal
import logging
# 导入模型 - 确保路径正确
from orders.models import Dingdan
from users.models import UserDashou, UserShangjia
from gvsdsdk.models import User
from utils.celery_utils import safe_decimal_operation, log_task_execution, rollback_on_failure
from gvsdsdk.fluent import db, func, FQ
logger = logging.getLogger(__name__)
@shared_task(bind=True, max_retries=3, default_retry_delay=60)
def process_expired_order(self, dingdan_id):
"""
处理单个超时订单(订单状态=8超过48小时未处理
【已禁用】ORDER_AUTO_SETTLEMENT_ENABLED=False 且已从 Celery autodiscover 移除
"""
if not getattr(settings, 'ORDER_AUTO_SETTLEMENT_ENABLED', False):
logger.warning('订单%s自动结算已关闭(ORDER_AUTO_SETTLEMENT_ENABLED=False),拒绝执行', dingdan_id)
return f"订单{dingdan_id}自动结算已禁用,跳过"
# --- 以下原结算逻辑保留备查 ---
try:
# 使用select_for_update锁定记录防止并发修改
with transaction.atomic():
# 获取订单,同时锁定记录
order = Dingdan.objects.select_for_update().get(
dingdan_id=dingdan_id
)
# 再次检查订单状态是否为8
if order.zhuangtai != 8:
logger.info(f"订单{dingdan_id}状态已不是8当前:{order.zhuangtai}),跳过处理")
return f"订单{dingdan_id}状态已变更,跳过处理"
# 获取发单平台类型
fadan_pingtai = order.fadan_pingtai
# 获取打手ID和分成金额
dashou_id = order.jiedan_dashou_id
dashou_fencheng = safe_decimal_operation(order.dashou_fencheng)
# 1. 更新订单状态为3已完成
order.zhuangtai = 3
order.save(update_fields=['zhuangtai'])
# 2. 更新打手信息(如果存在)
updated_dashou = False
if dashou_id:
try:
# 查询打手用户主表
dashou_user = User.query.filter(UserUID=dashou_id).first()
if dashou_user:
# 获取打手扩展表
dashou_profile = getattr(dashou_user, 'dashou_profile', None)
if dashou_profile:
# 使用F表达式原子更新
UserDashou.query.filter(pk=dashou_profile.pk).update(
chengjiaozongliang=F('chengjiaozongliang') + 1,
yue=F('yue') + dashou_fencheng,
zonge=F('zonge') + dashou_fencheng,
jinrishouyi=F('jinrishouyi') + dashou_fencheng,
jinyueshouyi=F('jinyueshouyi') + dashou_fencheng
)
updated_dashou = True
logger.info(f"更新打手{dashou_id}信息成功")
except Exception as e:
logger.error(f"更新打手信息失败打手ID: {dashou_id}, 错误: {str(e)}")
# 继续执行,不中断流程
# 3. 如果是商家发单,更新商家信息
updated_shangjia = False
if fadan_pingtai == 2: # 商家发单
try:
# 获取商家扩展信息
shangjia_kuozhan = getattr(order, 'shangjia_kuozhan', None)
if shangjia_kuozhan:
shangjia_id = shangjia_kuozhan.shangjia_id
if shangjia_id:
# 查询商家用户
shangjia_user = User.query.filter(UserUID=shangjia_id).first()
if shangjia_user:
shangjia_profile = getattr(shangjia_user, 'shop_profile', None)
if shangjia_profile:
# 更新商家成交订单数量
UserShangjia.query.filter(pk=shangjia_profile.pk).update(
chengjiao=F('chengjiao') + 1
)
updated_shangjia = True
logger.info(f"更新商家{shangjia_id}信息成功")
except Exception as e:
logger.error(f"更新商家信息失败订单ID: {dingdan_id}, 错误: {str(e)}")
# 继续执行,不中断流程
# 记录任务执行结果
result_msg = f"订单{dingdan_id}自动结算完成"
if updated_dashou:
result_msg += ",打手信息已更新"
if updated_shangjia:
result_msg += ",商家信息已更新"
if fadan_pingtai == 1:
pass # 平台收益更新逻辑待完善
log_task_execution(f"自动结算订单 {dingdan_id}", True, result_msg)
return result_msg
except Dingdan.DoesNotExist:
error_msg = f"订单{dingdan_id}不存在"
logger.warning(error_msg)
return error_msg
except Exception as e:
error_msg = f"处理订单{dingdan_id}时发生错误: {str(e)}"
logger.error(error_msg)
# 重试机制
if self.request.retries < self.max_retries:
logger.info(f"订单{dingdan_id}处理失败,准备第{self.request.retries + 1}次重试")
raise self.retry(exc=e)
log_task_execution(f"自动结算订单 {dingdan_id}", False, error_msg)
return error_msg
@shared_task
@rollback_on_failure("批量检查超时订单")
def check_order_expire_task():
"""
批量检查超时订单(补偿机制)
【已禁用】ORDER_AUTO_SETTLEMENT_ENABLED=False
"""
if not getattr(settings, 'ORDER_AUTO_SETTLEMENT_ENABLED', False):
logger.warning('订单自动结算补偿检查已关闭(ORDER_AUTO_SETTLEMENT_ENABLED=False),拒绝执行')
return {"success": True, "message": "自动结算已禁用", "count": 0}
# --- 以下原补偿逻辑保留备查 ---
try:
# 计算更宽松的时间点当前时间减去72小时48+24小时
# 这样避免误处理刚变为状态8的订单
check_time = timezone.now() - timedelta(seconds=settings.ORDER_EXPIRE_SECONDS + 86400) # 48+24=72小时
# 查询状态为8且创建时间早于检查时间的订单
expired_orders = Dingdan.query.filter(
zhuangtai=8,
create_time__lt=check_time
).values_list('dingdan_id', flat=True)
expired_count = expired_orders.count()
if expired_count == 0:
logger.info("补偿检查:无超时订单")
return {"success": True, "message": "无超时订单", "count": 0}
# 分批处理超时订单(避免一次处理太多)
batch_size = 10
processed_count = 0
for i in range(0, expired_count, batch_size):
batch = expired_orders[i:i+batch_size]
# 异步处理每个超时订单
for dingdan_id in batch:
process_expired_order.apply_async(
args=[dingdan_id],
queue='order_tasks',
priority=8 # 补偿任务的优先级低一些
)
processed_count += 1
result_msg = f"补偿检查:发现{expired_count}个可能超时的订单,已提交处理{processed_count}"
log_task_execution("批量检查超时订单", True, result_msg)
return {
"success": True,
"message": result_msg,
"total_count": expired_count,
"processed_count": processed_count
}
except Exception as e:
error_msg = f"批量检查超时订单失败: {str(e)}"
logger.error(error_msg)
log_task_execution("批量检查超时订单", False, error_msg)
return {
"success": False,
"message": error_msg,
"error": str(e)
}

View File

@@ -1,204 +1,204 @@
import logging
from datetime import date
from decimal import Decimal
from django.db import transaction
from django.db.models import F
from config.models import DailyIncomeStat, DailyPayoutStat
from orders.models import Dingdan, DingdanPingtai, DingdanShangjia, Lilubiao
from products.models import Gsfenhong
from users.models import UserDashou, UserGuanshi
from backend.utils import update_guanshi_daily_by_action
logger = logging.getLogger(__name__)
def get_order_user_id(order):
if order.fadan_pingtai == 1:
try:
ext = DingdanPingtai.objects.get(dingdan=order)
return ext.laoban_id
except DingdanPingtai.DoesNotExist:
return None
elif order.fadan_pingtai == 2:
try:
ext = DingdanShangjia.objects.get(dingdan=order)
return ext.shangjia_id
except DingdanShangjia.DoesNotExist:
return None
return None
def update_daily_income(amount):
"""
原子更新当日收入统计金额累加笔数加1
用于微信支付成功回调。
参数:
amount: Decimal 本次收入金额
"""
today = date.today()
year, month, day = today.year, today.month, today.day
with transaction.atomic():
stat, created = DailyIncomeStat.objects.select_for_update().get_or_create(
date=today,
defaults={
'year': year,
'month': month,
'day': day,
'total_amount': amount,
'total_count': 1
}
)
if not created:
# 原子累加
stat.total_amount = F('total_amount') + amount
stat.total_count = F('total_count') + 1
stat.save(update_fields=['total_amount', 'total_count'])
logger.info(
f"每日收入更新: {today}, +{amount}元, 总金额={stat.total_amount if created else stat.total_amount + amount}, 总笔数={stat.total_count if created else stat.total_count + 1}")
def update_daily_payout(amount):
"""
原子更新当日出款统计金额累加笔数加1
用于提现成功、结算打款等场景。
参数:
amount: Decimal 本次出款金额
"""
today = date.today()
year, month, day = today.year, today.month, today.day
with transaction.atomic():
stat, created = DailyPayoutStat.objects.select_for_update().get_or_create(
date=today,
defaults={
'year': year,
'month': month,
'day': day,
'total_amount': amount,
'total_count': 1
}
)
if not created:
# 原子累加
stat.total_amount = F('total_amount') + amount
stat.total_count = F('total_count') + 1
stat.save(update_fields=['total_amount', 'total_count'])
logger.info(f"每日出款更新: {today}, +{amount}元, 总金额={stat.total_amount if created else stat.total_amount + amount}, 总笔数={stat.total_count if created else stat.total_count + 1}")
def calc_shangjia_order_fencheng(jine):
"""
商家发单时计算打手/管事分成。
打手优先:打手+管事 > 订单金额时,管事分成为 0。
"""
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')
except Lilubiao.DoesNotExist:
rate_dashou = Decimal('1')
lilu_guanshi_obj = Lilubiao.objects.filter(fadanpingtai='13').first()
rate_guanshi = (
Decimal(str(lilu_guanshi_obj.lilu))
if lilu_guanshi_obj and lilu_guanshi_obj.lilu is not None
else Decimal('0')
)
dashou_fencheng = (jine * rate_dashou).quantize(Decimal('0.01'))
guanshi_raw = (jine * rate_guanshi).quantize(Decimal('0.01'))
if dashou_fencheng + guanshi_raw > jine:
guanshi_fencheng = Decimal('0.00')
else:
guanshi_fencheng = guanshi_raw
return dashou_fencheng, guanshi_fencheng
def settle_shangjia_order_guanshi_fenhong(order, dashou_id):
"""
商家订单结单时结算管事分红(幂等,失败不抛异常阻断主流程)。
"""
if getattr(order, 'fadan_pingtai', None) != 2:
return
guanshi_fencheng = order.guanshi_fencheng or Decimal('0')
if guanshi_fencheng <= 0:
return
if Gsfenhong.objects.filter(dingdan_id=order.dingdan_id).exists():
logger.info(f"商家订单管事分红已处理: {order.dingdan_id}")
return
if not dashou_id:
return
try:
dashou = UserDashou.objects.select_related('user').get(user__yonghuid=dashou_id)
except UserDashou.DoesNotExist:
logger.info(f"商家订单管事分红跳过: 打手{dashou_id}不存在")
return
guanshi_id = dashou.yaoqingren
if not guanshi_id:
logger.info(f"商家订单管事分红跳过: 打手{dashou_id}无邀请管事")
return
try:
with transaction.atomic():
guanshi = UserGuanshi.objects.select_for_update().get(user__yonghuid=guanshi_id)
UserGuanshi.objects.filter(id=guanshi.id).update(
yue=F('yue') + guanshi_fencheng,
chongzhifenrun=F('chongzhifenrun') + guanshi_fencheng,
)
user_main = dashou.user
Gsfenhong.objects.create(
dingdan_id=order.dingdan_id,
guanshi=guanshi_id,
dashouid=dashou_id,
shuoming='商家订单分红',
fenhong=guanshi_fencheng,
avatar=user_main.avatar if user_main else None,
nicheng=dashou.nicheng or '未知打手',
fenhong_leixing=3,
)
logger.info(
f"商家订单管事分红成功: 订单{order.dingdan_id}, 管事{guanshi_id}, "
f"打手{dashou_id}, 金额{guanshi_fencheng}"
)
except UserGuanshi.DoesNotExist:
logger.warning(f"商家订单管事分红跳过: 管事{guanshi_id}不存在")
return
except Exception as e:
logger.error(f"商家订单管事分红失败: {e}", exc_info=True)
return
try:
update_guanshi_daily_by_action(
yonghuid=guanshi_id,
action=3,
amount=guanshi_fencheng,
)
except Exception as e:
logger.error(f"商家订单管事日统计更新失败: {e}")
import logging
from datetime import date
from decimal import Decimal
from django.db import transaction
from django.db.models import F
from config.models import DailyIncomeStat, DailyPayoutStat
from orders.models import Dingdan, DingdanPingtai, DingdanShangjia, Lilubiao
from products.models import Gsfenhong
from users.models import UserDashou, UserGuanshi
from backend.utils import update_guanshi_daily_by_action
logger = logging.getLogger(__name__)
def get_order_user_id(order):
if order.fadan_pingtai == 1:
try:
ext = DingdanPingtai.objects.get(dingdan=order)
return ext.laoban_id
except DingdanPingtai.DoesNotExist:
return None
elif order.fadan_pingtai == 2:
try:
ext = DingdanShangjia.objects.get(dingdan=order)
return ext.shangjia_id
except DingdanShangjia.DoesNotExist:
return None
return None
def update_daily_income(amount):
"""
原子更新当日收入统计金额累加笔数加1
用于微信支付成功回调。
参数:
amount: Decimal 本次收入金额
"""
today = date.today()
year, month, day = today.year, today.month, today.day
with transaction.atomic():
stat, created = DailyIncomeStat.objects.select_for_update().get_or_create(
date=today,
defaults={
'year': year,
'month': month,
'day': day,
'total_amount': amount,
'total_count': 1
}
)
if not created:
# 原子累加
stat.total_amount = F('total_amount') + amount
stat.total_count = F('total_count') + 1
stat.save(update_fields=['total_amount', 'total_count'])
logger.info(
f"每日收入更新: {today}, +{amount}元, 总金额={stat.total_amount if created else stat.total_amount + amount}, 总笔数={stat.total_count if created else stat.total_count + 1}")
def update_daily_payout(amount):
"""
原子更新当日出款统计金额累加笔数加1
用于提现成功、结算打款等场景。
参数:
amount: Decimal 本次出款金额
"""
today = date.today()
year, month, day = today.year, today.month, today.day
with transaction.atomic():
stat, created = DailyPayoutStat.objects.select_for_update().get_or_create(
date=today,
defaults={
'year': year,
'month': month,
'day': day,
'total_amount': amount,
'total_count': 1
}
)
if not created:
# 原子累加
stat.total_amount = F('total_amount') + amount
stat.total_count = F('total_count') + 1
stat.save(update_fields=['total_amount', 'total_count'])
logger.info(f"每日出款更新: {today}, +{amount}元, 总金额={stat.total_amount if created else stat.total_amount + amount}, 总笔数={stat.total_count if created else stat.total_count + 1}")
def calc_shangjia_order_fencheng(jine):
"""
商家发单时计算打手/管事分成。
打手优先:打手+管事 > 订单金额时,管事分成为 0。
"""
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')
except Lilubiao.DoesNotExist:
rate_dashou = Decimal('1')
lilu_guanshi_obj = Lilubiao.objects.filter(fadanpingtai='13').first()
rate_guanshi = (
Decimal(str(lilu_guanshi_obj.lilu))
if lilu_guanshi_obj and lilu_guanshi_obj.lilu is not None
else Decimal('0')
)
dashou_fencheng = (jine * rate_dashou).quantize(Decimal('0.01'))
guanshi_raw = (jine * rate_guanshi).quantize(Decimal('0.01'))
if dashou_fencheng + guanshi_raw > jine:
guanshi_fencheng = Decimal('0.00')
else:
guanshi_fencheng = guanshi_raw
return dashou_fencheng, guanshi_fencheng
def settle_shangjia_order_guanshi_fenhong(order, dashou_id):
"""
商家订单结单时结算管事分红(幂等,失败不抛异常阻断主流程)。
"""
if getattr(order, 'fadan_pingtai', None) != 2:
return
guanshi_fencheng = order.guanshi_fencheng or Decimal('0')
if guanshi_fencheng <= 0:
return
if Gsfenhong.objects.filter(dingdan_id=order.dingdan_id).exists():
logger.info(f"商家订单管事分红已处理: {order.dingdan_id}")
return
if not dashou_id:
return
try:
dashou = UserDashou.objects.select_related('user').get(user__UserUID=dashou_id)
except UserDashou.DoesNotExist:
logger.info(f"商家订单管事分红跳过: 打手{dashou_id}不存在")
return
guanshi_id = dashou.yaoqingren
if not guanshi_id:
logger.info(f"商家订单管事分红跳过: 打手{dashou_id}无邀请管事")
return
try:
with transaction.atomic():
guanshi = UserGuanshi.objects.select_for_update().get(user__UserUID=guanshi_id)
UserGuanshi.objects.filter(id=guanshi.id).update(
yue=F('yue') + guanshi_fencheng,
chongzhifenrun=F('chongzhifenrun') + guanshi_fencheng,
)
user_main = dashou.user
Gsfenhong.objects.create(
dingdan_id=order.dingdan_id,
guanshi=guanshi_id,
dashouid=dashou_id,
shuoming='商家订单分红',
fenhong=guanshi_fencheng,
avatar=user_main.avatar if user_main else None,
nicheng=dashou.nicheng or '未知打手',
fenhong_leixing=3,
)
logger.info(
f"商家订单管事分红成功: 订单{order.dingdan_id}, 管事{guanshi_id}, "
f"打手{dashou_id}, 金额{guanshi_fencheng}"
)
except UserGuanshi.DoesNotExist:
logger.warning(f"商家订单管事分红跳过: 管事{guanshi_id}不存在")
return
except Exception as e:
logger.error(f"商家订单管事分红失败: {e}", exc_info=True)
return
try:
update_guanshi_daily_by_action(
yonghuid=guanshi_id,
action=3,
amount=guanshi_fencheng,
)
except Exception as e:
logger.error(f"商家订单管事日统计更新失败: {e}")

View File

@@ -62,7 +62,7 @@ from orders.models import (
Lilubiao, Pingfen, Tuikuanjilu
)
from products.models import Shangpin, ShangpinLeixing, Huiyuangoumai
from users.models import UserDashou, UserShangjia, UserBoss
from users.models import UserDashou, UserShangjia, UserBoss
from gvsdsdk.models import User
from rank.models import DashouBiaoxian, Chenghao, DingdanBiaoqian, YonghuChenghao
from config.models import (
@@ -241,7 +241,7 @@ class WechatPayNotifyView(APIView):
if hasattr(dingdan, 'pingtai_kuozhan'):
laoban_id = dingdan.pingtai_kuozhan.laoban_id
if laoban_id:
user_main = User.query.filter(yonghuid=laoban_id).first()
user_main = User.query.filter(UserUID=laoban_id).first()
if user_main and hasattr(user_main, 'boss_profile'):
boss = user_main.boss_profile
boss.zonge = (boss.zonge or 0) + (dingdan.jine or 0)
@@ -525,7 +525,7 @@ class PaymentVerifyView(APIView):
# 更新老板扩展表
laoban_id = dingdan.pingtai_kuozhan.laoban_id if hasattr(dingdan, 'pingtai_kuozhan') else None
if laoban_id:
user_main = User.query.filter(yonghuid=laoban_id).first()
user_main = User.query.filter(UserUID=laoban_id).first()
if user_main and hasattr(user_main, 'boss_profile'):
boss = user_main.boss_profile
boss.zonge = (boss.zonge or 0) + (dingdan.jine or 0)
@@ -712,7 +712,7 @@ class CreateOrderView(APIView):
if zhiding:
# 查询主表中是否存在该打手
zhiding_user = User.query.filter(
yonghuid=zhiding,
UserUID=zhiding,
#user_type='dashou'
).first()
@@ -1349,7 +1349,7 @@ class JiedanView(APIView):
# 7. 更新打手扩展表如果有打手ID和分成
if jiedan_dashou_id and dashou_fencheng > 0:
# 查询打手用户
dashou_user = User.query.filter(yonghuid=jiedan_dashou_id).first()
dashou_user = User.query.filter(UserUID=jiedan_dashou_id).first()
if dashou_user:
# 查询打手扩展表
@@ -1512,7 +1512,7 @@ class DingdanXiangqingView2(APIView):
jiedan_time = ''
tijiao_time = ''
if jiedan_dashou_id:
dashou_user = User.query.filter(yonghuid=jiedan_dashou_id).first()
dashou_user = User.query.filter(UserUID=jiedan_dashou_id).first()
if dashou_user:
dashou_touxiang = dashou_user.avatar or ''
try:
@@ -1661,7 +1661,7 @@ class JiedanView2(APIView):
# 9. 更新打手收益与状态
if jiedan_dashou_id and dashou_fencheng > 0:
dashou_user = User.query.filter(yonghuid=jiedan_dashou_id).first()
dashou_user = User.query.filter(UserUID=jiedan_dashou_id).first()
if dashou_user:
try:
dashou_ext = dashou_user.dashou_profile
@@ -1916,7 +1916,7 @@ class ShangjiaPaifaView(APIView):
zhiding_dashou = None
if zhiding_uid:
try:
zhiding_user = User.query.get(yonghuid=zhiding_uid)
zhiding_user = User.query.get(UserUID=zhiding_uid)
zhiding_dashou = zhiding_user.dashou_profile
if zhiding_dashou.zhanghaozhuangtai != 1:
return Response({'code': 400, 'msg': '指定打手状态异常'})
@@ -2223,7 +2223,7 @@ class ShangjiaDingdanXiangqingView(APIView):
dashou_avatar = ''
if dashou_yonghuid:
dashou_user = User.query.filter(
yonghuid=dashou_yonghuid
UserUID=dashou_yonghuid
).select_related('dashou_profile').first()
if dashou_user:
dashou_avatar = dashou_user.avatar or ''
@@ -2426,7 +2426,7 @@ class ShangjiaJiesuanView(APIView):
# ========== 本地订单正常结算给打手 ==========
# 查询打手信息
try:
dashou_user = User.query.get(yonghuid=jiedan_dashou_id)
dashou_user = User.query.get(UserUID=jiedan_dashou_id)
dashou = dashou_user.dashou_profile
except (User.DoesNotExist, UserDashou.DoesNotExist):
return Response({
@@ -2769,7 +2769,7 @@ class ShangjiaTuikuanShenqingView(APIView):
if dingdan.jiedan_dashou_id:
try:
dashou_main = User.query.filter(
yonghuid=dingdan.jiedan_dashou_id
UserUID=dingdan.jiedan_dashou_id
).first()
if dashou_main and hasattr(dashou_main, 'dashou_profile'):
dashou_profile = dashou_main.dashou_profile
@@ -2851,7 +2851,7 @@ class ShangjiaChufaShenqingView(APIView):
with transaction.atomic():
# 验证打手身份
try:
dashou_user = User.query.get(yonghuid=dashou_id)
dashou_user = User.query.get(UserUID=dashou_id)
dashou = dashou_user.dashou_profile
except User.DoesNotExist:
return Response({
@@ -3030,7 +3030,7 @@ class DashouDingdanHuoquView(APIView):
zhiding_info = {}
if zhiding_ids:
dashou_query = User.query.filter(
yonghuid__in=zhiding_ids
UserUID__in=zhiding_ids
).select_related('dashou_profile').annotate(
nicheng=F('dashou_profile__nicheng')
).values('yonghuid', 'avatar', 'nicheng')
@@ -3082,7 +3082,7 @@ class DashouDingdanHuoquView(APIView):
# 将 yonghuid 字符串转换为 User 的主键 id
user_id_map = {}
if yonghuid_set:
users = User.query.filter(yonghuid__in=yonghuid_set).values('id', 'yonghuid')
users = User.query.filter(UserUID__in=yonghuid_set).values('id', 'yonghuid')
for u in users:
user_id_map[u['yonghuid']] = u['id']
@@ -3347,7 +3347,7 @@ def send_group_message(
def check_user_permission(identity_type, uid, order):
"""验证用户身份、账号状态、以及是否属于该订单"""
try:
user = User.query.get(yonghuid=uid)
user = User.query.get(UserUID=uid)
except User.DoesNotExist:
return False, '用户不存在'
@@ -4674,7 +4674,7 @@ class AdGengHuanDaShou(APIView):
# 8. 验证新打手ID是否存在并且是打手身份
try:
new_dashou_user = User.query.get(
yonghuid=new_dashou_id,
UserUID=new_dashou_id,
#user_type='dashou'
)
except User.DoesNotExist:
@@ -4769,7 +4769,7 @@ class AdGengHuanDaShou(APIView):
try:
# 查询原打手主表
old_dashou_user = User.query.get(
yonghuid=old_dashou_id,
UserUID=old_dashou_id,
#user_type='dashou'
)
@@ -4913,7 +4913,7 @@ class AdQiangZhiJieDan(APIView):
try:
# 查询打手用户主表
dashou_user = User.query.get(
yonghuid=jiedan_dashou_id,
UserUID=jiedan_dashou_id,
#user_type='dashou'
)
@@ -4956,7 +4956,7 @@ class AdQiangZhiJieDan(APIView):
if shangjia_id:
# 查询商家用户主表
shangjia_user = User.query.get(
yonghuid=shangjia_id,
UserUID=shangjia_id,
#user_type='shop'
)
@@ -5089,7 +5089,7 @@ class AdJuJueTuiKuan(APIView):
try:
# 查询打手用户主表
dashou_user = User.query.get(
yonghuid=jiedan_dashou_id,
UserUID=jiedan_dashou_id,
#user_type='dashou'
)
@@ -5132,7 +5132,7 @@ class AdJuJueTuiKuan(APIView):
if shangjia_id:
# 查询商家用户主表
shangjia_user = User.query.get(
yonghuid=shangjia_id,
UserUID=shangjia_id,
#user_type='shop'
)
@@ -5320,7 +5320,7 @@ class AdTongYiTuiKuanShangJia(APIView):
try:
# 查询打手用户主表
dashou_user = User.query.get(
yonghuid=jiedan_dashou_id,
UserUID=jiedan_dashou_id,
#user_type='dashou'
)
@@ -5345,7 +5345,7 @@ class AdTongYiTuiKuanShangJia(APIView):
try:
# 查询商家用户主表
shangjia_user = User.query.get(
yonghuid=shangjia_id,
UserUID=shangjia_id,
#user_type='shop'
)
@@ -5529,7 +5529,7 @@ class AdTongYiTuiKuanPingTai(APIView):
# 14. 更新打手扩展表
if jiedan_dashou_id:
try:
dashou_user = User.query.get(yonghuid=jiedan_dashou_id)
dashou_user = User.query.get(UserUID=jiedan_dashou_id)
dashou_profile = dashou_user.dashou_profile
dashou_profile.zhuangtai = 1 # 打手状态设为空闲
dashou_profile.tuikuanliang += 1
@@ -5540,7 +5540,7 @@ class AdTongYiTuiKuanPingTai(APIView):
# 15. 更新老板扩展表
if laoban_id:
try:
laoban_user = User.query.get(yonghuid=laoban_id)
laoban_user = User.query.get(UserUID=laoban_id)
laoban_profile = laoban_user.boss_profile
laoban_profile.alltui += 1
laoban_profile.zonge -= jine
@@ -5865,7 +5865,7 @@ class AdJuJueJieSuan(APIView):
# 8. 更新打手扩展表
try:
dashou_user = User.query.get(yonghuid=jiedan_dashou_id)
dashou_user = User.query.get(UserUID=jiedan_dashou_id)
dashou_profile = dashou_user.dashou_profile
dashou_profile.zhuangtai = 1 # 打手状态设为正常
dashou_profile.tuikuanliang += 1 # 退款订单总量+1
@@ -5947,7 +5947,7 @@ class AdZhuanYiDaTing(APIView):
# 如果有接单打手,更新其扩展表
if jiedan_dashou_id:
try:
dashou_user = User.query.get(yonghuid=jiedan_dashou_id)
dashou_user = User.query.get(UserUID=jiedan_dashou_id)
dashou_profile = dashou_user.dashou_profile
dashou_profile.zhuangtai = 1
dashou_profile.tuikuanliang += 1
@@ -6225,7 +6225,7 @@ class ZxsjghdsView(APIView):
# 6.2 释放打手
if dashou_id:
try:
dashou_user = User.query.get(yonghuid=dashou_id)
dashou_user = User.query.get(UserUID=dashou_id)
dashou_profile = dashou_user.dashou_profile
dashou_profile.tuikuanliang = (dashou_profile.tuikuanliang or 0) + 1
dashou_profile.zhuangtai = 1 # 空闲