114 lines
2.6 KiB
Go
114 lines
2.6 KiB
Go
|
|
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
|
|||
|
|
}
|