diff --git a/utils/wechat/member_monitor.py b/utils/wechat/member_monitor.py index c6764c0..3713812 100644 --- a/utils/wechat/member_monitor.py +++ b/utils/wechat/member_monitor.py @@ -94,6 +94,7 @@ class ChatroomMemberMonitor: 'wxid': wxid, 'nick_name': m.get('nick_name', ''), 'display_name': m.get('display_name', ''), + 'status': m.get('status', 1) # 默认为1 } added = [] @@ -106,40 +107,47 @@ class ChatroomMemberMonitor: added.append(api_m) else: db_m = db_map[wxid] - # 检查群昵称是否修改 - # 逻辑:如果API的DisplayName与DB不同,或者(API没有DisplayName且NickName与DB不同) - # 简单起见,对比 display_name 和 nick_name - # 注意:API返回的 DisplayName 为空字符串时,通常表示未设置群昵称,此时展示的是 NickName - # 对比 display_name (群昵称) - api_disp = api_m['display_name'] - db_disp = db_m['display_name'] - - # 对比 nick_name (微信昵称) - 虽然题目主要关注"用户群昵称修改",但昵称变了也算信息变更 - api_nick = api_m['nick_name'] - db_nick = db_m['nick_name'] - - if api_disp != db_disp: - modified.append({ - 'wxid': wxid, - 'type': 'display_name_change', - 'old': db_disp, - 'new': api_disp, - 'member': api_m - }) - elif api_nick != db_nick: # 可选:如果只关心群昵称,可以注释掉这个elif - modified.append({ - 'wxid': wxid, - 'type': 'nick_name_change', - 'old': db_nick, - 'new': api_nick, - 'member': api_m - }) + # 如果数据库中状态非1(已退群),但API中有,说明重新加入 + if db_m['status'] != 1: + added.append(api_m) + else: + # 检查群昵称是否修改 + # 逻辑:如果API的DisplayName与DB不同,或者(API没有DisplayName且NickName与DB不同) + # 简单起见,对比 display_name 和 nick_name + # 注意:API返回的 DisplayName 为空字符串时,通常表示未设置群昵称,此时展示的是 NickName + + # 对比 display_name (群昵称) + api_disp = api_m['display_name'] + db_disp = db_m['display_name'] + + # 对比 nick_name (微信昵称) - 虽然题目主要关注"用户群昵称修改",但昵称变了也算信息变更 + api_nick = api_m['nick_name'] + db_nick = db_m['nick_name'] + + if api_disp != db_disp: + modified.append({ + 'wxid': wxid, + 'type': 'display_name_change', + 'old': db_disp, + 'new': api_disp, + 'member': api_m + }) + elif api_nick != db_nick: # 可选:如果只关心群昵称,可以注释掉这个elif + modified.append({ + 'wxid': wxid, + 'type': 'nick_name_change', + 'old': db_nick, + 'new': api_nick, + 'member': api_m + }) # 检查减少 for wxid, db_m in db_map.items(): if wxid not in api_map: - removed.append(db_m) + # 只有当前状态为1(在群里)的才算减少 + if db_m['status'] == 1: + removed.append(db_m) has_changes = bool(added or removed or modified) @@ -190,25 +198,24 @@ class ChatroomMemberMonitor: def _remove_members_from_db(self, group_id: str, wxid_list: List[str]): """ - 从数据库中删除指定的群成员 + 从数据库中删除指定的群成员(逻辑删除) """ if not wxid_list: return try: - # 构造 SQL 删除语句 - # 注意:ContactsDB 类可能没有直接删除特定成员的方法,这里我们需要手动执行 SQL 或者扩展 ContactsDB - # 查看 contacts_db.py 发现有 execute_update 方法,但通常建议封装在 DB 类中 - # 这里直接使用 execute_update 如果权限允许,或者我们假设 db 有这个能力 - placeholders = ', '.join(['%s'] * len(wxid_list)) - sql = f"DELETE FROM t_chatroom_member WHERE chatroom_id = %s AND wxid IN ({placeholders})" + sql = f""" + UPDATE t_chatroom_member + SET status = 2, update_time = CURRENT_TIMESTAMP + WHERE chatroom_id = %s AND wxid IN ({placeholders}) + """ params = [group_id] + wxid_list self.db.execute_update(sql, tuple(params)) - self.logger.info(f"从数据库移除 {len(wxid_list)} 个成员: {wxid_list}") + self.logger.info(f"群 {group_id} 逻辑删除 {len(wxid_list)} 名成员") except Exception as e: - self.logger.error(f"从数据库移除成员失败: {e}") + self.logger.error(f"逻辑删除群 {group_id} 成员失败: {e}") def parse_mod_contacts_msg(self, msg_content: Dict) -> List[str]: """