累死了,删除了所有跨平台逻辑,进行了表迁移

This commit is contained in:
2026-06-15 02:09:51 +08:00
parent 8b9dbcba6f
commit 9eb53ee57d
112 changed files with 468 additions and 6208 deletions

View File

@@ -1,38 +0,0 @@
# dingdan/cross_platform_tasks.py
import logging
import requests
from django.conf import settings
logger = logging.getLogger(__name__)
def send_partner_sync_order(partner_order_id, jine, dashou_fencheng, jieshao, beizhu, create_time):
"""
异步发送派单通知给对方平台使用简单线程非Celery
注意:此函数应在线程中调用,避免阻塞主请求。
生产环境建议使用Celery此处提供线程兼容版本。
"""
url = f"{settings.PARTNER_BASE_URL}/dingdan/partner_sync_order"
payload = {
'token': settings.CROSS_PLATFORM_TOKEN,
'partner_order_id': partner_order_id,
'jine': jine,
'dashou_fencheng': dashou_fencheng,
'jieshao': jieshao,
'beizhu': beizhu,
'create_time': create_time,
}
try:
response = requests.post(url, json=payload, timeout=5)
if response.status_code == 200:
data = response.json()
if data.get('code') == 0:
logger.info(f"跨平台派单同步成功: {partner_order_id}")
# 可在此处保存对方返回的 local_order_id 到本地订单(如果需要)
# local_order_id = data['data'].get('local_order_id')
# Dingdan.objects.filter(dingdan_id=partner_order_id).update(partner_order_id=local_order_id)
else:
logger.error(f"跨平台派单同步业务失败: {data}")
else:
logger.error(f"跨平台派单同步HTTP失败: {response.status_code}")
except Exception as e:
logger.error(f"跨平台派单同步异常: {str(e)}", exc_info=True)

View File

