第一次提交:阿龙电竞 Django 后端最新版本
This commit is contained in:
71
dingdan/tongzhi_tasks.py
Normal file
71
dingdan/tongzhi_tasks.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# dingdan/tongzhi_tasks.py
|
||||
import logging
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from a_long_dianjing.celery_app import app
|
||||
from yonghu.models import OfficialAccountUser
|
||||
from utils.weixin_broadcast import WeixinBroadcastSender
|
||||
|
||||
logger = logging.getLogger('weixin_broadcast')
|
||||
|
||||
|
||||
@app.task(bind=True, max_retries=3, default_retry_delay=60)
|
||||
def dingdan_guangbo(self, order_info):
|
||||
"""
|
||||
异步并发广播订单模板消息给所有关注服务号的用户
|
||||
order_info 字典字段示例:
|
||||
{
|
||||
'dingdan_id': 'PT123456',
|
||||
'game_type': '王者荣耀',
|
||||
'amount': '88.00',
|
||||
'order_desc': '星耀上王者'
|
||||
}
|
||||
"""
|
||||
sender = WeixinBroadcastSender()
|
||||
template_data = sender.build_order_message_data(order_info)
|
||||
order_id = order_info.get('dingdan_id')
|
||||
|
||||
# 查询所有已关注用户
|
||||
try:
|
||||
openids = list(
|
||||
OfficialAccountUser.objects
|
||||
.filter(is_subscribed=True)
|
||||
.values_list('official_openid', flat=True)
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f'查询订阅用户失败: {e}')
|
||||
raise self.retry(exc=e)
|
||||
|
||||
if not openids:
|
||||
return {'success': True, 'msg': '无订阅用户'}
|
||||
|
||||
total = len(openids)
|
||||
logger.info(f'📊 Celery 广播订单 {order_id} 开始,目标人数: {total}')
|
||||
|
||||
success = 0
|
||||
fail = 0
|
||||
|
||||
# 20 个线程并发发送,微信接口耗时 200-500ms,1000 人约 15 秒完成
|
||||
with ThreadPoolExecutor(max_workers=20) as executor:
|
||||
future_map = {
|
||||
executor.submit(sender.send_to_user, openid, template_data, order_id): openid
|
||||
for openid in openids
|
||||
}
|
||||
for future in as_completed(future_map):
|
||||
openid = future_map[future]
|
||||
try:
|
||||
res = future.result(timeout=30)
|
||||
if res.get('success'):
|
||||
success += 1
|
||||
else:
|
||||
fail += 1
|
||||
except Exception as e:
|
||||
fail += 1
|
||||
logger.error(f'发送异常 {openid[:10]}...: {e}')
|
||||
|
||||
logger.info(f'🏁 广播完成:成功 {success},失败 {fail},总计 {total}')
|
||||
return {
|
||||
'success': True,
|
||||
'total': total,
|
||||
'success_count': success,
|
||||
'fail_count': fail
|
||||
}
|
||||
Reference in New Issue
Block a user