6.3 KiB
6.3 KiB
接口定义
一、后端接口(Go)
文件位置:
internal/plugin/plugin.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
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
/** 插件能力标志位 */
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
// === 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 }