第一次提交:小程序前端最新版本
This commit is contained in:
114
a_long_dianjing/management/commands/sync_cross_order_status.py
Normal file
114
a_long_dianjing/management/commands/sync_cross_order_status.py
Normal file
@@ -0,0 +1,114 @@
|
||||
import time
|
||||
import requests
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.conf import settings
|
||||
from dingdan.models import Dingdan
|
||||
from peizhi.models import Club # 你的俱乐部模型,请确认类名
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = '同步我方派单跨平台订单状态(仅进行中订单,失败直接跳过,不重试)'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--concurrency', type=int, default=3, help='并发数(默认3)')
|
||||
parser.add_argument('--batch', type=int, default=0, help='处理前N单(0=全部)')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
concurrency = options['concurrency']
|
||||
batch = options['batch']
|
||||
|
||||
# 查询待同步订单
|
||||
orders = Dingdan.objects.filter(
|
||||
zhuangtai=2,
|
||||
dispatch_type=1,
|
||||
is_cross=1,
|
||||
partner_club_id__isnull=False,
|
||||
partner_order_id__isnull=False
|
||||
).only('dingdan_id', 'partner_order_id', 'partner_club_id', 'zhuangtai')
|
||||
|
||||
total = orders.count()
|
||||
self.stdout.write(f'待处理订单总数: {total}')
|
||||
if batch > 0:
|
||||
orders = orders[:batch]
|
||||
self.stdout.write(f'本次仅处理前 {batch} 单')
|
||||
|
||||
SYNC_TOKEN = getattr(settings, 'CROSS_PLATFORM_SYNC_TOKEN', 'xK9mP2vL8qW5rT7y')
|
||||
session = requests.Session()
|
||||
session.headers.update({'Content-Type': 'application/json'})
|
||||
|
||||
# 预加载域名映射
|
||||
domain_map = {}
|
||||
for club in Club.objects.all():
|
||||
if club.partner_club_id and club.partner_domain:
|
||||
domain_map[club.partner_club_id] = club.partner_domain
|
||||
|
||||
updated = success = skip = fail = 0
|
||||
start = time.time()
|
||||
|
||||
def process_one(order):
|
||||
# 获取对方域名
|
||||
domain = domain_map.get(order.partner_club_id)
|
||||
if not domain:
|
||||
try:
|
||||
club = Club.objects.filter(partner_club_id=order.partner_club_id).first()
|
||||
if club and club.partner_domain:
|
||||
domain = club.partner_domain
|
||||
domain_map[order.partner_club_id] = domain
|
||||
except Exception:
|
||||
pass
|
||||
if not domain:
|
||||
return ('skip', '无域名')
|
||||
|
||||
url = domain.rstrip('/') + '/houtai/kptxwztjb'
|
||||
payload = {
|
||||
'token': SYNC_TOKEN,
|
||||
'partner_order_id': order.partner_order_id,
|
||||
'our_order_id': order.dingdan_id,
|
||||
'club_id': order.partner_club_id
|
||||
}
|
||||
|
||||
try:
|
||||
resp = session.post(url, json=payload, timeout=5)
|
||||
if resp.status_code == 200:
|
||||
data = resp.json()
|
||||
if data.get('code') == 0:
|
||||
st = data['data']['status']
|
||||
if st in (5, 8):
|
||||
order.zhuangtai = st
|
||||
order.save(update_fields=['zhuangtai'])
|
||||
return ('updated', st)
|
||||
return ('success', st)
|
||||
else:
|
||||
return ('skip', data.get('msg', '对方业务错误'))
|
||||
else:
|
||||
# 429、404、500 等全部跳过
|
||||
return ('skip', f'HTTP {resp.status_code}')
|
||||
except requests.exceptions.Timeout:
|
||||
return ('skip', '超时')
|
||||
except Exception as e:
|
||||
return ('skip', str(e))
|
||||
|
||||
# 并发执行
|
||||
with ThreadPoolExecutor(max_workers=concurrency) as executor:
|
||||
future_map = {executor.submit(process_one, o): o for o in orders}
|
||||
for future in as_completed(future_map):
|
||||
order = future_map[future]
|
||||
try:
|
||||
res, detail = future.result()
|
||||
if res == 'updated':
|
||||
updated += 1
|
||||
success += 1
|
||||
self.stdout.write(f'✅ 更新: {order.dingdan_id} -> {detail}')
|
||||
elif res == 'success':
|
||||
success += 1
|
||||
else:
|
||||
skip += 1
|
||||
# 跳过的订单静默处理,不打印,以免刷屏
|
||||
except Exception as e:
|
||||
skip += 1
|
||||
|
||||
elapsed = time.time() - start
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
f'完成: 成功{success}(更新{updated}), 跳过{skip}, 耗时{elapsed:.1f}s'
|
||||
))
|
||||
Reference in New Issue
Block a user