增强插件系统:添加参数验证功能

- 在插件助手中新增 ValidateParams 函数,用于验证传入参数是否符合定义,确保参数的完整性和正确性。
- 更新 ExecuteAction 方法,集成参数验证逻辑,提升插件执行的安全性和可靠性。
- 示例程序中添加新的选项,展示如何生成插件API文档和OpenAPI/Swagger文档,增强用户体验。

此更新提升了插件系统的健壮性,便于开发者更好地管理和使用插件功能。
This commit is contained in:
2025-03-14 13:32:36 +08:00
parent 2e29253909
commit cc4c677553
8 changed files with 2330 additions and 1 deletions

View File

@@ -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]
// 准备参数