@@ -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()) | |||||
} |