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:
@@ -0,0 +1,40 @@
|
||||
"""插件 Web 子应用样例。
|
||||
|
||||
- 由 `__init__.py` 里 `register_web_plugin("template", ..., module_name=__name__)` 注册,
|
||||
hub 启动时自动挂载到 `/api/template`。
|
||||
- 鉴权统一走 `hexi.web_auth.require_admin`(OAuth2 + SQLite);注意它本身是 FastAPI 的
|
||||
`Depends` 实例,直接用 `_: dict = API` 注入,不要再包一层 `Depends(...)`。
|
||||
- 可直接读写 `hexi.web_config` 的插件配置。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.responses import HTMLResponse
|
||||
|
||||
from hexi import web_config
|
||||
from hexi.web_auth import require_admin as API
|
||||
|
||||
# 插件模块名(去掉 .web):= NoneBot 模块名 = plugin_id
|
||||
_PLUGIN_ID = __package__.rsplit(".", 1)[0]
|
||||
|
||||
|
||||
def build_admin_app() -> FastAPI:
|
||||
app = FastAPI(title="插件模板管理")
|
||||
|
||||
@app.get("/")
|
||||
async def index(_: dict = API) -> HTMLResponse:
|
||||
return HTMLResponse("<h1>插件模板 · Web 子应用</h1><p>鉴权已生效。</p>")
|
||||
|
||||
@app.get("/ping")
|
||||
async def ping(_: dict = API):
|
||||
return {"ok": True, "plugin": _PLUGIN_ID}
|
||||
|
||||
@app.get("/config")
|
||||
async def get_config(_: dict = API):
|
||||
cfg = web_config.get_config(_PLUGIN_ID)
|
||||
if cfg is None:
|
||||
return {"ok": False, "msg": "未注册配置 schema"}
|
||||
return {"ok": True, "plugin": _PLUGIN_ID, **cfg}
|
||||
|
||||
return app
|
||||
Reference in New Issue
Block a user