228 lines
6.3 KiB
Markdown
228 lines
6.3 KiB
Markdown
# 接口定义
|
||
|
||
## 一、后端接口(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<Component>
|
||
defaultVisible?: boolean
|
||
order?: number
|
||
keepAlive?: boolean
|
||
}
|
||
|
||
/** 文件预览处理器定义 */
|
||
export interface FilePreviewHandlerDefinition {
|
||
id: string
|
||
name: string
|
||
icon: string
|
||
priority: number
|
||
canHandle: (filename: string) => boolean
|
||
getComponent?: () => Promise<Component>
|
||
getRenderConfig?: (filePath: string) => RenderConfig
|
||
supportsEdit?: boolean
|
||
}
|
||
|
||
/** 渲染配置 */
|
||
export interface RenderConfig {
|
||
type: 'iframe' | 'html' | 'custom' | 'image' | 'video' | 'audio'
|
||
src?: string
|
||
htmlContent?: string
|
||
props?: Record<string, unknown>
|
||
}
|
||
```
|
||
|
||
## 四、前端 Registry API
|
||
|
||
> 文件位置:`frontend/src/plugin/registry.ts`
|
||
|
||
```typescript
|
||
// === Tab 插件 ===
|
||
function registerTabPlugin(def: TabPluginDefinition): void
|
||
function getTabComponent(key: string): (() => Promise<Component>) | null
|
||
function getAllTabDefinitions(): TabPluginDefinition[]
|
||
function hasTabPlugin(key: string): boolean
|
||
|
||
// === 文件预览 ===
|
||
function registerPreviewHandler(handler: FilePreviewHandlerDefinition): void
|
||
function resolvePreviewHandler(filename: string): FilePreviewHandlerDefinition | null
|
||
function getAllPreviewHandlers(): ReadonlyArray<FilePreviewHandlerDefinition>
|
||
|
||
// === 调试 ===
|
||
function getRegistryStats(): { tabCount, previewHandlerCount, tabKeys, handlerIds }
|
||
```
|