feat: revamp web hub — global connection status, array config editor, log streaming

- 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>
This commit is contained in:
2026-09-03 15:39:10 +08:00
co-authored by Claude Code
parent 9371a28e35
commit c53b210413
45 changed files with 1312 additions and 576 deletions
@@ -0,0 +1,38 @@
"""<插件名> — MTSS 结构 + 统一配置标准参考模板。
放在 hexi/plugins/ 后改名:目录 nonebot_plugin_<name>,并替换所有
`nonebot_plugin_template` / `template` 占位(建议全局搜索替换)。
结构:Trigger(handlers) → Service(services) → Model(repository/models)。
配置在 config.py 统一注册,Web 可读可改。
"""
from nonebot import require
from nonebot.plugin import PluginMetadata
require("nonebot_plugin_alconna")
__plugin_meta__ = PluginMetadata(
name="插件模板",
description="MTSS 结构 + 统一配置标准参考模板",
usage="模板指令 [参数]",
type="application",
)
# 入口只做四件事:require / meta / 导入子模块 / 配置注册
from . import config as _config # noqa: E402,F401
from . import handlers as _handlers # noqa: E402,F401
from . import web as _web # noqa: E402,F401
from hexi.web_plugin_registry import register_web_plugin # noqa: E402
_config.register_config()
# 注册到统一 Web 管理台(/hub):hub 启动时自动挂载 /api/template
register_web_plugin(
"template",
"插件模板",
"user",
lambda: _web.build_admin_app(),
module_name=__name__,
)