@@ -0,0 +1,8 @@ | |||
# 默认忽略的文件 | |||
/shelf/ | |||
/workspace.xml | |||
# 基于编辑器的 HTTP 客户端请求 | |||
/httpRequests/ | |||
# Datasource local storage ignored files | |||
/dataSources/ | |||
/dataSources.local.xml |
@@ -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_third_party_api.iml" filepath="$PROJECT_DIR$/.idea/zyos_go_third_party_api.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,9 @@ | |||
module code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git | |||
go 1.15 | |||
require ( | |||
github.com/syyongx/php2go v0.9.7 | |||
github.com/tidwall/gjson v1.14.1 | |||
) |
@@ -0,0 +1,8 @@ | |||
github.com/syyongx/php2go v0.9.7 h1:boZtLbm2xYbW49mX9M7Vq2zkVhBhv3fCqs2T16d2bGA= | |||
github.com/syyongx/php2go v0.9.7/go.mod h1:meN2eIhhUoxOd2nMxbpe8g6cFPXI5O9/UAAuz7oDdzw= | |||
github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo= | |||
github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= | |||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= | |||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= | |||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= | |||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= |
@@ -0,0 +1,115 @@ | |||
package tik_tok | |||
import ( | |||
"bytes" | |||
zhios_third_party_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/utils" | |||
"crypto/hmac" | |||
"crypto/sha256" | |||
"encoding/hex" | |||
"encoding/json" | |||
"github.com/syyongx/php2go" | |||
"sort" | |||
"strings" | |||
"time" | |||
) | |||
func Send(appkey, appSecret, method string, params map[string]interface{}, acctoken string) (string, error) { | |||
methodPath := strings.ReplaceAll(method, ".", "/") | |||
url := "https://openapi-fxg.jinritemai.com/" + methodPath | |||
paramJson := GetSortJson(params) | |||
paramJson = strings.ReplaceAll(paramJson, "\n", "") | |||
param := map[string]string{ | |||
"app_key": appkey, | |||
"method": method, | |||
"param_json": paramJson, | |||
"timestamp": zhios_third_party_utils.Int64ToStr(time.Now().Unix()), | |||
"v": "2", | |||
} | |||
sign := GetSign(appSecret, param) | |||
if acctoken != "" { | |||
param["access_token"] = acctoken | |||
} | |||
param["sign"] = sign | |||
param["sign_method"] = "hmac-sha256" | |||
for k, v := range param { | |||
if strings.Contains(url, "?") { | |||
url += "&" + k + "=" + php2go.URLEncode(v) | |||
} else { | |||
url += "?" + k + "=" + php2go.URLEncode(v) | |||
} | |||
} | |||
data, err := zhios_third_party_utils.CurlPost(url, paramJson, nil) | |||
return string(data), err | |||
} | |||
func GetSign(appSecret string, param map[string]string) string { | |||
str := "" | |||
keys := KsortToStr(param) | |||
for _, k := range keys { | |||
str += k + param[k] | |||
} | |||
signStr := appSecret + str + appSecret | |||
h := hmac.New(sha256.New, []byte(appSecret)) | |||
_, _ = h.Write([]byte(signStr)) | |||
return hex.EncodeToString(h.Sum(nil)) | |||
} | |||
func Ksort(params map[string]interface{}) []string { | |||
keys := make([]string, len(params)) | |||
i := 0 | |||
for k, _ := range params { | |||
keys[i] = k | |||
i++ | |||
} | |||
sort.Strings(keys) | |||
return keys | |||
} | |||
func KsortToStr(params map[string]string) []string { | |||
keys := make([]string, len(params)) | |||
i := 0 | |||
for k, _ := range params { | |||
keys[i] = k | |||
i++ | |||
} | |||
sort.Strings(keys) | |||
return keys | |||
} | |||
//func GetSortJson(params map[string]interface{}) string { | |||
// // 排序 | |||
// keys := Ksort(params) | |||
// for _, k := range keys { | |||
// fmt.Println(k) | |||
// } | |||
// | |||
// byteBuf := bytes.NewBuffer([]byte{}) | |||
// encoder := json.NewEncoder(byteBuf) | |||
// // 特殊字符不转义 | |||
// encoder.SetEscapeHTML(false) | |||
// err := encoder.Encode(params) | |||
// if err != nil { | |||
// panic(err) | |||
// } | |||
// data := byteBuf.String() | |||
// return data | |||
//} | |||
// Marshal 序列化参数 | |||
func GetSortJson(o interface{}) string { | |||
// 序列化一次 | |||
raw, _ := json.Marshal(o) | |||
// 反序列化为map | |||
m := make(map[string]interface{}) | |||
reader := bytes.NewReader(raw) | |||
decode := json.NewDecoder(reader) | |||
decode.UseNumber() | |||
_ = decode.Decode(&m) | |||
// 重新做一次序列化,并禁用Html Escape | |||
buffer := bytes.NewBufferString("") | |||
encoder := json.NewEncoder(buffer) | |||
encoder.SetEscapeHTML(false) | |||
_ = encoder.Encode(m) | |||
marshal := strings.TrimSpace(buffer.String()) // Trim掉末尾的换行符 | |||
return marshal | |||
} |
@@ -0,0 +1,27 @@ | |||
package tik_tok | |||
type TikTokGoods struct { | |||
Commission string `json:"commission"` | |||
CostPrice string `json:"cost_price"` | |||
DetailURL string `json:"detail_url"` | |||
GoodsID string `json:"goods_id"` | |||
GoodsImg string `json:"goods_img"` | |||
GoodsSales string `json:"goods_sales"` | |||
GoodsTitle string `json:"goods_title"` | |||
Imgs []interface{} `json:"imgs"` | |||
InStock string `json:"in_stock"` | |||
Price string `json:"price"` | |||
Sharable string `json:"sharable"` | |||
ShopID string `json:"shop_id"` | |||
ShopName string `json:"shop_name"` | |||
ShopTotalScore string `json:"shop_total_score"` | |||
YhqPrice string `json:"yhq_price"` | |||
} | |||
type TikTokLive struct { | |||
LiveId string `json:"live_id"` | |||
Name string `json:"name"` | |||
HeadImg string `json:"head_img"` | |||
FansNum string `json:"fans_num"` | |||
IsLive string `json:"is_live"` | |||
Pvd string `json:"pvd"` | |||
} |
@@ -0,0 +1,39 @@ | |||
package tik_tok | |||
import ( | |||
zhios_third_party_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/utils" | |||
"github.com/tidwall/gjson" | |||
"time" | |||
) | |||
//第一次授权 | |||
func FirstAuth(args map[string]string) map[string]string { | |||
params := map[string]interface{}{"code": args["code"], "grant_type": args["grantType"]} | |||
send, err := Send(args["appkey"], args["appSecret"], "token.create", params, args["acctoken"]) | |||
var data = map[string]string{} | |||
if err != nil { | |||
return data | |||
} | |||
endTime := time.Now().Unix() + gjson.Get(send, "data.expires_in").Int() - 10 | |||
data = map[string]string{ | |||
"tik_tok_acc_token": gjson.Get(send, "data.access_token").String(), | |||
"tik_tok_acc_token_time": zhios_third_party_utils.Int64ToStr(endTime), | |||
"tik_tok_acc_refresh_token": gjson.Get(send, "data.refresh_token").String(), | |||
} | |||
return data | |||
} | |||
func RefreshAuth(args map[string]string) map[string]string { | |||
params := map[string]interface{}{"refresh_token": args["refresh_token"], "grant_type": "refresh_token"} | |||
send, err := Send(args["appkey"], args["appSecret"], "token.refresh", params, args["acctoken"]) | |||
var data = map[string]string{} | |||
if err != nil { | |||
return data | |||
} | |||
endTime := time.Now().Unix() + gjson.Get(send, "data.expires_in").Int() - 10 | |||
data = map[string]string{ | |||
"tik_tok_acc_token": gjson.Get(send, "data.access_token").String(), | |||
"tik_tok_acc_token_time": zhios_third_party_utils.Int64ToStr(endTime), | |||
"tik_tok_acc_refresh_token": gjson.Get(send, "data.refresh_token").String(), | |||
} | |||
return data | |||
} |
@@ -0,0 +1,89 @@ | |||
package tik_tok | |||
import ( | |||
"fmt" | |||
"github.com/syyongx/php2go" | |||
"github.com/tidwall/gjson" | |||
) | |||
//创建推广位 | |||
func GoodsCreatePid(args map[string]string) map[string]string { | |||
//args = map[string]string{ | |||
// "appkey": "7076371480799348261", | |||
// "appSecret": "9e58409e-5729-441e-a9f3-c077ec939fbb", | |||
// "acctoken": "52f7ea67-5267-4874-9e05-a837dd1d6a48", | |||
// "media_name": "测试", | |||
// "site_name": "测试", | |||
//} | |||
params := map[string]interface{}{"media_type": "4", "media_name": args["media_name"], "site_name": args["site_name"]} | |||
send, err := Send(args["appkey"], args["appSecret"], "buyin.kolPidCreate", params, args["acctoken"]) | |||
fmt.Println(send) | |||
var data = map[string]string{} | |||
if err != nil { | |||
return data | |||
} | |||
data["pid"] = gjson.Get(send, "data.pid").String() | |||
return data | |||
} | |||
func GoodsConvertUrl(args map[string]string) map[string]string { | |||
//args = map[string]string{ | |||
// "appkey": "7076371480799348261", | |||
// "appSecret": "9e58409e-5729-441e-a9f3-c077ec939fbb", | |||
// "acctoken": "52f7ea67-5267-4874-9e05-a837dd1d6a48", | |||
// "external_info": "123", | |||
// "pid": "dy_107018934375430799627_13603_920074249", | |||
// "product_url": "https://haohuo.jinritemai.com/views/product/item2?id=3378039360158085752", | |||
//} | |||
params := map[string]interface{}{"pid": args["pid"], "external_info": args["external_info"], "product_url": args["product_url"]} | |||
send, err := Send(args["appkey"], args["appSecret"], "buyin.kolProductShare", params, args["acctoken"]) | |||
fmt.Println(send) | |||
var data = map[string]string{} | |||
if err != nil { | |||
return data | |||
} | |||
data["deeplink"] = gjson.Get(send, "data.dy_deeplink").String() | |||
data["content"] = php2go.Base64Encode(gjson.Get(send, "data.dy_password").String()) | |||
data["qr_code"] = gjson.Get(send, "data.qr_code.url").String() | |||
return data | |||
} | |||
func LiveCreatePid(args map[string]string) map[string]string { | |||
//args = map[string]string{ | |||
// "appkey": "7076371480799348261", | |||
// "appSecret": "9e58409e-5729-441e-a9f3-c077ec939fbb", | |||
// "acctoken": "52f7ea67-5267-4874-9e05-a837dd1d6a48", | |||
// "media_name": "测试", | |||
// "site_name": "测试", | |||
//} | |||
params := map[string]interface{}{"media_type": "4", "media_name": args["media_name"], "site_name": args["site_name"]} | |||
send, err := Send(args["appkey"], args["appSecret"], "buyin.institutePidCreate", params, args["acctoken"]) | |||
fmt.Println(send) | |||
var data = map[string]string{} | |||
if err != nil { | |||
return data | |||
} | |||
data["pid"] = gjson.Get(send, "data.pid").String() | |||
return data | |||
} | |||
func LiveConvertUrl(args map[string]string) map[string]string { | |||
//args = map[string]string{ | |||
// "appkey": "7076371480799348261", | |||
// "appSecret": "9e58409e-5729-441e-a9f3-c077ec939fbb", | |||
// "acctoken": "52f7ea67-5267-4874-9e05-a837dd1d6a48", | |||
// "external_info": "123", | |||
// "pid": "dy_107018934375430799627_13603_920074249", | |||
// "product_url": "https://haohuo.jinritemai.com/views/product/item2?id=3378039360158085752", | |||
//} | |||
params := map[string]interface{}{"pid_info": map[string]interface{}{"pid": args["pid"], "external_info": args["external_info"]}, "open_id": args["open_id"]} | |||
send, err := Send(args["appkey"], args["appSecret"], "buyin.instituteLiveShare", params, args["acctoken"]) | |||
fmt.Println(send) | |||
var data = map[string]string{} | |||
if err != nil { | |||
return data | |||
} | |||
data["deeplink"] = gjson.Get(send, "data.dy_deeplink").String() | |||
data["content"] = php2go.Base64Encode(gjson.Get(send, "data.dy_password").String()) | |||
data["qr_code"] = gjson.Get(send, "data.qr_code.url").String() | |||
return data | |||
} |
@@ -0,0 +1,142 @@ | |||
package tik_tok | |||
import ( | |||
zhios_third_party_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/utils" | |||
"encoding/json" | |||
"github.com/syyongx/php2go" | |||
"github.com/tidwall/gjson" | |||
) | |||
//抖音商品 | |||
func GoodsList(args map[string]string) []TikTokGoods { | |||
sortArr := map[string]map[string]string{ | |||
"default": {"search_type": "0", "sort_type": "0"}, | |||
"qhPriceDesc": {"search_type": "2", "sort_type": "1"}, | |||
"qhPriceAsc": {"search_type": "2", "sort_type": "0"}, | |||
"commissionDesc": {"search_type": "4", "sort_type": "1"}, | |||
"commissionAsc": {"search_type": "4", "sort_type": "0"}, | |||
"salesDesc": {"search_type": "1", "sort_type": "1"}, | |||
"salesAsc": {"search_type": "1", "sort_type": "0"}, | |||
} | |||
params := map[string]interface{}{ | |||
"search_type": sortArr[args["sort"]]["search_type"], | |||
"sort_type": sortArr[args["sort"]]["sort_type"], | |||
"page": args["page"], | |||
"page_size": args["page_size"], | |||
"share_status": "1", | |||
} | |||
if args["title"] != "" { | |||
params["title"] = args["title"] | |||
} | |||
if args["first_cids"] != "" { | |||
params["first_cids"] = []string{args["first_cids"]} | |||
} | |||
if args["price_min"] != "" { | |||
params["price_min"] = zhios_third_party_utils.Float64ToStr(zhios_third_party_utils.StrToFloat64(args["price_min"]) * 100) | |||
} | |||
if args["price_max"] != "" { | |||
params["price_max"] = zhios_third_party_utils.Float64ToStr(zhios_third_party_utils.StrToFloat64(args["price_max"]) * 100) | |||
} | |||
if args["sell_num_min"] != "" { | |||
params["sell_num_min"] = args["sell_num_min"] | |||
} | |||
if args["sell_num_max"] != "" { | |||
params["sell_num_max"] = args["sell_num_max"] | |||
} | |||
if args["cos_fee_min"] != "" { | |||
params["cos_fee_min"] = zhios_third_party_utils.Float64ToStr(zhios_third_party_utils.StrToFloat64(args["cos_fee_min"]) * 100) | |||
} | |||
if args["cos_fee_max"] != "" { | |||
params["cos_fee_max"] = zhios_third_party_utils.Float64ToStr(zhios_third_party_utils.StrToFloat64(args["cos_fee_max"]) * 100) | |||
} | |||
if args["cos_ratio_min"] != "" { | |||
params["cos_ratio_min"] = zhios_third_party_utils.Float64ToStr(zhios_third_party_utils.StrToFloat64(args["cos_ratio_min"]) * 100) | |||
} | |||
if args["cos_ratio_max"] != "" { | |||
params["cos_ratio_max"] = zhios_third_party_utils.Float64ToStr(zhios_third_party_utils.StrToFloat64(args["cos_ratio_max"]) * 100) | |||
} | |||
send, err := Send(args["appkey"], args["appSecret"], "alliance.materialsProductsSearch", params, args["acctoken"]) | |||
var goodsList = make([]TikTokGoods, 0) | |||
product := gjson.Get(send, "data.products").String() | |||
if err != nil || product == "" { | |||
return goodsList | |||
} | |||
var tmpList = make([]interface{}, 0) | |||
err = json.Unmarshal([]byte(product), &tmpList) | |||
if err != nil { | |||
return goodsList | |||
} | |||
for _, v := range tmpList { | |||
goods := v.(map[string]interface{}) | |||
tmp := CommGoodsDetail(goods) | |||
goodsList = append(goodsList, tmp) | |||
} | |||
return goodsList | |||
} | |||
//详情 | |||
func GetDetail(args map[string]string) TikTokGoods { | |||
params := map[string]interface{}{"product_ids": []string{args["id"]}, "with_share_status": true} | |||
send, err := Send(args["appkey"], args["appSecret"], "alliance.materialsProductsDetails", params, args["acctoken"]) | |||
var goodsList = TikTokGoods{} | |||
product := gjson.Get(send, "data.products").String() | |||
if err != nil || product == "" { | |||
return goodsList | |||
} | |||
var tmpList = make([]interface{}, 0) | |||
err = json.Unmarshal([]byte(product), &tmpList) | |||
if err != nil { | |||
return goodsList | |||
} | |||
for _, v := range tmpList { | |||
goods := v.(map[string]interface{}) | |||
tmp := CommGoodsDetail(goods) | |||
if tmp.GoodsID == args["id"] { | |||
return tmp | |||
} | |||
} | |||
return goodsList | |||
} | |||
func GetKlGoods(args map[string]string) TikTokGoods { | |||
params := map[string]interface{}{"command": php2go.Base64Encode(args["content"])} | |||
send, err := Send(args["appkey"], args["appSecret"], "buyin.shareCommandParse", params, args["acctoken"]) | |||
var goodsList = TikTokGoods{} | |||
product := gjson.Get(send, "data.product_info").String() | |||
if err != nil || product == "" { | |||
return goodsList | |||
} | |||
args["id"] = gjson.Get(product, "product_id").String() | |||
goodsList = GetDetail(args) | |||
return goodsList | |||
} | |||
func CommGoodsDetail(goods map[string]interface{}) TikTokGoods { | |||
img := make([]interface{}, 0) | |||
imgs, ok := goods["imgs"].([]interface{}) | |||
if ok { | |||
img = imgs | |||
} | |||
var tmp = TikTokGoods{ | |||
Commission: zhios_third_party_utils.AnyToString(goods["cos_ratio"]), | |||
CostPrice: zhios_third_party_utils.Float64ToStr(zhios_third_party_utils.AnyToFloat64(goods["price"]) / 100), | |||
DetailURL: zhios_third_party_utils.AnyToString(goods["detail_url"]), | |||
GoodsID: zhios_third_party_utils.AnyToString(goods["product_id"]), | |||
GoodsImg: zhios_third_party_utils.AnyToString(goods["cover"]), | |||
GoodsSales: zhios_third_party_utils.AnyToString(goods["sales"]), | |||
GoodsTitle: zhios_third_party_utils.AnyToString(goods["title"]), | |||
Imgs: img, | |||
InStock: zhios_third_party_utils.AnyToString(goods["in_stock"]), | |||
Price: zhios_third_party_utils.Float64ToStr(zhios_third_party_utils.AnyToFloat64(goods["coupon_price"]) / 100), | |||
Sharable: zhios_third_party_utils.AnyToString(goods["sharable"]), | |||
ShopID: zhios_third_party_utils.AnyToString(goods["shop_id"]), | |||
ShopName: zhios_third_party_utils.AnyToString(goods["shop_name"]), | |||
ShopTotalScore: zhios_third_party_utils.AnyToString(goods["shop_total_score"]), | |||
YhqPrice: "0", | |||
} | |||
if zhios_third_party_utils.StrToFloat64(tmp.Price) == 0 { | |||
tmp.Price = tmp.CostPrice | |||
} else { | |||
tmp.YhqPrice = zhios_third_party_utils.Float64ToStr(zhios_third_party_utils.AnyToFloat64(goods["price"])/100 - zhios_third_party_utils.AnyToFloat64(goods["coupon_price"])/100) | |||
} | |||
return tmp | |||
} |
@@ -0,0 +1,58 @@ | |||
package tik_tok | |||
import ( | |||
zhios_third_party_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/utils" | |||
"encoding/json" | |||
"github.com/tidwall/gjson" | |||
) | |||
func LiveList(args map[string]string) []TikTokLive { | |||
params := map[string]interface{}{"page": args["page"], "page_size": args["page_size"]} | |||
if args["author_type"] != "" { | |||
params["author_type"] = args["author_type"] | |||
} | |||
if args["author_levels"] != "" { | |||
params["author_levels"] = []string{args["author_levels"]} | |||
} | |||
if args["first_cids"] != "" { | |||
params["first_cids"] = []string{args["first_cids"]} | |||
} | |||
if args["keyword"] != "" { | |||
params["keyword"] = args["keyword"] | |||
} | |||
if args["sell_num_max"] != "" { | |||
params["sell_num_max"] = args["sell_num_max"] | |||
} | |||
if args["sort_type"] != "" { | |||
params["sort_type"] = args["sort_type"] | |||
} | |||
if args["sort_by"] != "" { | |||
params["sort_by"] = args["sort_by"] | |||
} | |||
send, err := Send(args["appkey"], args["appSecret"], "buyin.liveShareMaterial", params, args["acctoken"]) | |||
var goodsList = make([]TikTokLive, 0) | |||
product := gjson.Get(send, "data.data").String() | |||
if err != nil || product == "" { | |||
return goodsList | |||
} | |||
var tmpList = make([]interface{}, 0) | |||
err = json.Unmarshal([]byte(product), &tmpList) | |||
if err != nil { | |||
return goodsList | |||
} | |||
for _, v := range tmpList { | |||
goods := v.(map[string]interface{}) | |||
if zhios_third_party_utils.AnyToBool(goods["is_live"]) == false { | |||
continue | |||
} | |||
tmp := TikTokLive{ | |||
LiveId: zhios_third_party_utils.AnyToString(goods["author_openid"]), | |||
Name: zhios_third_party_utils.AnyToString(goods["author_name"]), | |||
HeadImg: zhios_third_party_utils.AnyToString(goods["author_pic"]), | |||
FansNum: zhios_third_party_utils.AnyToString(goods["fans_num"]), | |||
Pvd: "tikTok", | |||
} | |||
goodsList = append(goodsList, tmp) | |||
} | |||
return goodsList | |||
} |
@@ -0,0 +1,148 @@ | |||
package tik_tok | |||
import ( | |||
zhios_third_party_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/utils" | |||
"encoding/json" | |||
"fmt" | |||
"github.com/tidwall/gjson" | |||
"strings" | |||
) | |||
func GoodsOrder(args map[string]string) map[string]interface{} { | |||
args = map[string]string{ | |||
"appkey": "7076371480799348261", | |||
"appSecret": "9e58409e-5729-441e-a9f3-c077ec939fbb", | |||
"acctoken": "52f7ea67-5267-4874-9e05-a837dd1d6a48", | |||
"size": "10", | |||
"cursor": "0", | |||
"start_time": "2022-08-25 00:00:00", | |||
"end_time": "2022-08-26 00:00:00", | |||
} | |||
params := map[string]interface{}{"size": args["size"], "cursor": args["cursor"], "start_time": args["start_time"], "end_time": args["end_time"], "distribution_type": "ProductDetail"} | |||
send, err := Send(args["appkey"], args["appSecret"], "buyin.kolOrderAds", params, args["acctoken"]) | |||
fmt.Println(send) | |||
var data = map[string]interface{}{} | |||
if err != nil { | |||
return data | |||
} | |||
order := gjson.Get(send, "data.orders").String() | |||
data["cursor"] = gjson.Get(send, "data.cursor").String() | |||
var tmpList = make([]interface{}, 0) | |||
err = json.Unmarshal([]byte(order), &tmpList) | |||
if err != nil { | |||
return data | |||
} | |||
var orderTmp = make([]map[string]string, 0) | |||
statusArr := map[string]string{ | |||
"PAY_SUCC": "订单付款", | |||
"REFUND": "订单退款", | |||
"SETTLE": "订单结算", | |||
"CONFIRM": "订单成功", | |||
} | |||
for _, v := range tmpList { | |||
tmp := CommOrder(v, statusArr) | |||
if tmp["oid"] == "" { | |||
continue | |||
} | |||
orderTmp = append(orderTmp, tmp) | |||
} | |||
data["order"] = orderTmp | |||
return data | |||
} | |||
func LiveOrder(args map[string]string) map[string]interface{} { | |||
//args = map[string]string{ | |||
// "appkey": "7076371480799348261", | |||
// "appSecret": "9e58409e-5729-441e-a9f3-c077ec939fbb", | |||
// "acctoken": "52f7ea67-5267-4874-9e05-a837dd1d6a48", | |||
// "size": "10", | |||
// "cursor": "0", | |||
// "start_time": "2022-08-26 00:00:00", | |||
// "end_time": "2022-08-27 00:00:00", | |||
//} | |||
params := map[string]interface{}{"size": args["size"], "cursor": args["cursor"], "start_time": args["start_time"], "end_time": args["end_time"], "distribution_type": "Live"} | |||
send, err := Send(args["appkey"], args["appSecret"], "buyin.instituteOrderAds", params, args["acctoken"]) | |||
fmt.Println(send) | |||
var data = map[string]interface{}{} | |||
if err != nil { | |||
return data | |||
} | |||
order := gjson.Get(send, "data.orders").String() | |||
data["cursor"] = gjson.Get(send, "data.cursor").String() | |||
var tmpList = make([]interface{}, 0) | |||
err = json.Unmarshal([]byte(order), &tmpList) | |||
if err != nil { | |||
return data | |||
} | |||
var orderTmp = make([]map[string]string, 0) | |||
statusArr := map[string]string{ | |||
"PAY_SUCC": "订单付款", | |||
"REFUND": "订单退款", | |||
"SETTLE": "订单结算", | |||
"CONFIRM": "订单成功", | |||
} | |||
for _, v := range tmpList { | |||
tmp := CommOrder(v, statusArr) | |||
if tmp["oid"] == "" { | |||
continue | |||
} | |||
orderTmp = append(orderTmp, tmp) | |||
} | |||
data["order"] = orderTmp | |||
return data | |||
} | |||
func CommOrder(v interface{}, statusArr map[string]string) map[string]string { | |||
tmp := make(map[string]string) | |||
goods := v.(map[string]interface{}) | |||
pidInfo, ok := goods["pid_info"].(map[string]interface{}) | |||
mediaTypeName := "" | |||
if ok == false { | |||
return tmp | |||
} | |||
mediaTypeName = zhios_third_party_utils.AnyToString(pidInfo["media_type_name"]) | |||
tmp = map[string]string{ | |||
"pid": zhios_third_party_utils.AnyToString(pidInfo["pid"]), | |||
"oid": zhios_third_party_utils.AnyToString(goods["order_id"]), | |||
"info": zhios_third_party_utils.AnyToString(goods["product_name"]), | |||
"num": zhios_third_party_utils.AnyToString(goods["item_num"]), | |||
"type": zhios_third_party_utils.AnyToString(mediaTypeName), | |||
"product_id": zhios_third_party_utils.AnyToString(goods["product_id"]), | |||
"product_img": zhios_third_party_utils.AnyToString(goods["product_img"]), | |||
"payment": zhios_third_party_utils.AnyToString(zhios_third_party_utils.AnyToFloat64(goods["total_pay_amount"]) / 100), | |||
"status": statusArr[zhios_third_party_utils.AnyToString(goods["flow_point"])], | |||
"create_time": zhios_third_party_utils.Int64ToStr(zhios_third_party_utils.TimeStdParseUnix(zhios_third_party_utils.AnyToString(goods["pay_success_time"]))), | |||
"update_time": zhios_third_party_utils.Int64ToStr(zhios_third_party_utils.TimeStdParseUnix(zhios_third_party_utils.AnyToString(goods["update_time"]))), | |||
"refund_time": "", | |||
"lm_js_time": "", | |||
} | |||
external_info := zhios_third_party_utils.AnyToString(pidInfo["external_info"]) | |||
tmp["is_share"] = "0" | |||
split := strings.Split(external_info, "_") | |||
if len(split) > 1 { | |||
if split[0] == "s" { | |||
tmp["is_share"] = "1" | |||
} | |||
tmp["uid"] = split[1] | |||
} | |||
if tmp["type"] == "Live" { | |||
tmp["commission"] = zhios_third_party_utils.AnyToString(zhios_third_party_utils.AnyToFloat64(goods["ads_estimated_commission"]) / 100) | |||
if zhios_third_party_utils.AnyToFloat64(goods["ads_real_commission"]) > 0 { | |||
tmp["commission"] = zhios_third_party_utils.AnyToString(zhios_third_party_utils.AnyToFloat64(goods["ads_real_commission"]) / 100) | |||
} | |||
} | |||
if tmp["type"] == "ProductDetail" { | |||
tmp["commission"] = zhios_third_party_utils.AnyToString(zhios_third_party_utils.AnyToFloat64(goods["estimated_commission"]) / 100) | |||
if zhios_third_party_utils.AnyToFloat64(goods["real_commission"]) > 0 { | |||
tmp["commission"] = zhios_third_party_utils.AnyToString(zhios_third_party_utils.AnyToFloat64(goods["real_commission"]) / 100) | |||
} | |||
} | |||
if zhios_third_party_utils.AnyToString(goods["refund_time"]) != "" { | |||
tmp["refund_time"] = zhios_third_party_utils.Int64ToStr(zhios_third_party_utils.TimeStdParseUnix(zhios_third_party_utils.AnyToString(goods["pay_success_time"]))) | |||
} | |||
if zhios_third_party_utils.AnyToString(goods["settle_time"]) != "" { | |||
tmp["lm_js_time"] = zhios_third_party_utils.Int64ToStr(zhios_third_party_utils.TimeStdParseUnix(zhios_third_party_utils.AnyToString(goods["settle_time"]))) | |||
} | |||
return tmp | |||
} |
@@ -0,0 +1,9 @@ | |||
package tik_tok | |||
import ( | |||
"testing" | |||
) | |||
func TestGoods(t *testing.T) { | |||
GoodsOrder(map[string]string{}) | |||
} |
@@ -0,0 +1,366 @@ | |||
package zhios_third_party_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 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 Float64ToStrByPrec(f float64, prec int) string { | |||
return strconv.FormatFloat(f, 'f', prec, 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 StrToFormat(s string, prec int) string { | |||
ex := strings.Split(s, ".") | |||
if len(ex) == 2 { | |||
if StrToFloat64(ex[1]) == 0 { //小数点后面为空就是不要小数点了 | |||
return ex[0] | |||
} | |||
//看取多少位 | |||
str := ex[1] | |||
str1 := str | |||
if prec < len(str) { | |||
str1 = str[0:prec] | |||
} else { | |||
for i := 0; i < prec-len(str); i++ { | |||
str1 += "0" | |||
} | |||
} | |||
if prec > 0 { | |||
return ex[0] + "." + str1 | |||
} else { | |||
return ex[0] | |||
} | |||
} | |||
return s | |||
} | |||
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) | |||
} | |||
func IntToFloat64(i int) float64 { | |||
s := strconv.Itoa(i) | |||
res, err := strconv.ParseFloat(s, 64) | |||
if err != nil { | |||
return 0 | |||
} | |||
return res | |||
} | |||
func Int64ToFloat64(i int64) float64 { | |||
s := strconv.FormatInt(i, 10) | |||
res, err := strconv.ParseFloat(s, 64) | |||
if err != nil { | |||
return 0 | |||
} | |||
return res | |||
} |
@@ -0,0 +1,231 @@ | |||
package zhios_third_party_utils | |||
import ( | |||
"bytes" | |||
"crypto/tls" | |||
"encoding/json" | |||
"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) | |||
} | |||
func CurlGetJson(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl_new(http.MethodGet, router, body, 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 { | |||
va, ok := v.(string) | |||
if !ok { | |||
val.Set(k, convertToString(va)) | |||
} else { | |||
val.Set(k, va) | |||
} | |||
} | |||
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 curl_new(method, router string, body interface{}, header map[string]string) ([]byte, error) { | |||
var reqBody io.Reader | |||
contentType := "application/json" | |||
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) | |||
} | |||
func convertToString(v interface{}) string { | |||
if v == nil { | |||
return "" | |||
} | |||
var ( | |||
bs []byte | |||
err error | |||
) | |||
if bs, err = json.Marshal(v); err != nil { | |||
return "" | |||
} | |||
str := string(bs) | |||
return str | |||
} |
@@ -0,0 +1,23 @@ | |||
package zhios_third_party_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)) | |||
} |
@@ -0,0 +1,233 @@ | |||
package zhios_third_party_utils | |||
import ( | |||
"errors" | |||
"fmt" | |||
"strconv" | |||
"strings" | |||
"time" | |||
) | |||
func StrToTime(s string) (int64, error) { | |||
// delete all not int characters | |||
if s == "" { | |||
return time.Now().Unix(), nil | |||
} | |||
r := make([]rune, 14) | |||
l := 0 | |||
// 过滤除数字以外的字符 | |||
for _, v := range s { | |||
if '0' <= v && v <= '9' { | |||
r[l] = v | |||
l++ | |||
if l == 14 { | |||
break | |||
} | |||
} | |||
} | |||
for l < 14 { | |||
r[l] = '0' // 补0 | |||
l++ | |||
} | |||
t, err := time.Parse("20060102150405", string(r)) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return t.Unix(), nil | |||
} | |||
func String2Time(timeStr string) time.Time { | |||
toTime, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local) | |||
if err != nil { | |||
return time.Now() | |||
} | |||
return toTime | |||
} | |||
func TimeToStr(unixSecTime interface{}, layout ...string) string { | |||
i := AnyToInt64(unixSecTime) | |||
if i == 0 { | |||
return "" | |||
} | |||
f := "2006-01-02 15:04:05" | |||
if len(layout) > 0 { | |||
f = layout[0] | |||
} | |||
return time.Unix(i, 0).Format(f) | |||
} | |||
func Time2String(date time.Time, format string) string { | |||
if format == "" { | |||
format = "2006-01-02 15:04:05" | |||
} | |||
timeS := date.Format(format) | |||
if timeS == "0001-01-01 00:00:00" { | |||
return "" | |||
} | |||
return timeS | |||
} | |||
func FormatNanoUnix() string { | |||
return strings.Replace(time.Now().Format("20060102150405.0000000"), ".", "", 1) | |||
} | |||
func TimeParse(format, src string) (time.Time, error) { | |||
return time.ParseInLocation(format, src, time.Local) | |||
} | |||
func TimeParseStd(src string) time.Time { | |||
t, _ := TimeParse("2006-01-02 15:04:05", src) | |||
return t | |||
} | |||
func TimeStdParseUnix(src string) int64 { | |||
t, err := TimeParse("2006-01-02 15:04:05", src) | |||
if err != nil { | |||
return 0 | |||
} | |||
return t.Unix() | |||
} | |||
// 获取一个当前时间 时间间隔 时间戳 | |||
func GetTimeInterval(unit string, amount int) (startTime, endTime int64) { | |||
t := time.Now() | |||
nowTime := t.Unix() | |||
tmpTime := int64(0) | |||
switch unit { | |||
case "years": | |||
tmpTime = time.Date(t.Year()+amount, t.Month(), t.Day(), t.Hour(), 0, 0, 0, t.Location()).Unix() | |||
case "months": | |||
tmpTime = time.Date(t.Year(), t.Month()+time.Month(amount), t.Day(), t.Hour(), 0, 0, 0, t.Location()).Unix() | |||
case "days": | |||
tmpTime = time.Date(t.Year(), t.Month(), t.Day()+amount, t.Hour(), 0, 0, 0, t.Location()).Unix() | |||
case "hours": | |||
tmpTime = time.Date(t.Year(), t.Month(), t.Day(), t.Hour()+amount, 0, 0, 0, t.Location()).Unix() | |||
} | |||
if amount > 0 { | |||
startTime = nowTime | |||
endTime = tmpTime | |||
} else { | |||
startTime = tmpTime | |||
endTime = nowTime | |||
} | |||
return | |||
} | |||
// 几天前 | |||
func TimeInterval(newTime int) string { | |||
now := time.Now().Unix() | |||
newTime64 := AnyToInt64(newTime) | |||
if newTime64 >= now { | |||
return "刚刚" | |||
} | |||
interval := now - newTime64 | |||
switch { | |||
case interval < 60: | |||
return AnyToString(interval) + "秒前" | |||
case interval < 60*60: | |||
return AnyToString(interval/60) + "分前" | |||
case interval < 60*60*24: | |||
return AnyToString(interval/60/60) + "小时前" | |||
case interval < 60*60*24*30: | |||
return AnyToString(interval/60/60/24) + "天前" | |||
case interval < 60*60*24*30*12: | |||
return AnyToString(interval/60/60/24/30) + "月前" | |||
default: | |||
return AnyToString(interval/60/60/24/30/12) + "年前" | |||
} | |||
} | |||
// 时分秒字符串转时间戳,传入示例:8:40 or 8:40:10 | |||
func HmsToUnix(str string) (int64, error) { | |||
t := time.Now() | |||
arr := strings.Split(str, ":") | |||
if len(arr) < 2 { | |||
return 0, errors.New("Time format error") | |||
} | |||
h, _ := strconv.Atoi(arr[0]) | |||
m, _ := strconv.Atoi(arr[1]) | |||
s := 0 | |||
if len(arr) == 3 { | |||
s, _ = strconv.Atoi(arr[3]) | |||
} | |||
formatted1 := fmt.Sprintf("%d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(), h, m, s) | |||
res, err := time.ParseInLocation("20060102150405", formatted1, time.Local) | |||
if err != nil { | |||
return 0, err | |||
} else { | |||
return res.Unix(), nil | |||
} | |||
} | |||
// 获取特定时间范围 | |||
func GetTimeRange(s string) map[string]int64 { | |||
t := time.Now() | |||
var stime, etime time.Time | |||
switch s { | |||
case "today": | |||
stime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "yesterday": | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-1, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
case "within_seven_days": | |||
// 前6天0点 | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-6, 0, 0, 0, 0, t.Location()) | |||
// 明天 0点 | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "current_month": | |||
stime = time.Date(t.Year(), t.Month(), 0, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month()+1, 0, 0, 0, 0, 0, t.Location()) | |||
case "last_month": | |||
stime = time.Date(t.Year(), t.Month()-1, 0, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), 0, 0, 0, 0, 0, t.Location()) | |||
} | |||
return map[string]int64{ | |||
"start": stime.Unix(), | |||
"end": etime.Unix(), | |||
} | |||
} | |||
// 获取特定时间范围 | |||
func GetDateTimeRangeStr(s string) (string, string) { | |||
t := time.Now() | |||
var stime, etime time.Time | |||
switch s { | |||
case "today": | |||
stime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "yesterday": | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-1, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
case "within_seven_days": | |||
// 前6天0点 | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-6, 0, 0, 0, 0, t.Location()) | |||
// 明天 0点 | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "current_month": | |||
stime = time.Date(t.Year(), t.Month(), 0, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month()+1, 0, 0, 0, 0, 0, t.Location()) | |||
case "last_month": | |||
stime = time.Date(t.Year(), t.Month()-1, 0, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), 0, 0, 0, 0, 0, t.Location()) | |||
} | |||
return stime.Format("2006-01-02 15:04:05"), etime.Format("2006-01-02 15:04:05") | |||
} | |||
//获取传入的时间所在月份的第一天,即某月第一天的0点。如传入time.Now(), 返回当前月份的第一天0点时间。 | |||
func GetFirstDateOfMonth(d time.Time) time.Time { | |||
d = d.AddDate(0, 0, -d.Day()+1) | |||
return GetZeroTime(d) | |||
} | |||
//获取传入的时间所在月份的最后一天,即某月最后一天的0点。如传入time.Now(), 返回当前月份的最后一天0点时间。 | |||
func GetLastDateOfMonth(d time.Time) time.Time { | |||
return GetFirstDateOfMonth(d).AddDate(0, 1, -1) | |||
} | |||
//获取某一天的0点时间 | |||
func GetZeroTime(d time.Time) time.Time { | |||
return time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location()) | |||
} |