# 接口定义 ## 一、后端接口(Go) > 文件位置:`internal/plugin/plugin.go` ```go package plugin import ( "context" "time" "github.com/wailsapp/wails/v3/pkg/application" ) // ========== 类型定义 ========== type PluginID string type PluginSource string const ( SourceBuiltin PluginSource = "builtin" SourceMarket PluginSource = "market" ) // PluginMetadata 插件元数据(JSON 序列化传给前端) type PluginMetadata struct { ID PluginID `json:"id"` Name string `json:"name"` Version string `json:"version"` Description string `json:"description"` Author string `json:"author"` Source PluginSource `json:"source"` TabKey string `json:"tab_key,omitempty"` FileExtensions []string `json:"file_extensions,omitempty"` InstallPath string `json:"install_path,omitempty"` InstalledAt time.Time `json:"installed_at,omitempty"` UISlots []string `json:"ui_slots,omitempty"` // 声明占用的 UI 插槽(Phase 3) } // PluginCapability 插件能力标志位 type PluginCapability int const ( CapabilityNone PluginCapability = 0 CapabilityTabProvider PluginCapability = 1 << iota CapabilityFilePreview CapabilitySettings ) func (c PluginCapability) Has(cap PluginCapability) bool { return c&cap != 0 } // PreviewInfo 预览元信息 type PreviewInfo struct { Type string `json:"type"` Title string `json:"title"` Icon string `json:"icon,omitempty"` NeedsContainer bool `json:"needs_container,omitempty"` ContainerConfig map[string]any `json:"container_config,omitempty"` SupportsEdit bool `json:"supports_edit"` PreloadHint string `json:"preload_hint,omitempty"` } // TabDef Tab 定义 type TabDef struct { Key string `json:"key"` Title string `json:"title"` Icon string `json:"icon,omitempty"` Enabled bool `json:"enabled"` Order int `json:"order"` } // ========== 核心接口 ========== // CoreServices 插件可访问的核心服务(由 adapter 实现,不挂在 App 上) type CoreServices interface { Context() context.Context MainWindow() *application.WebviewWindow EmitEvent(eventName string, data ...any) FileSystem() any ConfigAPI() any GetFileServerURL() string } // Plugin 核心插件接口(所有插件必须实现) type Plugin interface { Meta() PluginMetadata Capabilities() PluginCapability Init(ctx context.Context, core CoreServices) error Start() error Stop() error } // TabProvider Tab 提供者接口(可选,实现 CapabilityTabProvider 时需同时实现) type TabProvider interface { Plugin TabDefinition() TabDef TabComponentPath() string } // FilePreviewHandler 文件预览处理器接口(可选,实现 CapabilityFilePreview 时需同时实现) type FilePreviewHandler interface { Plugin CanPreview(filename string, mimeType string) bool PreviewInfo(filename string) PreviewInfo } ``` ## 二、PluginManager API > 文件位置:`internal/plugin/manager.go` ```go type Manager struct { mu sync.RWMutex plugins map[PluginID]Plugin core CoreServices tabReg *TabRegistry previewReg *PreviewRegistry ctx context.Context initialized bool } // 生命周期 func NewManager(core CoreServices) *Manager func (m *Manager) Register(p Plugin) error // 注册 + 自动分发到子注册表 func (m *Manager) InitAll(ctx context.Context) error // 初始化所有插件 func (m *Manager) StartByTabKey(tabKey string) error // 按 Tab 懒启动 func (m *Manager) Shutdown() error // 停止所有插件 // 查询 func (m *Manager) GetPluginInfos() []PluginMetadata // 前端展示用 func (m *Manager) ResolvePreview(filename string) (*PreviewInfo, PluginID) func (m *Manager) GetTabDefinitions() []TabDef // 外部插件管理(Phase 4+) func (m *Manager) InstallPlugin(packagePath string) error func (m *Manager) UninstallPlugin(id PluginID) error func (m *Manager) SetPluginEnabled(id PluginID, enabled bool) error func (m *Manager) CheckPluginUpdates() []PluginUpdateInfo ``` ## 三、前端接口(TypeScript) > 文件位置:`frontend/src/plugin/types.ts` ```typescript /** 插件能力标志位 */ export enum PluginCapability { None = 0, TabProvider = 1 << 0, FilePreview = 1 << 1, Settings = 1 << 2, } export type PluginSource = 'builtin' | 'market' /** 后端返回的插件元信息 */ export interface PluginMetadata { id: string name: string version: string description: string author: string source: PluginSource tab_key?: string file_extensions?: string[] install_path?: string installed_at?: string ui_slots?: string[] } /** Tab 插件定义(前端注册用) */ export interface TabPluginDefinition { key: string title: string icon?: string componentLoader: () => Promise defaultVisible?: boolean order?: number keepAlive?: boolean } /** 文件预览处理器定义 */ export interface FilePreviewHandlerDefinition { id: string name: string icon: string priority: number canHandle: (filename: string) => boolean getComponent?: () => Promise getRenderConfig?: (filePath: string) => RenderConfig supportsEdit?: boolean } /** 渲染配置 */ export interface RenderConfig { type: 'iframe' | 'html' | 'custom' | 'image' | 'video' | 'audio' src?: string htmlContent?: string props?: Record } ``` ## 四、前端 Registry API > 文件位置:`frontend/src/plugin/registry.ts` ```typescript // === Tab 插件 === function registerTabPlugin(def: TabPluginDefinition): void function getTabComponent(key: string): (() => Promise) | null function getAllTabDefinitions(): TabPluginDefinition[] function hasTabPlugin(key: string): boolean // === 文件预览 === function registerPreviewHandler(handler: FilePreviewHandlerDefinition): void function resolvePreviewHandler(filename: string): FilePreviewHandlerDefinition | null function getAllPreviewHandlers(): ReadonlyArray // === 调试 === function getRegistryStats(): { tabCount, previewHandlerCount, tabKeys, handlerIds } ```