""" 在线状态检测工作进程 """ import time import threading from datetime import datetime from loguru import logger from config import settings from app.services.ecloud_client import ecloud_client from app.services.email_service import email_service from app.services.sms_service import sms_service class OnlineStatusWorker: """在线状态检测工作进程""" def __init__(self): self.running = False self.worker_thread = None self.last_notification_time = None self.notification_cooldown = 30 * 60 # 30分钟冷却时间,避免频繁发送通知 def start(self): """启动在线状态检测工作进程""" if not settings.online_status_enabled: logger.info("在线状态检测功能已禁用") return self.running = True self.worker_thread = threading.Thread(target=self._monitor_online_status, daemon=True) self.worker_thread.start() logger.info("在线状态检测工作进程已启动") def stop(self): """停止在线状态检测工作进程""" self.running = False if self.worker_thread and self.worker_thread.is_alive(): self.worker_thread.join(timeout=10) logger.info("在线状态检测工作进程已停止") def _monitor_online_status(self): """监控在线状态的主循环""" logger.info(f"开始监控在线状态,检测间隔: {settings.online_status_check_interval}分钟") while self.running: try: # 检测在线状态 self._check_online_status() # 等待下次检测 sleep_seconds = settings.online_status_check_interval * 60 for _ in range(sleep_seconds): if not self.running: break time.sleep(1) except Exception as e: logger.error(f"在线状态监控异常: {str(e)}") time.sleep(60) # 异常时等待1分钟再继续 def _check_online_status(self): """检测在线状态并发送通知""" try: logger.info("开始检测微信在线状态") # 查询在线微信列表 online_list = ecloud_client.query_online_wechat_list() if online_list is None: logger.error("查询在线微信列表失败,跳过本次检测") return online_count = len(online_list) logger.info(f"当前在线微信数量: {online_count}") # 如果有在线微信,更新w_id并重置通知时间 if online_count > 0: # 获取第一个在线微信的w_id并更新配置 if online_list and len(online_list) > 0: current_w_id = online_list[0].get("wId") if current_w_id: self._update_w_id_if_needed(current_w_id) if self.last_notification_time: logger.info("检测到在线微信,重置通知状态") self.last_notification_time = None return # 没有在线微信,检查是否需要发送通知 current_time = time.time() # 检查冷却时间 if (self.last_notification_time and current_time - self.last_notification_time < self.notification_cooldown): remaining_time = self.notification_cooldown - (current_time - self.last_notification_time) logger.info(f"通知冷却中,剩余时间: {remaining_time/60:.1f}分钟") return # 发送掉线通知 logger.warning("检测到微信全部掉线,发送通知") self._send_offline_notification() self.last_notification_time = current_time except Exception as e: logger.error(f"检测在线状态异常: {str(e)}") def _update_w_id_if_needed(self, current_w_id: str): """ 如果需要,更新w_id配置 Args: current_w_id: 当前检测到的w_id """ try: # 获取配置中的当前w_id config_w_id = settings.get_current_w_id() # 如果w_id发生变化,则更新配置 if current_w_id != config_w_id: logger.info(f"检测到w_id变化: {config_w_id} -> {current_w_id}") success = settings.update_ecloud_w_id(current_w_id) if success: logger.info("w_id更新成功") else: logger.error("w_id更新失败") except Exception as e: logger.error(f"更新w_id异常: {str(e)}") def _send_offline_notification(self): """发送掉线通知""" try: # 准备通知内容 subject = "微信掉线提醒" content = settings.online_status_notification_message timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 添加时间戳到内容 full_content = f"{content}\n\n检测时间: {timestamp}" # 发送邮件通知 email_success = False if settings.email_enabled: try: email_success = email_service.send_notification(subject, full_content) if email_success: logger.info("掉线通知邮件发送成功") else: logger.error("掉线通知邮件发送失败") except Exception as e: logger.error(f"发送掉线通知邮件异常: {str(e)}") # 发送短信通知 sms_success = False if settings.sms_enabled: try: # 短信内容不包含时间戳,避免过长 sms_success = sms_service.send_notification(content) if sms_success: logger.info("掉线通知短信发送成功") else: logger.error("掉线通知短信发送失败") except Exception as e: logger.error(f"发送掉线通知短信异常: {str(e)}") # 记录通知结果 if email_success or sms_success: logger.info("掉线通知发送完成") else: logger.error("掉线通知发送全部失败") except Exception as e: logger.error(f"发送掉线通知异常: {str(e)}") def get_status(self) -> dict: """获取工作进程状态""" return { "running": self.running, "enabled": settings.online_status_enabled, "check_interval_minutes": settings.online_status_check_interval, "last_notification_time": self.last_notification_time, "notification_cooldown_minutes": self.notification_cooldown / 60 } # 全局在线状态检测工作进程实例 online_status_worker = OnlineStatusWorker()