diff --git a/comm/api.go b/comm/api.go new file mode 100644 index 0000000..8b5921f --- /dev/null +++ b/comm/api.go @@ -0,0 +1,51 @@ +package comm + +import ( + "bytes" + "encoding/json" + "sort" + "strings" +) + +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 +} + +// 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/comm/cache.go b/comm/cache.go new file mode 100644 index 0000000..1b46d2d --- /dev/null +++ b/comm/cache.go @@ -0,0 +1,9 @@ +package comm + +import "time" + +// GetCacheFunc 获取缓存委托 +type getCacheFunc func(cacheKey string) []byte + +// SetCacheFunc 设置缓存委托 +type setCacheFunc func(cacheKey string, value []byte, expiration time.Duration) bool diff --git a/comm/client.go b/comm/client.go new file mode 100644 index 0000000..fd876f2 --- /dev/null +++ b/comm/client.go @@ -0,0 +1,324 @@ +package comm + +import ( + "bytes" + "crypto/md5" + "crypto/tls" + "encoding/hex" + "encoding/json" + "errors" + "io" + "io/ioutil" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "time" + + "github.com/bitly/go-simplejson" + "github.com/nilorg/sdk/convert" +) + +var ( + /**公用方法**/ + // Session 用户登录授权成功后,TOP颁发给应用的授权信息。当此API的标签上注明:“需要授权”,则此参数必传;“不需要授权”,则此参数不需要传;“可选授权”,则此参数为可选 + Session string + // Timeout ... + Timeout time.Duration + // CacheExpiration 缓存过期时间 + CacheExpiration = time.Hour + // GetCache 获取缓存 + GetCache getCacheFunc + // SetCache 设置缓存 + SetCache setCacheFunc + + /**淘宝平台信息**/ + TaobaoAppKey string + TaobaoAppSecret string + TaobaoRouter string + TaobaoVersion = "2.0" + + /**京东平台信息**/ + JDAppKey string + JDAppSecret string + JDRouter string + JDSdkRouter string + JDVersion = "2.0" + + /**拼多多平台信息**/ + PDDAppKey string + PDDAppSecret string + PDDRouter string + PDDVersion = "v1.0" + + /**考拉海购平台信息**/ + KaolaAppKey string + KaolaAppSecret string + KaolaRouter string + KaolaVersion = "1.0" +) + +// Arg 参数 +type Arg map[string]interface{} + +// copyArg 复制参数 +func copyArg(srcArgs Arg) Arg { + newArgs := make(Arg) + for key, value := range srcArgs { + newArgs[key] = value + } + return newArgs +} + +// newCacheKey 创建缓存Key +func newCacheKey(p Arg) string { + cpArgs := copyArg(p) + delete(cpArgs, "session") + delete(cpArgs, "timestamp") + delete(cpArgs, "sign") + + keys := []string{} + for k := range cpArgs { + keys = append(keys, k) + } + // 排序asc + sort.Strings(keys) + // 把所有参数名和参数值串在一起 + cacheKeyBuf := new(bytes.Buffer) + for _, k := range keys { + cacheKeyBuf.WriteString(k) + cacheKeyBuf.WriteString("=") + cacheKeyBuf.WriteString(interfaceToString(cpArgs[k])) + } + h := md5.New() + io.Copy(h, cacheKeyBuf) + return hex.EncodeToString(h.Sum(nil)) +} + +// execute 执行API接口 +func execute(p Arg, router string) (bytes []byte, err error) { + err = checkConfig() + if err != nil { + return + } + + var req *http.Request + req, err = http.NewRequest("POST", router, strings.NewReader(p.getReqData())) + if err != nil { + return + } + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + req.Header.Add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8") + httpClient := &http.Client{Transport: tr} + httpClient.Timeout = Timeout + var resp *http.Response + resp, err = httpClient.Do(req) + if err != nil { + return + } + + if resp.StatusCode != 200 { + err = errors.New("请求错误:" + strconv.Itoa(resp.StatusCode)) + return + } + + defer resp.Body.Close() + bytes, err = ioutil.ReadAll(resp.Body) + // fmt.Printf("\n\n\nreq: %v\n\nresp: %v\n\n\n", p.getReqData(), string(bytes)) + return +} + +// Execute 执行API接口 +func Execute(method string, p Arg) (res *simplejson.Json, err error) { + p, r := setReqData(p, method) + var bodyBytes []byte + bodyBytes, err = execute(p, r) + if err != nil { + return + } + + return bytesToResult(bodyBytes) +} + +func bytesToResult(bytes []byte) (res *simplejson.Json, err error) { + res, err = simplejson.NewJson(bytes) + if err != nil { + return + } + if responseError, ok := res.CheckGet("error_response"); ok { + if subMsg, subOk := responseError.CheckGet("sub_msg"); subOk { + err = errors.New(subMsg.MustString()) + } else if zhDesc, descOk := responseError.CheckGet("zh_desc"); descOk { + err = errors.New(zhDesc.MustString()) + } else { + err = errors.New(responseError.Get("msg").MustString()) + } + res = nil + } + return +} + +// ExecuteCache 执行API接口,缓存 +func ExecuteCache(method string, param Arg) (res *simplejson.Json, err error) { + p, r := setReqData(param, method) + + cacheKey := newCacheKey(p) + // 获取缓存 + if GetCache != nil { + cacheBytes := GetCache(cacheKey) + if len(cacheBytes) > 0 { + res, err = simplejson.NewJson(cacheBytes) + if err == nil && res != nil { + return + } + } + } + + var bodyBytes []byte + bodyBytes, err = execute(param, r) + if err != nil { + return + } + res, err = bytesToResult(bodyBytes) + if err != nil { + return + } + ejsonBody, _ := res.MarshalJSON() + // 设置缓存 + if SetCache != nil { + go SetCache(cacheKey, ejsonBody, CacheExpiration) + } + return +} + +// 检查配置 +func checkConfig() error { + if TaobaoAppKey == "" && JDAppKey == "" && KaolaAppKey == "" && PDDAppKey == "" { + return errors.New("至少需要设置一个平台参数") + } + return nil +} + +//组装参数及添加公共参数 +func setReqData(p Arg, method string) (Arg, string) { + platform := strings.Split(method, ".")[0] + router := "" + hh, _ := time.ParseDuration("8h") + loc := time.Now().UTC().Add(hh) + if platform == "taobao" { + //淘宝 + p["timestamp"] = strconv.FormatInt(loc.Unix(), 10) + p["partner_id"] = "Blant" + p["app_key"] = TaobaoAppKey + p["v"] = TaobaoVersion + if Session != "" { + p["session"] = Session + } + p["method"] = method + p["format"] = "json" + p["sign_method"] = "md5" + // 设置签名 + p["sign"] = getSign(p, TaobaoAppSecret) + router = TaobaoRouter + } else if platform == "jdSdk" || platform == "jd" { + //京东 + param := p + p = Arg{} + p["param_json"] = param + p["app_key"] = JDAppKey + p["v"] = JDVersion + p["timestamp"] = loc.Format("2006-01-02 15:04:05") + p["method"] = method + p["format"] = "json" + p["sign_method"] = "md5" + // 设置签名 + p["sign"] = getSign(p, JDAppSecret) + router = JDSdkRouter + if platform == "jd" { + router = JDRouter + } + } else if platform == "pdd" { + //拼多多 + p["type"] = method + p["data_type"] = "json" + p["version"] = PDDVersion + p["client_id"] = PDDAppKey + p["timestamp"] = strconv.FormatInt(loc.Unix(), 10) + // 设置签名 + p["sign"] = getSign(p, PDDAppSecret) + router = PDDRouter + } else if platform == "kaola" { + //考拉海购 + p["method"] = method + p["v"] = KaolaVersion + p["signMethod"] = "md5" + p["unionId"] = KaolaAppKey + p["timestamp"] = loc.Format("2006-01-02 15:04:05") + // 设置签名 + p["sign"] = getSign(p, KaolaAppSecret) + router = KaolaRouter + } else if platform == "suning" { + // TODO 苏宁 + + } else if platform == "vip" { + // TODO 唯品会 + } + + return p, router +} + +// 获取请求数据 +func (p Arg) getReqData() string { + // 公共参数 + args := url.Values{} + // 请求参数 + for key, val := range p { + args.Set(key, interfaceToString(val)) + } + return args.Encode() +} + +// 获取签名 +func getSign(p Arg, secret string) string { + // 获取Key + var keys []string + for k := range p { + keys = append(keys, k) + } + // 排序asc + sort.Strings(keys) + // 把所有参数名和参数值串在一起 + query := bytes.NewBufferString(secret) + for _, k := range keys { + query.WriteString(k) + query.WriteString(interfaceToString(p[k])) + } + query.WriteString(secret) + // 使用MD5加密 + h := md5.New() + _, _ = io.Copy(h, query) + // 把二进制转化为大写的十六进制 + return strings.ToUpper(hex.EncodeToString(h.Sum(nil))) +} + +func interfaceToString(src interface{}) string { + if src == nil { + panic(ErrTypeIsNil) + } + switch src.(type) { + case string: + return src.(string) + case int, int8, int32, int64: + case uint8, uint16, uint32, uint64: + case float32, float64: + return convert.ToString(src) + } + data, err := json.Marshal(src) + if err != nil { + panic(err) + } + return string(data) +} diff --git a/comm/errors.go b/comm/errors.go new file mode 100644 index 0000000..5076c72 --- /dev/null +++ b/comm/errors.go @@ -0,0 +1,8 @@ +package comm + +import "errors" + +var ( + ErrTypeIsNil = errors.New("类型为Nil") + ErrTypeUnknown = errors.New("未处理到的数据类型") +) diff --git a/go.mod b/go.mod index dab7a94..77e14a2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,11 @@ 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/bitly/go-simplejson v0.5.0 + github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/nilorg/sdk v0.0.0-20221104025912-4b6ccb7004d8 + github.com/syyongx/php2go v0.9.7 github.com/tidwall/gjson v1.14.1 ) diff --git a/go.sum b/go.sum index c7570e6..c61c6fa 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,17 @@ +github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/nilorg/sdk v0.0.0-20221104025912-4b6ccb7004d8 h1:9hvJ/9GQssABrUYNOW1Q6X9/7uY6+Srj9YYYQZVC0AE= +github.com/nilorg/sdk v0.0.0-20221104025912-4b6ccb7004d8/go.mod h1:X1swpPdqguAZaBDoEPyEWHSsJii0YQ1o+3piMv6W3JU= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= 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= diff --git a/jdSdk/api.go b/jdSdk/api.go new file mode 100644 index 0000000..55362eb --- /dev/null +++ b/jdSdk/api.go @@ -0,0 +1,19 @@ +package jdSdk + +import "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/comm" + +func init() { + comm.JDAppKey = "444ab671c4d095122916453d09af27fc" + comm.JDAppSecret = "aef3c2745cc44194816d0c89c65b3847" + comm.JDVersion = "1.0" + comm.JDRouter = "https://router.jd.com/api" + comm.JDSdkRouter = "https://router.jdSdk.com/api" + +} +func send(method string, args map[string]interface{}) ([]byte, error) { + result, err := comm.Execute(method, args) + if err != nil { + return nil, err + } + return result.MarshalJSON() +} diff --git a/jdSdk/convent_url.go b/jdSdk/convent_url.go new file mode 100644 index 0000000..fab94c7 --- /dev/null +++ b/jdSdk/convent_url.go @@ -0,0 +1,17 @@ +package jdSdk + +import "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/comm" + +func ConventUrl(r *RequestJD) ([]byte, error) { + method := "jd.union.open.promotion.byunionid.get" + args := map[string]interface{}{ + "materialId": r.MaterialId, //推广物料链接,建议链接使用微Q前缀,能较好适配微信手Q页面 + "unionId": r.UnionId, // 目标推客的联盟ID + "positionId": r.PositionId, //推广位id + "chainType": "3", //转链类型,1:长链, 2 :短链 ,3: 长链+短链,默认短链 + } + if r.CouponUrl != "" { + args["couponUrl"] = r.CouponUrl + } + return send(method, comm.Arg{"promotionCodeReq": args}) +} diff --git a/jdSdk/featured.go b/jdSdk/featured.go new file mode 100644 index 0000000..45ea320 --- /dev/null +++ b/jdSdk/featured.go @@ -0,0 +1,17 @@ +package jdSdk + +import "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/comm" + +// Featured is 京粉精选商品 https://open.jd.com/home/home#/doc/api?apiCateId=461&apiId=3588&apiName=jd.union.open.goods.jingfen.query +func Featured(r *RequestJD) ([]byte, error) { + method := "jdSdk.union.open.goods.jingfen.query" + args := map[string]interface{}{ + "pageIndex": r.PageIndex, + "pageSize": r.PageSize, + // 1-好券商品,2-精选卖场,10-9.9包邮,15-京东配送,22-实时热销榜,23-为你推荐,24-数码家电,25-超市,26-母婴玩具,27-家具日用,28-美妆穿搭,29-医药保健,30-图书文具,31-今日必推,32-京东好物,33-京东秒杀,34-拼购商品,40-高收益榜,41-自营热卖榜,109-新品首发,110-自营,112-京东爆品,125-首购商品,129-高佣榜单,130-视频商品,153-历史最低价商品榜 + "eliteId": r.EliteID, + // 排序字段(price:单价, commissionShare:佣金比例, commission:佣金, inOrderCount30DaysSku:sku维度30天引单量,comments:评论数,goodComments:好评数) + "sortName": r.SortName, + } + return send(method, comm.Arg{"goodsReq": args}) +} diff --git a/jdSdk/guess.go b/jdSdk/guess.go new file mode 100644 index 0000000..5b4b7c2 --- /dev/null +++ b/jdSdk/guess.go @@ -0,0 +1,21 @@ +package jdSdk + +import "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/comm" + +// Guess is 猜你喜欢 https://open.jd.com/home/home#/doc/api?apiCateId=461&apiId=5479&apiName=jd.union.open.goods.material.query +func Guess(r *RequestJD) ([]byte, error) { + method := "jdSdk.union.open.goods.material.query" + args := map[string]interface{}{ + "pageIndex": r.PageIndex, + "pageSize": r.PageSize, + // 1-好券商品,2-精选卖场,10-9.9包邮,15-京东配送,22-实时热销榜,23-为你推荐,24-数码家电,25-超市,26-母婴玩具,27-家具日用,28-美妆穿搭,29-医药保健,30-图书文具,31-今日必推,32-京东好物,33-京东秒杀,34-拼购商品,40-高收益榜,41-自营热卖榜,109-新品首发,110-自营,112-京东爆品,125-首购商品,129-高佣榜单,130-视频商品,153-历史最低价商品榜 + "eliteId": r.EliteID, + // 排序字段(price:单价, commissionShare:佣金比例, commission:佣金, inOrderCount30DaysSku:sku维度30天引单量,comments:评论数,goodComments:好评数) + "sortName": r.SortName, + } + if r.UserIDType != 0 && r.UserID != "" { + args["userIdType"] = r.UserIDType + args["userId"] = r.UserID + } + return send(method, comm.Arg{"goodsReq": args}) +} diff --git a/jdSdk/model.go b/jdSdk/model.go new file mode 100644 index 0000000..77dff23 --- /dev/null +++ b/jdSdk/model.go @@ -0,0 +1,95 @@ +package jdSdk + +// 1-好券商品,2-精选卖场,10-9.9包邮,15-京东配送,22-实时热销榜,23-为你推荐,24-数码家电,25-超市,26-母婴玩具,27-家具日用,28-美妆穿搭,29-医药保健,30-图书文具,31-今日必推,32-京东好物,33-京东秒杀,34-拼购商品,40-高收益榜,41-自营热卖榜,109-新品首发,110-自营,112-京东爆品,125-首购商品,129-高佣榜单,130-视频商品,153-历史最低价商品榜 +// 排序字段(price:单价, commissionShare:佣金比例, commission:佣金, inOrderCount30DaysSku:sku维度30天引单量,comments:评论数,goodComments:好评数) +//RequestJD is 请求 京东sdk的参数 +type RequestJD struct { + PageIndex int `json:"page_index"` + PageSize int `json:"page_size"` + EliteID int `json:"elite_id"` + SortName string `json:"sort_name"` + UserIDType int `json:"userid_type"` + UserID string `json:"user_id"` + MaterialId string `json:"materialId"` //推广物料链接,建议链接使用微Q前缀,能较好适配微信手Q页面 + UnionId string `json:"unionId"` // 目标推客的联盟ID + PositionId string `json:"positionId"` //推广位id + CouponUrl string `json:"couponUrl"` + Time string `json:"time"` + Type string `json:"type"` +} + + +// JDFeaturedResponse is return from taoke.jdSdk +type JDFeaturedResponse struct { + JdUnionOpenGoodsJingfenQueryResponse struct { + Code string `json:"code"` + Result string `json:"result"` + } `json:"jd_union_open_goods_jingfen_query_response"` +} + +// JDFeature is jdSdk 精选 for微信 +type JDFeature struct { + BrandCode string `json:"brandCode"` + BrandName string `json:"brandName"` + CategoryInfo struct { + Cid1 int `json:"cid1"` + Cid1Name string `json:"cid1Name"` + Cid2 int `json:"cid2"` + Cid2Name string `json:"cid2Name"` + Cid3 int `json:"cid3"` + Cid3Name string `json:"cid3Name"` + } `json:"categoryInfo"` + Comments int `json:"comments"` + CommissionInfo struct { + Commission float64 `json:"commission"` + CommissionShare float64 `json:"commissionShare"` + CouponCommission float64 `json:"couponCommission"` + PlusCommissionShare float64 `json:"plusCommissionShare"` + } `json:"commissionInfo"` + CouponInfo struct { + CouponList []struct { + BindType int `json:"bindType"` + Discount float64 `json:"discount"` + GetEndTime int64 `json:"getEndTime"` + GetStartTime int64 `json:"getStartTime"` + HotValue int `json:"hotValue"` + IsBest int `json:"isBest"` + Link string `json:"link"` + PlatformType int `json:"platformType"` + Quota float64 `json:"quota"` + UseEndTime int64 `json:"useEndTime"` + UseStartTime int64 `json:"useStartTime"` + } `json:"couponList"` + } `json:"couponInfo"` + GoodCommentsShare float64 `json:"goodCommentsShare"` + ImageInfo struct { + ImageList []struct { + URL string `json:"url"` + } `json:"imageList"` + } `json:"imageInfo"` + InOrderCount30Days int `json:"inOrderCount30Days"` + InOrderCount30DaysSku int `json:"inOrderCount30DaysSku"` + IsHot int `json:"isHot"` + MaterialURL string `json:"materialUrl"` + Owner string `json:"owner"` + PinGouInfo struct { + } `json:"pinGouInfo"` + PriceInfo struct { + LowestCouponPrice float64 `json:"lowestCouponPrice"` + LowestPrice float64 `json:"lowestPrice"` + LowestPriceType int `json:"lowestPriceType"` + Price float64 `json:"price"` + } `json:"priceInfo"` + ResourceInfo struct { + EliteID int `json:"eliteId"` + EliteName string `json:"eliteName"` + } `json:"resourceInfo"` + ShopInfo struct { + ShopID int `json:"shopId"` + ShopLevel float64 `json:"shopLevel"` + ShopName string `json:"shopName"` + } `json:"shopInfo"` + SkuID int64 `json:"skuId"` + SkuName string `json:"skuName"` + Spuid int64 `json:"spuid"` +} diff --git a/jdSdk/order_follow.go b/jdSdk/order_follow.go new file mode 100644 index 0000000..c314f36 --- /dev/null +++ b/jdSdk/order_follow.go @@ -0,0 +1,15 @@ +package jdSdk + +import "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/comm" + +func OrderFollow(r *RequestJD) ([]byte, error) { + method := "jd.union.open.order.query" + args := map[string]interface{}{ + "pageNo": r.PageIndex, // + "key": r.UnionId, // 目标推客的联盟ID + "pageSize": r.PageSize, //推广位id + "type": r.Type, //1:下单时间,2:完成时间,3:更新时间 + "time": r.Time, + } + return send(method, comm.Arg{"orderReq": args}) +} diff --git a/jdSdk/recommend.go b/jdSdk/recommend.go new file mode 100644 index 0000000..36a50b2 --- /dev/null +++ b/jdSdk/recommend.go @@ -0,0 +1,17 @@ +package jdSdk + +import "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/comm" + +// Recommend is 京东推荐商品https://open.jdSdk.com/home/home#/doc/api?apiCateId=461&apiId=3588&apiName=jdSdk.union.open.goods.jingfen.query +func Recommend(r *RequestJD) ([]byte, error) { + method := "jdSdk.kpl.open.union.search.byelited" + args := map[string]interface{}{ + "pageIndex": r.PageIndex, + "pageSize": r.PageSize, + // 1-好券商品,2-超级大卖场,10-9.9专区,22-热销爆品,23-为你推荐,24-数码家电,25-超市,26-母婴玩具,27-家具日用,28-美妆穿搭,29-医药保健,30-图书文具,31-今日必推,32-品牌好货,33-秒杀商品,34-拼购商品,109-新品首发,110-自营,125-首购商品,129-高佣榜单,130-视频商品 + "eliteId": r.EliteID, + // 排序字段price:单价, commissionShare:佣金比例, commission:佣金, inOrderCount30DaysSku:sku维度30天引单量,comments:评论数,goodComments:好评数 + "sortName": r.SortName, + } + return send(method, comm.Arg{"goodsReq": args}) +} diff --git a/jdSdk/sdk.go b/jdSdk/sdk.go new file mode 100644 index 0000000..8258f85 --- /dev/null +++ b/jdSdk/sdk.go @@ -0,0 +1,113 @@ +package jdSdk + +import ( + "encoding/json" +) + +//SDK is sdk for jdSdk +type SDK struct { + response []byte + fmap map[string]func(*RequestJD) + fname string + err error +} + +//Init is init sdk +func (s *SDK) Init() { + s.fmap = make(map[string]func(*RequestJD)) +} + +//SelectFunction is select func +func (s *SDK) SelectFunction(fname string) *SDK { + s.fname = fname + return s +} + +//WithArgs is request args +func (s *SDK) WithArgs(args *RequestJD) *SDK { + f := s.fmap[s.fname] + f(args) + return s +} + +// Result is func result +func (s *SDK) Result() (*SDK, error) { + return s, s.err +} + +// Register is register func +func (s *SDK) Register(name string, f func(*RequestJD)) { + s.fmap[name] = f +} + +//ToBytes is return []byte +func (s *SDK) ToBytes() []byte { + return s.response +} + +// ToString is return string +func (s *SDK) ToString() string { + return string(s.response) +} + +//ToMapInterface is return map[string]interface{} +func (s *SDK) ToMapInterface() map[string]interface{} { + m := make(map[string]interface{}) + json.Unmarshal(s.response, &m) + return m +} + +// Featured is jdSdk 精选列表 +func (s *SDK) Featured(r *RequestJD) { + d, err := Featured(r) + if err != nil { + s.err = err + } + s.response = d +} + +// Guess is 猜你喜欢列表 +func (s *SDK) Guess(r *RequestJD) { + d, err := Guess(r) + if err != nil { + s.err = err + } + s.response = d +} + +// Recommend is 推荐列表 +func (s *SDK) Recommend(r *RequestJD) { + d, err := Recommend(r) + if err != nil { + s.err = err + } + s.response = d +} + +//转链 +func (s *SDK) ConventUrl(r *RequestJD) { + d, err := ConventUrl(r) + if err != nil { + s.err = err + } + s.response = d +} +func (s *SDK) OrderFollow(r *RequestJD) { + d, err := OrderFollow(r) + if err != nil { + s.err = err + } + s.response = d +} + +//NewJDSDK is jingdong sdk +func NewJDSDK() *SDK { + sdk := new(SDK) + sdk.Init() + sdk.Register("featured", sdk.Featured) + sdk.Register("guess", sdk.Guess) + sdk.Register("recommend", sdk.Recommend) + sdk.Register("convent_url", sdk.ConventUrl) + sdk.Register("order_follow", sdk.OrderFollow) + return sdk +} diff --git a/jdSdk/to_test.go b/jdSdk/to_test.go new file mode 100644 index 0000000..983003c --- /dev/null +++ b/jdSdk/to_test.go @@ -0,0 +1,19 @@ +package jdSdk + +import ( + "fmt" + "testing" +) + +func TestConventUrl(t *testing.T) { + rq := &RequestJD{ + PageIndex: 1, // + UnionId: "d3ee30b44a6fec06fa8a4eee4bd541b2d279e836750f97dfe56144d7be74233d5d131b3028a81cfc", // 目标推客的联盟ID + PageSize: 100, //推广位id + Type: "3", //1:下单时间,2:完成时间,3:更新时间 + Time: "2022121910", + } + sdk, err := NewJDSDK().SelectFunction("order_follow").WithArgs(rq).Result() + fmt.Println(string(sdk.ToBytes())) + fmt.Println(err) +} diff --git a/macao_logistics/api.go b/macao_logistics/api.go new file mode 100644 index 0000000..8d7c4db --- /dev/null +++ b/macao_logistics/api.go @@ -0,0 +1,42 @@ +package macao_logistics + +import ( + "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/comm" + zhios_third_party_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/utils" + "strings" +) + +func GetSign(appSecret string, param map[string]string) string { + str := "" + keys := comm.KsortToStr(param) + + for _, k := range keys { + str += strings.ReplaceAll(param[k], "\\n", "") + } + return "" +} +func Send(method string, params map[string]interface{}, acctoken string) (string, error) { + url := "http://jyb-admin-backend-test.aoyunltd.cn/api/v1" + method + header := make(map[string]string, 0) + if acctoken != "" { + header["Authorization"] = "Bearer " + acctoken + } + data, err := zhios_third_party_utils.CurlPost(url, params, header) + return string(data), err +} +func SendGet(method string, params map[string]interface{}, acctoken string) (string, error) { + url := "http://jyb-admin-backend-test.aoyunltd.cn/api/v1" + method + header := make(map[string]string, 0) + if acctoken != "" { + header["Authorization"] = "Bearer " + acctoken + } + for k, v := range params { + if strings.Contains(url, "?") == false { + url += "?" + k + "=" + zhios_third_party_utils.AnyToString(v) + } else { + url += "&" + k + "=" + zhios_third_party_utils.AnyToString(v) + } + } + data, err := zhios_third_party_utils.CurlGet(url, header) + return string(data), err +} diff --git a/macao_logistics/macao_logistics.go b/macao_logistics/macao_logistics.go new file mode 100644 index 0000000..2ace57b --- /dev/null +++ b/macao_logistics/macao_logistics.go @@ -0,0 +1,31 @@ +package macao_logistics + +import "github.com/tidwall/gjson" + +func GetToken() string { + params := map[string]interface{}{ + "phone": "15217160421", + "password": "123456789@", + } + //7c2f6cbd480a96f1aa69509f9dd65462 + send, err := Send("/jyb/admin/login/password", params, "") + if err != nil { + return "" + } + return gjson.Get(send, "data.token").String() +} + +func GetGoods(params map[string]interface{}) string { + send, err := SendGet("/admin/goods/detailed/list", params, "7c2f6cbd480a96f1aa69509f9dd65462") + if err != nil { + return "" + } + return gjson.Get(send, "data.data").String() +} +func GetStore(params map[string]interface{}) string { + send, err := SendGet("/jyb/order/delivery/store", params, "7c2f6cbd480a96f1aa69509f9dd65462") + if err != nil { + return "" + } + return gjson.Get(send, "data.data").String() +} diff --git a/macao_logistics/macao_logistics_test.go b/macao_logistics/macao_logistics_test.go new file mode 100644 index 0000000..252e3e0 --- /dev/null +++ b/macao_logistics/macao_logistics_test.go @@ -0,0 +1,17 @@ +package macao_logistics + +import "testing" + +func TestLogin(t *testing.T) { + params := map[string]interface{}{ + "order_number": "test12311", //單號,長度不可以超過30 + "phone": "15217160421", // 电话号码長度為8 or 11 + "arrive": "60", // 門店個點ID,可以用ID 也可以用AYG001的參數 + "type": "1", // 是指的是快件是否預付,1代表是用戶支付2是商家餘額支付,3是商家月結 + "weight": "20", // 重量,必須是int,沒有小數點 + "order_type": "1", + "city": "珠海", + } + //7c2f6cbd480a96f1aa69509f9dd65462 + Send("/jyb/order/delivery/add", params, "7c2f6cbd480a96f1aa69509f9dd65462") +} diff --git a/md/provider.go b/md/provider.go index 0f5f6c1..832e3f4 100644 --- a/md/provider.go +++ b/md/provider.go @@ -6,7 +6,7 @@ const ( PVD_KUAISHOU = "kuaishou" PVD_TIKTOKLIVE = "tikTok_live" PVD_KUAISHOULIVE = "kuaishou_live" - PVD_JD = "jd" + PVD_JD = "jdSdk" PVD_SN = "suning" PVD_VIP = "vip" PVD_PDD = "pdd" @@ -71,7 +71,7 @@ var PVD_LIST = map[string]string{ var PVD_NEW_LIST = []map[string]string{ {"name": "淘宝", "key": "taobao", "is_more_union": "1"}, {"name": "抖音", "key": "tikTok", "is_more_union": "1"}, - {"name": "京东", "key": "jd", "is_more_union": "1"}, + {"name": "京东", "key": "jdSdk", "is_more_union": "1"}, {"name": "唯品会", "key": "vip", "is_more_union": "1"}, {"name": "拼多多", "key": "pdd", "is_more_union": "1"}, {"name": "苏宁", "key": "suning", "is_more_union": "1"}, diff --git a/tik_tok/api.go b/tik_tok/api.go index 875f14f..d6ff268 100644 --- a/tik_tok/api.go +++ b/tik_tok/api.go @@ -1,14 +1,12 @@ package tik_tok import ( - "bytes" + "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/comm" 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" ) @@ -16,7 +14,7 @@ import ( 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 := comm.GetSortJson(params) paramJson = strings.ReplaceAll(paramJson, "\n", "") param := map[string]string{ "app_key": appkey, @@ -43,7 +41,7 @@ func Send(appkey, appSecret, method string, params map[string]interface{}, accto } func GetSign(appSecret string, param map[string]string) string { str := "" - keys := KsortToStr(param) + keys := comm.KsortToStr(param) for _, k := range keys { str += k + param[k] } @@ -52,64 +50,3 @@ func GetSign(appSecret string, param map[string]string) string { _, _ = 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 -}