package weipinshang_api import ( "encoding/json" "fmt" "sort" "strconv" "strings" ) func SortedString(data any) string { // 1. 序列化成 JSON dataBytes, err := json.Marshal(data) if err != nil { return "" } // 2. 反序列化成 map[string]interface{} var tmp map[string]interface{} if err = json.Unmarshal(dataBytes, &tmp); err != nil { return "" } // 3. 提取并排序 keys keys := make([]string, 0, len(tmp)) for k := range tmp { keys = append(keys, k) } sort.Strings(keys) // 4. 构建键值对字符串 var sortedParams []string for _, key := range keys { if key == "hmac" { continue // 跳过 hmac 字段 } value := tmp[key] strValue, err := valueToString(value) if err != nil { return "" } sortedParams = append(sortedParams, fmt.Sprintf("%s=%s", key, strValue)) } return strings.Join(sortedParams, "&") } // valueToString 将任意 JSON 值转换为字符串 func valueToString(v interface{}) (string, error) { switch i := v.(type) { case string: return i, nil case bool: return strconv.FormatBool(i), nil case float64: // 判断是否是整数(如 2.0 → "2") if i == float64(int64(i)) { return strconv.FormatInt(int64(i), 10), nil } return strconv.FormatFloat(i, 'f', -1, 64), nil case json.Number: return i.String(), nil // 如果使用 json.Number,直接返回其字符串形式 case nil: return "", nil case map[string]interface{}, []interface{}: // 如果是嵌套结构,重新序列化成 JSON bytes, err := json.Marshal(i) if err != nil { return "", err } return string(bytes), nil default: return "", fmt.Errorf("unsupported type: %T", i) } }