855 协议版本-调整完毕内容
This commit is contained in:
23
db/base.py
23
db/base.py
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
from loguru import logger
|
||||
from typing import List, Dict, Any, Optional, Tuple, Union
|
||||
|
||||
from db.connection import DBConnectionManager
|
||||
@@ -7,12 +7,13 @@ from db.connection import DBConnectionManager
|
||||
|
||||
class BaseDBOperator:
|
||||
"""基础数据库操作类"""
|
||||
|
||||
|
||||
def __init__(self, db_manager: DBConnectionManager):
|
||||
self.db_manager = db_manager
|
||||
self.LOG = logging.getLogger(self.__class__.__name__)
|
||||
|
||||
def execute_query(self, sql: str, params: Optional[tuple] = None, fetch_one: bool = False) -> Union[List[Dict], Dict, None]:
|
||||
self.LOG = logger
|
||||
|
||||
def execute_query(self, sql: str, params: Optional[tuple] = None, fetch_one: bool = False) -> Union[
|
||||
List[Dict], Dict, None]:
|
||||
"""执行查询SQL"""
|
||||
conn = self.db_manager.get_mysql_connection()
|
||||
try:
|
||||
@@ -26,7 +27,7 @@ class BaseDBOperator:
|
||||
return None
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def execute_update(self, sql: str, params: Optional[tuple] = None) -> bool:
|
||||
"""执行更新SQL"""
|
||||
conn = self.db_manager.get_mysql_connection()
|
||||
@@ -41,12 +42,12 @@ class BaseDBOperator:
|
||||
return False
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def execute_batch(self, sql: str, params_list: List[tuple]) -> bool:
|
||||
"""批量执行SQL"""
|
||||
if not params_list:
|
||||
return True
|
||||
|
||||
|
||||
conn = self.db_manager.get_mysql_connection()
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
@@ -59,12 +60,12 @@ class BaseDBOperator:
|
||||
return False
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def execute_transaction(self, operations: List[Tuple[str, tuple]]) -> bool:
|
||||
"""执行事务"""
|
||||
if not operations:
|
||||
return True
|
||||
|
||||
|
||||
conn = self.db_manager.get_mysql_connection()
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
@@ -77,4 +78,4 @@ class BaseDBOperator:
|
||||
conn.rollback()
|
||||
return False
|
||||
finally:
|
||||
conn.close()
|
||||
conn.close()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import logging
|
||||
|
||||
from loguru import logger
|
||||
import mysql.connector
|
||||
import redis
|
||||
|
||||
@@ -35,7 +36,7 @@ class DBConnectionManager:
|
||||
mysql_config: MySQL配置
|
||||
redis_config: Redis配置
|
||||
"""
|
||||
self.logger = logging.getLogger("DBConnectionManager")
|
||||
self.LOG = logger
|
||||
self.mysql_pool = None
|
||||
self.redis_pool = None
|
||||
|
||||
@@ -55,7 +56,7 @@ class DBConnectionManager:
|
||||
"""
|
||||
try:
|
||||
if not config:
|
||||
self.logger.warning("MySQL配置为空,跳过初始化")
|
||||
self.LOG.warning("MySQL配置为空,跳过初始化")
|
||||
return
|
||||
|
||||
# 准备连接池配置
|
||||
@@ -74,9 +75,9 @@ class DBConnectionManager:
|
||||
|
||||
# 创建连接池
|
||||
self.mysql_pool = mysql.connector.pooling.MySQLConnectionPool(**pool_config)
|
||||
self.logger.info("MySQL连接池初始化成功")
|
||||
self.LOG.info("MySQL连接池初始化成功")
|
||||
except Exception as e:
|
||||
self.logger.error(f"MySQL连接池初始化失败: {e}")
|
||||
self.LOG.error(f"MySQL连接池初始化失败: {e}")
|
||||
self.mysql_pool = None
|
||||
|
||||
def init_redis_pool(self, config):
|
||||
@@ -87,7 +88,7 @@ class DBConnectionManager:
|
||||
"""
|
||||
try:
|
||||
if not config:
|
||||
self.logger.warning("Redis配置为空,跳过初始化")
|
||||
self.LOG.warning("Redis配置为空,跳过初始化")
|
||||
return
|
||||
|
||||
self.redis_pool = redis.ConnectionPool(
|
||||
@@ -98,9 +99,9 @@ class DBConnectionManager:
|
||||
decode_responses=config.get('decode_responses', True),
|
||||
max_connections=config.get('max_connections', 10)
|
||||
)
|
||||
self.logger.info("Redis连接池初始化成功")
|
||||
self.LOG.info("Redis连接池初始化成功")
|
||||
except Exception as e:
|
||||
self.logger.error(f"Redis连接池初始化失败: {e}")
|
||||
self.LOG.error(f"Redis连接池初始化失败: {e}")
|
||||
self.redis_pool = None
|
||||
|
||||
def get_mysql_connection(self):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import json
|
||||
import logging
|
||||
from loguru import logger
|
||||
from typing import Dict, Any, List, Optional
|
||||
|
||||
from db.connection import DBConnectionManager
|
||||
@@ -11,7 +11,7 @@ class GroupVirtualRedisDB:
|
||||
def __init__(self, db_manager: DBConnectionManager):
|
||||
self.db_manager = db_manager
|
||||
self.redis_client = db_manager.get_redis_connection()
|
||||
self.LOG = logging.getLogger("Plugin.GroupVirtual.Redis")
|
||||
self.LOG = logger
|
||||
self.chat_groups_key = "group_virtual:chat_groups"
|
||||
|
||||
def load_chat_groups(self) -> Dict[str, Any]:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from datetime import datetime
|
||||
import json
|
||||
import os
|
||||
import logging
|
||||
from loguru import logger
|
||||
from typing import Dict, Optional, List, Any, Set
|
||||
|
||||
from db.connection import DBConnectionManager
|
||||
@@ -14,14 +14,14 @@ class KidPhotoRedisDB:
|
||||
def __init__(self, db_manager: DBConnectionManager):
|
||||
self.db_manager = db_manager
|
||||
self.prefix = "group:kid_photo:"
|
||||
logger = logging.getLogger("DB.KidPhotoRedis")
|
||||
self.LOG = logger
|
||||
|
||||
def get_redis_connection(self):
|
||||
"""获取Redis连接"""
|
||||
try:
|
||||
return self.db_manager.get_redis_connection()
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取Redis连接失败: {e}")
|
||||
self.LOG.error(f"获取Redis连接失败: {e}")
|
||||
return None
|
||||
|
||||
def save_last_analysis_time(self, group_id: str) -> bool:
|
||||
@@ -34,7 +34,7 @@ class KidPhotoRedisDB:
|
||||
redis_client.set(f'{self.prefix}{group_id}:last_time', str(timestamp))
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"保存最后分析时间失败: {e}")
|
||||
self.LOG.error(f"保存最后分析时间失败: {e}")
|
||||
return False
|
||||
|
||||
def get_last_analysis_time(self, group_id: str) -> Optional[int]:
|
||||
@@ -50,7 +50,7 @@ class KidPhotoRedisDB:
|
||||
return int(timestamp)
|
||||
return None
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取最后分析时间失败: {e}")
|
||||
self.LOG.error(f"获取最后分析时间失败: {e}")
|
||||
return None
|
||||
|
||||
def save_analysis_result(self, group_id: str, result: Dict) -> bool:
|
||||
@@ -62,7 +62,7 @@ class KidPhotoRedisDB:
|
||||
redis_client.set(f'{self.prefix}{group_id}:results', json.dumps(result, ensure_ascii=False))
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"保存分析结果失败: {e}")
|
||||
self.LOG.error(f"保存分析结果失败: {e}")
|
||||
return False
|
||||
|
||||
def get_last_analysis_result(self, group_id: str) -> Optional[Dict]:
|
||||
@@ -78,10 +78,10 @@ class KidPhotoRedisDB:
|
||||
return json.loads(result)
|
||||
return None
|
||||
except json.JSONDecodeError as e:
|
||||
self.logger.error(f"解析分析结果JSON失败: {e}")
|
||||
self.LOG.error(f"解析分析结果JSON失败: {e}")
|
||||
return None
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取最后分析结果失败: {e}")
|
||||
self.LOG.error(f"获取最后分析结果失败: {e}")
|
||||
return None
|
||||
|
||||
def save_processed_photo(self, group_id: str, photo_path: str) -> bool:
|
||||
@@ -96,7 +96,7 @@ class KidPhotoRedisDB:
|
||||
redis_client.sadd(f'{self.prefix}{group_id}:processed_photos', photo_path)
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"保存已处理照片失败: {e}")
|
||||
self.LOG.error(f"保存已处理照片失败: {e}")
|
||||
return False
|
||||
|
||||
def save_processed_photos(self, group_id: str, photo_paths: List[str]) -> bool:
|
||||
@@ -128,7 +128,7 @@ class KidPhotoRedisDB:
|
||||
pipeline.execute()
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"批量保存已处理照片失败: {e}")
|
||||
self.LOG.error(f"批量保存已处理照片失败: {e}")
|
||||
return False
|
||||
|
||||
def get_processed_photos(self, group_id: str) -> Set[str]:
|
||||
@@ -146,7 +146,7 @@ class KidPhotoRedisDB:
|
||||
photos.add(path)
|
||||
return photos
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取已处理照片失败: {e}")
|
||||
self.LOG.error(f"获取已处理照片失败: {e}")
|
||||
return set()
|
||||
|
||||
def is_photo_processed(self, group_id: str, photo_path: str) -> bool:
|
||||
@@ -160,7 +160,7 @@ class KidPhotoRedisDB:
|
||||
return False
|
||||
return redis_client.sismember(f'{self.prefix}{group_id}:processed_photos', photo_path)
|
||||
except Exception as e:
|
||||
self.logger.error(f"检查照片是否已处理失败: {e}")
|
||||
self.LOG.error(f"检查照片是否已处理失败: {e}")
|
||||
return False
|
||||
|
||||
def save_photo_mapping(self, group_id: str, kid_id: str, photo_path: str) -> bool:
|
||||
@@ -183,7 +183,7 @@ class KidPhotoRedisDB:
|
||||
pipeline.execute()
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"保存照片映射关系失败: {e}")
|
||||
self.LOG.error(f"保存照片映射关系失败: {e}")
|
||||
return False
|
||||
|
||||
def get_kid_photos(self, group_id: str, kid_id: str) -> List[str]:
|
||||
@@ -204,7 +204,7 @@ class KidPhotoRedisDB:
|
||||
photos.append(path)
|
||||
return photos
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取小朋友照片失败: {e}")
|
||||
self.LOG.error(f"获取小朋友照片失败: {e}")
|
||||
return []
|
||||
|
||||
def get_photo_kid(self, group_id: str, photo_name: str) -> Optional[str]:
|
||||
@@ -222,7 +222,7 @@ class KidPhotoRedisDB:
|
||||
kid_id = kid_id.decode('utf-8')
|
||||
return kid_id
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取照片对应的小朋友ID失败: {e}")
|
||||
self.LOG.error(f"获取照片对应的小朋友ID失败: {e}")
|
||||
return None
|
||||
|
||||
def save_last_process_time(self, group_id: str) -> bool:
|
||||
@@ -235,7 +235,7 @@ class KidPhotoRedisDB:
|
||||
redis_client.set(f'{self.prefix}{group_id}:last_process_time', str(timestamp))
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"保存最后处理时间失败: {e}")
|
||||
self.LOG.error(f"保存最后处理时间失败: {e}")
|
||||
return False
|
||||
|
||||
def get_last_process_time(self, group_id: str) -> Optional[int]:
|
||||
@@ -252,7 +252,7 @@ class KidPhotoRedisDB:
|
||||
return int(timestamp)
|
||||
return None
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取最后处理时间失败: {e}")
|
||||
self.LOG.error(f"获取最后处理时间失败: {e}")
|
||||
return None
|
||||
|
||||
def clear_processed_photos(self, group_id: str) -> bool:
|
||||
@@ -264,7 +264,7 @@ class KidPhotoRedisDB:
|
||||
redis_client.delete(f'{self.prefix}{group_id}:processed_photos')
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"清理已处理照片记录失败: {e}")
|
||||
self.LOG.error(f"清理已处理照片记录失败: {e}")
|
||||
return False
|
||||
|
||||
def clear_analysis_data(self, group_id: str) -> bool:
|
||||
@@ -301,5 +301,5 @@ class KidPhotoRedisDB:
|
||||
pipeline.execute()
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"清理分析数据失败: {e}")
|
||||
self.LOG.error(f"清理分析数据失败: {e}")
|
||||
return False
|
||||
@@ -5,7 +5,7 @@ from typing import Dict, List, Optional
|
||||
|
||||
from db.base import BaseDBOperator
|
||||
from db.connection import DBConnectionManager
|
||||
from gewechat.call_back_message.message import WxMessage
|
||||
from wechat_ipad.models.message import WxMessage
|
||||
|
||||
|
||||
class MessageStorageDB(BaseDBOperator):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"""
|
||||
积分系统数据库操作类
|
||||
"""
|
||||
import logging
|
||||
from loguru import logger
|
||||
from datetime import datetime, timedelta
|
||||
from enum import Enum
|
||||
from typing import Dict, List, Optional, Tuple, Any
|
||||
@@ -27,7 +27,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
def __init__(self, db_manager=None):
|
||||
"""初始化积分数据库操作类"""
|
||||
super().__init__(db_manager or DBConnectionManager.get_instance())
|
||||
self.logger = logging.getLogger("PointsDBOperator")
|
||||
self.LOG = logger
|
||||
|
||||
# 确保数据库表存在,后续不需要处理了。
|
||||
# self._ensure_tables_exist()
|
||||
@@ -93,9 +93,9 @@ class PointsDBOperator(BaseDBOperator):
|
||||
) ENGINE=InnoDB CHARACTER SET utf8mb4;
|
||||
""")
|
||||
|
||||
self.logger.info("积分系统数据库表检查/创建完成")
|
||||
self.LOG.info("积分系统数据库表检查/创建完成")
|
||||
except Exception as e:
|
||||
self.logger.error(f"创建积分系统数据库表失败: {e}")
|
||||
self.LOG.error(f"创建积分系统数据库表失败: {e}")
|
||||
raise
|
||||
|
||||
def get_user_points(self, user_id: str, group_id: str) -> Dict:
|
||||
@@ -122,7 +122,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
# 如果新表没有数据,尝试从旧表迁移数据
|
||||
return self._migrate_user_points(user_id, group_id)
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取用户积分失败: {e}")
|
||||
self.LOG.error(f"获取用户积分失败: {e}")
|
||||
return {
|
||||
"user_id": user_id,
|
||||
"group_id": group_id,
|
||||
@@ -188,7 +188,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
WHERE user_id = %s AND group_id = %s
|
||||
""", (user_id, group_id), fetch_one=True) or result
|
||||
except Exception as e:
|
||||
self.logger.error(f"迁移用户积分失败: {e}")
|
||||
self.LOG.error(f"迁移用户积分失败: {e}")
|
||||
return result
|
||||
|
||||
def add_points(self, user_id: str, group_id: str, points: int,
|
||||
@@ -261,7 +261,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
|
||||
return True, updated_points
|
||||
except Exception as e:
|
||||
self.logger.error(f"增加用户积分失败: {e}")
|
||||
self.LOG.error(f"增加用户积分失败: {e}")
|
||||
return False, {"error": str(e)}
|
||||
|
||||
def deduct_points(self, user_id: str, group_id: str, points: int,
|
||||
@@ -318,7 +318,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
|
||||
return True, updated_points
|
||||
except Exception as e:
|
||||
self.logger.error(f"扣除用户积分失败: {e}")
|
||||
self.LOG.error(f"扣除用户积分失败: {e}")
|
||||
return False, {"error": str(e)}
|
||||
|
||||
def transfer_points(self, from_user_id: str, to_user_id: str, group_id: str,
|
||||
@@ -368,7 +368,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
"to_user": to_result
|
||||
}
|
||||
except Exception as e:
|
||||
self.logger.error(f"转移用户积分失败: {e}")
|
||||
self.LOG.error(f"转移用户积分失败: {e}")
|
||||
return False, {"error": str(e)}
|
||||
|
||||
def get_user_transactions(self, user_id: str, group_id: str, limit: int = 10) -> List[Dict]:
|
||||
@@ -391,7 +391,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
LIMIT %s
|
||||
""", (user_id, group_id, limit))
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取用户交易记录失败: {e}")
|
||||
self.LOG.error(f"获取用户交易记录失败: {e}")
|
||||
return []
|
||||
|
||||
def get_points_ranking(self, group_id: str, limit: int = 10) -> List[Dict]:
|
||||
@@ -414,7 +414,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
LIMIT %s
|
||||
""", (group_id, limit))
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取积分排行榜失败: {e}")
|
||||
self.LOG.error(f"获取积分排行榜失败: {e}")
|
||||
return []
|
||||
|
||||
def get_plugin_config(self, plugin_name: str) -> Optional[Dict]:
|
||||
@@ -433,7 +433,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
WHERE plugin_name = %s
|
||||
""", (plugin_name,), fetch_one=True)
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取插件积分配置失败: {e}")
|
||||
self.LOG.error(f"获取插件积分配置失败: {e}")
|
||||
return None
|
||||
|
||||
def set_plugin_config(self, plugin_name: str, points_required: int,
|
||||
@@ -462,7 +462,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
""", (plugin_name, points_required, is_enabled, description))
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"设置插件积分配置失败: {e}")
|
||||
self.LOG.error(f"设置插件积分配置失败: {e}")
|
||||
return False
|
||||
|
||||
def get_all_plugin_configs(self) -> List[Dict]:
|
||||
@@ -475,7 +475,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
try:
|
||||
return self.execute_query("SELECT * FROM t_plugin_point_config")
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取所有插件积分配置失败: {e}")
|
||||
self.LOG.error(f"获取所有插件积分配置失败: {e}")
|
||||
return []
|
||||
|
||||
def check_plugin_points(self, user_id: str, group_id: str, plugin_name: str) -> Tuple[bool, Dict]:
|
||||
@@ -515,7 +515,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
"required_points": plugin_config["points_required"]
|
||||
}
|
||||
except Exception as e:
|
||||
self.logger.error(f"检查插件积分失败: {e}")
|
||||
self.LOG.error(f"检查插件积分失败: {e}")
|
||||
return True, {"error": str(e)} # 出错时默认允许使用
|
||||
|
||||
def use_plugin(self, user_id: str, group_id: str, plugin_name: str) -> Tuple[bool, Dict]:
|
||||
@@ -547,7 +547,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
PointSource.PLUGIN, f"使用插件: {plugin_name}"
|
||||
)
|
||||
except Exception as e:
|
||||
self.logger.error(f"使用插件扣除积分失败: {e}")
|
||||
self.LOG.error(f"使用插件扣除积分失败: {e}")
|
||||
return False, {"error": str(e)}
|
||||
|
||||
def get_user_points_stats(self, group_id: str) -> Dict[str, Any]:
|
||||
@@ -591,7 +591,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
|
||||
return stats
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取群组积分统计信息失败: {e}")
|
||||
self.LOG.error(f"获取群组积分统计信息失败: {e}")
|
||||
return stats
|
||||
|
||||
def imprison_user(self, user_id: str, group_id: str, hours: int = 24, reason: str = None) -> bool:
|
||||
@@ -612,7 +612,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
""", (user_id, group_id, end_time, reason, end_time, reason))
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"关押用户失败: {e}")
|
||||
self.LOG.error(f"关押用户失败: {e}")
|
||||
return False
|
||||
|
||||
def check_prison_status(self, user_id: str, group_id: str) -> Optional[Dict]:
|
||||
@@ -630,7 +630,7 @@ class PointsDBOperator(BaseDBOperator):
|
||||
""", (user_id, group_id))
|
||||
return records[0] if records else None
|
||||
except Exception as e:
|
||||
self.logger.error(f"检查用户在押状态失败: {e}")
|
||||
self.LOG.error(f"检查用户在押状态失败: {e}")
|
||||
return None
|
||||
|
||||
def bailout_user(self, prisoner_id: str, bailout_user_id: str, group_id: str) -> Tuple[bool, str]:
|
||||
@@ -660,5 +660,5 @@ class PointsDBOperator(BaseDBOperator):
|
||||
|
||||
return True, "保释成功"
|
||||
except Exception as e:
|
||||
self.logger.error(f"保释用户失败: {e}")
|
||||
self.LOG.error(f"保释用户失败: {e}")
|
||||
return False, f"保释失败: {str(e)}"
|
||||
Reference in New Issue
Block a user