855 协议版本-调整完毕内容

This commit is contained in:
liuwei
2025-04-30 13:22:33 +08:00
parent 869bce8a18
commit 454d084715
88 changed files with 1565 additions and 7816 deletions

View File

@@ -4,7 +4,7 @@
用于管理微信联系人信息的存储和查询
"""
import logging
from loguru import logger
import json
from typing import List, Dict, Optional, Union, Any
@@ -18,7 +18,7 @@ class ContactsDBOperator(BaseDBOperator):
def __init__(self, db_manager: DBConnectionManager):
super().__init__(db_manager)
self.logger = logging.getLogger(__name__)
self.LOG = logger
def _ensure_table_exists(self):
"""确保联系人表存在"""
@@ -106,9 +106,9 @@ class ContactsDBOperator(BaseDBOperator):
UNIQUE KEY `idx_chatroom_id` (`chatroom_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信群信息表';
""")
self.logger.info("成功创建或确认微信群信息表存在")
self.LOG.info("成功创建或确认微信群信息表存在")
except Exception as e:
self.logger.error(f"创建微信联系人表或群成员表失败: {e}")
self.LOG.error(f"创建微信联系人表或群成员表失败: {e}")
raise
def save_contacts(self, contacts_data: List[Dict], contact_type: str) -> bool:
@@ -122,7 +122,7 @@ class ContactsDBOperator(BaseDBOperator):
bool: 是否成功保存
"""
if not contacts_data:
self.logger.warning(f"没有{contact_type}类型的联系人数据需要保存")
self.LOG.warning(f"没有{contact_type}类型的联系人数据需要保存")
return True
try:
@@ -169,11 +169,11 @@ class ContactsDBOperator(BaseDBOperator):
self.execute_update(sql, values)
self.logger.info(f"成功保存{len(contacts_data)}{contact_type}类型的联系人")
self.LOG.info(f"成功保存{len(contacts_data)}{contact_type}类型的联系人")
return True
except Exception as e:
self.logger.error(f"保存{contact_type}类型的联系人失败: {e}")
self.LOG.error(f"保存{contact_type}类型的联系人失败: {e}")
return False
def save_simple_contacts(self, contact_list: List[str], contact_type: str) -> bool:
@@ -187,7 +187,7 @@ class ContactsDBOperator(BaseDBOperator):
bool: 是否成功保存
"""
if not contact_list:
self.logger.warning(f"没有{contact_type}类型的联系人数据需要保存")
self.LOG.warning(f"没有{contact_type}类型的联系人数据需要保存")
return True
try:
@@ -201,11 +201,11 @@ class ContactsDBOperator(BaseDBOperator):
self.execute_update(sql, (user_name, contact_type))
self.logger.info(f"成功保存{len(contact_list)}{contact_type}类型的简单联系人")
self.LOG.info(f"成功保存{len(contact_list)}{contact_type}类型的简单联系人")
return True
except Exception as e:
self.logger.error(f"保存{contact_type}类型的简单联系人失败: {e}")
self.LOG.error(f"保存{contact_type}类型的简单联系人失败: {e}")
return False
def get_contacts_by_type(self, contact_type: str) -> List[Dict]:
@@ -227,7 +227,7 @@ class ContactsDBOperator(BaseDBOperator):
results = self.execute_query(sql, (contact_type,))
return results
except Exception as e:
self.logger.error(f"获取{contact_type}类型的联系人失败: {e}")
self.LOG.error(f"获取{contact_type}类型的联系人失败: {e}")
return []
def get_contact_by_user_name(self, user_name: str) -> Optional[Dict]:
@@ -249,7 +249,7 @@ class ContactsDBOperator(BaseDBOperator):
result = self.execute_query(sql, (user_name,), fetch_one=True)
return result
except Exception as e:
self.logger.error(f"获取联系人{user_name}失败: {e}")
self.LOG.error(f"获取联系人{user_name}失败: {e}")
return None
def get_display_name(self, user_name: str) -> str:
@@ -294,10 +294,10 @@ class ContactsDBOperator(BaseDBOperator):
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)} 个联系人信息")
self.LOG.info(f"从数据库获取了 {len(contacts_dict)} 个联系人信息")
return contacts_dict
except Exception as e:
self.logger.error(f"获取所有联系人信息失败: {e}")
self.LOG.error(f"获取所有联系人信息失败: {e}")
return {}
def get_all_contacts_name_map(self) -> Dict[str, str]:
@@ -323,7 +323,7 @@ class ContactsDBOperator(BaseDBOperator):
return name_map
except Exception as e:
self.logger.error(f"获取所有联系人名称映射失败: {e}")
self.LOG.error(f"获取所有联系人名称映射失败: {e}")
return {}
def save_chatroom_member_simple(self, chatroom_id: str, member_details: List[Dict]) -> bool:
"""保存简化版的群成员信息到数据库
@@ -331,35 +331,79 @@ class ContactsDBOperator(BaseDBOperator):
Args:
chatroom_id: 群聊ID
member_details: 群成员信息列表,格式为:
[{'wxid': str, 'nickName': str, 'inviterUserName': str,
'memberFlag': int, 'displayName': str,
'bigHeadImgUrl': str, 'smallHeadImgUrl': str}]
[{'UserName': str, 'NickName': str, 'InviterUserName': str,
'ChatroomMemberFlag': int, 'DisplayName': str}]
Returns:
bool: 是否成功保存
"""
if not member_details or not chatroom_id:
self.logger.warning(f"没有群聊{chatroom_id}的成员信息需要保存")
self.LOG.warning(f"没有群聊{chatroom_id}的成员信息需要保存")
return False
try:
for member in member_details:
wxid = member.get('wxid', '')
# 处理新的数据结构
wxid = ""
if "UserName" in member:
if isinstance(member["UserName"], dict):
wxid = member["UserName"].get("string", "")
else:
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 = {
'chatroom_id': chatroom_id,
'wxid': wxid,
'nick_name': member.get('nickName', ''),
'display_name': member.get('displayName', ''),
'inviter_user_name': member.get('inviterUserName', ''),
'member_flag': member.get('memberFlag', 0),
'nick_name': nick_name,
'display_name': member.get('DisplayName', ''),
'inviter_user_name': inviter_user_name,
'member_flag': member_flag,
'big_head_img_url': member.get('bigHeadImgUrl', ''),
'small_head_img_url': member.get('smallHeadImgUrl', ''),
'is_owner': 0, # 默认值
'is_admin': 0, # 默认值
'is_owner': is_owner,
'is_admin': 1 if member_flag == 2049 else 0, # 根据memberFlag判断是否为管理员
# 其他字段使用默认值
'sex': 0,
'signature': '',
@@ -387,11 +431,11 @@ class ContactsDBOperator(BaseDBOperator):
self.execute_update(sql, values)
self.logger.info(f"成功保存群聊{chatroom_id}{len(member_details)}个成员信息")
self.LOG.info(f"成功保存群聊{chatroom_id}{len(member_details)}个成员信息")
return True
except Exception as e:
self.logger.error(f"保存群聊{chatroom_id}的成员信息失败: {e}")
self.LOG.error(f"保存群聊{chatroom_id}的成员信息失败: {e}")
return False
def save_chatroom_member_detail(self, chatroom_id: str, member_details: List[Dict]) -> bool:
"""保存群成员详细信息到数据库
@@ -404,7 +448,7 @@ class ContactsDBOperator(BaseDBOperator):
bool: 是否成功保存
"""
if not member_details or not chatroom_id:
self.logger.warning(f"没有群聊{chatroom_id}的成员详细信息需要保存")
self.LOG.warning(f"没有群聊{chatroom_id}的成员详细信息需要保存")
return False
try:
@@ -473,11 +517,11 @@ class ContactsDBOperator(BaseDBOperator):
self.execute_update(sql, values)
self.logger.info(f"成功保存群聊{chatroom_id}{len(member_details)}个成员详细信息")
self.LOG.info(f"成功保存群聊{chatroom_id}{len(member_details)}个成员详细信息")
return True
except Exception as e:
self.logger.error(f"保存群聊{chatroom_id}的成员详细信息失败: {e}")
self.LOG.error(f"保存群聊{chatroom_id}的成员详细信息失败: {e}")
return False
def process_chatroom_member_detail_response(self, chatroom_id: str, response: Dict) -> bool:
@@ -492,51 +536,95 @@ class ContactsDBOperator(BaseDBOperator):
"""
try:
if response.get('ret') != 200:
self.logger.error(f"获取群聊{chatroom_id}成员详情失败: {response.get('msg')}")
self.LOG.error(f"获取群聊{chatroom_id}成员详情失败: {response.get('msg')}")
return False
data = response.get('data', [])
if not data:
self.logger.warning(f"群聊{chatroom_id}成员详情数据为空")
self.LOG.warning(f"群聊{chatroom_id}成员详情数据为空")
return False
return self.save_chatroom_member_detail(chatroom_id, data)
except Exception as e:
self.logger.error(f"处理群聊{chatroom_id}成员详情数据失败: {e}")
self.LOG.error(f"处理群聊{chatroom_id}成员详情数据失败: {e}")
return False
def save_chatroom_info(self, chatroom_data: dict) -> bool:
"""保存群信息到数据库"""
try:
# 处理新的数据结构
user_name = ""
if isinstance(chatroom_data, dict):
if "UserName" in chatroom_data and isinstance(chatroom_data["UserName"], dict):
user_name = chatroom_data["UserName"].get("string", "")
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 = {
'chatroom_id': chatroom_data.get('chatroomId', ''),
'nick_name': chatroom_data.get('nickName', ''),
'py_initial': chatroom_data.get('pyInitial', ''),
'quan_pin': chatroom_data.get('quanPin', ''),
'sex': chatroom_data.get('sex', 0),
'remark': chatroom_data.get('remark', ''),
'remark_py_initial': chatroom_data.get('remarkPyInitial', ''),
'remark_quan_pin': chatroom_data.get('remarkQuanPin', ''),
'chat_room_notify': chatroom_data.get('chatRoomNotify', 0),
'chat_room_owner': chatroom_data.get('chatRoomOwner', ''),
'small_head_img_url': chatroom_data.get('smallHeadImgUrl', ''),
'member_list': json.dumps(chatroom_data.get('memberList', []))
'chatroom_id': user_name,
'nick_name': nick_name,
'py_initial': chatroom_data.get('Pyinitial', {}).get('string', ''),
'quan_pin': chatroom_data.get('QuanPin', {}).get('string', ''),
'sex': chatroom_data.get('Sex', 0),
'remark': chatroom_data.get('Remark', {}).get('string', ''),
'remark_py_initial': chatroom_data.get('RemarkPyinitial', {}).get('string', ''),
'remark_quan_pin': chatroom_data.get('RemarkQuanPin', {}).get('string', ''),
'chat_room_notify': chat_room_notify,
'chat_room_owner': chat_room_owner,
'small_head_img_url': small_head_img_url,
'member_list': json.dumps(member_list)
}
fields = ', '.join(data.keys())
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())
sql = f"""
INSERT INTO t_chatrooms ({fields})
VALUES ({placeholders})
ON DUPLICATE KEY UPDATE {update_clause}
"""
self.execute_update(sql, values)
self.logger.info(f"成功保存群聊 {data['chatroom_id']} 信息")
self.LOG.info(f"成功保存群聊 {data['chatroom_id']} 信息")
return True
except Exception as e:
self.logger.error(f"保存群聊信息失败: {e}")
self.LOG.error(f"保存群聊信息失败: {e}")
return False
def get_chatroom_info(self, chatroom_id: str) -> Optional[dict]:
@@ -548,7 +636,7 @@ class ContactsDBOperator(BaseDBOperator):
result['member_list'] = json.loads(result['member_list'])
return result
except Exception as e:
self.logger.error(f"获取群聊{chatroom_id}信息失败: {e}")
self.LOG.error(f"获取群聊{chatroom_id}信息失败: {e}")
return None
def update_chatroom_info(self, chatroom_id: str, update_data: dict) -> bool:
@@ -559,10 +647,10 @@ class ContactsDBOperator(BaseDBOperator):
values.append(chatroom_id)
sql = f"UPDATE t_chatrooms SET {set_clause} WHERE chatroom_id = %s"
self.execute_update(sql, tuple(values))
self.logger.info(f"成功更新群聊 {chatroom_id} 信息")
self.LOG.info(f"成功更新群聊 {chatroom_id} 信息")
return True
except Exception as e:
self.logger.error(f"更新群聊{chatroom_id}信息失败: {e}")
self.LOG.error(f"更新群聊{chatroom_id}信息失败: {e}")
return False
def delete_chatroom_info(self, chatroom_id: str) -> bool:
@@ -570,8 +658,8 @@ class ContactsDBOperator(BaseDBOperator):
try:
sql = "DELETE FROM t_chatrooms WHERE chatroom_id = %s"
self.execute_update(sql, (chatroom_id,))
self.logger.info(f"成功删除群聊 {chatroom_id} 信息")
self.LOG.info(f"成功删除群聊 {chatroom_id} 信息")
return True
except Exception as e:
self.logger.error(f"删除群聊{chatroom_id}信息失败: {e}")
self.LOG.error(f"删除群聊{chatroom_id}信息失败: {e}")
return False