Files
u-desk/docs/04-功能迭代/GO-DESK-9.插件系统/任务规划/Phase0-基础设施.md
T

150 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 3:Tab 注册表
**新建** `internal/plugin/tab_registry.go`
内容:
- `TabRegistry` struct(mu + entries map)
- Register(冲突检测)、GetByTabKey、GetAllDefinitions(按 Order 排序)、GetAllProviders、Count
依赖:Step 1
---
### Step 4:预览注册表
**新建** `internal/plugin/preview_registry.go`
内容:
- `PreviewRegistry` struct(mu + handlers 切片,按 priority 降序)
- Register(自动排序)、Resolve(遍历匹配第一个 canHandle)、GetAllHandlers、Count
依赖:Step 1
---
### Step 5:PluginManager
**新建** `internal/plugin/manager.go`
内容:
- `Manager` struct(plugins 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 state(tabPlugins Map + previewHandlers 数组)
- Tab API:registerTabPlugin / getTabComponent / getAllTabDefinitions / hasTabPlugin
- Preview API:registerPreviewHandler(按 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 |