增强插件系统:添加参数验证功能
- 在插件助手中新增 ValidateParams 函数,用于验证传入参数是否符合定义,确保参数的完整性和正确性。 - 更新 ExecuteAction 方法,集成参数验证逻辑,提升插件执行的安全性和可靠性。 - 示例程序中添加新的选项,展示如何生成插件API文档和OpenAPI/Swagger文档,增强用户体验。 此更新提升了插件系统的健壮性,便于开发者更好地管理和使用插件功能。
This commit is contained in:
@@ -133,6 +133,103 @@ func (h *PluginHelper) GetAvailableActions() []string {
|
||||
return actions
|
||||
}
|
||||
|
||||
// ValidateParams 验证传入的参数是否符合操作的参数定义
|
||||
func ValidateParams(paramsDef map[string]interface{}, params map[string]interface{}) error {
|
||||
// 检查参数定义是否存在
|
||||
if paramsDef == nil {
|
||||
return nil // 没有参数定义,不需要验证
|
||||
}
|
||||
|
||||
// 获取参数定义中的每个参数
|
||||
paramsInfo, ok := paramsDef["parameters"].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil // 参数定义格式不正确,跳过验证
|
||||
}
|
||||
|
||||
// 遍历每个参数定义进行验证
|
||||
errors := make([]string, 0)
|
||||
|
||||
for paramName, paramInfo := range paramsInfo {
|
||||
info, ok := paramInfo.(map[string]interface{})
|
||||
if !ok {
|
||||
continue // 参数信息格式不正确,跳过
|
||||
}
|
||||
|
||||
// 检查是否为必需参数
|
||||
required, ok := info["required"].(bool)
|
||||
if ok && required {
|
||||
// 对于结构体参数,要检查至少有一个字段被提供
|
||||
if info["type"] == "struct" {
|
||||
// 结构体参数的验证
|
||||
if fields, ok := info["fields"].(map[string]interface{}); ok {
|
||||
// 检查必填的结构体字段
|
||||
for fieldName, fieldInfo := range fields {
|
||||
if fieldInfoMap, ok := fieldInfo.(map[string]interface{}); ok {
|
||||
fieldRequired, ok := fieldInfoMap["required"].(bool)
|
||||
if ok && fieldRequired {
|
||||
if _, exists := params[fieldName]; !exists {
|
||||
errors = append(errors, fmt.Sprintf("缺少必需的结构体字段: %s", fieldName))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 普通参数验证是否存在
|
||||
if _, exists := params[paramName]; !exists {
|
||||
errors = append(errors, fmt.Sprintf("缺少必需参数: %s", paramName))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果参数存在,验证其类型
|
||||
if value, exists := params[paramName]; exists && info["type"] != nil {
|
||||
expectedType := info["type"].(string)
|
||||
// 根据期望的类型验证参数
|
||||
switch expectedType {
|
||||
case "string":
|
||||
if _, ok := value.(string); !ok {
|
||||
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为字符串", paramName))
|
||||
}
|
||||
case "integer":
|
||||
// 支持多种整数类型
|
||||
switch value.(type) {
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
|
||||
// 这些类型都是可接受的
|
||||
default:
|
||||
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为整数", paramName))
|
||||
}
|
||||
case "float":
|
||||
switch value.(type) {
|
||||
case float32, float64:
|
||||
// 这些类型是可接受的
|
||||
default:
|
||||
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为浮点数", paramName))
|
||||
}
|
||||
case "boolean":
|
||||
if _, ok := value.(bool); !ok {
|
||||
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为布尔值", paramName))
|
||||
}
|
||||
case "array":
|
||||
if _, ok := value.([]interface{}); !ok {
|
||||
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为数组", paramName))
|
||||
}
|
||||
case "object":
|
||||
if _, ok := value.(map[string]interface{}); !ok {
|
||||
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为对象", paramName))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果有错误,返回组合的错误信息
|
||||
if len(errors) > 0 {
|
||||
return fmt.Errorf("参数验证失败: %s", strings.Join(errors, "; "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExecuteAction 执行指定的动作
|
||||
func (h *PluginHelper) ExecuteAction(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
|
||||
// 转换为小写以实现不区分大小写的匹配
|
||||
@@ -143,6 +240,15 @@ func (h *PluginHelper) ExecuteAction(ctx context.Context, action string, params
|
||||
return nil, fmt.Errorf("未知的操作: %s", action)
|
||||
}
|
||||
|
||||
// 获取操作的参数信息并验证参数
|
||||
opInfo, err := h.GetParameterInfo(action)
|
||||
if err == nil {
|
||||
// 验证参数
|
||||
if err := ValidateParams(opInfo, params); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
paramTypes := h.methodParams[action]
|
||||
|
||||
// 准备参数
|
||||
|
Reference in New Issue
Block a user