优化服务号订单广播(Celery并发)与群聊状态实时推送

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-06-24 00:43:30 +08:00
parent 56c66846cc
commit 49ba67ecaf
9 changed files with 458 additions and 331 deletions

72
utils/order_broadcast.py Normal file
View File

@@ -0,0 +1,72 @@
"""
订单服务号模板消息广播 — 统一入口Celery 异步,接口立即返回)
"""
import logging
from django.conf import settings
logger = logging.getLogger('weixin_broadcast')
def _game_type_name(leixing_id):
try:
from shangpin.models import ShangpinLeixing
gt = ShangpinLeixing.objects.filter(id=leixing_id).first()
return gt.jieshao if gt else '游戏订单'
except Exception:
return '游戏订单'
def build_order_broadcast_payload(dingdan, order_type='普通订单', game_type=None):
return {
'dingdan_id': dingdan.dingdan_id,
'game_type': game_type or _game_type_name(dingdan.leixing_id),
'amount': str(dingdan.jine),
'order_desc': (dingdan.jieshao or '')[:50],
'order_type': order_type,
}
def submit_dingdan_guangbo(order_info):
"""提交 Celery 广播任务broadcast 优先队列)"""
if not getattr(settings, 'WEIXIN_BROADCAST_ENABLED', True):
logger.info('服务号广播已关闭,跳过')
return False
if not order_info or not order_info.get('dingdan_id'):
return False
try:
from dingdan.tongzhi_tasks import dingdan_guangbo
dingdan_guangbo.apply_async(
args=[order_info],
queue='broadcast',
priority=9,
countdown=0,
)
logger.info(f'已提交服务号广播任务: {order_info.get("dingdan_id")}')
return True
except Exception as e:
logger.error(f'Celery 广播提交失败,降级线程发送: {e}', exc_info=True)
_fallback_thread_broadcast(order_info)
return False
def schedule_dingdan_guangbo_from_order(dingdan, order_type='普通订单', game_type=None):
"""根据订单对象构建 payload 并提交广播"""
order_info = build_order_broadcast_payload(dingdan, order_type=order_type, game_type=game_type)
return submit_dingdan_guangbo(order_info)
def _fallback_thread_broadcast(order_info):
"""Celery 不可用时,后台线程并发发送(不阻塞下单接口)"""
import threading
from utils.weixin_broadcast import WeixinBroadcastSender
def _run():
try:
sender = WeixinBroadcastSender()
sender.broadcast_parallel(order_info)
except Exception as ex:
logger.error(f'线程降级广播失败: {ex}', exc_info=True)
t = threading.Thread(target=_run, daemon=True)
t.start()