sequenceDiagram participant WX as 企微消息 participant API as FastAPI participant Router as MessageRouter participant Score as ScoringService participant Vip as VipService participant DB as PostgreSQL participant Redis as Redis WX->>API: 员工消息回调 API->>Router: route_message(msg) rect rgb(255, 240, 240) Note over Router,Score: Step 1: VIP检测 Router->>Vip: is_vip(employee_id) Vip->>Redis: GET vip_cache:{employee_id} alt 缓存命中 Redis-->>Vip: is_vip=True/False else 缓存未命中 Vip->>Vip: get_user_info(employee_id) Vip->>Vip: _check_vip_rules(user_info) Note over Vip: 规则: 总监及以上 或 关键部门 Vip->>Redis: SET vip_cache:{employee_id} EX 3600 end Vip-->>Router: is_vip=True/False end rect rgb(255, 255, 220) Note over Router,Score: Step 2: 情绪关键词检测 Router->>Score: detect_emotion(msg) Score->>DB: SELECT FROM system_configs WHERE key LIKE 'emotion_keywords_%' DB-->>Score: 关键词列表 Score->>Score: 遍历关键词匹配消息内容 Score-->>Router: emotion="urgent" end rect rgb(220, 255, 220) Note over Router,Score: Step 3: 举手检测 Router->>Score: detect_hand_raise(msg) Score->>DB: SELECT FROM system_configs WHERE key='hand_raise_keywords' DB-->>Score: ["转人工","人工",...] Score->>Score: 遍历关键词匹配 Score-->>Router: hand_raise=True end rect rgb(220, 220, 255) Note over Router,Score: Step 4: 需介入检测 Router->>Score: detect_need_intervene(conv) Score->>DB: SELECT COUNT FROM messages WHERE conversation_id=... AND sender_type='employee' DB-->>Score: 员工消息数 Score->>DB: SELECT FROM system_configs WHERE key='intervene_round_threshold' DB-->>Score: 3 Score->>Score: 员工连续追问 > 3轮? Score-->>Router: need_intervene=True end rect rgb(255, 220, 255) Note over Router,Score: Step 5: 紧急度计算 Router->>Score: calculate_urgency(conv, msg) Score->>Score: base = keyword_score(1) Score->>Score: + emotion_bonus(1) Score->>Score: + vip_bonus(1) Score->>Score: + repeat_bonus(1) Score->>Score: total = min(5, base+emotion+vip+repeat) Score-->>Router: urgency_score=4 end Router->>DB: UPDATE conversations SET tags=..., urgency_score=4, is_vip=... Router-->>API: 更新后的会话