feat: hash路由 + 插件页面内联加载 + 侧边栏插件面板展开项

- Hash路由: #/dashboard #/files #/plugins/xxx 支持刷新保持/前进后退
- 登录过期保留hash,登录后自动跳回原页面
- 插件WebUI页面内联加载到page-container(不再弹新窗)
- 插件页面HTML自动处理: style提取/body剥离/script执行/padding归零
- 侧边栏新增「插件面板」可折叠项,展开列出所有已注册插件页面
- 内存卡片显示 已用/总容量(百分比右侧)
- 插件开发指南新增 2.6 WebUI页面开发章节

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
qinglong
2026-06-11 20:56:39 +08:00
parent eeca8e37e1
commit 99c3e3e853
10 changed files with 330 additions and 82 deletions
+68
View File
@@ -5,6 +5,7 @@
- [SenSu 插件开发超详细指南](#sensu-插件开发超详细指南)
- [一、插件系统架构深度解析](#一插件系统架构深度解析)
- [二、插件开发完整方案](#二插件开发完整方案)
- [2.6 插件 WebUI 页面](#26-插件-webui-页面-v060)
- [三、插件生命周期管理](#三插件生命周期管理)
- [四、插件开发最佳实践](#四插件开发最佳实践)
- [4.1 错误处理最佳实践](#41-错误处理最佳实践)
@@ -3400,6 +3401,73 @@ class PluginResourceManager:
```
### 2.6 插件 WebUI 页面 (v0.6.0)
插件可以注册 WebUI 页面自动出现在 SenSu 管理面板侧边栏的插件面板折叠项中
#### 2.6.1 注册页面
```python
from sdk.plugin_web import PluginWebMixin
class MyPlugin(PluginWebMixin):
async def initialize(self):
self.register_web_page(
path="mypanel", # 访问路径: /plugin/{plugin_name}
title="我的面板", # 侧边栏显示名称
html_content="<h1>Hello</h1>", # 完整 HTML 页面
icon="M" # 侧边栏图标 (单字符)
)
```
#### 2.6.2 页面渲染机制
插件页面在 SenSu 主面板的 `page-container` 区域内联加载(不弹新窗口):
1. 用户点击侧边栏「插件面板」→ 展开子项 → 点击插件页面
2. 前端 fetch `/plugin/{plugin_name}` 获取完整 HTML
3. 渲染管线自动处理:
- 提取 `<style>` 标签并注入页面
- 剥离 `<html>/<head>/<body>` 包装标签
- 提取 `<script>` 标签,通过动态 script 元素执行
- 页面 content 区 padding 归零,插件内容边到边铺满
#### 2.6.3 HTML 编写建议
```html
<!-- 推荐:使用内联样式 + 容器类,不依赖 body 选择器 -->
<style>
/* body 选择器不会生效(body 标签已被剥离) */
/* 改用类选择器或直接用容器 div */
.plugin-root {
background: var(--bg); /* 继承 SenSu 主题背景 */
color: var(--text); /* 继承 SenSu 主题文字 */
font-family: system-ui, sans-serif;
padding: 16px;
min-height: 100%;
}
.plugin-root h2 { color: var(--primary); }
</style>
<div class="plugin-root">
<h2>插件面板标题</h2>
<button class="btn btn-sm btn-tonal" onclick="...">操作</button>
</div>
<script>
// 脚本会被动态 script 元素执行,声明的函数可被 onclick 调用
function handleClick() { ... }
</script>
```
#### 2.6.4 注意事项
| 事项 | 说明 |
|------|------|
| `body` 选择器 | CSS 中 `body { ... }` 不会生效,改用容器类 |
| 硬编码背景色 | 避免 `background: #000`,用 `var(--bg)` 自适应主题 |
| `onclick` 函数 | 函数需在 `<script>` 中声明,浏览器 innerHTML 不执行 script |
| `<html>/<head>` | 可省略,直接写 body 内容 |
| 文件管理器调用 | 可通过 postMessage API 唤出文件选择器 (见第八章) |
## 三、插件生命周期管理
### 3.1 插件完整生命周期