package main import ( "context" "encoding/base64" "fmt" "os" "path/filepath" "sync" "github.com/darkit/goproxy/examples/plugin" ) // StoragePlugin 存储插件 // 提供简单的文件存储功能 type StoragePlugin struct { *plugin.BasePlugin // 嵌入基本插件结构 storageDir string // 存储目录 config map[string]interface{} // 配置 mu sync.RWMutex // 读写锁 } // Plugin 导出的插件变量 // 注意:变量名必须是Plugin,大小写敏感 var Plugin = &StoragePlugin{ BasePlugin: plugin.NewBasePlugin( "StoragePlugin", "1.0.0", "简单的文件存储插件", "开发者", plugin.PluginTypeStorage, // 设置插件类型为存储插件 ), } // 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() { // 不会被执行,仅用于编译插件 }