tianyuan-api-server/pkg/schema/schemaVerify.go
2024-10-02 00:57:17 +08:00

87 lines
2.4 KiB
Go

package schema
import (
"encoding/json"
"fmt"
"github.com/xeipuuv/gojsonschema"
"os"
"path/filepath"
"strings"
)
// ValidationResult 结构用于保存校验结果
type ValidationResult struct {
Valid bool
Data map[string]interface{}
Errors string
}
// 校验函数:接受 schema 文件路径和 JSON 数据
func ValidateJSONWithSchema(schemaFileName string, data []byte) (ValidationResult, error) {
// 获取项目根目录
rootPath, err := os.Getwd()
if err != nil {
return ValidationResult{}, fmt.Errorf("无法获取项目根目录: %v", err)
}
// 构建本地 Schema 文件路径
schemaPath := filepath.Join(rootPath, "internal", "schema", schemaFileName)
// 将文件路径转换为 file:// URI 格式
schemaURI := "file:///" + filepath.ToSlash(schemaPath)
// 读取 schema 文件,通过 URI 加载
schemaLoader := gojsonschema.NewReferenceLoader(schemaURI)
// 将传入的 []byte 数据转为 JSON Loader
jsonLoader := gojsonschema.NewBytesLoader(data)
// 执行校验
result, err := gojsonschema.Validate(schemaLoader, jsonLoader)
if err != nil {
return ValidationResult{}, fmt.Errorf("校验过程中出错: %v", err)
}
// 初始化返回结果
validationResult := ValidationResult{
Valid: result.Valid(),
Data: make(map[string]interface{}),
Errors: "",
}
// 如果校验失败,收集并自定义错误信息
if !result.Valid() {
errorMessages := collectErrors(result.Errors())
validationResult.Errors = formatErrors(errorMessages)
return validationResult, nil
}
// 校验成功,解析 JSON
if err := json.Unmarshal(data, &validationResult.Data); err != nil {
return validationResult, fmt.Errorf("JSON 解析出错: %v", err)
}
return validationResult, nil
}
// collectErrors 自定义处理错误信息
func collectErrors(errors []gojsonschema.ResultError) []string {
var errorMessages []string
for _, err := range errors {
// 从 Details() 中获取真正的字段名
details := err.Details()
fieldName, ok := details["property"].(string)
if !ok {
fieldName = err.Field() // 默认使用 err.Field(),如果 property 不存在
}
errorMessages = append(errorMessages, fmt.Sprintf("%s: %s", fieldName, err.Description()))
}
return errorMessages
}
// formatErrors 将错误列表格式化为美观的字符串
func formatErrors(errors []string) string {
return strings.Join(errors, ", ") // 用换行符连接每个错误信息
}