refactor: 移除企微Webhook机器人代码,修复VLM日志

- 删除 wechat_service.send_webhook_alarm 方法
- 删除 config.py 中 webhook_url 配置
- 简化 notify_dispatch 通知逻辑(仅保留应用消息)
- 修复 vlm_service 使用项目统一 logger
- 添加 VLM 调用 URL 调试日志

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 15:35:32 +08:00
parent 0fbc1ca7a0
commit 24c94ccfbe
4 changed files with 8 additions and 72 deletions

View File

@@ -62,7 +62,6 @@ class WeChatConfig:
enabled: bool = False enabled: bool = False
test_uids: str = "" # 演示模式逗号分隔的企微userid如 "zhangsan,lisi" test_uids: str = "" # 演示模式逗号分隔的企微userid如 "zhangsan,lisi"
service_base_url: str = "" # H5页面公网地址如 https://vsp.viewshanghai.com service_base_url: str = "" # H5页面公网地址如 https://vsp.viewshanghai.com
webhook_url: str = "" # 群机器人Webhook地址
@dataclass @dataclass
@@ -171,7 +170,6 @@ def load_settings() -> Settings:
enabled=os.getenv("WECHAT_ENABLED", "false").lower() == "true", enabled=os.getenv("WECHAT_ENABLED", "false").lower() == "true",
test_uids=os.getenv("WECHAT_TEST_UIDS", ""), test_uids=os.getenv("WECHAT_TEST_UIDS", ""),
service_base_url=os.getenv("SERVICE_BASE_URL", ""), service_base_url=os.getenv("SERVICE_BASE_URL", ""),
webhook_url=os.getenv("WECHAT_WEBHOOK_URL", ""),
), ),
agent=AgentConfig( agent=AgentConfig(
llm_api_key=os.getenv("DASHSCOPE_API_KEY", ""), llm_api_key=os.getenv("DASHSCOPE_API_KEY", ""),

View File

@@ -97,26 +97,8 @@ async def process_alarm_notification(alarm_data: Dict):
event_time.strftime("%Y-%m-%d %H:%M:%S") event_time.strftime("%Y-%m-%d %H:%M:%S")
if isinstance(event_time, datetime) else str(event_time or "") if isinstance(event_time, datetime) else str(event_time or "")
) )
detail_url = f"{service_base_url}/static/alarm_detail.html?alarm_id={alarm_id}"
sent = False if wechat_service.enabled:
# 优先 Webhook无需IP白名单
if settings.wechat.webhook_url:
sent = await wechat_service.send_webhook_alarm(
webhook_url=settings.wechat.webhook_url,
alarm_id=alarm_id,
alarm_type=alarm_type,
area_name=area_name,
camera_name=camera_name,
description=description,
event_time=event_time_str,
alarm_level=alarm_level,
detail_url=detail_url,
)
# Webhook 未配置或失败时,降级到应用消息
if not sent and wechat_service.enabled:
user_ids = [p["wechat_uid"] for p in persons] user_ids = [p["wechat_uid"] for p in persons]
sent = await wechat_service.send_alarm_card( sent = await wechat_service.send_alarm_card(
user_ids=user_ids, user_ids=user_ids,
@@ -130,11 +112,12 @@ async def process_alarm_notification(alarm_data: Dict):
alarm_level=alarm_level, alarm_level=alarm_level,
service_base_url=service_base_url, service_base_url=service_base_url,
) )
if sent:
if not sent: logger.info(f"告警通知完成: {alarm_id}")
logger.warning(f"告警通知未发送: {alarm_id}, webhook和应用消息均未成功") else:
logger.warning(f"告警通知发送失败: {alarm_id}")
else: else:
logger.info(f"告警通知完成: {alarm_id}") logger.info(f"企微未启用,跳过通知: {alarm_id}")
except Exception as e: except Exception as e:
logger.error(f"告警通知处理失败: {alarm_id}, error={e}", exc_info=True) logger.error(f"告警通知处理失败: {alarm_id}, error={e}", exc_info=True)

View File

@@ -7,12 +7,11 @@ VLM 视觉语言模型复核服务
import asyncio import asyncio
import json import json
import logging
from typing import Optional, Dict from typing import Optional, Dict
from openai import AsyncOpenAI from openai import AsyncOpenAI
logger = logging.getLogger(__name__) from app.utils.logger import logger
# 算法类型 → VLM Prompt 模板 # 算法类型 → VLM Prompt 模板
VLM_PROMPTS = { VLM_PROMPTS = {
@@ -110,6 +109,7 @@ class VLMService:
) )
try: try:
logger.info(f"VLM 复核开始: type={alarm_type}, url={snapshot_url[:80]}...")
resp = await asyncio.wait_for( resp = await asyncio.wait_for(
self._client.chat.completions.create( self._client.chat.completions.create(
model=self._model, model=self._model,

View File

@@ -176,51 +176,6 @@ class WeChatService:
logger.error(f"发送文本消息异常: {e}") logger.error(f"发送文本消息异常: {e}")
return False return False
async def send_webhook_alarm(
self,
webhook_url: str,
alarm_id: str,
alarm_type: str,
area_name: str,
camera_name: str,
description: str,
event_time: str,
alarm_level: int = 2,
detail_url: str = "",
) -> bool:
"""通过群机器人 Webhook 发送告警通知无需IP白名单"""
type_names = {"leave_post": "人员离岗", "intrusion": "周界入侵"}
level_names = {1: "提醒", 2: "一般", 3: "严重", 4: "紧急"}
type_name = type_names.get(alarm_type, alarm_type)
level_name = level_names.get(alarm_level, "一般")
content = (
f"## 【{level_name}{type_name}告警\n"
f"> 区域:<font color=\"warning\">{area_name}</font>\n"
f"> 摄像头:{camera_name}\n"
f"> 时间:{event_time}\n"
f"> AI描述**{description}**\n"
)
if detail_url:
content += f"> [查看详情]({detail_url})\n"
msg = {"msgtype": "markdown", "markdown": {"content": content}}
try:
async with httpx.AsyncClient(timeout=10) as client:
resp = await client.post(webhook_url, json=msg)
data = resp.json()
if data.get("errcode") != 0:
logger.error(f"Webhook发送失败: {data}")
return False
logger.info(f"Webhook告警已发送: alarm={alarm_id}")
return True
except Exception as e:
logger.error(f"Webhook发送异常: {e}")
return False
# 全局单例 # 全局单例
_wechat_service: Optional[WeChatService] = None _wechat_service: Optional[WeChatService] = None