package service import ( "encoding/json" "strings" "github.com/gogf/gf/v2/container/gvar" ) func normalizeFormValue(v any) any { // 目标:对外永远返回 JSON 数组/对象,而不是字符串。 if v == nil { return []any{} } switch t := v.(type) { case string: s := strings.TrimSpace(t) if s == "" { return []any{} } return normalizeFormValueFromJSONString(s) case []byte: if len(t) == 0 { return []any{} } return normalizeFormValueFromJSONBytes(t) case *gvar.Var: // goframe 常见的 DB 返回类型 if t == nil { return []any{} } b := t.Bytes() if len(b) > 0 { return normalizeFormValueFromJSONBytes(b) } s := strings.TrimSpace(t.String()) if s == "" { return []any{} } return normalizeFormValueFromJSONString(s) default: // 尝试兼容其他“像 JSON 的值类型”(例如实现了 Bytes/String 的包装类型) if vb, ok := v.(interface{ Bytes() []byte }); ok { if b := vb.Bytes(); len(b) > 0 { return normalizeFormValueFromJSONBytes(b) } } if vs, ok := v.(interface{ String() string }); ok { if s := strings.TrimSpace(vs.String()); s != "" { return normalizeFormValueFromJSONString(s) } } // 已经是 []any / map[string]any 等结构 return v } } // 兼容“JSONB 里存了 JSON 字符串”的历史数据: // 例如 form_json = '"[]"' 或 '"[{...}]"'(外层是字符串,内层才是数组/对象) func normalizeFormValueFromJSONString(s string) any { var out any if err := json.Unmarshal([]byte(s), &out); err != nil || out == nil { return []any{} } // 如果解出来还是 string,且看起来是 JSON,再解一层 if inner, ok := out.(string); ok { inner = strings.TrimSpace(inner) if inner == "" { return []any{} } if strings.HasPrefix(inner, "[") || strings.HasPrefix(inner, "{") { var out2 any if err := json.Unmarshal([]byte(inner), &out2); err == nil && out2 != nil { return out2 } } return []any{} } return out } func normalizeFormValueFromJSONBytes(b []byte) any { var out any if err := json.Unmarshal(b, &out); err != nil || out == nil { return []any{} } // bytes 解出来也可能是 string(同上) if inner, ok := out.(string); ok { return normalizeFormValueFromJSONString(inner) } return out } func ParseJSONField(field any) any { var v *gvar.Var switch val := field.(type) { case *gvar.Var: v = val default: return field } if v == nil || v.IsNil() || v.IsEmpty() { return nil } str := v.String() var result any if json.Unmarshal([]byte(str), &result) == nil { return result } return str }