@@ -0,0 +1,8 @@ | |||||
# 默认忽略的文件 | |||||
/shelf/ | |||||
/workspace.xml | |||||
# Datasource local storage ignored files | |||||
/dataSources/ | |||||
/dataSources.local.xml | |||||
# 基于编辑器的 HTTP 客户端请求 | |||||
/httpRequests/ |
@@ -0,0 +1,8 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="ProjectModuleManager"> | |||||
<modules> | |||||
<module fileurl="file://$PROJECT_DIR$/.idea/zyos_go_jg_push.iml" filepath="$PROJECT_DIR$/.idea/zyos_go_jg_push.iml" /> | |||||
</modules> | |||||
</component> | |||||
</project> |
@@ -0,0 +1,6 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="VcsDirectoryMappings"> | |||||
<mapping directory="$PROJECT_DIR$" vcs="Git" /> | |||||
</component> | |||||
</project> |
@@ -0,0 +1,9 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<module type="WEB_MODULE" version="4"> | |||||
<component name="Go" enabled="true" /> | |||||
<component name="NewModuleRootManager"> | |||||
<content url="file://$MODULE_DIR$" /> | |||||
<orderEntry type="inheritedJdk" /> | |||||
<orderEntry type="sourceFolder" forTests="false" /> | |||||
</component> | |||||
</module> |
@@ -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 |
@@ -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= |
@@ -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 | |||||
} |
@@ -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) | |||||
} |
@@ -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 系统浏览器打开 | |||||
} |
@@ -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) | |||||
} |
@@ -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) | |||||
} |
@@ -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)) | |||||
} |