diff --git a/db/contacts_db.py b/db/contacts_db.py index 14756b1..48ec11f 100644 --- a/db/contacts_db.py +++ b/db/contacts_db.py @@ -87,9 +87,9 @@ class ContactsDBOperator(BaseDBOperator): ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信群成员信息表'; """) - logger.info("成功创建或确认微信联系人表和群成员表存在") + self.logger.info("成功创建或确认微信联系人表和群成员表存在") except Exception as e: - logger.error(f"创建微信联系人表或群成员表失败: {e}") + self.logger.error(f"创建微信联系人表或群成员表失败: {e}") raise def save_contacts(self, contacts_data: List[Dict], contact_type: str) -> bool: @@ -103,7 +103,7 @@ class ContactsDBOperator(BaseDBOperator): bool: 是否成功保存 """ if not contacts_data: - logger.warning(f"没有{contact_type}类型的联系人数据需要保存") + self.logger.warning(f"没有{contact_type}类型的联系人数据需要保存") return True try: @@ -150,11 +150,11 @@ class ContactsDBOperator(BaseDBOperator): self.execute_update(sql, values) - 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}") + self.logger.error(f"保存{contact_type}类型的联系人失败: {e}") return False def save_simple_contacts(self, contact_list: List[str], contact_type: str) -> bool: @@ -168,7 +168,7 @@ class ContactsDBOperator(BaseDBOperator): bool: 是否成功保存 """ if not contact_list: - logger.warning(f"没有{contact_type}类型的联系人数据需要保存") + self.logger.warning(f"没有{contact_type}类型的联系人数据需要保存") return True try: @@ -182,11 +182,11 @@ class ContactsDBOperator(BaseDBOperator): self.execute_update(sql, (user_name, contact_type)) - 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}") + self.logger.error(f"保存{contact_type}类型的简单联系人失败: {e}") return False def get_contacts_by_type(self, contact_type: str) -> List[Dict]: @@ -208,7 +208,7 @@ class ContactsDBOperator(BaseDBOperator): 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 [] def get_contact_by_user_name(self, user_name: str) -> Optional[Dict]: @@ -230,7 +230,7 @@ class ContactsDBOperator(BaseDBOperator): 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 def get_display_name(self, user_name: str) -> str: @@ -248,6 +248,32 @@ class ContactsDBOperator(BaseDBOperator): return contact.get('remark') or contact.get('nick_name') or user_name + def get_all_contacts(self) -> Dict[str, str]: + """获取所有联系人信息 + + Returns: + Dict[str, str]: 联系人字典,格式为 {"wxid": "NickName"} + """ + try: + sql = """ + SELECT user_name, nick_name, remark FROM t_wechat_contacts + """ + + results = self.execute_query(sql) + + contacts_dict = {} + for result in results: + user_name = result.get('user_name') + # 优先使用备注,其次是昵称,最后是微信ID + display_name = result.get('remark') or result.get('nick_name') or user_name + contacts_dict[user_name] = display_name + + self.logger.info(f"从数据库获取了 {len(contacts_dict)} 个联系人信息") + return contacts_dict + except Exception as e: + self.logger.error(f"获取所有联系人信息失败: {e}") + return {} + def get_all_contacts_name_map(self) -> Dict[str, str]: """获取所有联系人的ID到显示名称的映射 @@ -271,7 +297,7 @@ class ContactsDBOperator(BaseDBOperator): return name_map except Exception as e: - logger.error(f"获取所有联系人名称映射失败: {e}") + self.logger.error(f"获取所有联系人名称映射失败: {e}") return {} def save_chatroom_member_detail(self, chatroom_id: str, member_details: List[Dict]) -> bool: @@ -285,7 +311,7 @@ class ContactsDBOperator(BaseDBOperator): bool: 是否成功保存 """ if not member_details or not chatroom_id: - logger.warning(f"没有群聊{chatroom_id}的成员详细信息需要保存") + self.logger.warning(f"没有群聊{chatroom_id}的成员详细信息需要保存") return False try: @@ -354,11 +380,11 @@ class ContactsDBOperator(BaseDBOperator): self.execute_update(sql, values) - 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}") + self.logger.error(f"保存群聊{chatroom_id}的成员详细信息失败: {e}") return False def process_chatroom_member_detail_response(self, chatroom_id: str, response: Dict) -> bool: @@ -373,16 +399,16 @@ class ContactsDBOperator(BaseDBOperator): """ 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 diff --git a/main.py b/main.py index cc8ed72..ad8d1db 100644 --- a/main.py +++ b/main.py @@ -121,7 +121,7 @@ def main(chat_type: int): register_robot(app_id, robot) # 机器人启动发送测试消息 - client.post_text(app_id, send_msg_wxid, "gewechat client 启动成功!") + client.post_text(app_id, send_msg_wxid, "client 启动成功!") # # # 每天 8:30 发送新闻 # robot.onEveryTime("08:30", robot.news_baidu_report_auto) @@ -145,17 +145,17 @@ def main(chat_type: int): # 启动Dashboard服务器 dashboard_server = None - # try: - # # 创建Dashboard服务器实例,共享robot对象 - # from admin.dashboard.server import DashboardServer - # dashboard_server = DashboardServer(robot_instance=robot) - # - # # 在单独的线程中启动Dashboard服务器 - # dashboard_thread = threading.Thread(target=dashboard_server.run, daemon=True) - # dashboard_thread.start() - # robot.LOG.info(f"Dashboard服务器已在 http://{dashboard_server.host}:{dashboard_server.port} 启动") - # except Exception as e: - # robot.LOG.error(f"Dashboard服务器启动失败: {e}") + try: + # 创建Dashboard服务器实例,共享robot对象 + from admin.dashboard.server import DashboardServer + dashboard_server = DashboardServer(robot_instance=robot) + + # 在单独的线程中启动Dashboard服务器 + dashboard_thread = threading.Thread(target=dashboard_server.run, daemon=True) + dashboard_thread.start() + robot.LOG.info(f"Dashboard服务器已在 http://{dashboard_server.host}:{dashboard_server.port} 启动") + except Exception as e: + robot.LOG.error(f"Dashboard服务器启动失败: {e}") # 让机器人一直跑 robot.keep_running_and_block_process() diff --git a/robot.py b/robot.py index 219889f..152d6cd 100644 --- a/robot.py +++ b/robot.py @@ -404,7 +404,19 @@ class Robot(Job): def get_all_contacts(self) -> dict: """获取所有联系人信息并返回字典格式 {wxid: nickname}""" + # 从数据库提取信息,如果数据库没内容,则完成第一次初始化。 try: + # 先尝试从数据库获取联系人信息 + contacts_dict = self.contacts_db.get_all_contacts() + + # 如果数据库中有联系人信息,直接返回 + if contacts_dict: + self.LOG.info(f"从数据库成功获取了 {len(contacts_dict)} 个联系人信息") + return contacts_dict + + # 数据库中没有联系人信息,需要初始化 + self.LOG.info("数据库中没有联系人信息,开始初始化...") + contacts_dict = {} # 获取所有联系人列表 response = self.client.fetch_contacts_list(self.app_id) @@ -421,7 +433,7 @@ class Robot(Job): friends = contact_data.get("friends", []) for wxid in friends: contacts_dict[wxid] = wxid # 默认使用wxid作为昵称 - + # 处理群聊列表 chatrooms = contact_data.get("chatrooms", []) for chatroom_id in chatrooms: