Private
Public Access
1
0

新增: SFTP直连+网站预览+OSS区域嗅探+热键+BGM播放

This commit is contained in:
2026-05-12 11:06:28 +08:00
parent 545d7a864d
commit 2a363fd729
62 changed files with 6687 additions and 660 deletions

View File

@@ -0,0 +1,149 @@
# Phase 0基础设施骨架
## 目标
建好管道,不改现有功能。验证编译通过 + API 可调用。
**不包含**:无 UI 变化、无真实插件注册、无设置面板。
---
## 文件清单与实施顺序
### Step 1核心接口定义
**新建** `internal/plugin/plugin.go`
内容PluginID、PluginSource、PluginMetadata、PluginCapability、Plugin 接口、TabProvider、FilePreviewHandler、PreviewInfo、TabDef、CoreServices 接口定义。
依赖:无
---
### Step 2适配器避免方法泄漏
**新建** `internal/plugin/adapter.go`
内容:`adapter` 结构体实现 `CoreServices` 接口的 6 个方法。构造函数 `NewAdapter(app *App) CoreServices`
关键设计:不在 App 上直接实现 CoreServices会导致 6 个内部方法被 Wails v3 自动暴露为前端 API而是通过独立 adapter 封装。
依赖Step 1
---
### Step 3Tab 注册表
**新建** `internal/plugin/tab_registry.go`
内容:
- `TabRegistry` structmu + entries map
- Register冲突检测、GetByTabKey、GetAllDefinitions按 Order 排序、GetAllProviders、Count
依赖Step 1
---
### Step 4预览注册表
**新建** `internal/plugin/preview_registry.go`
内容:
- `PreviewRegistry` structmu + handlers 切片,按 priority 降序)
- Register自动排序、Resolve遍历匹配第一个 canHandle、GetAllHandlers、Count
依赖Step 1
---
### Step 5PluginManager
**新建** `internal/plugin/manager.go`
内容:
- `Manager` structplugins map + core + tabReg + previewReg + ctx + initialized
- NewManager、Register自动分发到子注册表 + 回滚、InitAll、StartByTabKey
- GetPluginInfos、ResolvePreview附加 PluginID 到响应、GetTabDefinitions、Shutdown
依赖Step 1 ~ 4 全部
---
### Step 6前端类型定义
**新建** `frontend/src/plugin/types.ts`
内容PluginCapability enum、PluginMetadata、TabPluginDefinition、FilePreviewHandlerDefinition、RenderConfig 接口。
依赖:无
---
### Step 7前端注册中心
**新建** `frontend/src/plugin/registry.ts`
内容:
- Vue reactive statetabPlugins Map + previewHandlers 数组)
- Tab APIregisterTabPlugin / getTabComponent / getAllTabDefinitions / hasTabPlugin
- Preview APIregisterPreviewHandler按 priority 插入)/ resolvePreviewHandler / getAllPreviewHandlers
- 调试工具getRegistryStats
依赖Step 6
---
### Step 8集成到 App
**修改** `app.go`
改动点:
1. **新增字段**`pluginMgr *plugin.Manager`(在 `mu` 字段之后)
2. **ServiceStartup 中**(步骤 4 之后):初始化 pluginMgr
```go
fmt.Println("[启动] 初始化插件管理器...")
a.pluginMgr = plugin.NewManager(plugin.NewAdapter(a))
```
3. **ServiceShutdown 末尾**:关闭 pluginMgr
```go
if a.pluginMgr != nil { a.pluginMgr.Shutdown() }
```
4. **新增绑定方法**Wails v3 自动暴露前端):
- `GetPluginInfos() ([]map[string]interface{}, error)` — 返回空数组或插件列表
- `ResolvePreview(req ResolvePreviewRequest) (map[string]interface{}, error)` — 解析文件预览处理器
- `ResolvePreviewRequest{Filename string}` 请求结构体
依赖Step 5
---
## 验证方案
### 编译验证
```bash
go build ./internal/plugin/
go build .
cd frontend && npx vue-tsc --noEmit
```
### 运行时验证
| # | 操作 | 预期结果 |
|---|------|---------|
| V1 | 运行应用 | 日志出现 `[启动] 初始化插件管理器...` |
| V2 | 关闭应用 | 日志出现 `[插件管理器] 已关闭` |
| V3 | DevTools: `GetPluginInfos()` | 返回 `{success:true, data:[]}` |
| V4 | DevTools: `ResolvePreview({filename:'test'})` | 返回 `{success:false, message:"no preview handler..."}` |
| V5 | 前端 import registry | 无 TS 错误 |
### 边界情况
| 场景 | 预期行为 |
|------|---------|
| pluginMgr 为 nil 调用 GetPluginInfos | 返回空数组,不 panic |
| pluginMgr 为 nil 调用 ResolvePreview | 返回 success:false不 panic |
| TabRegistry.Register 同一 TabKey 两次 | 返回冲突错误 |
| PreviewRegistry.Resolve 无匹配文件 | 返回 nil, "" |
| Manager.Shutdown 无插件注册 | 正常返回 nil |

