import os import time import logging from datetime import datetime from typing import Dict from db.chat_log_db import get_waiting_customer_pool from db.pending_transfer_db import count_open_pending_transfers from services.service_wecom_bot import wecom_bot_service logger = logging.getLogger("cs_agent") DESIGNER_ALERT_START_HOUR = int(os.getenv("DESIGNER_ALERT_START_HOUR", "8")) DESIGNER_ALERT_END_HOUR = int(os.getenv("DESIGNER_ALERT_END_HOUR", "24")) DESIGNER_ALERT_COOLDOWN_SECONDS = int(os.getenv("DESIGNER_ALERT_COOLDOWN_SECONDS", "300")) DESIGNER_ALERT_POOL_WINDOW_MINUTES = int(os.getenv("DESIGNER_ALERT_POOL_WINDOW_MINUTES", "30")) class DesignerAlertService: def __init__(self): self._last_alert_at = 0.0 @staticmethod def _in_active_window(now: datetime) -> bool: hour = now.hour return DESIGNER_ALERT_START_HOUR <= hour < DESIGNER_ALERT_END_HOUR @staticmethod def _render_shop_lines(pool: Dict) -> str: shops = pool.get("shops") or [] if not shops: return "- 暂无店铺明细" lines = [] for item in shops[:10]: acc_id = str(item.get("acc_id") or "") waiting = int(item.get("waiting_customers") or 0) lines.append(f"- {acc_id}:{waiting}人") return "\n".join(lines) async def notify_if_needed(self, *, trigger: str = "", customer_id: str = "", acc_id: str = "") -> bool: now = datetime.now() if not self._in_active_window(now): return False now_ts = time.time() if now_ts - self._last_alert_at < max(DESIGNER_ALERT_COOLDOWN_SECONDS, 30): return False pending_count = count_open_pending_transfers() pool = get_waiting_customer_pool(DESIGNER_ALERT_POOL_WINDOW_MINUTES) waiting_total = int(pool.get("total_waiting_customers") or 0) if pending_count <= 0 and waiting_total <= 0: return False content = ( "【设计师在线提醒】\n" f"当前时间:{now.strftime('%Y-%m-%d %H:%M:%S')}\n" "8点到24点内检测到暂无设计师接单,有客户待转接。\n" f"触发来源:{trigger or '-'}\n" f"当前会话:{customer_id or '-'} / {acc_id or '-'}\n" f"待转接池:{pending_count}人\n" f"当前客户池:{waiting_total}人(近{pool.get('window_minutes') or DESIGNER_ALERT_POOL_WINDOW_MINUTES}分钟最后一条仍是客户消息)\n" "店铺分布:\n" f"{self._render_shop_lines(pool)}\n" "群里如果有设计师在线,麻烦看一下。" ) ok = await wecom_bot_service.send_text(content) if ok: self._last_alert_at = now_ts logger.info( f"[DesignerAlert] 已发送企微提醒 trigger={trigger} pending={pending_count} waiting={waiting_total}" ) return ok designer_alert_service = DesignerAlertService()