✨ 添加bot画像

* ✨ 新增自我介绍功能及自动发送图片支持

- 在 bot_profile.py 中实现自我介绍指令及重载功能
- 在 group_handle 中添加自动发送自我介绍图片的逻辑
- 在 fg_request 中实现添加好友时自动发送自我介绍图片
- 新增 bot_profile_manager.py 管理 BOT 自我介绍及图片生成
- 更新 models.py 以支持插件自我介绍和注意事项字段

* 🎨 调整管理帮助宽度

* ✨ 更新数据访问层,优化获取数据的方法并引入缓存机制

* ✨ 更新用户数据访问逻辑,优化获取用户信息的方法,使用新的函数替代原有实现

* ✨ 在 BotProfileManager 中添加自我介绍文件不存在的日志记录,优化文件读取逻辑

* ✨ 更新 BOT 自我介绍帮助信息,增加文件不存在时自动创建功能
This commit is contained in:
HibiKier
2025-07-16 02:51:06 +08:00
committed by GitHub
parent b993450a23
commit 205f4ff1fa
12 changed files with 372 additions and 87 deletions
@@ -25,6 +25,11 @@ __plugin_meta__ = PluginMetadata(
version="0.1",
plugin_type=PluginType.ADMIN,
admin_level=1,
introduction="""这是 群主/群管理 的帮助列表,里面记录了群组内开关功能的
方法帮助以及群管特权方法,建议首次时在群组中发送 '管理员帮助' 查看""",
precautions=[
"只有群主/群管理 才能使用哦,群主拥有6级权限,管理员拥有5级权限!"
],
configs=[
RegisterConfig(
key="type",
@@ -16,7 +16,8 @@ async def get_task() -> dict[str, str] | None:
"name": "被动技能",
"description": "控制群组中的被动技能状态",
"usage": "通过 开启/关闭群被动 来控制群被动 <br>"
+ " 示例:开启/关闭群被动早晚安 <br> ---------- <br> "
+ " 示例:开启/关闭群被动早晚安 <br> 示例:开启/关闭全部群被动"
+ " <br> ---------- <br> "
+ "<br>".join([task.name for task in task_list]),
}
return None
@@ -47,7 +48,7 @@ async def build_html_help():
}
},
pages={
"viewport": {"width": 1024, "height": 1024},
"viewport": {"width": 824, "height": 10},
"base_url": f"file://{TEMPLATE_PATH}",
},
wait=2,
+58
View File
@@ -0,0 +1,58 @@
from nonebot.permission import SUPERUSER
from nonebot.plugin import PluginMetadata
from nonebot.rule import to_me
from nonebot_plugin_alconna import Alconna, Arparma, on_alconna
from nonebot_plugin_uninfo import Uninfo
from zhenxun.configs.config import BotConfig
from zhenxun.configs.utils import PluginExtraData
from zhenxun.services.log import logger
from zhenxun.utils.manager.bot_profile_manager import BotProfileManager
from zhenxun.utils.message import MessageUtils
__plugin_meta__ = PluginMetadata(
name="自我介绍",
description=f"这是{BotConfig.self_nickname}的深情告白",
usage="""
指令:
自我介绍
""".strip(),
extra=PluginExtraData(
author="HibiKier",
version="0.1",
menu_type="其他",
superuser_help="""
在data/bot_profile/bot_id/profile.txt 中编辑BOT自我介绍
在data/bot_profile/bot_id/bot_id.png 中编辑BOT头像
指令:
重载自我介绍
""".strip(),
).to_dict(),
)
_matcher = on_alconna(Alconna("自我介绍"), priority=5, block=True, rule=to_me())
_reload_matcher = on_alconna(
Alconna("重载自我介绍"), priority=1, block=True, permission=SUPERUSER
)
@_matcher.handle()
async def _(session: Uninfo, arparma: Arparma):
file_path = await BotProfileManager.build_bot_profile_image(session.self_id)
if not file_path:
await MessageUtils.build_message(
f"{BotConfig.self_nickname}当前没有自我简介哦"
).finish(reply_to=True)
await MessageUtils.build_message(file_path).send()
logger.info("BOT自我介绍", arparma.header_result, session=session)
@_reload_matcher.handle()
async def _(session: Uninfo, arparma: Arparma):
BotProfileManager.clear_profile_image(session.self_id)
await MessageUtils.build_message(f"重载{BotConfig.self_nickname}自我介绍成功").send(
reply_to=True
)
logger.info("重载BOT自我介绍", arparma.header_result, session=session)
@@ -131,7 +131,9 @@ async def get_plugin_and_user(
# 并行查询插件和用户数据
plugin_task = plugin_dao.safe_get_or_none(module=module)
user_task = user_dao.safe_get_or_none(user_id=user_id)
user_task = user_dao.get_by_func_or_none(
UserConsole.get_user, False, user_id=user_id
)
try:
plugin, user = await with_timeout(
@@ -155,7 +157,9 @@ async def get_plugin_and_user(
)
user = None
try:
user = await user_dao.safe_get_or_none(user_id=user_id)
user = await user_dao.get_by_func_or_none(
UserConsole.get_user, False, user_id=user_id
)
except IntegrityError as e:
raise PermissionExemption("重复创建用户,已跳过该次权限检查...") from e
if not user:
@@ -10,7 +10,7 @@ from nonebot_plugin_uninfo import Uninfo
import ujson as json
from zhenxun.builtin_plugins.platform.qq.exception import ForceAddGroupError
from zhenxun.configs.config import Config
from zhenxun.configs.config import BotConfig, Config
from zhenxun.configs.path_config import DATA_PATH, IMAGE_PATH
from zhenxun.models.fg_request import FgRequest
from zhenxun.models.group_console import GroupConsole
@@ -20,6 +20,7 @@ from zhenxun.models.plugin_info import PluginInfo
from zhenxun.services.log import logger
from zhenxun.utils.common_utils import CommonUtils
from zhenxun.utils.enum import RequestHandleType
from zhenxun.utils.manager.bot_profile_manager import BotProfileManager
from zhenxun.utils.message import MessageUtils
from zhenxun.utils.platform import PlatformUtils
from zhenxun.utils.utils import FreqLimiter
@@ -153,6 +154,17 @@ class GroupManager:
await cls.__handle_add_group(bot, group_id, group)
"""刷新群管理员权限"""
await cls.__refresh_level(bot, group_id)
if BotProfileManager.is_auto_send_profile():
file_path = await BotProfileManager.build_bot_profile_image(bot.self_id)
if file_path:
await MessageUtils.build_message(
[
f"嗨,大家好,我是{BotConfig.self_nickname}, "
"希望我们可以友好相处(眨眼眨眼)!",
file_path,
]
).send()
logger.info("加入群组自动发送BOT自我介绍图片", session=group_id)
@classmethod
def get_path(cls, session: Uninfo) -> Path | None:
@@ -344,6 +344,16 @@ class ShopManage:
if goods_name.isdigit():
try:
user = await UserConsole.get_user(user_id=session.user.id)
goods_list = await GoodsInfo.filter(uuid__in=user.props.keys()).all()
goods_by_uuid = {item.uuid: item for item in goods_list}
props_str = str(user.props)
user.props = {
uuid: count
for uuid, count in user.props.items()
if count > 0 and goods_by_uuid.get(uuid)
}
if props_str != str(user.props):
await user.save(update_fields=["props"])
uuid = list(user.props.keys())[int(goods_name)]
goods_info = await GoodsInfo.get_or_none(uuid=uuid)
except IndexError:
@@ -501,11 +511,14 @@ class ShopManage:
goods_list = await GoodsInfo.filter(uuid__in=user.props.keys()).all()
goods_by_uuid = {item.uuid: item for item in goods_list}
props_str = str(user.props)
user.props = {
uuid: count
for uuid, count in user.props.items()
if count > 0 and goods_by_uuid.get(uuid)
}
if props_str != str(user.props):
await user.save(update_fields=["props"])
table_rows = []
for i, prop_uuid in enumerate(user.props):
@@ -163,15 +163,20 @@ async def _(
req = await FgRequest.ignore(handle_id)
except NotFoundError:
await MessageUtils.build_message("未发现此id的请求...").finish(reply_to=True)
except Exception:
await MessageUtils.build_message("其他错误, 可能flag已失效...").finish(
except Exception as e:
logger.error(f"处理请求失败 ID: {handle_id}", session=session, e=e)
await MessageUtils.build_message(f"其他错误, 可能flag已失效...: {e}").finish(
reply_to=True
)
logger.info(
f"处理请求 Id: {req.id if req else ''}", arparma.header_result, session=session
)
await MessageUtils.build_message("成功处理请求!").send(reply_to=True)
if req and handle_type == RequestHandleType.APPROVE:
if (
req
and req.request_type == RequestType.GROUP
and handle_type == RequestHandleType.APPROVE
):
await bot.send_private_msg(
user_id=req.user_id,
message=f"管理员已同意此次群组邀请,请不要让{BotConfig.self_nickname}受委屈哦(狠狠监控)"
@@ -51,7 +51,7 @@ async def build_html_help():
}
},
pages={
"viewport": {"width": 1024, "height": 1024},
"viewport": {"width": 824, "height": 10},
"base_url": f"file://{TEMPLATE_PATH}",
},
wait=2,