From cc5b0ce75a58572c20bcb35cb996573105c5b60e Mon Sep 17 00:00:00 2001 From: huangjiajun <582604932@qq.com> Date: Fri, 26 Aug 2022 13:35:11 +0800 Subject: [PATCH] =?UTF-8?q?add=20reverse:for=20v1.0.0=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .idea/zyos_go_third_party_api.iml | 9 + go.mod | 9 + go.sum | 8 + tik_tok/api.go | 115 ++++++++++ tik_tok/md_tik_tok_goods.go | 27 +++ tik_tok/svc_tik_tok_auth.go | 39 ++++ tik_tok/svc_tik_tok_convert.go | 89 ++++++++ tik_tok/svc_tik_tok_goods.go | 142 ++++++++++++ tik_tok/svc_tik_tok_live.go | 58 +++++ tik_tok/svc_tik_tok_order.go | 148 ++++++++++++ tik_tok/tik_tok_test.go | 9 + utils/convert.go | 366 ++++++++++++++++++++++++++++++ utils/curl.go | 231 +++++++++++++++++++ utils/serialize.go | 23 ++ utils/time.go | 233 +++++++++++++++++++ 18 files changed, 1528 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/zyos_go_third_party_api.iml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 tik_tok/api.go create mode 100644 tik_tok/md_tik_tok_goods.go create mode 100644 tik_tok/svc_tik_tok_auth.go create mode 100644 tik_tok/svc_tik_tok_convert.go create mode 100644 tik_tok/svc_tik_tok_goods.go create mode 100644 tik_tok/svc_tik_tok_live.go create mode 100644 tik_tok/svc_tik_tok_order.go create mode 100644 tik_tok/tik_tok_test.go create mode 100644 utils/convert.go create mode 100644 utils/curl.go create mode 100644 utils/serialize.go create mode 100644 utils/time.go diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5f6ea10 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/zyos_go_third_party_api.iml b/.idea/zyos_go_third_party_api.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/zyos_go_third_party_api.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..dab7a94 --- /dev/null +++ b/go.mod @@ -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 + +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..c7570e6 --- /dev/null +++ b/go.sum @@ -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= diff --git a/tik_tok/api.go b/tik_tok/api.go new file mode 100644 index 0000000..875f14f --- /dev/null +++ b/tik_tok/api.go @@ -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 +} diff --git a/tik_tok/md_tik_tok_goods.go b/tik_tok/md_tik_tok_goods.go new file mode 100644 index 0000000..82e767d --- /dev/null +++ b/tik_tok/md_tik_tok_goods.go @@ -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"` +} diff --git a/tik_tok/svc_tik_tok_auth.go b/tik_tok/svc_tik_tok_auth.go new file mode 100644 index 0000000..5af8c85 --- /dev/null +++ b/tik_tok/svc_tik_tok_auth.go @@ -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 +} diff --git a/tik_tok/svc_tik_tok_convert.go b/tik_tok/svc_tik_tok_convert.go new file mode 100644 index 0000000..08e7459 --- /dev/null +++ b/tik_tok/svc_tik_tok_convert.go @@ -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 +} diff --git a/tik_tok/svc_tik_tok_goods.go b/tik_tok/svc_tik_tok_goods.go new file mode 100644 index 0000000..b6cd6cf --- /dev/null +++ b/tik_tok/svc_tik_tok_goods.go @@ -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 + +} diff --git a/tik_tok/svc_tik_tok_live.go b/tik_tok/svc_tik_tok_live.go new file mode 100644 index 0000000..1b0d5d5 --- /dev/null +++ b/tik_tok/svc_tik_tok_live.go @@ -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 +} diff --git a/tik_tok/svc_tik_tok_order.go b/tik_tok/svc_tik_tok_order.go new file mode 100644 index 0000000..c79c3d0 --- /dev/null +++ b/tik_tok/svc_tik_tok_order.go @@ -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 +} diff --git a/tik_tok/tik_tok_test.go b/tik_tok/tik_tok_test.go new file mode 100644 index 0000000..5404527 --- /dev/null +++ b/tik_tok/tik_tok_test.go @@ -0,0 +1,9 @@ +package tik_tok + +import ( + "testing" +) + +func TestGoods(t *testing.T) { + GoodsOrder(map[string]string{}) +} diff --git a/utils/convert.go b/utils/convert.go new file mode 100644 index 0000000..2c6bade --- /dev/null +++ b/utils/convert.go @@ -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 +} diff --git a/utils/curl.go b/utils/curl.go new file mode 100644 index 0000000..1cbeb4b --- /dev/null +++ b/utils/curl.go @@ -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 +} diff --git a/utils/serialize.go b/utils/serialize.go new file mode 100644 index 0000000..ed07194 --- /dev/null +++ b/utils/serialize.go @@ -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)) +} diff --git a/utils/time.go b/utils/time.go new file mode 100644 index 0000000..a1a6046 --- /dev/null +++ b/utils/time.go @@ -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()) +}