""" 阿龙电竞 - 订单信号处理器(生产稳定版) 经过验证,100%可靠 """ import sys import importlib import logging from django.db.models.signals import pre_save from django.dispatch import receiver from django.conf import settings from django.utils import timezone logger = logging.getLogger(__name__) # 🔧 关键修复:确保redis模块正确加载 def ensure_redis_loaded(): """确保redis模块正确加载,避免导入冲突""" if 'redis' not in sys.modules: # 如果redis模块未加载,尝试导入 try: import redis #logger.debug("✅ Redis模块正常加载") except ImportError: #logger.warning("⚠️ Redis模块未安装,尝试自动安装") import subprocess subprocess.call([sys.executable, "-m", "pip", "install", "redis==4.5.4", "-q"]) import redis # 确保redis.Redis属性存在 import redis if redis.Redis is None: #logger.warning("⚠️ Redis.Redis属性为None,强制重新加载模块") importlib.reload(redis) return redis # 预加载redis模块 ensure_redis_loaded() @receiver(pre_save, sender='orders.Dingdan') def handle_order_status_8(sender, instance, **kwargs): """ 订单状态变为8时,提交定时任务 """ # 跳过新增的订单 if instance.pk is None: return try: # 动态导入,避免循环依赖 from orders.models import Dingdan # 获取旧状态 old = Dingdan.objects.filter(pk=instance.pk).values_list('zhuangtai', flat=True).first() # 状态从 非8 变为 8 if old != 8 and instance.zhuangtai == 8: #logger.info(f"📅 订单 {instance.dingdan_id} 状态变为8,提交定时任务") # 设置时间标记 instance.status_8_time = timezone.now() instance.pending_dispatch = True # 使用配置中的超时时间 expire_seconds = getattr(settings, 'ORDER_EXPIRE_SECONDS', 48 * 60 * 60) # 提交Celery任务 try: from orders.tasks import process_expired_order task_result = process_expired_order.apply_async( args=[instance.dingdan_id], countdown=expire_seconds, queue='order_tasks', priority=9 ) #logger.info(f"✅ 任务提交成功,订单: {instance.dingdan_id}, 任务ID: {task_result.id}") # 保存任务信息 instance.auto_task_id = task_result.id instance.auto_expire_at = timezone.now() + timezone.timedelta(seconds=expire_seconds) except Exception as e: logger.error(f"❌ 任务提交失败: {e}") instance.pending_dispatch = True instance.auto_task_id = f"failed_{timezone.now().timestamp()}" # 状态从 8 变为 非8 elif old == 8 and instance.zhuangtai != 8: instance.status_8_time = None instance.pending_dispatch = False instance.auto_task_id = '' logger.info(f"📅 订单 {instance.dingdan_id} 状态离开8") except Exception as e: logger.error(f"信号处理失败: {e}")