- Global connection badge in app header (persistent dashboard SSE via ConnectionProvider) - LogProvider keeps log data and SSE stream alive across page switches (no reload spinner) - Config drawer: password reveal toggle, array-type row editor for list fields - Plugin management: optimistic updates, race-free loading, reset all group overrides - Logs: load-earlier pagination; backend tail-read optimization (before/end offsets) - web_auth: Web password changes persist (sync_admin seeding only when .env has explicit key) - Dashboard: collect in thread pool + 1s result cache - ErrorBoundary + local Suspense: plugin chunk loading stays inside content area - UI polish: table row hover, mobile header/breadcrumb fixes, wider config drawer - config_standard: array type inference for list fields; array env skip - random_jm_code / steam_info: array schema migration; README web frontend note Co-Authored-By: Claude Code <noreply@anthropic.com>
43 lines
2.7 KiB
Markdown
43 lines
2.7 KiB
Markdown
# 插件模板(MTSS 结构)
|
||
|
||
按《插件结构标准 + 插件配置文件标准》编写的可复制插件骨架,含配置标准 + Web 子应用样例。
|
||
|
||
## 结构(MTSS)
|
||
|
||
```text
|
||
nonebot_plugin_template/
|
||
├── __init__.py # 入口(薄): require + meta + 导入 + config.register_config() + register_web_plugin
|
||
├── config.py # 配置注册(register_model_config / register_config_items / register_object_set)
|
||
├── handlers/ # Trigger 层
|
||
│ ├── __init__.py
|
||
│ └── entry.py # on_command 示例
|
||
├── services/ # Service 层(不 import nonebot)
|
||
│ └── main.py
|
||
├── models.py # 模型/异常
|
||
├── repository.py # Model 数据访问(唯一读写入口)
|
||
├── web/ # 可选: 插件自带 Web 子应用(FastAPI)
|
||
│ ├── __init__.py
|
||
│ └── admin.py # build_admin_app() → 挂载到 /api/template
|
||
├── data/ # 运行时数据
|
||
└── utils/ # 纯工具
|
||
```
|
||
|
||
## 使用
|
||
1. 把 `nonebot_plugin_template` 目录复制到 `hexi/plugins/nonebot_plugin_<name>`。
|
||
2. 全局搜索替换 `nonebot_plugin_template` → `nonebot_plugin_<name>`,包括 `_PLUGIN_ID` 相关说明。
|
||
3. 在 `__init__.py` 改 `__plugin_meta__` 的 name/description/usage,并把 `register_web_plugin("template", ...)` 的 id/name/icon 改掉;Web id 只能使用安全的短标识,不要直接使用带点的模块名。
|
||
4. 在 `config.py` 改成你要的配置项;在 `handlers/entry.py` 改成你的命令/触发。
|
||
5. 重启 bot;/hub 插件页能看到配置,点「打开 Web 页面」进入 `/hub/template`(子应用挂在 `/api/template`)。
|
||
|
||
## Web 子应用
|
||
- `web/admin.py::build_admin_app()` 返回一个 FastAPI 实例,经 `register_web_plugin` 由 hub 挂载到 `/api/template`。
|
||
- 鉴权统一 `hexi.web_auth.require_admin`;示例端点:`GET /ping`、`GET /config`(读插件配置)。
|
||
- 想要更丰富的管理页:前端放 `web/dist/`,在 admin.py 里挂 `StaticFiles` + SPA 兜底即可(参考 `nonebot_plugin_web_hub`)。
|
||
|
||
## 约定
|
||
- `plugin_id` = 模块名(自动取 `__package__`;web 子应用用 `__package__.rsplit(".", 1)[0]`)。
|
||
- Trigger/View 可 import nonebot;Service/Model/repository 尽量不 import nonebot。
|
||
- 配置默认值写进 schema,Web 自动回填;敏感字段 `secret=True`。GET 只显示 `****`;保存配置时带上 GET 返回的 `revision`,修改冲突会返回 409。
|
||
- 同一 `plugin_id` 多次注册会自动合并(getter/apply 组合),但字段 key 应由单一注册者负责,避免定义冲突。
|
||
- Service 中的文件/数据库访问应使用异步 repository 或 `asyncio.to_thread`,不要阻塞事件循环。
|