From e810958ec6ea2fc8ec4cdb3ffe6603dae3343ff7 Mon Sep 17 00:00:00 2001 From: liuwei Date: Tue, 22 Apr 2025 11:42:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=B3=E6=B3=A8=E6=95=B0=E6=8D=AE=E7=9B=91?= =?UTF-8?q?=E5=90=AC=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/contacts_db.py | 149 ++++++++++++++-------------------------------- main.py | 22 +++---- 2 files changed, 55 insertions(+), 116 deletions(-) diff --git a/db/contacts_db.py b/db/contacts_db.py index 5dc8b82..f0f03a9 100644 --- a/db/contacts_db.py +++ b/db/contacts_db.py @@ -8,20 +8,27 @@ import logging import json from typing import List, Dict, Optional, Union, Any +from db.base import BaseDBOperator from db.connection import DBConnectionManager logger = logging.getLogger(__name__) -class ContactsDBOperator: +class ContactsDBOperator(BaseDBOperator): """微信联系人数据库操作类""" - def __init__(self, db_manager: DBConnectionManager): - super().__init__(db_manager) + def __init__(self, db_manager=None): + """初始化联系人数据库操作类""" + super().__init__(db_manager or DBConnectionManager.get_instance()) + self.logger = logging.getLogger("ContactsDBOperator") + + # 确保数据库表存在 + # self._ensure_table_exists() + def _ensure_table_exists(self): """确保联系人表存在""" try: # 创建联系人表 - sql = """ + self.execute_update(""" CREATE TABLE IF NOT EXISTS t_wechat_contacts ( id INT AUTO_INCREMENT PRIMARY KEY, user_name VARCHAR(64) NOT NULL COMMENT '微信ID', @@ -49,13 +56,10 @@ class ContactsDBOperator: update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', UNIQUE KEY `idx_user_name` (`user_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信联系人信息表'; - """ - conn = self.db_manager.get_connection() - cursor = conn.cursor() - cursor.execute(sql) + """) # 创建群成员表 - 增加了更多字段以支持详细信息 - sql_chatroom_member = """ + self.execute_update(""" CREATE TABLE IF NOT EXISTS t_chatroom_member ( id INT AUTO_INCREMENT PRIMARY KEY, chatroom_id VARCHAR(64) NOT NULL COMMENT '群聊ID', @@ -84,19 +88,12 @@ class ContactsDBOperator: update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', UNIQUE KEY `idx_chatroom_member` (`chatroom_id`, `wxid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信群成员信息表'; - """ - cursor.execute(sql_chatroom_member) + """) - conn.commit() - logger.info("成功创建或确认微信联系人表和群成员表存在") + self.logger.info("成功创建或确认微信联系人表和群成员表存在") except Exception as e: - logger.error(f"创建微信联系人表或群成员表失败: {e}") + self.logger.error(f"创建微信联系人表或群成员表失败: {e}") raise - finally: - if 'cursor' in locals(): - cursor.close() - if 'conn' in locals(): - self.db_manager.release_connection(conn) def save_contacts(self, contacts_data: List[Dict], contact_type: str) -> bool: """保存联系人信息到数据库 @@ -109,13 +106,10 @@ class ContactsDBOperator: bool: 是否成功保存 """ if not contacts_data: - logger.warning(f"没有{contact_type}类型的联系人数据需要保存") + self.logger.warning(f"没有{contact_type}类型的联系人数据需要保存") return True try: - conn = self.db_manager.get_connection() - cursor = conn.cursor() - for contact in contacts_data: # 将驼峰命名转换为下划线命名 data = { @@ -156,22 +150,14 @@ class ContactsDBOperator: ON DUPLICATE KEY UPDATE {update_clause} """ - cursor.execute(sql, values) + self.execute_update(sql, values) - conn.commit() - logger.info(f"成功保存{len(contacts_data)}个{contact_type}类型的联系人") + self.logger.info(f"成功保存{len(contacts_data)}个{contact_type}类型的联系人") return True except Exception as e: - logger.error(f"保存{contact_type}类型的联系人失败: {e}") - if 'conn' in locals(): - conn.rollback() + self.logger.error(f"保存{contact_type}类型的联系人失败: {e}") return False - finally: - if 'cursor' in locals(): - cursor.close() - if 'conn' in locals(): - self.db_manager.release_connection(conn) def save_simple_contacts(self, contact_list: List[str], contact_type: str) -> bool: """保存简单联系人列表(只有user_name)到数据库 @@ -184,13 +170,10 @@ class ContactsDBOperator: bool: 是否成功保存 """ if not contact_list: - logger.warning(f"没有{contact_type}类型的联系人数据需要保存") + self.logger.warning(f"没有{contact_type}类型的联系人数据需要保存") return True try: - conn = self.db_manager.get_connection() - cursor = conn.cursor() - for user_name in contact_list: # 构建SQL语句 sql = """ @@ -199,22 +182,14 @@ class ContactsDBOperator: ON DUPLICATE KEY UPDATE type = VALUES(type), update_time = CURRENT_TIMESTAMP """ - cursor.execute(sql, (user_name, contact_type)) + self.execute_update(sql, (user_name, contact_type)) - conn.commit() - logger.info(f"成功保存{len(contact_list)}个{contact_type}类型的简单联系人") + self.logger.info(f"成功保存{len(contact_list)}个{contact_type}类型的简单联系人") return True except Exception as e: - logger.error(f"保存{contact_type}类型的简单联系人失败: {e}") - if 'conn' in locals(): - conn.rollback() + self.logger.error(f"保存{contact_type}类型的简单联系人失败: {e}") return False - finally: - if 'cursor' in locals(): - cursor.close() - if 'conn' in locals(): - self.db_manager.release_connection(conn) def get_contacts_by_type(self, contact_type: str) -> List[Dict]: """根据类型获取联系人列表 @@ -226,27 +201,17 @@ class ContactsDBOperator: List[Dict]: 联系人列表 """ try: - conn = self.db_manager.get_connection() - cursor = conn.cursor(dictionary=True) - sql = """ SELECT * FROM t_wechat_contacts WHERE type = %s ORDER BY nick_name """ - cursor.execute(sql, (contact_type,)) - results = cursor.fetchall() - + results = self.execute_query(sql, (contact_type,)) return results except Exception as e: - logger.error(f"获取{contact_type}类型的联系人失败: {e}") + self.logger.error(f"获取{contact_type}类型的联系人失败: {e}") return [] - finally: - if 'cursor' in locals(): - cursor.close() - if 'conn' in locals(): - self.db_manager.release_connection(conn) def get_contact_by_user_name(self, user_name: str) -> Optional[Dict]: """根据user_name获取联系人信息 @@ -258,27 +223,17 @@ class ContactsDBOperator: Optional[Dict]: 联系人信息,如果不存在则返回None """ try: - conn = self.db_manager.get_connection() - cursor = conn.cursor(dictionary=True) - sql = """ SELECT * FROM t_wechat_contacts WHERE user_name = %s LIMIT 1 """ - cursor.execute(sql, (user_name,)) - result = cursor.fetchone() - + result = self.execute_query(sql, (user_name,), fetch_one=True) return result except Exception as e: - logger.error(f"获取联系人{user_name}失败: {e}") + self.logger.error(f"获取联系人{user_name}失败: {e}") return None - finally: - if 'cursor' in locals(): - cursor.close() - if 'conn' in locals(): - self.db_manager.release_connection(conn) def get_display_name(self, user_name: str) -> str: """获取联系人的显示名称(优先使用备注,其次是昵称,最后是微信ID) @@ -302,30 +257,24 @@ class ContactsDBOperator: Dict[str, str]: 联系人ID到显示名称的映射 """ try: - conn = self.db_manager.get_connection() - cursor = conn.cursor() - sql = """ SELECT user_name, remark, nick_name FROM t_wechat_contacts """ - cursor.execute(sql) - results = cursor.fetchall() + results = self.execute_query(sql) name_map = {} - for user_name, remark, nick_name in results: + for result in results: + user_name = result.get('user_name') + remark = result.get('remark') + nick_name = result.get('nick_name') display_name = remark or nick_name or user_name name_map[user_name] = display_name return name_map except Exception as e: - logger.error(f"获取所有联系人名称映射失败: {e}") + self.logger.error(f"获取所有联系人名称映射失败: {e}") return {} - finally: - if 'cursor' in locals(): - cursor.close() - if 'conn' in locals(): - self.db_manager.release_connection(conn) def save_chatroom_member_detail(self, chatroom_id: str, member_details: List[Dict]) -> bool: """保存群成员详细信息到数据库 @@ -338,20 +287,18 @@ class ContactsDBOperator: bool: 是否成功保存 """ if not member_details or not chatroom_id: - logger.warning(f"没有群聊{chatroom_id}的成员详细信息需要保存") + self.logger.warning(f"没有群聊{chatroom_id}的成员详细信息需要保存") return False try: - conn = self.db_manager.get_connection() - cursor = conn.cursor() - # 获取现有的群成员信息,以便更新而不是替换 existing_members_sql = """ SELECT wxid, is_owner, is_admin FROM t_chatroom_member WHERE chatroom_id = %s """ - cursor.execute(existing_members_sql, (chatroom_id,)) - existing_members = {row[0]: (row[1], row[2]) for row in cursor.fetchall()} + existing_members_result = self.execute_query(existing_members_sql, (chatroom_id,)) + existing_members = {row.get('wxid'): (row.get('is_owner'), row.get('is_admin')) + for row in existing_members_result} for member in member_details: wxid = member.get('userName', '') @@ -407,22 +354,14 @@ class ContactsDBOperator: VALUES ({placeholders}) """ - cursor.execute(sql, values) + self.execute_update(sql, values) - conn.commit() - logger.info(f"成功保存群聊{chatroom_id}的{len(member_details)}个成员详细信息") + self.logger.info(f"成功保存群聊{chatroom_id}的{len(member_details)}个成员详细信息") return True except Exception as e: - logger.error(f"保存群聊{chatroom_id}的成员详细信息失败: {e}") - if 'conn' in locals(): - conn.rollback() + self.logger.error(f"保存群聊{chatroom_id}的成员详细信息失败: {e}") return False - finally: - if 'cursor' in locals(): - cursor.close() - if 'conn' in locals(): - self.db_manager.release_connection(conn) def process_chatroom_member_detail_response(self, chatroom_id: str, response: Dict) -> bool: """处理获取群成员详情的API响应 @@ -436,16 +375,16 @@ class ContactsDBOperator: """ try: if response.get('ret') != 200: - logger.error(f"获取群聊{chatroom_id}成员详情失败: {response.get('msg')}") + self.logger.error(f"获取群聊{chatroom_id}成员详情失败: {response.get('msg')}") return False data = response.get('data', []) if not data: - logger.warning(f"群聊{chatroom_id}成员详情数据为空") + self.logger.warning(f"群聊{chatroom_id}成员详情数据为空") return False return self.save_chatroom_member_detail(chatroom_id, data) except Exception as e: - logger.error(f"处理群聊{chatroom_id}成员详情数据失败: {e}") + self.logger.error(f"处理群聊{chatroom_id}成员详情数据失败: {e}") return False \ No newline at end of file diff --git a/main.py b/main.py index 04f98cd..58d2a99 100644 --- a/main.py +++ b/main.py @@ -109,17 +109,17 @@ def main(chat_type: int): print(f"已将新的APP_ID: {app_id} 写入配置文件") # 同时更新当前配置对象中的APP_ID config.APP_ID = app_id - # - # # 创建机器人实例 - # robot = Robot(config, app_id, client, chat_type) - # robot.LOG.info(f"WeChatRobot gewechat 成功启动···") - # - # # # 注册Robot实例到callback模块 - # # from gewechat.api.callback import register_robot - # # register_robot(app_id, robot) - # - # # 机器人启动发送测试消息 - # client.post_text(app_id, send_msg_wxid, "gewechat client 启动成功!") + + # 创建机器人实例 + robot = Robot(config, app_id, client, chat_type) + robot.LOG.info(f"WeChatRobot gewechat 成功启动···") + + # # 注册Robot实例到callback模块 + from gewechat.api.callback import register_robot + register_robot(app_id, robot) + + # 机器人启动发送测试消息 + client.post_text(app_id, send_msg_wxid, "gewechat client 启动成功!") # # # 每天 8:30 发送新闻 # robot.onEveryTime("08:30", robot.news_baidu_report_auto)