From 15a13e5dd973c80a33a176f7a44cda887f6435b8 Mon Sep 17 00:00:00 2001
From: huangjiajun <582604932@qq.com>
Date: Mon, 4 Jul 2022 11:07:41 +0800
Subject: [PATCH] =?UTF-8?q?add=20reverse:for=20v1.0.0=20=E6=9E=81=E5=85=89?=
=?UTF-8?q?=E6=8E=A8=E9=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/.gitignore | 8 +
.idea/modules.xml | 8 +
.idea/vcs.xml | 6 +
.idea/zyos_go_jg_push.iml | 9 ++
go.mod | 5 +
go.sum | 2 +
hdl/jg_push.go | 65 ++++++++
hdl/push_test.go | 30 ++++
md/jg_push.go | 90 +++++++++++
utils/convert.go | 328 ++++++++++++++++++++++++++++++++++++++
utils/curl.go | 170 ++++++++++++++++++++
utils/serialize.go | 23 +++
12 files changed, 744 insertions(+)
create mode 100644 .idea/.gitignore
create mode 100644 .idea/modules.xml
create mode 100644 .idea/vcs.xml
create mode 100644 .idea/zyos_go_jg_push.iml
create mode 100644 go.mod
create mode 100644 go.sum
create mode 100644 hdl/jg_push.go
create mode 100644 hdl/push_test.go
create mode 100644 md/jg_push.go
create mode 100644 utils/convert.go
create mode 100644 utils/curl.go
create mode 100644 utils/serialize.go
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..6ac1cc3
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..3ba676a
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/zyos_go_jg_push.iml b/.idea/zyos_go_jg_push.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/zyos_go_jg_push.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..3343900
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module code.fnuoos.com/go_rely_warehouse/zyos_go_jg_push.git
+
+go 1.15
+
+require github.com/syyongx/php2go v0.9.7
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..6ba1677
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,2 @@
+github.com/syyongx/php2go v0.9.7 h1:boZtLbm2xYbW49mX9M7Vq2zkVhBhv3fCqs2T16d2bGA=
+github.com/syyongx/php2go v0.9.7/go.mod h1:meN2eIhhUoxOd2nMxbpe8g6cFPXI5O9/UAAuz7oDdzw=
diff --git a/hdl/jg_push.go b/hdl/jg_push.go
new file mode 100644
index 0000000..09d49e3
--- /dev/null
+++ b/hdl/jg_push.go
@@ -0,0 +1,65 @@
+package jg_push
+
+import (
+ "code.fnuoos.com/go_rely_warehouse/zyos_go_jg_push.git/md"
+ jg_push_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_jg_push.git/utils"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/syyongx/php2go"
+)
+
+func Send(appKey, appSecret string, param md.PushParam) (interface{}, error) {
+
+ if appKey == "" || appSecret == "" {
+ return nil, errors.New("配置未设置")
+ }
+ url := "https://api.jpush.cn/v3/push"
+ var iosAlert = md.PushIosAlert{Title: param.Title, Body: param.Content}
+ req := md.PushRequest{
+ Platform: param.Platform,
+ Audience: param.Audience,
+ Notification: struct {
+ Android md.PushAndroid `json:"android"`
+ Ios md.PushIos `json:"ios"`
+ }{
+ Android: md.PushAndroid{
+ Alert: param.Content,
+ Extras: param.Extras,
+ Title: param.Title,
+ },
+ Ios: md.PushIos{
+ Alert: iosAlert,
+ Extras: param.Extras,
+ Sound: "default",
+ },
+ },
+ Message: struct {
+ Extras interface{} `json:"extras"`
+ MsgContent string `json:"msg_content"`
+ }{
+ Extras: param.Extras,
+ MsgContent: param.Content,
+ },
+ Options: struct {
+ TimeToLive int `json:"time_to_live"`
+ }{
+ TimeToLive: 86400,
+ },
+ }
+ key := php2go.Base64Encode(appKey + ":" + appSecret)
+ headers := map[string]string{
+ "Content-Type": "application/json",
+ "Authorization": "Basic " + key,
+ }
+ b, err := json.Marshal(req)
+ if err != nil {
+ return nil, err
+ }
+ res, err := jg_push_utils.CurlPost(url, b, headers)
+ if err != nil {
+ return nil, err
+ }
+ fmt.Println(res)
+ return res, nil
+}
diff --git a/hdl/push_test.go b/hdl/push_test.go
new file mode 100644
index 0000000..072c00f
--- /dev/null
+++ b/hdl/push_test.go
@@ -0,0 +1,30 @@
+package jg_push
+
+import (
+ "code.fnuoos.com/go_rely_warehouse/zyos_go_jg_push.git/md"
+ "encoding/json"
+ "testing"
+)
+
+func TestPush(t *testing.T) {
+ var aud = md.PushAudience{Alias: []string{"123456_736"}}
+ var extrasData = md.NextCommModData{}
+ extrasStr, _ := json.Marshal(extrasData)
+ var extras = md.SkipData{
+ SkipName: "测试",
+ SkipIdentifier: "pub.flutter.invite_friends",
+ RequiredLogin: "1",
+ RequiredTaobaoAuth: "0",
+ IsJump: "1",
+ Url: "",
+ Data: string(extrasStr),
+ }
+ var param = md.PushParam{
+ Platform: "all",
+ Audience: aud,
+ Title: "API推送",
+ Content: "哈哈哈哈",
+ Extras: extras,
+ }
+ Send("6033fc3e19543740413d19aa", "ca7db52b63f7833299042f6a", param)
+}
diff --git a/md/jg_push.go b/md/jg_push.go
new file mode 100644
index 0000000..67bdff0
--- /dev/null
+++ b/md/jg_push.go
@@ -0,0 +1,90 @@
+package md
+
+type PushAndroid struct {
+ Alert string `json:"alert"` //通知内容
+ //BuilderID int64 `json:"builder_id"` 通知栏样式 ID
+ Extras interface{} `json:"extras"`
+ Title string `json:"title"` //通知标题
+}
+type PushIos struct {
+ Alert interface{} `json:"alert"`
+ Extras interface{} `json:"extras"`
+ Sound string `json:"sound"`
+}
+type PushIosAlert struct {
+ Title string `json:"title"`
+ Body string `json:"body"`
+}
+type PushAudience struct {
+ Alias []string `json:"alias"`
+}
+type PushRequest struct {
+ Platform interface{} `json:"platform"` //推送平台设置 全部:all 安卓:android iOS:ios ["android", "ios","quickapp"]
+ Audience interface{} `json:"audience"` //全部:all 别名 {"alias" : [ "4314", "892", "4531"] }
+ Notification struct { //通知内容体,是被推送到客户端的内容。
+ Android PushAndroid `json:"android"`
+ Ios PushIos `json:"ios"`
+ } `json:"notification"`
+ Message struct {
+ Extras interface{} `json:"extras"`
+ MsgContent string `json:"msg_content"`
+ } `json:"message"`
+
+ Options struct {
+ TimeToLive int `json:"time_to_live"`
+ } `json:"options"`
+}
+
+type PushParam struct {
+ Platform interface{} `json:"platform"` //推送平台设置 全部:all 安卓:android iOS:ios ["android", "ios","quickapp"]
+ Audience interface{} `json:"audience"` //全部:all 别名 {"alias" : [ "4314", "892", "4531"] }
+ Title string `json:"title"`
+ Content string `json:"content"`
+ Extras interface{} `json:"extras"`
+}
+
+type SkipData struct {
+ SkipName string `json:"skip_name"`
+ SkipIdentifier string `json:"skip_identifier"`
+ RequiredLogin string `json:"required_login"`
+ RequiredTaobaoAuth string `json:"required_taobao_auth"`
+ IsJump string `json:"is_jump"`
+ Url string `json:"url"`
+ Data string `json:"data"`
+}
+type NextCommModData struct {
+ FromCoinId string `json:"from_coin_id"`
+ ToCoinId string `json:"to_coin_id"`
+ Url string `json:"url"`
+ AppId string `json:"app_id"`
+ StoreId string `json:"store_id"`
+ AlipayUrl string `json:"alipay_url"`
+ AlipayAppid string `json:"alipay_appid"`
+ ActivityId string `json:"activity_id"`
+ Id string `json:"id"`
+ AdName string `json:"ad_name"`
+ AndroidAdID string `json:"android_ad_id"`
+ AndroidMediaID string `json:"android_media_id"`
+ AutoClickAd string `json:"auto_click_ad"`
+ Autoplay string `json:"autoplay"`
+ BrandID string `json:"brand_id"`
+ Conditions string `json:"conditions"`
+ CreateAt string `json:"create_at"`
+ EndTime string `json:"end_time"`
+ Img string `json:"img"`
+ IosAdID string `json:"ios_ad_id"`
+ IosMediaID string `json:"ios_media_id"`
+ IsRecommend interface{} `json:"is_recommend"`
+ LevelLimitID string `json:"level_limit_id"`
+ LevelLimitName string `json:"level_limit_name"`
+ LevelWeight string `json:"level_weight"`
+ NeedLocation int64 `json:"need_location"`
+ SdkType string `json:"sdk_type"`
+ SourceType string `json:"source_type"`
+ StartTime string `json:"start_time"`
+ UpdateAt string `json:"update_at"`
+ VisitCount string `json:"visit_count"`
+ CountingDown string `json:"counting_down" `
+ LevelType string `json:"level_type"`
+ OpenType string `json:"open_type" ` //app 应用内打开 browser 系统浏览器打开
+}
diff --git a/utils/convert.go b/utils/convert.go
new file mode 100644
index 0000000..f990d11
--- /dev/null
+++ b/utils/convert.go
@@ -0,0 +1,328 @@
+package jg_push_utils
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+)
+
+func ToString(raw interface{}, e error) (res string) {
+ if e != nil {
+ return ""
+ }
+ return AnyToString(raw)
+}
+
+func ToInt64(raw interface{}, e error) int64 {
+ if e != nil {
+ return 0
+ }
+ return AnyToInt64(raw)
+}
+func Float64ToStrByPrec(f float64, prec int) string {
+ return strconv.FormatFloat(f, 'f', prec, 64)
+}
+func AnyToBool(raw interface{}) bool {
+ switch i := raw.(type) {
+ case float32, float64, int, int64, uint, uint8, uint16, uint32, uint64, int8, int16, int32:
+ return i != 0
+ case []byte:
+ return i != nil
+ case string:
+ if i == "false" {
+ return false
+ }
+ return i != ""
+ case error:
+ return false
+ case nil:
+ return true
+ }
+ val := fmt.Sprint(raw)
+ val = strings.TrimLeft(val, "&")
+ if strings.TrimLeft(val, "{}") == "" {
+ return false
+ }
+ if strings.TrimLeft(val, "[]") == "" {
+ return false
+ }
+ // ptr type
+ b, err := json.Marshal(raw)
+ if err != nil {
+ return false
+ }
+ if strings.TrimLeft(string(b), "\"\"") == "" {
+ return false
+ }
+ if strings.TrimLeft(string(b), "{}") == "" {
+ return false
+ }
+ return true
+}
+
+func AnyToInt64(raw interface{}) int64 {
+ switch i := raw.(type) {
+ case string:
+ res, _ := strconv.ParseInt(i, 10, 64)
+ return res
+ case []byte:
+ return BytesToInt64(i)
+ case int:
+ return int64(i)
+ case int64:
+ return i
+ case uint:
+ return int64(i)
+ case uint8:
+ return int64(i)
+ case uint16:
+ return int64(i)
+ case uint32:
+ return int64(i)
+ case uint64:
+ return int64(i)
+ case int8:
+ return int64(i)
+ case int16:
+ return int64(i)
+ case int32:
+ return int64(i)
+ case float32:
+ return int64(i)
+ case float64:
+ return int64(i)
+ case error:
+ return 0
+ case bool:
+ if i {
+ return 1
+ }
+ return 0
+ }
+ return 0
+}
+
+func AnyToString(raw interface{}) string {
+ switch i := raw.(type) {
+ case []byte:
+ return string(i)
+ case int:
+ return strconv.FormatInt(int64(i), 10)
+ case int64:
+ return strconv.FormatInt(i, 10)
+ case float32:
+ return Float64ToStr(float64(i))
+ case float64:
+ return Float64ToStr(i)
+ case uint:
+ return strconv.FormatInt(int64(i), 10)
+ case uint8:
+ return strconv.FormatInt(int64(i), 10)
+ case uint16:
+ return strconv.FormatInt(int64(i), 10)
+ case uint32:
+ return strconv.FormatInt(int64(i), 10)
+ case uint64:
+ return strconv.FormatInt(int64(i), 10)
+ case int8:
+ return strconv.FormatInt(int64(i), 10)
+ case int16:
+ return strconv.FormatInt(int64(i), 10)
+ case int32:
+ return strconv.FormatInt(int64(i), 10)
+ case string:
+ return i
+ case error:
+ return i.Error()
+ case bool:
+ return strconv.FormatBool(i)
+ }
+ return fmt.Sprintf("%#v", raw)
+}
+
+func AnyToFloat64(raw interface{}) float64 {
+ switch i := raw.(type) {
+ case []byte:
+ f, _ := strconv.ParseFloat(string(i), 64)
+ return f
+ case int:
+ return float64(i)
+ case int64:
+ return float64(i)
+ case float32:
+ return float64(i)
+ case float64:
+ return i
+ case uint:
+ return float64(i)
+ case uint8:
+ return float64(i)
+ case uint16:
+ return float64(i)
+ case uint32:
+ return float64(i)
+ case uint64:
+ return float64(i)
+ case int8:
+ return float64(i)
+ case int16:
+ return float64(i)
+ case int32:
+ return float64(i)
+ case string:
+ f, _ := strconv.ParseFloat(i, 64)
+ return f
+ case bool:
+ if i {
+ return 1
+ }
+ }
+ return 0
+}
+
+func ToByte(raw interface{}, e error) []byte {
+ if e != nil {
+ return []byte{}
+ }
+ switch i := raw.(type) {
+ case string:
+ return []byte(i)
+ case int:
+ return Int64ToBytes(int64(i))
+ case int64:
+ return Int64ToBytes(i)
+ case float32:
+ return Float32ToByte(i)
+ case float64:
+ return Float64ToByte(i)
+ case uint:
+ return Int64ToBytes(int64(i))
+ case uint8:
+ return Int64ToBytes(int64(i))
+ case uint16:
+ return Int64ToBytes(int64(i))
+ case uint32:
+ return Int64ToBytes(int64(i))
+ case uint64:
+ return Int64ToBytes(int64(i))
+ case int8:
+ return Int64ToBytes(int64(i))
+ case int16:
+ return Int64ToBytes(int64(i))
+ case int32:
+ return Int64ToBytes(int64(i))
+ case []byte:
+ return i
+ case error:
+ return []byte(i.Error())
+ case bool:
+ if i {
+ return []byte("true")
+ }
+ return []byte("false")
+ }
+ return []byte(fmt.Sprintf("%#v", raw))
+}
+
+func Int64ToBytes(i int64) []byte {
+ var buf = make([]byte, 8)
+ binary.BigEndian.PutUint64(buf, uint64(i))
+ return buf
+}
+
+func BytesToInt64(buf []byte) int64 {
+ return int64(binary.BigEndian.Uint64(buf))
+}
+
+func StrToInt(s string) int {
+ res, _ := strconv.Atoi(s)
+ return res
+}
+
+func StrToInt64(s string) int64 {
+ res, _ := strconv.ParseInt(s, 10, 64)
+ return res
+}
+
+func Float32ToByte(float float32) []byte {
+ bits := math.Float32bits(float)
+ bytes := make([]byte, 4)
+ binary.LittleEndian.PutUint32(bytes, bits)
+
+ return bytes
+}
+
+func ByteToFloat32(bytes []byte) float32 {
+ bits := binary.LittleEndian.Uint32(bytes)
+ return math.Float32frombits(bits)
+}
+
+func Float64ToByte(float float64) []byte {
+ bits := math.Float64bits(float)
+ bytes := make([]byte, 8)
+ binary.LittleEndian.PutUint64(bytes, bits)
+ return bytes
+}
+
+func ByteToFloat64(bytes []byte) float64 {
+ bits := binary.LittleEndian.Uint64(bytes)
+ return math.Float64frombits(bits)
+}
+
+func Float64ToStr(f float64) string {
+ return strconv.FormatFloat(f, 'f', 2, 64)
+}
+func Float64ToStrPrec1(f float64) string {
+ return strconv.FormatFloat(f, 'f', 1, 64)
+}
+
+func Float64ToStrPrec6(f float64) string {
+ return strconv.FormatFloat(f, 'f', 6, 64)
+}
+
+func Float32ToStr(f float32) string {
+ return Float64ToStr(float64(f))
+}
+
+func StrToFloat64(s string) float64 {
+ res, err := strconv.ParseFloat(s, 64)
+ if err != nil {
+ return 0
+ }
+ return res
+}
+
+func StrToFloat32(s string) float32 {
+ res, err := strconv.ParseFloat(s, 32)
+ if err != nil {
+ return 0
+ }
+ return float32(res)
+}
+
+func StrToBool(s string) bool {
+ b, _ := strconv.ParseBool(s)
+ return b
+}
+
+func BoolToStr(b bool) string {
+ if b {
+ return "true"
+ }
+ return "false"
+}
+
+func FloatToInt64(f float64) int64 {
+ return int64(f)
+}
+
+func IntToStr(i int) string {
+ return strconv.Itoa(i)
+}
+
+func Int64ToStr(i int64) string {
+ return strconv.FormatInt(i, 10)
+}
diff --git a/utils/curl.go b/utils/curl.go
new file mode 100644
index 0000000..8b09d3f
--- /dev/null
+++ b/utils/curl.go
@@ -0,0 +1,170 @@
+package jg_push_utils
+
+import (
+ "bytes"
+ "crypto/tls"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "sort"
+ "strings"
+ "time"
+)
+
+var CurlDebug bool
+
+func CurlGet(router string, header map[string]string) ([]byte, error) {
+ return curl(http.MethodGet, router, nil, header)
+}
+
+// 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string
+func CurlPost(router string, body interface{}, header map[string]string) ([]byte, error) {
+ return curl(http.MethodPost, router, body, header)
+}
+
+func CurlPut(router string, body interface{}, header map[string]string) ([]byte, error) {
+ return curl(http.MethodPut, router, body, header)
+}
+
+// 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string
+func CurlPatch(router string, body interface{}, header map[string]string) ([]byte, error) {
+ return curl(http.MethodPatch, router, body, header)
+}
+
+// CurlDelete is curl delete
+func CurlDelete(router string, body interface{}, header map[string]string) ([]byte, error) {
+ return curl(http.MethodDelete, router, body, header)
+}
+
+func curl(method, router string, body interface{}, header map[string]string) ([]byte, error) {
+ var reqBody io.Reader
+ contentType := "application/json"
+ switch v := body.(type) {
+ case string:
+ reqBody = strings.NewReader(v)
+ case []byte:
+ reqBody = bytes.NewReader(v)
+ case map[string]string:
+ val := url.Values{}
+ for k, v := range v {
+ val.Set(k, v)
+ }
+ reqBody = strings.NewReader(val.Encode())
+ contentType = "application/x-www-form-urlencoded"
+ case map[string]interface{}:
+ val := url.Values{}
+ for k, v := range v {
+ val.Set(k, v.(string))
+ }
+ reqBody = strings.NewReader(val.Encode())
+ contentType = "application/x-www-form-urlencoded"
+ }
+ if header == nil {
+ header = map[string]string{"Content-Type": contentType}
+ }
+ if _, ok := header["Content-Type"]; !ok {
+ header["Content-Type"] = contentType
+ }
+ resp, er := CurlReq(method, router, reqBody, header)
+ if er != nil {
+ return nil, er
+ }
+ res, err := ioutil.ReadAll(resp.Body)
+ if CurlDebug {
+ blob := SerializeStr(body)
+ if contentType != "application/json" {
+ blob = HttpBuild(body)
+ }
+ fmt.Printf("\n\n=====================\n[url]: %s\n[time]: %s\n[method]: %s\n[content-type]: %v\n[req_header]: %s\n[req_body]: %#v\n[resp_err]: %v\n[resp_header]: %v\n[resp_body]: %v\n=====================\n\n",
+ router,
+ time.Now().Format("2006-01-02 15:04:05.000"),
+ method,
+ contentType,
+ HttpBuildQuery(header),
+ blob,
+ err,
+ SerializeStr(resp.Header),
+ string(res),
+ )
+ }
+ resp.Body.Close()
+ return res, err
+}
+
+func CurlReq(method, router string, reqBody io.Reader, header map[string]string) (*http.Response, error) {
+ req, _ := http.NewRequest(method, router, reqBody)
+ if header != nil {
+ for k, v := range header {
+ req.Header.Set(k, v)
+ }
+ }
+ // 绕过github等可能因为特征码返回503问题
+ // https://www.imwzk.com/posts/2021-03-14-why-i-always-get-503-with-golang/
+ defaultCipherSuites := []uint16{0xc02f, 0xc030, 0xc02b, 0xc02c, 0xcca8, 0xcca9, 0xc013, 0xc009,
+ 0xc014, 0xc00a, 0x009c, 0x009d, 0x002f, 0x0035, 0xc012, 0x000a}
+ client := &http.Client{
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{
+ InsecureSkipVerify: true,
+ CipherSuites: append(defaultCipherSuites[8:], defaultCipherSuites[:8]...),
+ },
+ },
+ // 获取301重定向
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
+ return http.ErrUseLastResponse
+ },
+ }
+ return client.Do(req)
+}
+
+// 组建get请求参数,sortAsc true为小到大,false为大到小,nil不排序 a=123&b=321
+func HttpBuildQuery(args map[string]string, sortAsc ...bool) string {
+ str := ""
+ if len(args) == 0 {
+ return str
+ }
+ if len(sortAsc) > 0 {
+ keys := make([]string, 0, len(args))
+ for k := range args {
+ keys = append(keys, k)
+ }
+ if sortAsc[0] {
+ sort.Strings(keys)
+ } else {
+ sort.Sort(sort.Reverse(sort.StringSlice(keys)))
+ }
+ for _, k := range keys {
+ str += "&" + k + "=" + args[k]
+ }
+ } else {
+ for k, v := range args {
+ str += "&" + k + "=" + v
+ }
+ }
+ return str[1:]
+}
+
+func HttpBuild(body interface{}, sortAsc ...bool) string {
+ params := map[string]string{}
+ if args, ok := body.(map[string]interface{}); ok {
+ for k, v := range args {
+ params[k] = AnyToString(v)
+ }
+ return HttpBuildQuery(params, sortAsc...)
+ }
+ if args, ok := body.(map[string]string); ok {
+ for k, v := range args {
+ params[k] = AnyToString(v)
+ }
+ return HttpBuildQuery(params, sortAsc...)
+ }
+ if args, ok := body.(map[string]int); ok {
+ for k, v := range args {
+ params[k] = AnyToString(v)
+ }
+ return HttpBuildQuery(params, sortAsc...)
+ }
+ return AnyToString(body)
+}
diff --git a/utils/serialize.go b/utils/serialize.go
new file mode 100644
index 0000000..9534f93
--- /dev/null
+++ b/utils/serialize.go
@@ -0,0 +1,23 @@
+package jg_push_utils
+
+import (
+ "encoding/json"
+)
+
+func Serialize(data interface{}) []byte {
+ res, err := json.Marshal(data)
+ if err != nil {
+ return []byte{}
+ }
+ return res
+}
+
+func Unserialize(b []byte, dst interface{}) {
+ if err := json.Unmarshal(b, dst); err != nil {
+ dst = nil
+ }
+}
+
+func SerializeStr(data interface{}, arg ...interface{}) string {
+ return string(Serialize(data))
+}