添加 刷新通讯录功能,用于解决冗余数据问题。

This commit is contained in:
liuwei
2025-05-07 12:29:27 +08:00
parent 86c8ad4889
commit 32201f6274
2 changed files with 71 additions and 155 deletions

View File

@@ -331,116 +331,71 @@ class ContactsDBOperator(BaseDBOperator):
self.LOG.error(f"获取所有联系人名称映射失败: {e}") self.LOG.error(f"获取所有联系人名称映射失败: {e}")
return {} return {}
def save_chatroom_member_simple(self, chatroom_id: str, member_details: List[Dict]) -> bool: def save_chatroom_member_simple(self, chatroom_id: str, member_details: List[Dict]) -> bool:
"""保存简化版的群成员信息到数据库 """
保存群成员简要信息到数据库,兼容不同数据结构
Args: Args:
chatroom_id: 群聊ID chatroom_id: 群聊ID
member_details: 群成员信息列表,格式为: member_details: 群成员信息列表
[{'UserName': str, 'NickName': str, 'InviterUserName': str,
'ChatroomMemberFlag': int, 'DisplayName': str}]
Returns: Returns:
bool: 是否成功保存 bool: 是否成功保存
""" """
if not member_details or not chatroom_id: if not member_details:
self.LOG.warning(f"没有群聊{chatroom_id}的成员信息需要保存") self.LOG.warning(f"{chatroom_id} 没有成员数据需要保存")
return False return True
try: try:
for member in member_details: for member in member_details:
# 处理新的数据结构 # 兼容微信协议风格的数据结构
wxid = "" def get_str(field, default=""):
if "UserName" in member: val = member.get(field, default)
if isinstance(member["UserName"], dict): if isinstance(val, dict):
wxid = member["UserName"].get("string", "") return val.get("string", default)
else: return val if val is not None else default
wxid = member.get("UserName", "")
elif "wxid" in member:
wxid = member.get("wxid", "")
if not wxid:
continue
# 提取昵称
nick_name = ""
if "NickName" in member:
if isinstance(member["NickName"], dict):
nick_name = member["NickName"].get("string", "")
else:
nick_name = member.get("NickName", "")
elif "nickName" in member:
nick_name = member.get("nickName", "")
# 提取邀请人
inviter_user_name = ""
if "InviterUserName" in member:
inviter_user_name = member.get("InviterUserName", "")
elif "inviterUserName" in member:
inviter_user_name = member.get("inviterUserName", "")
# 提取成员标志
member_flag = 0
if "ChatroomMemberFlag" in member:
member_flag = member.get("ChatroomMemberFlag", 0)
elif "memberFlag" in member:
member_flag = member.get("memberFlag", 0)
# 判断是否为群主
is_owner = 0
if chatroom_id and wxid:
# 查询群信息,检查是否为群主
chat_room_owner_sql = """
SELECT chat_room_owner FROM t_chatrooms
WHERE chatroom_id = %s
"""
chat_room_owner_result = self.execute_query(chat_room_owner_sql, (chatroom_id,), fetch_one=True)
if chat_room_owner_result and chat_room_owner_result.get('chat_room_owner') == wxid:
is_owner = 1
# 构建数据
data = { data = {
'chatroom_id': chatroom_id, 'chatroom_id': chatroom_id,
'wxid': wxid, 'wxid': get_str('UserName'),
'nick_name': nick_name, 'nick_name': get_str('NickName'),
'display_name': member.get('DisplayName', ''), 'display_name': get_str('DisplayName'),
'inviter_user_name': inviter_user_name, 'inviter_user_name': get_str('InviterUserName'),
'member_flag': member_flag, 'member_flag': member.get('MemberFlag', 0),
'big_head_img_url': member.get('bigHeadImgUrl', ''), 'big_head_img_url': get_str('BigHeadImgUrl'),
'small_head_img_url': member.get('smallHeadImgUrl', ''), 'small_head_img_url': get_str('SmallHeadImgUrl'),
'is_owner': is_owner, 'is_owner': 1 if member.get('IsOwner', False) else 0,
'is_admin': 1 if member_flag == 2049 else 0, # 根据memberFlag判断是否为管理员 'is_admin': 1 if member.get('IsAdmin', False) else 0,
# 其他字段使用默认值 'sex': member.get('Sex', 0),
'sex': 0, 'signature': get_str('Signature'),
'signature': '', 'alias': get_str('Alias'),
'alias': '', 'country': get_str('Country'),
'country': '', 'province': get_str('Province'),
'province': '', 'city': get_str('City'),
'city': '', 'label_list': '', # 可根据需要补充
'label_list': '', 'phone_num_list': '', # 可根据需要补充
'phone_num_list': '', 'py_initial': get_str('Pyinitial'),
'py_initial': '', 'quan_pin': get_str('QuanPin'),
'quan_pin': '', 'remark_py_initial': get_str('RemarkPyinitial'),
'remark_py_initial': '', 'remark_quan_pin': get_str('RemarkQuanPin'),
'remark_quan_pin': ''
} }
# 构建SQL语句
fields = ', '.join(data.keys()) fields = ', '.join(data.keys())
placeholders = ', '.join(['%s'] * len(data)) placeholders = ', '.join(['%s'] * len(data))
values = tuple(data.values()) values = tuple(data.values())
update_clause = ', '.join([f"{k}=VALUES({k})" for k in data.keys() if k not in ('chatroom_id', 'wxid')])
sql = f""" sql = f"""
REPLACE INTO t_chatroom_member ({fields}) INSERT INTO t_chatroom_member ({fields})
VALUES ({placeholders}) VALUES ({placeholders})
ON DUPLICATE KEY UPDATE {update_clause}
""" """
self.execute_update(sql, values) self.execute_update(sql, values)
self.LOG.info(f"成功保存群{chatroom_id}{len(member_details)}个成员信息") self.LOG.info(f"成功保存群 {chatroom_id}{len(member_details)} 个成员信息")
return True return True
except Exception as e: except Exception as e:
self.LOG.error(f"保存群{chatroom_id}成员信息失败: {e}") self.LOG.error(f"保存群 {chatroom_id} 成员信息失败: {e}")
return False return False
def save_chatroom_member_detail(self, chatroom_id: str, member_details: List[Dict]) -> bool: def save_chatroom_member_detail(self, chatroom_id: str, member_details: List[Dict]) -> bool:
"""保存群成员详细信息到数据库 """保存群成员详细信息到数据库
@@ -556,68 +511,34 @@ class ContactsDBOperator(BaseDBOperator):
return False return False
def save_chatroom_info(self, chatroom_data: dict) -> bool: def save_chatroom_info(self, chatroom_data: dict) -> bool:
"""保存群信息到数据库""" """保存群信息到数据库,兼容微信协议风格字段"""
try: try:
# 处理新的数据结构 def get_str(field, default=""):
user_name = "" val = chatroom_data.get(field, default)
if isinstance(chatroom_data, dict): if isinstance(val, dict):
if "UserName" in chatroom_data and isinstance(chatroom_data["UserName"], dict): return val.get("string", default)
user_name = chatroom_data["UserName"].get("string", "") return val if val is not None else default
elif "chatroomId" in chatroom_data:
user_name = chatroom_data.get("chatroomId", "")
if not user_name:
self.LOG.warning("无法获取群聊ID保存失败")
return False
# 提取群聊名称
nick_name = ""
if "NickName" in chatroom_data and isinstance(chatroom_data["NickName"], dict):
nick_name = chatroom_data["NickName"].get("string", "")
elif "chatroomName" in chatroom_data:
nick_name = chatroom_data.get("chatroomName", "")
# 提取群主信息
chat_room_owner = ""
if "ChatRoomOwner" in chatroom_data:
chat_room_owner = chatroom_data.get("ChatRoomOwner", "")
# 提取群通知设置
chat_room_notify = 0
if "ChatRoomNotify" in chatroom_data:
chat_room_notify = chatroom_data.get("ChatRoomNotify", 0)
# 提取群头像
small_head_img_url = ""
if "SmallHeadImgUrl" in chatroom_data:
small_head_img_url = chatroom_data.get("SmallHeadImgUrl", "").strip()
# 提取群成员列表
member_list = []
if "NewChatroomData" in chatroom_data and "ChatRoomMember" in chatroom_data["NewChatroomData"]:
member_list = chatroom_data["NewChatroomData"].get("ChatRoomMember", [])
elif "memberList" in chatroom_data:
member_list = chatroom_data.get("memberList", [])
data = { data = {
'chatroom_id': user_name, 'chatroom_id': get_str('UserName'),
'nick_name': nick_name, 'nick_name': get_str('NickName'),
'py_initial': chatroom_data.get('Pyinitial', {}).get('string', ''), 'py_initial': get_str('Pyinitial'),
'quan_pin': chatroom_data.get('QuanPin', {}).get('string', ''), 'quan_pin': get_str('QuanPin'),
'sex': chatroom_data.get('Sex', 0), 'sex': chatroom_data.get('Sex', 0),
'remark': chatroom_data.get('Remark', {}).get('string', ''), 'remark': get_str('Remark'),
'remark_py_initial': chatroom_data.get('RemarkPyinitial', {}).get('string', ''), 'remark_py_initial': get_str('RemarkPyinitial'),
'remark_quan_pin': chatroom_data.get('RemarkQuanPin', {}).get('string', ''), 'remark_quan_pin': get_str('RemarkQuanPin'),
'chat_room_notify': chat_room_notify, 'chat_room_notify': chatroom_data.get('ChatRoomNotify', 0),
'chat_room_owner': chat_room_owner, 'chat_room_owner': chatroom_data.get('ChatRoomOwner', ''),
'small_head_img_url': small_head_img_url, 'small_head_img_url': chatroom_data.get('SmallHeadImgUrl', ''),
'member_list': json.dumps(member_list) # 成员列表可选存储为JSON字符串
'member_list': json.dumps(chatroom_data.get('NewChatroomData', {}).get('ChatRoomMember', []), ensure_ascii=False)
} }
fields = ', '.join(data.keys()) fields = ', '.join(data.keys())
placeholders = ', '.join(['%s'] * len(data)) placeholders = ', '.join(['%s'] * len(data))
update_clause = ', '.join([f"{k}=VALUES({k})" for k in data.keys() if k != 'chatroom_id'])
values = tuple(data.values()) values = tuple(data.values())
update_clause = ', '.join([f"{k}=VALUES({k})" for k in data.keys() if k != 'chatroom_id'])
sql = f""" sql = f"""
INSERT INTO t_chatrooms ({fields}) INSERT INTO t_chatrooms ({fields})
@@ -626,7 +547,7 @@ class ContactsDBOperator(BaseDBOperator):
""" """
self.execute_update(sql, values) self.execute_update(sql, values)
self.LOG.info(f"成功保存群聊 {data['chatroom_id']} 信息") self.LOG.info(f"成功保存群聊信息: {data['chatroom_id']}")
return True return True
except Exception as e: except Exception as e:
self.LOG.error(f"保存群聊信息失败: {e}") self.LOG.error(f"保存群聊信息失败: {e}")

