package configser import ( "bytes" "encoding/json" "strings" ) // UnmarshalJSON 兼容 seoNavInfo 为空字符串,以及 dhKeyworld 为字符串/数组。 func (s *SeoNavInfo) UnmarshalJSON(raw []byte) error { if s == nil { return nil } raw = bytes.TrimSpace(raw) if len(raw) == 0 || bytes.Equal(raw, []byte("null")) { return nil } if raw[0] == '"' { var encoded string if err := json.Unmarshal(raw, &encoded); err != nil { return err } encoded = strings.TrimSpace(encoded) if encoded == "" { return nil } inner := bytes.TrimSpace([]byte(encoded)) if len(inner) == 0 || inner[0] != '{' { return nil } return s.UnmarshalJSON(inner) } var aux struct { DhTitle string `json:"dhTitle"` DhDescription string `json:"dhDescription"` DhSiteName string `json:"dhSiteName"` DhKeyworld json.RawMessage `json:"dhKeyworld"` Keywords json.RawMessage `json:"keywords"` } if err := json.Unmarshal(raw, &aux); err != nil { return err } s.DhTitle = strings.TrimSpace(aux.DhTitle) s.DhDescription = strings.TrimSpace(aux.DhDescription) s.DhSiteName = strings.TrimSpace(aux.DhSiteName) s.DhKeyworld = decodeNavKeywords(aux.DhKeyworld, aux.Keywords) return nil } func decodeNavKeywords(values ...json.RawMessage) []string { for _, raw := range values { raw = bytes.TrimSpace(raw) if len(raw) == 0 || bytes.Equal(raw, []byte("null")) { continue } if raw[0] == '[' { var list []string if err := json.Unmarshal(raw, &list); err != nil { continue } out := make([]string, 0, len(list)) for _, item := range list { item = strings.TrimSpace(item) if item != "" { out = append(out, item) } } if len(out) > 0 { return out } continue } var s string if err := json.Unmarshal(raw, &s); err != nil { continue } s = strings.TrimSpace(s) if s == "" { continue } parts := strings.Split(s, ",") out := make([]string, 0, len(parts)) for _, p := range parts { p = strings.TrimSpace(p) if p != "" { out = append(out, p) } } if len(out) > 0 { return out } } return nil }