✨ feat(group-settings): 实现群插件配置管理系统

- 引入 GroupSettingsService 服务,提供统一的群插件配置管理接口
- 新增 GroupPluginSetting 模型,用于持久化存储插件在不同群组的配置
- 插件扩展数据 PluginExtraData 增加 group_config_model 字段,用于注册分群配置模型
- 新增 GetGroupConfig 依赖注入,允许插件轻松获取和解析当前群组的配置

【核心服务 GroupSettingsService】
- 支持按群组、插件名和键设置、获取和删除配置项
- 实现配置聚合缓存机制,提升配置读取效率,减少数据库查询
- 支持配置继承与覆盖逻辑(群配置覆盖全局默认值)
- 提供批量设置功能 set_bulk,方便为多个群组同时更新配置

【管理与缓存】
- 新增超级用户命令 pconf (plugin_config_manager),用于命令行管理插件的分群和全局配置
- 新增 CacheType.GROUP_PLUGIN_SETTINGS 缓存类型并注册
- 增加 Pydantic model_construct 兼容函数
This commit is contained in:
webjoin111
2025-11-15 21:13:14 +08:00
parent c839b44256
commit b29c8b0695
9 changed files with 890 additions and 0 deletions
+30
View File
@@ -1,6 +1,7 @@
from typing import Any, Literal
from nonebot.adapters import Bot, Event
from nonebot.exception import SkippedException
from nonebot.internal.params import Depends
from nonebot.matcher import Matcher
from nonebot.params import Command
@@ -9,6 +10,7 @@ from nonebot_plugin_session import EventSession
from nonebot_plugin_uninfo import Uninfo
from zhenxun.configs.config import Config
from zhenxun.services import group_settings_service
from zhenxun.utils.limiters import ConcurrencyLimiter, FreqLimiter, RateLimiter
from zhenxun.utils.message import MessageUtils
from zhenxun.utils.time_utils import TimeUtils
@@ -249,6 +251,34 @@ def GetConfig(
return Depends(dependency)
def GetGroupConfig(model: type[Any]):
"""
依赖注入函数,用于获取并解析插件的分群配置。
"""
async def dependency(matcher: Matcher, session: EventSession):
"""
实际的依赖注入逻辑。
"""
plugin_name = matcher.plugin_name
group_id = session.id3 or session.id2
if not plugin_name:
raise SkippedException("无法确定插件名称以获取配置")
if not group_id:
try:
return model()
except Exception:
raise SkippedException("在私聊中无法获取分群配置")
return await group_settings_service.get_all_for_plugin(
group_id, plugin_name, parse_model=model
)
return Depends(dependency)
def CheckConfig(
module: str | None = None,
config: str | list[str] = "",
+2
View File
@@ -53,6 +53,8 @@ class CacheType(StrEnum):
"""全局全部插件"""
GROUPS = "GLOBAL_ALL_GROUPS"
"""全局全部群组"""
GROUP_PLUGIN_SETTINGS = "GROUP_PLUGIN_SETTINGS"
"""插件分群配置"""
USERS = "GLOBAL_ALL_USERS"
"""全部用户"""
BAN = "GLOBAL_ALL_BAN"
+11
View File
@@ -24,6 +24,7 @@ __all__ = [
"_is_pydantic_type",
"compat_computed_field",
"dump_json_safely",
"model_construct",
"model_copy",
"model_dump",
"model_json_schema",
@@ -45,6 +46,16 @@ def model_copy(
return model.copy(update=update_dict, deep=deep)
def model_construct(model_class: type[T], **kwargs: Any) -> T:
"""
Pydantic `model_construct` (v2) 与 `construct` (v1) 的兼容函数。
"""
if PYDANTIC_V2:
return model_class.model_construct(**kwargs)
else:
return model_class.construct(**kwargs)
def model_validate(model_class: type[T], obj: Any) -> T:
"""
Pydantic `model_validate` (v2) 与 `parse_obj` (v1) 的兼容函数。