WebUI 前端开发
July 28, 2026 · View on GitHub
控制台 UI 由独立仓库 Pallas-Bot-WebUI 构建,产物由主仓 pb_webui 挂载,基址 /pallas/。本页覆盖本地联调、构建挂载、OpenAPI 契约与窄屏约定。运行日志落盘与导出见 维护者 · 日志。
后端 API 见 WebUI API;插件配置热重载见 WebUI 配置与热重载。普通 LLM 聊天走 Bot Provider(侧栏 AI 配置),与媒体 / RWKV 用的 Pallas-Bot-AI 分开。
先做联调
# 终端 1:主仓 Bot
cd Pallas-Bot
uv run pallas
# 终端 2:WebUI 开发服务器(React,仓库根)
cd Pallas-Bot-WebUI
npm install
npm run dev # 默认 http://127.0.0.1:5173/pallas/
npm run dev 将 /pallas/api 等代理到 Bot;端口非 8088 时:
VITE_PROXY_TARGET=http://127.0.0.1:<port> npm run dev
构建与挂载
默认生产栈为 React(pallas_webui_frontend=react),静态目录 data/pb_webui/public-react/。历史 Vue 见 WebUI 分支 archive/vue。
cd Pallas-Bot-WebUI
npm install
npm run build # → dist/;写入 console-version.json
主仓 CI / Release 从 Pallas-Bot-WebUI 仓库根构建,经 tools/build_webui_dist.sh 打包 dist.zip(zip 根为 public-react/),随 Pallas-Bot Release 附件发布。Bot 启动时解压到 data/pb_webui。
本地手动部署:将构建产物放入 data/pb_webui/public-react/,或解压 Release 的 dist.zip 到 data/pb_webui/。
./tools/build_webui_dist.sh /path/to/Pallas-Bot-WebUI dist.zip
unzip -d data/pb_webui dist.zip
自动更新默认从 PallasBot/Pallas-Bot Release 下载 dist.zip(配置项 pallas_webui_dist_zip_repo)。
OpenAPI 契约
控制台后端可在线提供:
/pallas/api/openapi.json
离线 schema 与 WebUI 生成类型(推荐一条命令):
cd Pallas-Bot
uv run python tools/sync_console_openapi.py
# 写出 openspec/pallas-console-v1.json
# 同级存在 Pallas-Bot-WebUI 且已 npm ci 时,一并 gen 类型
仅导出 / 仅校验:
uv run python tools/export_pb_webui_openapi.py
uv run python tools/check_console_openapi_drift.py
cd ../Pallas-Bot-WebUI
npm run sync:console-openapi-types # 或 gen / check
npm run check:console-openapi-types
- Bot pre-commit:每次 commit 跑
sync-console-openapi(openspec 有实质变更时改写并要求重新 stage) - WebUI pre-commit:从同级 Bot
openspecgen 类型(有改动则 exit 1 以便 stage) - 路径:
PALLAS_WEBUI_ROOT/PALLAS_BOT_ROOT;默认互为同级目录 - CI:Bot drift check;WebUI 对照主仓
main的 openspec 校验已提交类型
合并顺序:先合 Bot(含 openspec)→ 再合 WebUI(含生成类型)。
DynamicConfigPanel(插件 config 元数据)
插件 config.py 的 Pydantic 字段可通过 Field(..., json_schema_extra={...}) 驱动 WebUI 表单:
| 键 | 作用 |
|---|---|
ui_group | 分组标题(DynamicConfigPanel 折叠卡片) |
ui_order | 组内排序,越小越靠前 |
ui_hidden | 进阶项,默认折叠在「高级」组 |
secret | 字符串打码 + 眼睛切换 |
multiline | 多行 textarea |
ui_widget / ui_gateway | 非默认控件;provider_gateway 渲染主备 Provider 线路面板(用 ui_provider_gateway() 生成) |
未在 schema 声明但写入 webui.json 的键会在面板底部「未声明的环境键」列出;需改 Raw TOML 模式编辑。主备线路细节见 DynamicConfigPanel。
代码约定
| 项 | 约定 |
|---|---|
| 技术栈 | React 18、TypeScript、Vite、react-router-dom、TanStack Query、shadcn/ui |
| 主要目录 | src/pages/ 页面、src/styles/ 全局与控制台样式 |
| 样式 | 优先复用 src/styles/console/ 与既有 utility;页面特有样式带根类名前缀 |
| 控件 | 优先 src/components/ui/(shadcn) |
| 函数命名 | 非必要不以 _ 开头;注释保持精简 |
仓库根 AGENTS.md 与主仓 AGENTS.md 中 WebUI 章节保持一致。
窄屏体验(必做)
大量用户在手机或窄窗口使用控制台。新增或改动标题栏、表格、批量操作、侧栏按钮时,必须在 ≤560px 下可用。
自检断点:src/styles/console/app.css(或等价全局样式)中 @media (max-width: 560px)。
| 场景 | 做法 |
|---|---|
| 面板标题 +「添加到侧栏」 | 宽屏标题与操作同排;窄屏标题与 + 同一行,批量/危险按钮次行 |
| 实例/协议双行标题 | 沿用 inst-db-panel__* / PageChrome 布局 |
| 多列表格 | 列多或长路径时窄屏优先卡片列表 |
| 全局按钮全宽规则 | 勿误伤标题栏内按钮 |
参考页面:FriendsGroupsPage.tsx、DatabaseBackupsPage.tsx、InstancesPage.tsx、ProtocolPage.tsx。
提交前用 DevTools 响应式模式或真机预览 ≤560px 宽度,勿只验桌面宽屏。
与主仓协作
| 改动类型 | 仓库 |
|---|---|
| 新页面、样式、前端交互 | Pallas-Bot-WebUI |
| 新 API、权限、配置落盘 | Pallas-Bot(pb_webui / pallas/console/webui) |
| 内嵌协议端静态页 | 主仓 packages/pb_protocol/web/static/(同样遵守窄屏) |
PR 仍建议单一主题:前后端分拆为两个 PR 时,在描述中互相链接。
插件包内视觉资源
插件列表、商店本地插件与帮助图共用后端 resolve_catalog_visuals()。在 local/plugins/<id>/ 或 packages/<id>/ 放置 assets/cover.png、assets/icon.png 等(完整候选见 Golden Plugin · 包内视觉资源)后:
- API 字段
cover/icon/avatar按 包内 → 商店缓存 → 远程 合并后返回/pallas/plugin-assets/…或/pallas/store-assets/… - 前端
resolvePluginIconForRow()优先使用上述 API 字段,再回退商店远程 URL 或品牌 mascot - bundled README 中相对路径
assets/…会改写为同前缀 URL(normalizeBundledReadmeMarkdown)
提交
npm run build # 提交前确保通过
Commit 推荐:feat(webui): 中文说明 / fix(webui): …