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,92 @@
|
||||
"""配置注册:按《插件配置文件标准》统一接入 Web 管理台。
|
||||
|
||||
此处演示三类:
|
||||
1) register_model_config → 读 .env / NoneBot config 的 pydantic Config
|
||||
2) register_config_items → 来源无关(模块常量)
|
||||
3) register_object_set → 一组结构化条目(数组/对象集合)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from nonebot import get_plugin_config
|
||||
from pydantic import BaseModel
|
||||
|
||||
from hexi.config_standard import register_config_items, register_model_config, register_object_set
|
||||
|
||||
# plugin_id = NoneBot 插件模块名
|
||||
_PLUGIN_ID = __package__
|
||||
|
||||
|
||||
class Config(BaseModel):
|
||||
enable: bool = True
|
||||
reply: str = "你好,我是模板插件!"
|
||||
|
||||
|
||||
config = get_plugin_config(Config)
|
||||
|
||||
# —— 来源无关示例:模块级常量(Web 可读可改) ——
|
||||
_COLOR = "red"
|
||||
|
||||
|
||||
def _get_color() -> str:
|
||||
return _COLOR
|
||||
|
||||
|
||||
def _set_color(v: str) -> None:
|
||||
global _COLOR
|
||||
_COLOR = v
|
||||
|
||||
|
||||
# —— 对象集示例:一组条目(如服务器/关键词/白名单) ——
|
||||
_ITEMS: dict[str, dict] = {}
|
||||
|
||||
|
||||
def _obj_getter() -> list[dict]:
|
||||
return [{"name": k, "value": v.get("value", "")} for k, v in _ITEMS.items()]
|
||||
|
||||
|
||||
def _obj_setter(rows: list[dict]) -> None:
|
||||
_ITEMS.clear()
|
||||
for row in rows:
|
||||
_ITEMS[str(row["name"])] = {"value": row.get("value", "")}
|
||||
|
||||
|
||||
def register_config() -> None:
|
||||
# 1) env/pydantic 配置
|
||||
register_model_config(
|
||||
_PLUGIN_ID,
|
||||
config,
|
||||
fields=["enable", "reply"],
|
||||
labels={"enable": "启用", "reply": "回复内容"},
|
||||
descriptions={"enable": "关闭后指令直接提示已停用", "reply": "模板指令的默认回复"},
|
||||
)
|
||||
|
||||
# 2) 来源无关(模块常量)
|
||||
register_config_items(
|
||||
_PLUGIN_ID,
|
||||
[
|
||||
{
|
||||
"key": "color",
|
||||
"label": "主题色",
|
||||
"type": "string",
|
||||
"getter": _get_color,
|
||||
"setter": _set_color,
|
||||
"secret": False,
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
# 3) 对象集(数组/结构化条目)
|
||||
register_object_set(
|
||||
_PLUGIN_ID,
|
||||
"dict_items",
|
||||
[
|
||||
{"key": "name", "label": "名称", "type": "string"},
|
||||
{"key": "value", "label": "值", "type": "string"},
|
||||
],
|
||||
key_field="name",
|
||||
getter=_obj_getter,
|
||||
setter=_obj_setter,
|
||||
label="条目表",
|
||||
# nosave=True 表示权威源在插件自身(文件/DB);此处写进 plugin_config.json,故为 False
|
||||
)
|
||||
Reference in New Issue
Block a user