package main import ( "context" "encoding/base64" "fmt" "os" "path/filepath" "sync" "github.com/darkit/goproxy/examples/plugin" ) // StoragePlugin 存储插件 // 提供简单的文件存储功能 type StoragePlugin struct { plugin.Plugin // 嵌入接口,确保类型检查 name string // 插件名称 version string // 插件版本 description string // 插件描述 author string // 插件作者 pluginType plugin.PluginType // 插件类型 enabled bool // 是否启用 storageDir string // 存储目录 config map[string]interface{} // 配置 mu sync.RWMutex // 读写锁 } // Plugin 导出的插件变量 // 注意:变量名必须是Plugin,大小写敏感 var Plugin = &StoragePlugin{ name: "StoragePlugin", version: "1.0.0", description: "简单的文件存储插件", author: "开发者", pluginType: plugin.PluginTypeStorage, // 设置插件类型为存储插件 enabled: true, } // Name 返回插件名称 func (p *StoragePlugin) Name() string { return p.name } // Version 返回插件版本 func (p *StoragePlugin) Version() string { return p.version } // Description 返回插件描述 func (p *StoragePlugin) Description() string { return p.description } // Author 返回插件作者 func (p *StoragePlugin) Author() string { return p.author } // Type 返回插件类型 func (p *StoragePlugin) Type() plugin.PluginType { return p.pluginType } // IsEnabled 返回插件是否启用 func (p *StoragePlugin) IsEnabled() bool { return p.enabled } // SetEnabled 设置插件启用状态 func (p *StoragePlugin) SetEnabled(enabled bool) { p.enabled = enabled } // GetOperationInfo 获取操作的参数信息 func (p *StoragePlugin) GetOperationInfo(operation string) (map[string]interface{}, error) { return map[string]interface{}{}, nil } // GetAllOperations 获取所有操作及其参数信息 func (p *StoragePlugin) GetAllOperations() map[string]map[string]interface{} { return map[string]map[string]interface{}{} } // Init 初始化插件 func (p *StoragePlugin) Init(ctx context.Context, config map[string]interface{}) error { p.config = config // 获取存储目录路径 storageDir, ok := config["storage_dir"].(string) if !ok { // 使用默认路径 storageDir = "storage" } // 确保存储目录存在 if err := os.MkdirAll(storageDir, 0o755); err != nil { return fmt.Errorf("创建存储目录失败: %v", err) } p.storageDir = storageDir fmt.Println("存储插件初始化完成,存储目录:", storageDir) return nil } // Start 启动插件 func (p *StoragePlugin) Start(ctx context.Context) error { if p.storageDir == "" { return fmt.Errorf("插件未初始化") } fmt.Println("存储插件已启动") return nil } // Stop 停止插件 func (p *StoragePlugin) Stop(ctx context.Context) error { fmt.Println("存储插件已停止") return nil } // Execute 执行插件功能 func (p *StoragePlugin) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) { switch action { case "saveFile": // 需要参数: filename, data filename, ok := params["filename"].(string) if !ok { return nil, fmt.Errorf("缺少必需参数: filename") } // 处理两种数据格式:字符串或Base64编码的二进制数据 var data []byte if dataStr, ok := params["data"].(string); ok { // 检查是否为Base64编码 if base64Str, ok := params["isBase64"].(bool); ok && base64Str { var err error data, err = base64.StdEncoding.DecodeString(dataStr) if err != nil { return nil, fmt.Errorf("Base64解码失败: %v", err) } } else { data = []byte(dataStr) } } else { return nil, fmt.Errorf("缺少必需参数: data") } err := p.SaveFile(filename, data) return err == nil, err case "loadFile": // 需要参数: filename, returnBase64 filename, ok := params["filename"].(string) if !ok { return nil, fmt.Errorf("缺少必需参数: filename") } returnBase64, _ := params["returnBase64"].(bool) data, err := p.LoadFile(filename) if err != nil { return nil, err } if returnBase64 { return base64.StdEncoding.EncodeToString(data), nil } return string(data), nil case "deleteFile": // 需要参数: filename filename, ok := params["filename"].(string) if !ok { return nil, fmt.Errorf("缺少必需参数: filename") } err := p.DeleteFile(filename) return err == nil, err case "listFiles": // 不需要参数 files, err := p.ListFiles() return files, err case "getStorageInfo": // 不需要参数 info := map[string]interface{}{ "storageDir": p.storageDir, "config": p.config, } return info, nil default: return nil, fmt.Errorf("未知的操作: %s", action) } } // SaveFile 保存文件 func (p *StoragePlugin) SaveFile(filename string, data []byte) error { p.mu.Lock() defer p.mu.Unlock() if p.storageDir == "" { return fmt.Errorf("插件未初始化") } filePath := filepath.Join(p.storageDir, filename) return os.WriteFile(filePath, data, 0o644) } // LoadFile 加载文件 func (p *StoragePlugin) LoadFile(filename string) ([]byte, error) { p.mu.RLock() defer p.mu.RUnlock() if p.storageDir == "" { return nil, fmt.Errorf("插件未初始化") } filePath := filepath.Join(p.storageDir, filename) return os.ReadFile(filePath) } // DeleteFile 删除文件 func (p *StoragePlugin) DeleteFile(filename string) error { p.mu.Lock() defer p.mu.Unlock() if p.storageDir == "" { return fmt.Errorf("插件未初始化") } filePath := filepath.Join(p.storageDir, filename) return os.Remove(filePath) } // ListFiles 列出所有文件 func (p *StoragePlugin) ListFiles() ([]string, error) { p.mu.RLock() defer p.mu.RUnlock() if p.storageDir == "" { return nil, fmt.Errorf("插件未初始化") } var files []string entries, err := os.ReadDir(p.storageDir) if err != nil { return nil, err } for _, entry := range entries { if !entry.IsDir() { files = append(files, entry.Name()) } } return files, nil } // main 函数是必须的,但不会被调用 func main() { // 不会被执行,仅用于编译插件 }