diff --git a/utils/wechat/message_to_db.py b/utils/wechat/message_to_db.py index 7063827..2ab01d6 100644 --- a/utils/wechat/message_to_db.py +++ b/utils/wechat/message_to_db.py @@ -11,7 +11,7 @@ import aiohttp import re from threading import Lock -from typing import Dict, Optional +from typing import Dict, List, Optional from db.connection import DBConnectionManager from db.contacts_db import ContactsDBOperator @@ -689,6 +689,84 @@ class MessageStorage: "emoji_count": 0, } + # ==================== Dashboard 兼容查询代理 ==================== + # 说明: + # 1. DashboardServer 现在持有的通常是当前 MessageStorage 包装层对象; + # 2. 但后台蓝图历史上直接依赖的是 MessageStorageDB 上的查询方法; + # 3. 为了兼容两套调用习惯,这里把后台会用到的查询接口显式代理到 message_db; + # 4. 这样既保留包装层上的异步归档、表情资产等能力,也避免 Dashboard 再次出现属性缺失。 + + def get_recent_group_chat_messages(self, group_id: str, limit: int = 20) -> List[Dict]: + """代理获取群聊最近消息,供后台聊天面板直接使用。""" + return self.message_db.get_recent_group_chat_messages(group_id, limit=limit) + + def get_recent_personal_messages(self, wxid: str, limit: int = 20) -> List[Dict]: + """代理获取私聊最近消息,兼容后台联系人会话预览。""" + return self.message_db.get_recent_personal_messages(wxid, limit=limit) + + def get_messages_by_filter(self, group_id=None, start_date=None, end_date=None, + search_text=None, page: int = 1, page_size: int = 20) -> Dict: + """代理后台消息筛选分页查询,保持原有调用签名稳定。""" + return self.message_db.get_messages_by_filter( + group_id=group_id, + start_date=start_date, + end_date=end_date, + search_text=search_text, + page=page, + page_size=page_size, + ) + + def get_message_by_message_id(self, message_id): + """代理按 message_id 反查消息,用于引用消息预览和追踪。""" + return self.message_db.get_message_by_message_id(message_id) + + def get_image_message_by_md5(self, md5: str): + """代理按 md5 反查图片消息,兼容引用图片的缩略图补全逻辑。""" + return self.message_db.get_image_message_by_md5(md5) + + def get_hourly_message_trend(self, group_id: str = None, days: int = 1) -> List[Dict]: + """代理按小时消息趋势查询,供 Dashboard 趋势图接口调用。""" + return self.message_db.get_hourly_message_trend(group_id=group_id, days=days) + + def get_message_trend(self, group_id: str, days: int = 7) -> List[Dict]: + """代理按天消息趋势查询,兼容群详情页与群管理页。""" + return self.message_db.get_message_trend(group_id, days) + + def get_group_member_message_ranking(self, group_id: str, start_time: datetime, + end_time: datetime, limit: int = 10) -> List[Dict]: + """代理群成员发言排行查询,供群详情聚合接口直接使用。""" + return self.message_db.get_group_member_message_ranking( + group_id, + start_time, + end_time, + limit=limit, + ) + + def get_group_last_message(self, group_id: str): + """代理查询群最后一条消息,避免后台绕过包装层直接访问 DB。""" + return self.message_db.get_group_last_message(group_id) + + def get_group_hourly_distribution(self, group_id: str, days: int = 30) -> List[Dict]: + """代理查询群消息小时分布,用于识别高峰发言时段。""" + return self.message_db.get_group_hourly_distribution(group_id, days) + + def get_recent_emoji_assets(self, limit: int = 200) -> List[Dict]: + """代理读取最近表情消息记录,兼容仍走 message_storage 的老逻辑。""" + return self.message_db.get_recent_emoji_assets(limit=limit) + + def get_emoji_asset_by_md5(self, md5: str): + """代理按 md5 查找表情记录,给表情发送补参数时兜底。""" + return self.message_db.get_emoji_asset_by_md5(md5) + + def get_pending_media_messages(self, minutes_ago: int = 10, limit: int = 50, + group_ids: Optional[List[str]] = None) -> List[Dict]: + """代理待处理媒体消息查询,统一包装层与底层 DB 的访问入口。""" + return self.message_db.get_pending_media_messages( + minutes_ago=minutes_ago, + limit=limit, + group_ids=group_ids, + ) + def _format_messages_optimized(self, messages: list, all_contacts: dict) -> str: """优化的消息格式化方法,减少冗余