@@ -174,7 +174,7 @@ class Migration(migrations.Migration):
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('laoban_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='老板ID')),
('laoban_pingjia', models.TextField(blank=True, null=True, verbose_name='老板评价')),
('dingdan', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='pingtai_kuozhan', to='dingdan.dingdan', verbose_name='订单')),
('dingdan', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='pingtai_kuozhan', to='orders.dingdan', verbose_name='订单')),
],
options={
'verbose_name': '平台订单扩展',
@@ -193,7 +193,7 @@ class Migration(migrations.Migration):
('sqzhuangtai', models.IntegerField(blank=True, default=0, null=True, verbose_name='处罚申请状态:0待处理,1成功,2驳回')),
('bhliyou', models.TextField(blank=True, null=True, verbose_name='驳回商家处罚理由')),
('sjnicheng', models.CharField(max_length=50, null=True, verbose_name='商家昵称')),
('dingdan', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='shangjia_kuozhan', to='dingdan.dingdan', verbose_name='订单')),
('dingdan', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='shangjia_kuozhan', to='orders.dingdan', verbose_name='订单')),
],
options={
'verbose_name': '商家订单扩展',

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0001_initial'),
('orders', '0001_initial'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0002_dingdan_auto_expire_at_dingdan_auto_task_id'),
('orders', '0002_dingdan_auto_expire_at_dingdan_auto_task_id'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0003_dingdan_pending_dispatch_dingdan_status_8_time'),
('orders', '0003_dingdan_pending_dispatch_dingdan_status_8_time'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0004_alter_tuikuanjilu_chuliid'),
('orders', '0004_alter_tuikuanjilu_chuliid'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0005_alter_chufajilu_chuliid'),
('orders', '0005_alter_chufajilu_chuliid'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0006_chufatupian'),
('orders', '0006_chufatupian'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0007_chufajilu_ssliyou'),
('orders', '0007_chufajilu_ssliyou'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0008_dingdan_is_cross_dingdan_partner_order_id'),
('orders', '0008_dingdan_is_cross_dingdan_partner_order_id'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0009_dingdanpingtai_clkf_dingdanpingtai_jjjs_biaoshi'),
('orders', '0009_dingdanpingtai_clkf_dingdanpingtai_jjjs_biaoshi'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0010_remove_dingdanpingtai_clkf_dingdan_clkf'),
('orders', '0010_remove_dingdanpingtai_clkf_dingdan_clkf'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0011_dingdan_tkly'),
('orders', '0011_dingdan_tkly'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0012_dingdan_wechat_transaction_id_and_more'),
('orders', '0012_dingdan_wechat_transaction_id_and_more'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0013_alter_chufajilu_qingqiuid'),
('orders', '0013_alter_chufajilu_qingqiuid'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0014_dingdan_dispatch_type_dingdan_partner_club_id'),
('orders', '0014_dingdan_dispatch_type_dingdan_partner_club_id'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0015_presettlement_orderdashouhistory_and_more'),
('orders', '0015_presettlement_orderdashouhistory_and_more'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0016_alter_presettlement_dingdan_id_and_more'),
('orders', '0016_alter_presettlement_dingdan_id_and_more'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0017_dingdanpingtai_dianpu_id_and_more'),
('orders', '0017_dingdanpingtai_dianpu_id_and_more'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0018_dingdanshangjia_partner_yonghu_id'),
('orders', '0018_dingdanshangjia_partner_yonghu_id'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0019_dingdanpingtai_shangji_dianpu_id_and_more'),
('orders', '0019_dingdanpingtai_shangji_dianpu_id_and_more'),
]
operations = [

View File

@@ -7,7 +7,7 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0020_fadanfenhong_fadan'),
('orders', '0020_fadanfenhong_fadan'),
]
operations = [
@@ -18,7 +18,7 @@ class Migration(migrations.Migration):
('beichufa_id', models.CharField(db_index=True, max_length=7, verbose_name='被处罚用户ID')),
('tupian_url', models.CharField(max_length=500, verbose_name='图片相对URL')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('fadan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shensu_tupians', to='dingdan.fadan', verbose_name='关联罚单')),
('fadan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shensu_tupians', to='orders.fadan', verbose_name='关联罚单')),
],
options={
'verbose_name': '罚款申诉图片',

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0021_fadanshensutupian'),
('orders', '0021_fadanshensutupian'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0022_fadan_partner_club_id_fadan_shenqingren_shenfen'),
('orders', '0022_fadan_partner_club_id_fadan_shenqingren_shenfen'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0023_fadanshensutupian_yongtu'),
('orders', '0023_fadanshensutupian_yongtu'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0024_fadan_chulizhe_fadan_chulizhe_shenfen'),
('orders', '0024_fadan_chulizhe_fadan_chulizhe_shenfen'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0025_alter_fadan_shenqingren_shenfen'),
('orders', '0025_alter_fadan_shenqingren_shenfen'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0026_fadanfenhonglilv_alter_fadan_shenqingren_shenfen_and_more'),
('orders', '0026_fadanfenhonglilv_alter_fadan_shenqingren_shenfen_and_more'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0027_dingdanpeihu'),
('orders', '0027_dingdanpeihu'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0028_dingdanshangjia_shangyige_dingdan_id'),
('orders', '0028_dingdanshangjia_shangyige_dingdan_id'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0029_fadanfenhong_is_individual_rate'),
('orders', '0029_fadanfenhong_is_individual_rate'),
]
operations = [

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dingdan', '0030_fadan_shenqingren_fenhong_jine'),
('orders', '0030_fadan_shenqingren_fenhong_jine'),
]
operations = [

View File

@@ -0,0 +1,43 @@
# Generated by Django 4.2.27 on 2026-06-15 01:42
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('orders', '0031_dingdan_guanshi_fencheng'),
]
operations = [
migrations.DeleteModel(
name='CrossPlatformOrderData',
),
migrations.DeleteModel(
name='PreSettlement',
),
migrations.RemoveField(
model_name='dingdan',
name='dispatch_type',
),
migrations.RemoveField(
model_name='dingdan',
name='is_cross',
),
migrations.RemoveField(
model_name='dingdan',
name='partner_club_id',
),
migrations.RemoveField(
model_name='dingdan',
name='partner_order_id',
),
migrations.RemoveField(
model_name='dingdanshangjia',
name='partner_yonghu_id',
),
migrations.RemoveField(
model_name='fadan',
name='partner_club_id',
),
]

View File

@@ -26,12 +26,7 @@ class Dingdan(models.Model):
# 订单描述信息
jieshao = models.TextField(null=True, blank=True, verbose_name='订单介绍')
beizhu = models.TextField(null=True, blank=True, verbose_name='订单备注')
partner_order_id = models.CharField(max_length=32, null=True, blank=True, db_index=True,verbose_name='对方平台订单ID')
is_cross = models.IntegerField(default=0, verbose_name='是否跨平台订单(0否,1是)')
dispatch_type = models.IntegerField(default=0, choices=[(1, '我方派单'), (2, '对方派单')], verbose_name='派发情况')
# 🔥 新增对方俱乐部ID
partner_club_id = models.CharField(max_length=6, null=True, blank=True, db_index=True, verbose_name='对方俱乐部ID')
# 新增字段:游戏昵称(前端提交的游戏昵称)
nicheng = models.CharField(max_length=50, null=True, blank=True, verbose_name='游戏昵称')
user1_id = models.CharField(max_length=30,null=True, db_index=True, verbose_name='用户1标识')
@@ -112,7 +107,6 @@ class DingdanShangjia(models.Model):
sqzhuangtai =models.IntegerField(default=0, null=True, blank=True, verbose_name='处罚申请状态:0待处理,1成功,2驳回')
bhliyou = models.TextField(null=True, blank=True, verbose_name='驳回商家处罚理由')
sjnicheng =models.CharField(max_length=50,null=True, verbose_name='商家昵称')
partner_yonghu_id = models.CharField(max_length=32, blank=True, null=True, verbose_name='对方平台用户ID')
# 在 dingdan/models.py 的 DingdanShangjia 类中添加
shangyige_dingdan_id = models.CharField(
max_length=32,
@@ -186,9 +180,6 @@ class DingdanPeihu(models.Model):
# 建议路径dingdan/models.py 或 独立 fadan/models.py
from django.db import models
class Fadan(models.Model):
"""罚单表——平台各类处罚信息"""
id = models.AutoField(primary_key=True, verbose_name='自增主键')
@@ -206,8 +197,6 @@ class Fadan(models.Model):
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
# 在 Fadan 模型中添加
partner_club_id = models.CharField(max_length=6, blank=True, null=True, db_index=True, verbose_name='对方俱乐部ID')
# 在 class Fadan 中添加
shenqingren_shenfen = models.IntegerField(
choices=[(1, '客服'), (2, '售后'), (3, '管理员'),(4,'店铺'),(5,'商家')], # 按实际扩展
default=1,
@@ -310,88 +299,6 @@ class FadanFenhongLilv(models.Model):
class CrossPlatformOrderData(models.Model):
"""
跨平台订单扩展数据表
存储我方订单与对方平台订单的关联及对方订单状态
"""
dingdan_id = models.CharField(max_length=32, unique=True, db_index=True, verbose_name='我方订单ID')
partner_order_id = models.CharField(max_length=32, db_index=True, verbose_name='对方平台订单ID')
partner_club_id = models.CharField(max_length=6, db_index=True, verbose_name='对方俱乐部ID')
partner_order_status = models.IntegerField(default=0, verbose_name='对方平台订单状态') # 对方订单当前状态码
partner_dashou_id = models.CharField(max_length=32, blank=True, default='', verbose_name='对方平台接单打手ID')
partner_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='对方平台订单金额')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'cross_platform_order_data'
verbose_name = '跨平台订单扩展'
verbose_name_plural = '跨平台订单扩展'
indexes = [
models.Index(fields=['dingdan_id']),
models.Index(fields=['partner_order_id']),
models.Index(fields=['partner_club_id']),
]
def __str__(self):
return f"{self.dingdan_id} -> {self.partner_order_id}"
# apps/dingdan/models.py 中添加
class PreSettlement(models.Model):
"""
预结算表
用于记录对方平台派单订单的待结算款项,等待对方确认后才能真正入账
"""
STATUS_CHOICES = (
(0, '待结算'),
(1, '已结算'),
(2, '已拒绝'),
)
# 我方订单ID
dingdan_id = models.CharField(max_length=32, db_index=True, verbose_name='我方订单ID')
# 对方订单ID
partner_order_id = models.CharField(max_length=32, db_index=True, verbose_name='对方订单ID')
# 对方俱乐部ID
partner_club_id = models.CharField(max_length=6, db_index=True, verbose_name='对方俱乐部ID')
# 接单打手ID
dashou_id = models.CharField(max_length=7, db_index=True, verbose_name='接单打手ID')
# 打手应分金额
amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='打手应分金额')
# 订单金额(原金额,可选)
order_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='订单原金额')
# 结算状态
status = models.SmallIntegerField(choices=STATUS_CHOICES, default=0, verbose_name='结算状态')
# 处理时间(结算或拒绝的时间)
process_time = models.DateTimeField(null=True, blank=True, verbose_name='处理时间')
# 处理客服/对方操作人(可选)
operator = models.CharField(max_length=32, blank=True, default='', verbose_name='操作人')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'pre_settlement'
verbose_name = '预结算表'
verbose_name_plural = verbose_name
unique_together = [['dingdan_id', 'dashou_id']]
indexes = [
models.Index(fields=['dingdan_id']),
models.Index(fields=['partner_order_id']),
models.Index(fields=['partner_club_id']),
models.Index(fields=['dashou_id']),
models.Index(fields=['status']),
]
def __str__(self):
return f"预结算-{self.dingdan_id} -> {self.partner_order_id}"
# apps/dingdan/models.py 中添加
class OrderDashouHistory(models.Model):
"""
订单打手变更历史表

View File

@@ -38,7 +38,7 @@ def ensure_redis_loaded():
# 预加载redis模块
ensure_redis_loaded()
@receiver(pre_save, sender='dingdan.Dingdan')
@receiver(pre_save, sender='orders.Dingdan')
def handle_order_status_8(sender, instance, **kwargs):
"""
订单状态变为8时提交定时任务

View File

@@ -18,8 +18,6 @@ from orders.models import Dingdan
from users.models import UserMain, UserDashou, UserShangjia
from utils.celery_utils import safe_decimal_operation, log_task_execution, rollback_on_failure
# from users.utils import update_platform_profit # 导入函数
logger = logging.getLogger(__name__)
@@ -110,11 +108,7 @@ def process_expired_order(self, dingdan_id):
result_msg += ",商家信息已更新"
if fadan_pingtai == 1:
try:
update_platform_profit(dingdan_id)
except Exception as e:
# 平台收益更新失败不影响主流程,但记录日志
logger.error(f"强制结单后更新平台收益失败: {str(e)}")
pass # 平台收益更新逻辑待完善
log_task_execution(f"自动结算订单 {dingdan_id}", True, result_msg)
return result_msg

View File

@@ -7,7 +7,7 @@ from .views import CreateOrderView, WechatPayNotifyView, \
ShangjiaChexiaoView, DashouDingdanHuoquView, ShangpinLeixingHuoquView, QiangdanView, \
DashouDingdanHuoquView1, DashouCOSZhengshuView, DashouTijiaoView, DashouDingdanXiangqingView, AdGetDingdanXiangQing, \
AdTongYiTuiKuanPingTai, AdTongYiTuiKuanShangJia, AdQiangZhiJieDan, AdJuJueTuiKuan,\
AdGengHuanDaShou,ShangjiaCOSZhengshuView, DashouHuoquLeixingView,PartnerNotifyClaimView, PartnerSyncOrderView, PartnerCheckClaimView, PartnerRefundNotifyView,AdJuJueJieSuan, AdZhuanYiDaTing, AdQuXiaoZhiDing,DashouXiugaiView,DaiLiQunLiaoXiaoXiView,\
AdGengHuanDaShou,ShangjiaCOSZhengshuView, DashouHuoquLeixingView,AdJuJueJieSuan, AdZhuanYiDaTing, AdQuXiaoZhiDing,DashouXiugaiView,DaiLiQunLiaoXiaoXiView,\
ShangjiaLianjieLiuYanZhuanFaView, DingdanXiangqingView2, JiedanView2, ZxsjghdsView, \
ShangjiaFakuanApplyView, ShangjiaFakuaiXiugaiView
@@ -65,12 +65,6 @@ urlpatterns = [
path('partner_sync_order', csrf_exempt(PartnerSyncOrderView.as_view()), name='东道主派单接口'),
path('partner_check_claim', csrf_exempt(PartnerCheckClaimView.as_view()), name='对方抢单询问接口'),
path('partner_notify_claim', csrf_exempt(PartnerNotifyClaimView.as_view()), name='东道主订单被抢通知接口'),
#path('partner_refund_notify', csrf_exempt(PartnerRefundNotifyView.as_view()), name='接受东道主退款通知'),
path('dsxiugaidd', DashouXiugaiView.as_view(), name='打手修改订单详情'),
path('kptxxfs', DaiLiQunLiaoXiaoXiView.as_view(), name='前端聊天转发'), # 群聊消息代理发送

View File

@@ -1,17 +1,13 @@
import threading
import requests
import time
import logging
from datetime import date
from decimal import Decimal
from django.conf import settings
from django.db import transaction
from django.db.models import F
from config.models import Club, DailyDispatchStat, DailyIncomeStat, DailyPayoutStat
from config.models import DailyIncomeStat, DailyPayoutStat
from orders.models import Dingdan, DingdanPingtai, DingdanShangjia, Lilubiao
from products.models import ShangpinLeixing, Gsfenhong
from products.models import Gsfenhong
from users.models import UserDashou, UserGuanshi
from backend.utils import update_guanshi_daily_by_action
@@ -19,234 +15,22 @@ from backend.utils import update_guanshi_daily_by_action
logger = logging.getLogger(__name__)
# 可选:线程池限制(避免大量线程同时创建,建议使用 Celery这里简单用线程
THREAD_POOL_SIZE = 10
_semaphore = threading.Semaphore(THREAD_POOL_SIZE)
def sync_order_to_partners(dingdan_id):
"""
异步向所有开启互通的合作平台同步订单。
使用信号量限制并发线程数。
"""
def _task():
_semaphore.acquire()
try:
_sync_order_task(dingdan_id)
finally:
_semaphore.release()
thread = threading.Thread(target=_task)
thread.daemon = True
thread.start()
def _sync_order_task(dingdan_id):
"""实际同步任务(在线程中执行)"""
try:
# 获取订单对象(只取必要字段,提升性能)
dingdan = Dingdan.objects.only(
'dingdan_id', 'zhuangtai', 'jine', 'dashou_fencheng', 'jieshao',
'beizhu', 'nicheng', 'leixing_id', 'yaoqiuleixing', 'huiyuan_id',
'yongjin', 'zhiding_id', 'create_time'
).get(dingdan_id=dingdan_id)
# 基本条件判断
if dingdan.zhuangtai != 1:
logger.info(f"订单 {dingdan_id} 状态 {dingdan.zhuangtai} 不是1不同步")
return
if dingdan.zhiding_id:
logger.info(f"订单 {dingdan_id} 是指定单,不同步")
return
if dingdan.yaoqiuleixing != 1:
logger.info(f"订单 {dingdan_id} 抢单要求类型不是会员抢单,不同步")
return
if not dingdan.leixing_id:
logger.info(f"订单 {dingdan_id} 无商品类型,不同步")
return
try:
leixing = ShangpinLeixing.objects.get(id=dingdan.leixing_id)
if not leixing.is_cross_enabled:
logger.info(f"订单 {dingdan_id} 的商品类型未开启互通,不同步")
return
except ShangpinLeixing.DoesNotExist:
logger.info(f"订单 {dingdan_id} 的商品类型不存在,不同步")
return
# 查询所有开启互通的俱乐部
clubs = Club.objects.filter(is_interop_enabled=True).select_related()
if not clubs.exists():
return
# 为每个俱乐部发送订单
for club in clubs:
_send_to_single_partner(dingdan, club)
except Exception as e:
logger.error(f"同步订单任务异常: {e}", exc_info=True)
def _send_to_single_partner(dingdan, club):
"""向单个俱乐部发送订单(带重试,幂等处理)"""
# 计算实际金额:订单打手分成 × 对方费率
actual_amount = dingdan.dashou_fencheng * club.dashou_rate
# 构建请求数据
payload = {
'token': settings.CROSS_PLATFORM_TOKEN,
'our_club_id': club.club_id, # 我方在对方系统中的标识(存储于对方表的 partner_club_id
'partner_club_id': club.partner_club_id, # 对方自己的俱乐部ID
'partner_order_id': dingdan.dingdan_id, # 我方订单ID作为对方的外部订单号
'jine': str(actual_amount), # 对方平台应展示的订单金额
'dashou_fencheng': str(actual_amount), # 对方平台打手分成(与金额一致)
'jieshao': dingdan.jieshao,
'beizhu': dingdan.beizhu,
'create_time': dingdan.create_time.isoformat(),
'nicheng': dingdan.nicheng,
'leixing_id': dingdan.leixing_id, # 我方商品类型ID对方需要映射
'user_id': get_order_user_id(dingdan), # 对方平台下单用户ID不带前缀
}
# 重试机制最多3次指数退避
for attempt in range(1, 4):
try:
response = requests.post(
club.partner_domain + '/dingdan/partner_sync_order',
json=payload,
timeout=5
)
if response.status_code == 200:
data = response.json()
# 对方返回 code=0 表示成功(包括新建或已存在)
if data.get('code') == 0:
# 判断本次响应是新创建还是已存在
status = data.get('data', {}).get('status', '')
if status == 'existed':
# 订单已经存在于对方系统,不重复统计
logger.info(f"订单 {dingdan.dingdan_id} 在俱乐部 {club.club_id} 已存在,跳过统计")
else:
# 新创建成功,更新统计
try:
update_daily_dispatch_stat(
direction=1, # 我方派单
partner_club_id=club.partner_club_id,
dispatch_amount=actual_amount,
)
logger.info(f"成功同步订单 {dingdan.dingdan_id} 到俱乐部 {club.club_id}")
except Exception as e:
logger.error(f"更新派单统计失败: {e}", exc_info=True)
# 标记订单为跨平台(仅当第一次成功时标记,避免重复标记)
if not dingdan.is_cross:
Dingdan.objects.filter(dingdan_id=dingdan.dingdan_id).update(
is_cross=1,
dispatch_type=1 # 我方派单
)
logger.info(f"订单 {dingdan.dingdan_id} 已标记为跨平台订单")
break
else:
# 对方返回业务错误(如映射不存在等),不重试
logger.error(f"同步订单失败(业务): {data}")
break
else:
logger.error(f"同步订单HTTP失败: {response.status_code}")
except Exception as e:
logger.error(f"同步订单异常(尝试 {attempt}/3: {e}")
if attempt < 3:
time.sleep(2 ** attempt) # 指数退避
else:
logger.error(f"同步订单 {dingdan.dingdan_id} 到俱乐部 {club.club_id} 最终失败")
# 获取下单方ID根据订单类型
def get_order_user_id(order):
if order.fadan_pingtai == 1:
try:
ext = DingdanPingtai.objects.get(dingdan=order)
return ext.laoban_id # 老板ID
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 # 商家ID
return ext.shangjia_id
except DingdanShangjia.DoesNotExist:
return None
return None
def update_daily_dispatch_stat(direction, partner_club_id,
dispatch_amount=None, dispatch_count=1,
claimed_amount=None, claimed_count=1,
success_amount=None, success_count=1):
"""
原子更新每日派单统计(支持派单、抢单、成交三种类型)。
只更新传递了非None参数的字段未传递的字段保持不变。
参数:
direction: 1=我方派单2=对方派单
partner_club_id: 对方俱乐部ID
dispatch_amount: 派单金额Decimal如果提供则累加到 dispatch_amount 和 dispatch_count
dispatch_count: 派单数量默认为1与 dispatch_amount 同时提供时生效
claimed_amount: 抢单金额Decimal如果提供则累加到 claimed_amount 和 claimed_count
claimed_count: 抢单数量默认为1与 claimed_amount 同时提供时生效
success_amount: 成交金额Decimal如果提供则累加到 success_amount 和 success_count
success_count: 成交数量默认为1与 success_amount 同时提供时生效
"""
today = date.today()
year, month, day = today.year, today.month, today.day
with transaction.atomic():
# 使用 select_for_update 锁定行,避免并发累加冲突
stat, created = DailyDispatchStat.objects.select_for_update().get_or_create(
date=today,
year=year,
month=month,
day=day,
direction=direction,
partner_club_id=partner_club_id,
defaults={
'dispatch_count': dispatch_count if dispatch_amount is not None else 0,
'dispatch_amount': dispatch_amount or Decimal('0.00'),
'claimed_count': claimed_count if claimed_amount is not None else 0,
'claimed_amount': claimed_amount or Decimal('0.00'),
'success_count': success_count if success_amount is not None else 0,
'success_amount': success_amount or Decimal('0.00'),
}
)
if not created:
update_fields = []
if dispatch_amount is not None:
stat.dispatch_count = F('dispatch_count') + dispatch_count
stat.dispatch_amount = F('dispatch_amount') + dispatch_amount
update_fields.extend(['dispatch_count', 'dispatch_amount'])
if claimed_amount is not None:
stat.claimed_count = F('claimed_count') + claimed_count
stat.claimed_amount = F('claimed_amount') + claimed_amount
update_fields.extend(['claimed_count', 'claimed_amount'])
if success_amount is not None:
stat.success_count = F('success_count') + success_count
stat.success_amount = F('success_amount') + success_amount
update_fields.extend(['success_count', 'success_amount'])
if update_fields:
stat.save(update_fields=update_fields)
logger.info(f"更新派单统计: 日期={today}, 方向={direction}, 俱乐部={partner_club_id}, "
f"派单+{dispatch_count if dispatch_amount else 0}单/{dispatch_amount or 0}, "
f"抢单+{claimed_count if claimed_amount else 0}单/{claimed_amount or 0}, "
f"成交+{success_count if success_amount else 0}单/{success_amount or 0}")
def update_daily_income(amount):
"""
原子更新当日收入统计金额累加笔数加1

File diff suppressed because it is too large Load Diff