View File

@@ -363,22 +363,17 @@ class Robot(Job):
# 保存群成员信息 # 保存群成员信息
if "NewChatroomData" in chatroom_info and "ChatRoomMember" in chatroom_info["NewChatroomData"]: if "NewChatroomData" in chatroom_info and "ChatRoomMember" in chatroom_info["NewChatroomData"]:
member_list = chatroom_info["NewChatroomData"]["ChatRoomMember"] member_list = chatroom_info["NewChatroomData"]["ChatRoomMember"]
# 兼容逻辑已放到save_chatroom_member_simple内部
self.contacts_db.save_chatroom_member_simple(group_id, member_list) self.contacts_db.save_chatroom_member_simple(group_id, member_list)
# 更新联系人缓存 # 更新联系人缓存
for member in member_list: for member in member_list:
wxid = ""
if isinstance(member.get("UserName"), dict):
wxid = member["UserName"].get("string", "")
else:
wxid = member.get("UserName", "") wxid = member.get("UserName", "")
if isinstance(wxid, dict):
nick_name = "" wxid = wxid.get("string", "")
if isinstance(member.get("NickName"), dict):
nick_name = member["NickName"].get("string", "")
else:
nick_name = member.get("NickName", "") nick_name = member.get("NickName", "")
if isinstance(nick_name, dict):
nick_name = nick_name.get("string", "")
if wxid: if wxid:
self.allContacts[wxid] = nick_name self.allContacts[wxid] = nick_name