增强插件系统:添加操作参数信息获取功能
- 在插件接口中新增 GetOperationInfo 和 GetAllOperations 方法,支持获取特定操作及所有操作的参数信息。 - 更新 PluginHelper 以实现获取操作参数信息的功能,提升插件的可用性和灵活性。 - 在日志插件中实现操作信息获取,展示如何使用新方法获取操作的详细参数信息。 - 示例程序中添加新的选项,展示如何获取插件操作的参数信息。 此更新提升了插件系统的可扩展性和易用性,便于开发者更好地管理和使用插件功能。
This commit is contained in:
@@ -14,7 +14,8 @@ func main() {
|
|||||||
fmt.Println("请选择要运行的示例:")
|
fmt.Println("请选择要运行的示例:")
|
||||||
fmt.Println("1. 基本插件加载和管理")
|
fmt.Println("1. 基本插件加载和管理")
|
||||||
fmt.Println("2. 动态参数传递示例")
|
fmt.Println("2. 动态参数传递示例")
|
||||||
fmt.Print("请输入选项 (1-2): ")
|
fmt.Println("3. 插件操作参数信息示例")
|
||||||
|
fmt.Print("请输入选项 (1-3): ")
|
||||||
|
|
||||||
var choice int
|
var choice int
|
||||||
fmt.Scan(&choice)
|
fmt.Scan(&choice)
|
||||||
@@ -24,6 +25,8 @@ func main() {
|
|||||||
BasicPluginExample()
|
BasicPluginExample()
|
||||||
case 2:
|
case 2:
|
||||||
DynamicParamsExample()
|
DynamicParamsExample()
|
||||||
|
case 3:
|
||||||
|
OperationInfoExample()
|
||||||
default:
|
default:
|
||||||
fmt.Println("无效的选项")
|
fmt.Println("无效的选项")
|
||||||
}
|
}
|
||||||
|
182
examples/plugin/example/operation_info.go
Normal file
182
examples/plugin/example/operation_info.go
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/darkit/goproxy/examples/plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 格式化输出JSON
|
||||||
|
func prettyPrint(data interface{}) {
|
||||||
|
bytes, err := json.MarshalIndent(data, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("错误: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(string(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 演示插件操作信息获取功能
|
||||||
|
func OperationInfoExample() {
|
||||||
|
// 创建上下文
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// 获取插件目录
|
||||||
|
pluginsDir := filepath.Join("..", "plugins", "dist")
|
||||||
|
if _, err := os.Stat(pluginsDir); os.IsNotExist(err) {
|
||||||
|
fmt.Printf("插件目录不存在: %s\n", pluginsDir)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建插件管理器
|
||||||
|
pm := plugin.NewPluginManager(pluginsDir)
|
||||||
|
|
||||||
|
// 加载插件
|
||||||
|
fmt.Println("正在加载插件...")
|
||||||
|
if err := pm.LoadPlugins(); err != nil {
|
||||||
|
fmt.Printf("加载插件失败: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化所有插件
|
||||||
|
if err := pm.InitPlugins(ctx); err != nil {
|
||||||
|
fmt.Printf("初始化插件失败: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动所有插件
|
||||||
|
if err := pm.StartPlugins(ctx); err != nil {
|
||||||
|
fmt.Printf("启动插件失败: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印所有插件信息
|
||||||
|
fmt.Println("\n=== 已加载的插件 ===")
|
||||||
|
for _, info := range pm.GetPluginInfos() {
|
||||||
|
fmt.Printf("插件: %s (版本: %s, 类型: %s)\n", info.Name, info.Version, info.Type)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// 示例1: 获取StatsPlugin的所有操作信息
|
||||||
|
fmt.Println("=== 示例1: 获取StatsPlugin的所有操作信息 ===")
|
||||||
|
operations, err := pm.GetPluginAllOperations("StatsPlugin")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("获取操作信息失败: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("StatsPlugin支持 %d 个操作:\n", len(operations))
|
||||||
|
for opName := range operations {
|
||||||
|
fmt.Printf(" - %s\n", opName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择一个操作详细展示
|
||||||
|
if len(operations) > 0 {
|
||||||
|
selectedOp := ""
|
||||||
|
for opName := range operations {
|
||||||
|
if strings.Contains(strings.ToLower(opName), "record") {
|
||||||
|
selectedOp = opName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if selectedOp != "" {
|
||||||
|
fmt.Printf("\n%s 操作的详细信息:\n", selectedOp)
|
||||||
|
prettyPrint(operations[selectedOp])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 示例2: 获取特定操作的参数信息
|
||||||
|
fmt.Println("\n=== 示例2: 获取特定操作的参数信息 ===")
|
||||||
|
recordInfo, err := pm.GetPluginOperationInfo("StatsPlugin", "recordrequest")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("获取recordrequest参数信息失败: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("recordrequest操作的参数信息:")
|
||||||
|
prettyPrint(recordInfo)
|
||||||
|
|
||||||
|
// 基于参数信息构建调用参数
|
||||||
|
if paramsInfo, ok := recordInfo["parameters"].(map[string]interface{}); ok {
|
||||||
|
fmt.Println("\n基于参数信息自动构建调用参数:")
|
||||||
|
|
||||||
|
callParams := make(map[string]interface{})
|
||||||
|
for paramName, paramInfo := range paramsInfo {
|
||||||
|
if paramInfoMap, ok := paramInfo.(map[string]interface{}); ok {
|
||||||
|
if paramInfoMap["type"] == "struct" {
|
||||||
|
// 处理结构体参数
|
||||||
|
if fields, ok := paramInfoMap["fields"].(map[string]interface{}); ok {
|
||||||
|
for fieldName, fieldInfo := range fields {
|
||||||
|
if fieldInfoMap, ok := fieldInfo.(map[string]interface{}); ok {
|
||||||
|
// 根据字段类型设置默认值
|
||||||
|
fieldType, _ := fieldInfoMap["type"].(string)
|
||||||
|
switch fieldType {
|
||||||
|
case "integer":
|
||||||
|
callParams[fieldName] = int64(1000)
|
||||||
|
case "boolean":
|
||||||
|
callParams[fieldName] = false
|
||||||
|
case "string":
|
||||||
|
callParams[fieldName] = "自动生成的值"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 处理基本类型参数
|
||||||
|
paramType, _ := paramInfoMap["type"].(string)
|
||||||
|
switch paramType {
|
||||||
|
case "integer":
|
||||||
|
callParams[paramName] = int64(42)
|
||||||
|
case "boolean":
|
||||||
|
callParams[paramName] = true
|
||||||
|
case "string":
|
||||||
|
callParams[paramName] = "自动生成的值"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印构建的参数
|
||||||
|
prettyPrint(callParams)
|
||||||
|
|
||||||
|
// 使用构建的参数调用操作
|
||||||
|
fmt.Println("\n使用自动构建的参数调用操作:")
|
||||||
|
result, err := pm.ExecutePlugin(ctx, "StatsPlugin", "recordrequest", callParams)
|
||||||
|
fmt.Printf("调用结果: %v, 错误: %v\n", result, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 示例3: 获取所有插件的所有操作信息
|
||||||
|
fmt.Println("\n=== 示例3: 获取所有插件的所有操作信息 ===")
|
||||||
|
allOperations := pm.GetAllPluginsOperations()
|
||||||
|
fmt.Printf("找到 %d 个插件的操作信息:\n", len(allOperations))
|
||||||
|
|
||||||
|
var totalOps int
|
||||||
|
for pluginName, ops := range allOperations {
|
||||||
|
fmt.Printf(" 插件 %s: %d 个操作\n", pluginName, len(ops))
|
||||||
|
totalOps += len(ops)
|
||||||
|
}
|
||||||
|
fmt.Printf("总计 %d 个可用操作\n", totalOps)
|
||||||
|
|
||||||
|
// 示例4: 按插件类型获取操作信息
|
||||||
|
fmt.Println("\n=== 示例4: 按插件类型获取操作信息 ===")
|
||||||
|
utilsOps := pm.GetOperationsByType(plugin.PluginTypeUtils)
|
||||||
|
fmt.Printf("工具类插件操作:\n")
|
||||||
|
for pluginName, ops := range utilsOps {
|
||||||
|
fmt.Printf(" 插件 %s: %d 个操作\n", pluginName, len(ops))
|
||||||
|
for opName := range ops {
|
||||||
|
fmt.Printf(" - %s\n", opName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 停止所有插件
|
||||||
|
if err := pm.StopPlugins(ctx); err != nil {
|
||||||
|
fmt.Printf("停止插件失败: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("\n示例结束")
|
||||||
|
}
|
@@ -8,7 +8,7 @@ cd ../example
|
|||||||
|
|
||||||
# 编译示例程序
|
# 编译示例程序
|
||||||
echo "===== 编译示例程序 ====="
|
echo "===== 编译示例程序 ====="
|
||||||
go build -o plugin_demo
|
go build -o plugin_demo *.go
|
||||||
|
|
||||||
# 运行示例程序
|
# 运行示例程序
|
||||||
echo "===== 运行示例程序 ====="
|
echo "===== 运行示例程序 ====="
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/darkit/goproxy/examples/plugin"
|
"github.com/darkit/goproxy/examples/plugin"
|
||||||
)
|
)
|
||||||
@@ -76,6 +77,99 @@ func (p *LogPlugin) SetEnabled(enabled bool) {
|
|||||||
p.enabled = enabled
|
p.enabled = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOperationInfo 获取操作的参数信息
|
||||||
|
func (p *LogPlugin) GetOperationInfo(operation string) (map[string]interface{}, error) {
|
||||||
|
// 转换为小写以便不区分大小写匹配
|
||||||
|
operation = strings.ToLower(operation)
|
||||||
|
|
||||||
|
switch operation {
|
||||||
|
case "log":
|
||||||
|
return map[string]interface{}{
|
||||||
|
"name": "log",
|
||||||
|
"description": "记录日志消息",
|
||||||
|
"parameters": map[string]interface{}{
|
||||||
|
"message": map[string]interface{}{
|
||||||
|
"type": "string",
|
||||||
|
"description": "要记录的日志消息",
|
||||||
|
"required": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"returns": map[string]interface{}{
|
||||||
|
"result": map[string]interface{}{
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "操作是否成功",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
case "setlevel":
|
||||||
|
return map[string]interface{}{
|
||||||
|
"name": "setLevel",
|
||||||
|
"description": "设置日志级别",
|
||||||
|
"parameters": map[string]interface{}{
|
||||||
|
"level": map[string]interface{}{
|
||||||
|
"type": "string",
|
||||||
|
"description": "日志级别,如:info、debug、warn、error",
|
||||||
|
"required": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"returns": map[string]interface{}{
|
||||||
|
"result": map[string]interface{}{
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "操作是否成功",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
case "getlevel":
|
||||||
|
return map[string]interface{}{
|
||||||
|
"name": "getLevel",
|
||||||
|
"description": "获取当前日志级别",
|
||||||
|
"parameters": map[string]interface{}{},
|
||||||
|
"returns": map[string]interface{}{
|
||||||
|
"result": map[string]interface{}{
|
||||||
|
"type": "string",
|
||||||
|
"description": "当前日志级别",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
case "getstatus":
|
||||||
|
return map[string]interface{}{
|
||||||
|
"name": "getStatus",
|
||||||
|
"description": "获取插件状态信息",
|
||||||
|
"parameters": map[string]interface{}{},
|
||||||
|
"returns": map[string]interface{}{
|
||||||
|
"result": map[string]interface{}{
|
||||||
|
"type": "object",
|
||||||
|
"description": "包含插件状态的对象",
|
||||||
|
"properties": map[string]interface{}{
|
||||||
|
"name": map[string]interface{}{"type": "string"},
|
||||||
|
"version": map[string]interface{}{"type": "string"},
|
||||||
|
"level": map[string]interface{}{"type": "string"},
|
||||||
|
"enabled": map[string]interface{}{"type": "boolean"},
|
||||||
|
"type": map[string]interface{}{"type": "string"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("未知的操作: %s", operation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllOperations 获取所有操作及其参数信息
|
||||||
|
func (p *LogPlugin) GetAllOperations() map[string]map[string]interface{} {
|
||||||
|
operations := make(map[string]map[string]interface{})
|
||||||
|
|
||||||
|
// 获取所有操作的信息
|
||||||
|
for _, op := range []string{"log", "setlevel", "getlevel", "getstatus"} {
|
||||||
|
info, err := p.GetOperationInfo(op)
|
||||||
|
if err == nil {
|
||||||
|
operations[op] = info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return operations
|
||||||
|
}
|
||||||
|
|
||||||
func (p *LogPlugin) Init(ctx context.Context, config map[string]interface{}) error {
|
func (p *LogPlugin) Init(ctx context.Context, config map[string]interface{}) error {
|
||||||
if level, ok := config["level"].(string); ok {
|
if level, ok := config["level"].(string); ok {
|
||||||
p.level = level
|
p.level = level
|
||||||
|
@@ -43,6 +43,10 @@ type Plugin interface {
|
|||||||
// params: 操作所需的参数
|
// params: 操作所需的参数
|
||||||
// 返回操作结果和可能的错误
|
// 返回操作结果和可能的错误
|
||||||
Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error)
|
Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error)
|
||||||
|
// GetOperationInfo 获取操作的参数信息
|
||||||
|
GetOperationInfo(operation string) (map[string]interface{}, error)
|
||||||
|
// GetAllOperations 获取所有操作及其参数信息
|
||||||
|
GetAllOperations() map[string]map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PluginHelper 插件辅助器
|
// PluginHelper 插件辅助器
|
||||||
@@ -469,6 +473,169 @@ func convertParamValue(value interface{}, targetType reflect.Type) (reflect.Valu
|
|||||||
return reflect.Value{}, fmt.Errorf("不支持将 %T 类型转换为 %s", value, targetType)
|
return reflect.Value{}, fmt.Errorf("不支持将 %T 类型转换为 %s", value, targetType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetParameterInfo 获取操作的参数信息
|
||||||
|
func (h *PluginHelper) GetParameterInfo(action string) (map[string]interface{}, error) {
|
||||||
|
action = strings.ToLower(action)
|
||||||
|
method, exists := h.methods[action]
|
||||||
|
if !exists {
|
||||||
|
return nil, fmt.Errorf("未知的操作: %s", action)
|
||||||
|
}
|
||||||
|
|
||||||
|
paramTypes := h.methodParams[action]
|
||||||
|
returnTypes := h.methodRetValues[action]
|
||||||
|
|
||||||
|
result := map[string]interface{}{
|
||||||
|
"name": action,
|
||||||
|
"description": fmt.Sprintf("%s 操作", method.Name),
|
||||||
|
"parameters": make(map[string]interface{}),
|
||||||
|
"returns": make(map[string]interface{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理参数信息
|
||||||
|
paramsInfo := make(map[string]interface{})
|
||||||
|
|
||||||
|
// 首先检查是否有context参数
|
||||||
|
hasContext := false
|
||||||
|
if len(paramTypes) > 0 && paramTypes[0].String() == "context.Context" {
|
||||||
|
hasContext = true
|
||||||
|
result["hasContext"] = true
|
||||||
|
paramTypes = paramTypes[1:] // 跳过context参数
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, paramType := range paramTypes {
|
||||||
|
// 如果是结构体参数,展开其字段
|
||||||
|
if paramType.Kind() == reflect.Struct {
|
||||||
|
structInfo := getStructInfo(paramType)
|
||||||
|
structInfo["position"] = i + 1 // 考虑到接收者和可能的context
|
||||||
|
if hasContext {
|
||||||
|
structInfo["position"] = i + 2
|
||||||
|
}
|
||||||
|
paramsInfo[paramType.Name()] = structInfo
|
||||||
|
} else {
|
||||||
|
// 基本类型参数
|
||||||
|
paramName := fmt.Sprintf("arg%d", i)
|
||||||
|
typeInfo := getTypeInfo(paramType)
|
||||||
|
typeInfo["position"] = i + 1 // 考虑到接收者
|
||||||
|
if hasContext {
|
||||||
|
typeInfo["position"] = i + 2
|
||||||
|
}
|
||||||
|
paramsInfo[paramName] = typeInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result["parameters"] = paramsInfo
|
||||||
|
|
||||||
|
// 处理返回值信息
|
||||||
|
returnsInfo := make(map[string]interface{})
|
||||||
|
for i, returnType := range returnTypes {
|
||||||
|
returnName := fmt.Sprintf("return%d", i)
|
||||||
|
if i == len(returnTypes)-1 && returnType.String() == "error" {
|
||||||
|
returnName = "error"
|
||||||
|
} else if i == 0 && len(returnTypes) == 2 && returnTypes[1].String() == "error" {
|
||||||
|
returnName = "result"
|
||||||
|
}
|
||||||
|
returnsInfo[returnName] = getTypeInfo(returnType)
|
||||||
|
}
|
||||||
|
result["returns"] = returnsInfo
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getStructInfo 获取结构体类型的详细信息
|
||||||
|
func getStructInfo(t reflect.Type) map[string]interface{} {
|
||||||
|
info := map[string]interface{}{
|
||||||
|
"type": "struct",
|
||||||
|
"name": t.Name(),
|
||||||
|
"package": t.PkgPath(),
|
||||||
|
"fields": make(map[string]interface{}),
|
||||||
|
"fieldCount": t.NumField(),
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := make(map[string]interface{})
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
field := t.Field(i)
|
||||||
|
|
||||||
|
// 跳过非导出字段
|
||||||
|
if field.PkgPath != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldName := field.Name
|
||||||
|
jsonTag := field.Tag.Get("json")
|
||||||
|
if jsonTag != "" && jsonTag != "-" {
|
||||||
|
parts := strings.Split(jsonTag, ",")
|
||||||
|
if parts[0] != "" {
|
||||||
|
fieldName = parts[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldInfo := getTypeInfo(field.Type)
|
||||||
|
fieldInfo["name"] = field.Name
|
||||||
|
fieldInfo["jsonName"] = fieldName
|
||||||
|
fieldInfo["position"] = i
|
||||||
|
fieldInfo["tags"] = string(field.Tag)
|
||||||
|
|
||||||
|
fields[fieldName] = fieldInfo
|
||||||
|
}
|
||||||
|
info["fields"] = fields
|
||||||
|
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
|
// getTypeInfo 获取类型的基本信息
|
||||||
|
func getTypeInfo(t reflect.Type) map[string]interface{} {
|
||||||
|
info := map[string]interface{}{
|
||||||
|
"typeName": t.String(),
|
||||||
|
"kind": t.Kind().String(),
|
||||||
|
"type": typeKindToString(t.Kind()),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为不同类型添加特定信息
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
info["elemType"] = getTypeInfo(t.Elem())
|
||||||
|
case reflect.Map:
|
||||||
|
info["keyType"] = getTypeInfo(t.Key())
|
||||||
|
info["valueType"] = getTypeInfo(t.Elem())
|
||||||
|
case reflect.Ptr:
|
||||||
|
info["elemType"] = getTypeInfo(t.Elem())
|
||||||
|
case reflect.Struct:
|
||||||
|
// 对于结构体,提供简略信息
|
||||||
|
info["structName"] = t.Name()
|
||||||
|
info["package"] = t.PkgPath()
|
||||||
|
info["fieldCount"] = t.NumField()
|
||||||
|
}
|
||||||
|
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
|
// typeKindToString 将类型Kind转换为字符串表示
|
||||||
|
func typeKindToString(kind reflect.Kind) string {
|
||||||
|
switch kind {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return "integer"
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return "unsigned integer"
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return "float"
|
||||||
|
case reflect.Bool:
|
||||||
|
return "boolean"
|
||||||
|
case reflect.String:
|
||||||
|
return "string"
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
return "array"
|
||||||
|
case reflect.Map:
|
||||||
|
return "map"
|
||||||
|
case reflect.Struct:
|
||||||
|
return "object"
|
||||||
|
case reflect.Ptr:
|
||||||
|
return "pointer"
|
||||||
|
case reflect.Interface:
|
||||||
|
return "interface"
|
||||||
|
default:
|
||||||
|
return kind.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// BasePluginImpl 提供插件接口的基本实现,用于适配Plugin接口
|
// BasePluginImpl 提供插件接口的基本实现,用于适配Plugin接口
|
||||||
// 这个结构体包装了BasePlugin,以便兼容context参数
|
// 这个结构体包装了BasePlugin,以便兼容context参数
|
||||||
type BasePluginImpl struct {
|
type BasePluginImpl struct {
|
||||||
@@ -531,6 +698,23 @@ func (p *BasePluginImpl) GetAvailableActions() []string {
|
|||||||
return p.helper.GetAvailableActions()
|
return p.helper.GetAvailableActions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOperationInfo 获取操作的参数信息
|
||||||
|
func (p *BasePluginImpl) GetOperationInfo(operation string) (map[string]interface{}, error) {
|
||||||
|
return p.helper.GetParameterInfo(operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllOperations 获取所有操作及其参数信息
|
||||||
|
func (p *BasePluginImpl) GetAllOperations() map[string]map[string]interface{} {
|
||||||
|
operations := make(map[string]map[string]interface{})
|
||||||
|
for _, action := range p.helper.GetAvailableActions() {
|
||||||
|
info, err := p.helper.GetParameterInfo(action)
|
||||||
|
if err == nil {
|
||||||
|
operations[action] = info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return operations
|
||||||
|
}
|
||||||
|
|
||||||
// PluginInfo 插件信息
|
// PluginInfo 插件信息
|
||||||
type PluginInfo struct {
|
type PluginInfo struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
@@ -1099,3 +1283,75 @@ func (pm *PluginManager) ExecuteAllPlugins(ctx context.Context, action string, p
|
|||||||
|
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPluginOperationInfo 获取插件特定操作的参数信息
|
||||||
|
func (pm *PluginManager) GetPluginOperationInfo(name string, operation string) (map[string]interface{}, error) {
|
||||||
|
pm.mu.RLock()
|
||||||
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
|
plugin, exists := pm.plugins[name]
|
||||||
|
if !exists {
|
||||||
|
return nil, fmt.Errorf("插件 %s 不存在", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !plugin.IsEnabled() {
|
||||||
|
return nil, fmt.Errorf("插件 %s 已禁用", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin.GetOperationInfo(operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPluginAllOperations 获取插件所有操作及其参数信息
|
||||||
|
func (pm *PluginManager) GetPluginAllOperations(name string) (map[string]map[string]interface{}, error) {
|
||||||
|
pm.mu.RLock()
|
||||||
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
|
plugin, exists := pm.plugins[name]
|
||||||
|
if !exists {
|
||||||
|
return nil, fmt.Errorf("插件 %s 不存在", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !plugin.IsEnabled() {
|
||||||
|
return nil, fmt.Errorf("插件 %s 已禁用", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin.GetAllOperations(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOperationsByType 获取指定类型插件的所有操作信息
|
||||||
|
func (pm *PluginManager) GetOperationsByType(pluginType PluginType) map[string]map[string]map[string]interface{} {
|
||||||
|
pm.mu.RLock()
|
||||||
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
|
result := make(map[string]map[string]map[string]interface{})
|
||||||
|
|
||||||
|
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
|
||||||
|
for name, plugin := range typePlugins {
|
||||||
|
if !plugin.IsEnabled() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result[name] = plugin.GetAllOperations()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllPluginsOperations 获取所有插件的所有操作信息
|
||||||
|
func (pm *PluginManager) GetAllPluginsOperations() map[string]map[string]map[string]interface{} {
|
||||||
|
pm.mu.RLock()
|
||||||
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
|
result := make(map[string]map[string]map[string]interface{})
|
||||||
|
|
||||||
|
for name, plugin := range pm.plugins {
|
||||||
|
if !plugin.IsEnabled() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result[name] = plugin.GetAllOperations()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
@@ -123,7 +123,7 @@ func main() {
|
|||||||
// 创建测试插件
|
// 创建测试插件
|
||||||
plugin := NewTestPlugin()
|
plugin := NewTestPlugin()
|
||||||
|
|
||||||
fmt.Println("===== 测试自动方法注册与调用机制 =====\n")
|
fmt.Println("===== 测试自动方法注册与调用机制 =====")
|
||||||
|
|
||||||
// 获取可用的操作列表
|
// 获取可用的操作列表
|
||||||
fmt.Println("可用操作列表:")
|
fmt.Println("可用操作列表:")
|
||||||
|
Reference in New Issue
Block a user