package util import ( "encoding/json" "fmt" "model-gateway/model/entity" "strings" "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/util/gconv" tgjson "github.com/tidwall/gjson" ) // ======================== 响应解析 ======================== // ParseAndValidate 解析模型响应,校验必填字段,返回标准 rounds 格式 func ParseAndValidate(raw map[string]any, requiredFields []string) (map[string]any, error) { contentStr := gconv.String(raw[entity.ResponseBody]) if strings.TrimSpace(contentStr) == "" { return raw, fmt.Errorf("字段 %s 为空", entity.ResponseBody) } contentStr = cleanControlChars(contentStr) var arr []any if err := json.Unmarshal([]byte(contentStr), &arr); err != nil { return raw, fmt.Errorf("JSON解析失败: %w", err) } if len(arr) == 0 { return raw, fmt.Errorf("解析后数组为空") } for _, field := range requiredFields { for i, r := range arr { round, _ := r.(map[string]any) if round != nil && gjson.New(round).Get(field).IsNil() { return raw, fmt.Errorf("rounds[%d] 缺少必填字段: %s", i, field) } } } return map[string]any{"total_rounds": len(arr), "rounds": arr}, nil } // MapResponsePayload 映射模型响应为标准格式 func MapResponsePayload(mapping map[string]any, result map[string]any) (map[string]any, error) { if len(mapping) == 0 { return result, nil } // 把 result 转成 JSON 字符串,tidwall/gjson 需要字符串输入 resultBytes, _ := json.Marshal(result) resultStr := string(resultBytes) mapped := make(map[string]any) for standardField, modelPath := range mapping { path := gconv.String(modelPath) if path == "" { continue } value := tgjson.Get(resultStr, path) if !value.Exists() { continue } if strings.Contains(path, "#") { var arr []any for _, v := range value.Array() { arr = append(arr, v.Value()) } mapped[standardField] = arr } else { mapped[standardField] = value.Value() } } return mapped, nil } // ======================== 内部辅助 ======================== func cleanControlChars(s string) string { return strings.Map(func(r rune) rune { if r < 32 && r != ' ' { return -1 } return r }, s) }