feat: 优化整体项目

This commit is contained in:
2025-12-05 18:06:13 +08:00
parent b4df26f61d
commit 7d3ef70093
13 changed files with 2661 additions and 305 deletions

View File

@@ -18,6 +18,7 @@ from utils.decorators import (
on_file_message,
on_emoji_message
)
from utils.redis_cache import RedisCache, get_cache
import pymysql
from WechatHook import WechatHookClient
from minio import Minio
@@ -39,6 +40,7 @@ class MessageLogger(PluginBase):
super().__init__()
self.config = None
self.db_config = None
self.redis_cache = None # Redis 缓存实例
# 创建独立的日志记录器
self._setup_logger()
@@ -83,9 +85,22 @@ class MessageLogger(PluginBase):
self.db_config = self.config["database"]
# 初始化 Redis 缓存
redis_config = self.config.get("redis", {})
if redis_config.get("enabled", False):
self.log.info("正在初始化 Redis 缓存...")
self.redis_cache = RedisCache(redis_config)
if self.redis_cache.enabled:
self.log.success(f"Redis 缓存初始化成功TTL={redis_config.get('ttl', 3600)}")
else:
self.log.warning("Redis 缓存初始化失败,将不使用缓存")
self.redis_cache = None
else:
self.log.info("Redis 缓存未启用")
# 初始化 MinIO 客户端
self.minio_client = Minio(
"101.201.65.129:19000",
"115.190.113.141:19000",
access_key="admin",
secret_key="80012029Lz",
secure=False
@@ -216,7 +231,7 @@ class MessageLogger(PluginBase):
return ("", "", "", "", "0")
async def download_image_and_upload(self, bot, cdnurl: str, aeskey: str) -> str:
"""下载图片并上传到 MinIO"""
"""下载图片并上传到 MinIO,同时缓存 base64 供其他插件使用"""
try:
temp_file = Path(__file__).parent / f"temp_{uuid.uuid4().hex}.jpg"
success = await bot.cdn_download(cdnurl, aeskey, str(temp_file), file_type=2)
@@ -225,12 +240,26 @@ class MessageLogger(PluginBase):
# 等待文件下载完成
import asyncio
import base64
for _ in range(50):
if temp_file.exists() and temp_file.stat().st_size > 0:
break
await asyncio.sleep(0.1)
if temp_file.exists() and temp_file.stat().st_size > 0:
# 读取文件并缓存 base64供 AIChat 等插件使用)
with open(temp_file, "rb") as f:
image_data = f.read()
base64_data = f"data:image/jpeg;base64,{base64.b64encode(image_data).decode()}"
# 缓存到 Redis5分钟过期
redis_cache = get_cache()
if redis_cache and redis_cache.enabled:
media_key = RedisCache.generate_media_key(cdnurl, aeskey)
if media_key:
redis_cache.cache_media(media_key, base64_data, "image", ttl=300)
self.log.debug(f"图片已缓存到 Redis: {media_key[:20]}...")
media_url = await self.upload_file_to_minio(str(temp_file), "images")
temp_file.unlink()
return media_url
@@ -326,13 +355,25 @@ class MessageLogger(PluginBase):
return ""
async def download_and_upload(self, url: str, file_type: str, ext: str) -> str:
"""下载文件并上传到 MinIO"""
"""下载文件并上传到 MinIO,同时缓存 base64 供其他插件使用"""
try:
import base64
# 下载文件
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
if resp.status == 200:
data = await resp.read()
# 缓存表情包 base64供 AIChat 等插件使用)
if file_type == "emojis" and data:
redis_cache = get_cache()
if redis_cache and redis_cache.enabled:
base64_data = f"data:image/gif;base64,{base64.b64encode(data).decode()}"
media_key = RedisCache.generate_media_key(cdnurl=url)
if media_key:
redis_cache.cache_media(media_key, base64_data, "emoji", ttl=300)
self.log.debug(f"表情包已缓存到 Redis: {media_key[:20]}...")
# 保存到临时文件
temp_file = Path(__file__).parent / f"temp_{uuid.uuid4().hex}{ext}"
temp_file.write_bytes(data)
@@ -374,7 +415,7 @@ class MessageLogger(PluginBase):
)
# 返回访问 URL
url = f"http://101.201.65.129:19000/{self.minio_bucket}/{object_name}"
url = f"http://115.190.113.141:19000/{self.minio_bucket}/{object_name}"
self.log.debug(f"文件上传成功: {url}")
return url
@@ -405,29 +446,45 @@ class MessageLogger(PluginBase):
avatar_url = ""
if is_group and self.config["behavior"]["fetch_avatar"]:
try:
self.log.info(f"尝试获取用户信息: from_wxid={from_wxid}, sender_wxid={sender_wxid}")
user_info = await bot.get_user_info_in_chatroom(from_wxid, sender_wxid)
self.log.info(f"获取到用户信息: {user_info}")
cache_hit = False
if user_info:
# 处理不同的数据结构
if isinstance(user_info.get("nickName"), dict):
nickname = user_info.get("nickName", {}).get("string", "")
# 1. 先尝试从 Redis 缓存获取
if self.redis_cache and self.redis_cache.enabled:
cached_info = self.redis_cache.get_user_basic_info(from_wxid, sender_wxid)
if cached_info:
nickname = cached_info.get("nickname", "")
avatar_url = cached_info.get("avatar_url", "")
if nickname and avatar_url:
cache_hit = True
self.log.debug(f"[缓存命中] {sender_wxid}: {nickname}")
# 2. 缓存未命中,调用 API 获取
if not cache_hit:
try:
self.log.info(f"[缓存未命中] 调用API获取用户信息: {sender_wxid}")
user_info = await bot.get_user_info_in_chatroom(from_wxid, sender_wxid)
if user_info:
# 处理不同的数据结构
if isinstance(user_info.get("nickName"), dict):
nickname = user_info.get("nickName", {}).get("string", "")
else:
nickname = user_info.get("nickName", "")
avatar_url = user_info.get("bigHeadImgUrl", "")
self.log.info(f"API获取成功: nickname={nickname}, avatar_url={avatar_url[:50] if avatar_url else ''}...")
# 3. 将用户信息存入 Redis 缓存
if self.redis_cache and self.redis_cache.enabled and nickname:
self.redis_cache.set_user_info(from_wxid, sender_wxid, user_info)
self.log.debug(f"[已缓存] {sender_wxid}: {nickname}")
else:
nickname = user_info.get("nickName", "")
self.log.warning(f"用户信息为空: {sender_wxid}")
avatar_url = user_info.get("bigHeadImgUrl", "")
self.log.info(f"解析用户信息: nickname={nickname}, avatar_url={avatar_url[:50]}...")
else:
self.log.warning(f"用户信息为空: {sender_wxid}")
except Exception as e:
self.log.error(f"获取用户信息失败: {e}")
except Exception as e:
self.log.error(f"获取用户信息失败: {e}")
import traceback
self.log.error(f"详细错误: {traceback.format_exc()}")
# 如果获取失败,从历史记录中查找
# 4. 如果仍然没有获取到,从历史记录中查找
if not nickname or not avatar_url:
self.log.info(f"尝试从历史记录获取用户信息: {sender_wxid}")
try: