feat: 初始化 Wails + React + Go 桌面应用模板
- Wails v2.16.0 + React 19 + TypeScript + Vite 7 - 插件系统(build tag 控制编译,plugin.json 运行时配置) - 支付插件(授权、账号、订单、退款、账单) - 高并发基础设施(任务池、批量处理器、限流器、环形缓冲、管道) - Windows 系统托盘(Win32 API) - CodeGraph 索引 + .memory 记忆包 - 默认图标 assets/icon.png
This commit is contained in:
150
internal/plugins/plugins.go
Normal file
150
internal/plugins/plugins.go
Normal file
@@ -0,0 +1,150 @@
|
||||
// Package plugins 插件系统核心接口与注册中心
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Plugin 插件接口,所有插件必须实现
|
||||
type Plugin interface {
|
||||
Name() string
|
||||
Init(ctx context.Context) error
|
||||
Register(app *App) error
|
||||
Shutdown() error
|
||||
Enabled() bool
|
||||
}
|
||||
|
||||
// App 插件可见的应用上下文
|
||||
type App struct {
|
||||
ctx context.Context
|
||||
config map[string]interface{}
|
||||
}
|
||||
|
||||
// NewApp 创建应用上下文
|
||||
func NewApp(ctx context.Context, config map[string]interface{}) *App {
|
||||
return &App{ctx: ctx, config: config}
|
||||
}
|
||||
|
||||
// Registry 插件注册中心(线程安全)
|
||||
type Registry struct {
|
||||
mu sync.Mutex
|
||||
plugins map[string]Plugin
|
||||
}
|
||||
|
||||
var globalRegistry *Registry
|
||||
var once sync.Once
|
||||
|
||||
func getGlobalRegistry() *Registry {
|
||||
once.Do(func() {
|
||||
globalRegistry = &Registry{plugins: make(map[string]Plugin)}
|
||||
})
|
||||
return globalRegistry
|
||||
}
|
||||
|
||||
// Register 全局注册插件(由各插件 build.go 的 init() 调用)
|
||||
func Register(p Plugin) {
|
||||
r := getGlobalRegistry()
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.plugins[p.Name()] = p
|
||||
log.Printf("[plugins] registered: %s (enabled=%v)", p.Name(), p.Enabled())
|
||||
}
|
||||
|
||||
// Get 获取已注册插件
|
||||
func Get(name string) Plugin {
|
||||
r := getGlobalRegistry()
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
return r.plugins[name]
|
||||
}
|
||||
|
||||
// List 列出所有已注册插件名
|
||||
func List() []string {
|
||||
r := getGlobalRegistry()
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
names := make([]string, 0, len(r.plugins))
|
||||
for name := range r.plugins {
|
||||
names = append(names, name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// Count 返回已注册插件数
|
||||
func Count() int {
|
||||
r := getGlobalRegistry()
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
return len(r.plugins)
|
||||
}
|
||||
|
||||
// Start 启动所有已启用的插件
|
||||
func Start(ctx context.Context) error {
|
||||
r := getGlobalRegistry()
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
for name, p := range r.plugins {
|
||||
if !p.Enabled() {
|
||||
log.Printf("[plugins] skip disabled: %s", name)
|
||||
continue
|
||||
}
|
||||
if err := p.Init(ctx); err != nil {
|
||||
log.Printf("[plugins] init %s failed: %v", name, err)
|
||||
continue
|
||||
}
|
||||
if err := p.Register(NewApp(ctx, nil)); err != nil {
|
||||
log.Printf("[plugins] register %s failed: %v", name, err)
|
||||
continue
|
||||
}
|
||||
log.Printf("[plugins] started: %s", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Shutdown 关闭所有插件
|
||||
func Shutdown() error {
|
||||
r := getGlobalRegistry()
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
for name, p := range r.plugins {
|
||||
if err := p.Shutdown(); err != nil {
|
||||
log.Printf("[plugins] shutdown %s error: %v", name, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnabledPlugins 返回所有已启用插件列表
|
||||
func EnabledPlugins() []Plugin {
|
||||
r := getGlobalRegistry()
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
result := make([]Plugin, 0)
|
||||
for _, p := range r.plugins {
|
||||
if p.Enabled() {
|
||||
result = append(result, p)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// PrintStatus 打印当前插件状态(调试用)
|
||||
func PrintStatus() {
|
||||
r := getGlobalRegistry()
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
fmt.Println("[plugins] current status:")
|
||||
for name, p := range r.plugins {
|
||||
status := "disabled"
|
||||
if p.Enabled() {
|
||||
status = "enabled"
|
||||
}
|
||||
fmt.Printf(" - %s: %s\n", name, status)
|
||||
}
|
||||
if len(r.plugins) == 0 {
|
||||
fmt.Println(" (no plugins registered — check build tags)")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user