View File

@@ -0,0 +1,167 @@
# 实施路线图
## 总览
```
Phase 0 ████████████ 基础设施骨架
Phase 1 ████ Draw.io 验证插件
Phase 2 █████████████ 预览系统重构
Phase 3 █████████████ Tab 插件化 + 设置面板
Phase 4 ██████ 外部插件支持
Phase 5 ░░░░░░░░░░░░░ 插件市场(远景)
```
每个 Phase 可独立交付验证。
---
## Phase 0基础设施骨架
**目标**:建好管道,不改现有功能。验证编译通过 + API 可调用。
详细步骤见 [Phase0-基础设施.md](./Phase0-基础设施.md)
---
## Phase 1首个内置插件验证Draw.io
**目标**:用第一个真实插件验证整条链路端到端打通。
| 步骤 | 文件 | 操作 |
|------|------|------|
| 1 | `internal/plugin/builtin/drawio_plugin.go` | 新建 DrawIoPlugin 实现 |
| 2 | `frontend/src/plugin/built-in/drawio-handler.ts` | 新建前端 handler 注册 |
| 3 | `app.go` | 在 ServiceStartup 中 Register(DrawIoPlugin) |
| 4 | `FileEditorPanel.vue` | 在 v-if 链末尾追加 drawio 分支 |
**验证标准**:打开 `.drawio` 文件 → 显示 iframe 预览 → 其他文件不受影响。
---
## Phase 2文件预览系统重构
**目标**:将全部 10 种内置预览迁移到插件注册表,消除 v-if 链。
| 步骤 | 文件 | 操作 |
|------|------|------|
| 1 | `frontend/src/plugin/built-in/preview-handlers.ts` | 新建,注册 image/video/audio/pdf/html/md/excel/word/csv/text/code 共 12 个处理器 |
| 2 | `FileEditorPanel.vue` | 模板重写为 `<component :is>` + `<iframe>` 双分支 |
| 3 | `registry.ts` | 被 FileEditorPanel 实际导入使用 |
**收益**:新增文件类型只需写一个 TS 文件(~20 行),零改动核心组件。
---
## Phase 3Tab 系统插件化 + 设置面板 + UI 插槽
**目标**App.vue 不再硬编码,设置面板支持插件管理,建立 UI 插槽体系。
| 步骤 | 文件 | 操作 |
|------|------|------|
| 1 | `frontend/src/plugin/built-in/tabs.ts` | 注册 file-system / markdown-editor 等内置 Tab |
| 2 | `frontend/src/plugin/built-in/index.ts` | 统一副作用入口 |
| 3 | `frontend/src/plugin/slots.ts` | UISlotRegistry 实现(插槽注册/查询) |
| 4 | `App.vue` | getComponent 改为查 registryKeepAlive 动态化;接入 slot: titlebar-extra / sidebar-left / toolbar-extra 等 |
| 5 | `stores/config.ts` | loadConfig 合并插件 Tab修复前后端断层 |
| 6 | `SettingsPanel.vue` | 新增「插件管理」Tab 页(列表 + 启用/禁用) |
| 7 | `app.go` | 新增 SetPluginEnabled 绑定方法PluginMetadata 新增 UISlots 字段 |
| 8 | `service/config_service.go` | defaultTabConfig 改为动态合并插件 Tab |
| 9 | SQLite | 写入 plugin_state 初始数据 |
> UI 插槽详细设计见 `设计文档/架构设计.md` 第四章
---
## Phase 4外部插件支持
**目标**:用户可安装 .zip 格式的外部插件包。
### 插件包格式 (.uplugin)
```
my-plugin-v1.0.0.uplugin (ZIP)
├── manifest.json # 插件清单(必须)
├── plugin.wasm # WASM 入口(跨平台首选)
├── assets/ # 静态资源
└── frontend/ # 前端组件(可选)
```
### manifest.json 结构
```json
{
"id": "com.example.my-plugin",
"name": "My Plugin",
"version": "1.0.0",
"entry": "plugin.wasm",
"capabilities": ["file-preview"],
"file_extensions": [".xyz"],
"min_app_version": "0.4.0",
"permissions": ["filesystem:read"],
"checksum_sha256": "..."
}
```
### Manager 新增能力
```go
InstallPlugin(packagePath string) error // 解压 + 校验 + 注册
UninstallPlugin(id PluginID) error // 停止 + 删除 + 清理
SetPluginEnabled(id, enabled) error // 启用/停用
ScanInstalledPlugins() error // 扫描恢复
```
### 安全模型
| 层级 | 措施 | Phase |
|------|------|-------|
| 签名校验 | checksum_sha256 安装时验证 | Phase 4 |
| 权限声明 | permissions 列表安装时展示确认 | Phase 4 |
| 沙箱执行 | WASM 沙箱 / 子进程隔离 | Phase 5 |
| 版本兼容 | min_app_version 检查 | Phase 4 |
---
## Phase 5插件市场远景
### 整体架构
```
┌──────────────────┐ ┌──────────────────┐
│ 插件市场服务端 │ │ u-desk 客户端 │
│ │◄───────►│ │
│ · 插件仓库 CRUD │ HTTPS │ · 浏览/搜索 │
│ · 元数据 API │ │ · 一键安装 │
│ · 包文件分发 │ │ · 自动更新检查 │
│ · 签名 & 信誉 │ │ · 评分/评论(预留) │
└──────────────────┘ └──────────────────┘
```
### 服务端职责(优先级排序)
| P0 | P1 | P2 | P3 |
|----|----|----|----|
| 插件仓库 CRUD | 搜索过滤 | 开发者门户 | 评分评论 |
| 包分发 CDN | 自动更新通知 | 审核流程 | |
| 版本管理 | | | |
| 签名验证 | | | |
### 客户端 MarketplaceClient API
```typescript
interface MarketplaceClient {
searchPlugins(query, category?): Promise<MarketplacePlugin[]>
getPluginDetail(id): Promise<MarketplacePluginDetail>
installPlugin(id): Promise<InstallProgress>
uninstallPlugin(id): Promise<void>
checkUpdates(): Promise<PluginUpdateInfo[]>
updatePlugin(id): Promise<InstallProgress>
}
```
### 更新机制(复用现有 UpdateAPI
```
应用更新已有CheckUpdate → DownloadUpdate → VerifyUpdateFile → InstallUpdateWithHash
插件更新新增CheckPluginUpdates → DownloadPlugin → VerifyPlugin → InstallPlugin
```