feat(help): 重构帮助系统为图片渲染模式

添加浏览器管理器和图片管理器,用于通过 Playwright 渲染帮助菜单为图片
重构命令管理器以支持图片缓存和同步功能
添加 HTML 模板用于帮助菜单渲染
This commit is contained in:
2026-01-11 21:10:42 +08:00
parent 862ed0d581
commit de1f2e5119
8 changed files with 403 additions and 7 deletions

View File

@@ -7,12 +7,16 @@
"""
from typing import Any, Callable, Dict, Optional, Tuple
import os
import base64
from models.events.message import MessageSegment
from ..config_loader import global_config
from ..handlers.event_handler import MessageHandler, NoticeHandler, RequestHandler
from .help_pic import help_pic
from .redis_manager import redis_manager
from .image_manager import image_manager
from ..utils.logger import logger
# 从配置中获取命令前缀
_config_prefixes = global_config.bot.command
@@ -59,6 +63,40 @@ class CommandManager:
# 注册内置的 /help 命令
self._register_internal_commands()
async def sync_help_pic(self):
"""
启动时或插件重载时同步 help 图片到 Redis
"""
try:
logger.info("正在生成帮助图片...")
# 1. 收集插件数据
plugins_data = []
for plugin_name, meta in self.plugins.items():
plugins_data.append({
"name": meta.get("name", plugin_name),
"description": meta.get("description", "暂无描述"),
"usage": meta.get("usage", "暂无用法")
})
# 2. 渲染图片
# 使用 png 格式以获得更好的文字清晰度
base64_str = await image_manager.render_template_to_base64(
template_name="help.html",
data={"plugins": plugins_data},
output_name="help_menu.png",
image_type="png"
)
if base64_str:
await redis_manager.set("neobot:core:help_pic", base64_str)
logger.success("帮助图片已更新并缓存到 Redis")
else:
logger.error("帮助图片生成失败")
except Exception as e:
logger.error(f"同步帮助图片失败: {e}")
def _register_internal_commands(self):
"""
注册框架内置的命令
@@ -160,9 +198,22 @@ class CommandManager:
async def _help_command(self, bot, event):
"""
内置的 `/help` 命令的实现。
直接从 Redis 获取缓存的图片。
"""
help_text = "--- 可用指令列表 ---\n"
# 1. 尝试从 Redis 获取
help_pic = await redis_manager.get("neobot:core:help_pic")
if not help_pic:
await bot.send(event, "帮助图片缓存缺失,正在重新生成...")
await self.sync_help_pic()
help_pic = await redis_manager.get("neobot:core:help_pic")
if help_pic:
await bot.send(event, MessageSegment.image(help_pic))
return
# 2. 最后的兜底:发送纯文本
help_text = "--- 可用指令列表 ---\n"
for plugin_name, meta in self.plugins.items():
name = meta.get("name", "未命名插件")
description = meta.get("description", "暂无描述")
@@ -171,9 +222,8 @@ class CommandManager:
help_text += f"\n{name}:\n"
help_text += f" 功能: {description}\n"
help_text += f" 用法: {usage}\n"
await bot.send(event, MessageSegment.image(help_pic))
# await bot.send(event, help_text.strip())
await bot.send(event, help_text.strip())
# 实例化全局唯一的命令管理器