"""
|
在线状态检测工作进程
|
"""
|
|
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()
|