diff --git a/CHANGELOG.md b/CHANGELOG.md index df3be64c..6b00f8b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v1.0.36 / 2021-12-27 + +- update pinduoduo service + ## v1.0.35 / 2021-12-25 - update utils diff --git a/README.md b/README.md index 603da38d..406b6757 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -

Golang Library

+

+Golang Library +

📦 Golang 扩展包 @@ -16,7 +18,6 @@ [![codecov](https://codecov.io/gh/dtapps/go-library/branch/master/graph/badge.svg?token=BrtbyKKPQX)](https://codecov.io/gh/dtapps/go-library) [![Build Status](https://app.travis-ci.com/dtapps/go-library.svg?branch=master)](https://app.travis-ci.com/dtapps/go-library) - #### 安装使用 ```go diff --git a/library.go b/library.go index c3e19916..b6d89646 100644 --- a/library.go +++ b/library.go @@ -1,5 +1,5 @@ package go_library func Version() string { - return "v1.0.35" + return "v1.0.36" } diff --git a/service/pinduoduo/app.go b/service/pinduoduo/app.go new file mode 100644 index 00000000..b1a8ba59 --- /dev/null +++ b/service/pinduoduo/app.go @@ -0,0 +1,71 @@ +package pinduoduo + +import ( + "encoding/json" + "fmt" + "github.com/dtapps/go-library/utils/gohttp" + "github.com/dtapps/go-library/utils/gostring" + "regexp" + "strconv" + "strings" +) + +// App 公共请求参数 +type App struct { + ClientId string // POP分配给应用的client_id + ClientSecret string // POP分配给应用的client_secret + Pid string // 推广位 +} + +type ErrResp struct { + ErrorResponse struct { + ErrorMsg string `json:"error_msg"` + SubMsg string `json:"sub_msg"` + SubCode interface{} `json:"sub_code"` + ErrorCode int `json:"error_code"` + RequestId string `json:"request_id"` + } `json:"error_response"` +} + +type CustomParametersResult struct { + Sid string `json:"sid"` + Uid string `json:"uid"` +} + +func (app *App) request(params map[string]interface{}) (resp []byte, err error) { + // 签名 + app.Sign(params) + // 发送请求 + httpGet, err := gohttp.Get("https://gw-api.pinduoduo.com/api/router", params) + // 检查错误 + var errResp ErrResp + _ = json.Unmarshal(httpGet.Body, &errResp) + return httpGet.Body, err +} + +func (app *App) SalesTipParseInt64(salesTip string) int64 { + parseInt, err := strconv.ParseInt(salesTip, 10, 64) + if err != nil { + salesTipStr := salesTip + if strings.Contains(salesTip, "万+") { + salesTipStr = strings.Replace(salesTip, "万+", "0000", -1) + } else if strings.Contains(salesTip, "万") { + salesTipStr = strings.Replace(salesTip, "万", "000", -1) + } + re := regexp.MustCompile("[0-9]+") + SalesTipMap := re.FindAllString(salesTipStr, -1) + if len(SalesTipMap) == 2 { + return gostring.ToInt64(fmt.Sprintf("%s%s", SalesTipMap[0], SalesTipMap[1])) + } else if len(SalesTipMap) == 1 { + return gostring.ToInt64(SalesTipMap[0]) + } else { + return 0 + } + } else { + return parseInt + } +} + +func (app *App) CommissionIntegralToInt64(GoodsPrice, CouponProportion int64) int64 { + return (GoodsPrice * CouponProportion) / 1000 +} diff --git a/service/pinduoduo/crypto.go b/service/pinduoduo/crypto.go new file mode 100644 index 00000000..15246af9 --- /dev/null +++ b/service/pinduoduo/crypto.go @@ -0,0 +1,15 @@ +package pinduoduo + +import ( + "crypto/md5" + "encoding/hex" + "strings" +) + +// 签名 +func createSign(signStr string) string { + h := md5.New() + h.Write([]byte(signStr)) + cipherStr := h.Sum(nil) + return strings.ToUpper(hex.EncodeToString(cipherStr)) +} diff --git a/service/pinduoduo/param.go b/service/pinduoduo/param.go new file mode 100644 index 00000000..ec4530c0 --- /dev/null +++ b/service/pinduoduo/param.go @@ -0,0 +1,7 @@ +package pinduoduo + +// CommonGenCustomParameters 自定义参数 +type CommonGenCustomParameters struct { + Uid string `json:"uid"` + Sid string `json:"sid"` +} diff --git a/service/pinduoduo/params.go b/service/pinduoduo/params.go new file mode 100644 index 00000000..6de13577 --- /dev/null +++ b/service/pinduoduo/params.go @@ -0,0 +1,85 @@ +package pinduoduo + +import ( + "encoding/json" + "net/url" + "sort" + "strconv" + "time" +) + +// Params 请求参数 +type Params map[string]interface{} + +func NewParams() Params { + p := make(Params) + return p +} + +func NewParamsWithType(_type string, params ...Params) Params { + p := make(Params) + p["type"] = _type + p["timestamp"] = strconv.FormatInt(time.Now().Unix(), 10) + for _, v := range params { + p.SetParams(v) + } + return p +} + +func (app *App) Sign(p Params) { + p["client_id"] = app.ClientId + // 排序所有的 key + var keys []string + for key := range p { + keys = append(keys, key) + } + sort.Strings(keys) + signStr := app.ClientSecret + for _, key := range keys { + signStr += key + getString(p[key]) + } + signStr += app.ClientSecret + p["sign"] = createSign(signStr) +} + +func (p Params) Set(key string, value interface{}) { + p[key] = value +} + +func (p Params) SetParams(params Params) { + for key, value := range params { + p[key] = value + } +} + +func (p Params) SetCustomParameters(uid string, sid string) { + p["custom_parameters"] = map[string]interface{}{ + "uid": uid, + "sid": sid, + } +} + +func (p Params) GetQuery() string { + u := url.Values{} + for k, v := range p { + u.Set(k, getString(v)) + } + return u.Encode() +} + +func getString(i interface{}) string { + switch v := i.(type) { + case string: + return v + case []byte: + return string(v) + case int: + return strconv.Itoa(v) + case bool: + return strconv.FormatBool(v) + default: + + bytes, _ := json.Marshal(v) + return string(bytes) + } +} diff --git a/service/pinduoduo/pdd.ddk.goods.detail.go b/service/pinduoduo/pdd.ddk.goods.detail.go new file mode 100644 index 00000000..e3117ee7 --- /dev/null +++ b/service/pinduoduo/pdd.ddk.goods.detail.go @@ -0,0 +1,90 @@ +package pinduoduo + +// GoodsDetailResult 返回参数 +type GoodsDetailResult struct { + GoodsDetailResponse struct { + GoodsDetails []struct { + ActivityPromotionRate int `json:"activity_promotion_rate,omitempty"` // 活动佣金比例,千分比(特定活动期间的佣金比例) + ActivityTags []int `json:"activity_tags,omitempty"` // 商品活动标记数组,例:[4,7],4-秒杀 7-百亿补贴等 + BrandName string `json:"brand_name,omitempty"` // 商品品牌词信息,如“苹果”、“阿迪达斯”、“李宁”等 + CashGiftAmount int `json:"cash_gift_amount,omitempty"` // 全局礼金金额,单位分 + CatId int `json:"cat_id,omitempty"` // 商品类目ID,使用pdd.goods.cats.get接口获取 + CatIds []int `json:"cat_ids,omitempty"` // 商品一~四级类目ID列表 + CltCpnBatchSn string `json:"clt_cpn_batch_sn,omitempty"` // 店铺收藏券id + CltCpnDiscount int `json:"clt_cpn_discount,omitempty"` // 店铺收藏券面额,单位为分 + CltCpnEndTime int `json:"clt_cpn_end_time,omitempty"` // 店铺收藏券截止时间 + CltCpnMinAmt int `json:"clt_cpn_min_amt,omitempty"` // 店铺收藏券使用门槛价格,单位为分 + CltCpnQuantity int `json:"clt_cpn_quantity,omitempty"` // 店铺收藏券总量 + CltCpnRemainQuantity int `json:"clt_cpn_remain_quantity,omitempty"` // 店铺收藏券剩余量 + CltCpnStartTime int `json:"clt_cpn_start_time,omitempty"` // 店铺收藏券起始时间 + CouponDiscount int64 `json:"coupon_discount,omitempty"` // 优惠券面额,单位为分 + CouponEndTime int `json:"coupon_end_time,omitempty"` // 优惠券失效时间,UNIX时间戳 + CouponMinOrderAmount int `json:"coupon_min_order_amount,omitempty"` // 优惠券门槛金额,单位为分 + CouponRemainQuantity int `json:"coupon_remain_quantity,omitempty"` // 优惠券剩余数量 + CouponStartTime int `json:"coupon_start_time,omitempty"` // 优惠券生效时间,UNIX时间戳 + CouponTotalQuantity int `json:"coupon_total_quantity,omitempty"` // 优惠券总数量 + CreateAt int `json:"create_at,omitempty"` // 创建时间(unix时间戳) + DescTxt string `json:"desc_txt,omitempty"` // 描述分 + ExtraCouponAmount int `json:"extra_coupon_amount,omitempty"` // 额外优惠券 + GoodsDesc string `json:"goods_desc,omitempty"` // 参与多多进宝的商品描述 + GoodsGalleryUrls []string `json:"goods_gallery_urls,omitempty"` // 商品轮播图 + GoodsImageUrl string `json:"goods_image_url,omitempty"` // 多多进宝商品主图 + GoodsName string `json:"goods_name,omitempty"` // 参与多多进宝的商品标题 + GoodsSign string `json:"goods_sign,omitempty"` // 商品goodsSign,支持通过goodsSign查询商品。goodsSign是加密后的goodsId, goodsId已下线,请使用goodsSign来替代。使用说明:https://jinbao.pinduoduo.com/qa-system?questionId=252 + GoodsThumbnailUrl string `json:"goods_thumbnail_url,omitempty"` // 商品缩略图 + HasCoupon bool `json:"has_coupon,omitempty"` // 商品是否有优惠券 true-有,false-没有 + HasMallCoupon bool `json:"has_mall_coupon,omitempty"` // 是否有店铺券 + LgstTxt string `json:"lgst_txt,omitempty"` // 物流分 + MallCouponDiscountPct int64 `json:"mall_coupon_discount_pct,omitempty"` // 店铺折扣 + MallCouponEndTime int `json:"mall_coupon_end_time,omitempty"` // 店铺券使用结束时间 + MallCouponMaxDiscountAmount int64 `json:"mall_coupon_max_discount_amount,omitempty"` // 最大使用金额 + MallCouponMinOrderAmount int64 `json:"mall_coupon_min_order_amount,omitempty"` // 最小使用金额 + MallCouponRemainQuantity int `json:"mall_coupon_remain_quantity,omitempty"` // 店铺券余量 + MallCouponStartTime int `json:"mall_coupon_start_time,omitempty"` // 店铺券使用开始时间 + MallCouponTotalQuantity int `json:"mall_coupon_total_quantity,omitempty"` // 店铺券总量 + MallCps int64 `json:"mall_cps,omitempty"` // 该商品所在店铺是否参与全店推广,0:否,1:是 + MallId int64 `json:"mall_id,omitempty"` // 商家id + MallImgUrl string `json:"mall_img_url,omitempty"` // 店铺logo图 + MallName string `json:"mall_name,omitempty"` // 店铺名称 + MaterialList []struct { + Id string `json:"id,omitempty"` // 素材ID + ImageList []string `json:"image_list,omitempty"` // 图片列表 + TextList []string `json:"text_list,omitempty"` // 文字列表 + ThumbnailUrl string `json:"thumbnail_url,omitempty"` // 视频缩略图 + Mtype int `json:"type,omitempty"` // 素材类型,1-图文,2-视频 + VideoUrl string `json:"video_url,omitempty"` // 视频url + } `json:"material_list"` + MerchantType int `json:"merchant_type,omitempty"` // 店铺类型,1-个人,2-企业,3-旗舰店,4-专卖店,5-专营店,6-普通店(未传为全部) + MinGroupPrice int64 `json:"min_group_price,omitempty"` // 最低价sku的拼团价,单位为分 + MinNormalPrice int64 `json:"min_normal_price,omitempty"` // 最低价sku的单买价,单位为分 + OnlySceneAuth bool `json:"only_scene_auth,omitempty"` // 快手专享 + OptId int `json:"opt_id,omitempty"` // 商品标签ID,使用pdd.goods.opt.get接口获取 + OptIds []int `json:"opt_ids,omitempty"` // 商品标签ID + OptName string `json:"opt_name,omitempty"` // 商品标签名称 + PlanType int `json:"plan_type,omitempty"` // 推广计划类型: 1-全店推广 2-单品推广 3-定向推广 4-招商推广 5-分销推广 + PredictPromotionRate int `json:"predict_promotion_rate,omitempty"` // 比价行为预判定佣金,需要用户备案 + PromotionRate int64 `json:"promotion_rate,omitempty"` // 佣金比例,千分比 + SalesTip string `json:"sales_tip,omitempty"` // 已售卖件数 + ServiceTags []int `json:"service_tags,omitempty"` // 服务标签: 4-送货入户并安装,5-送货入户,6-电子发票,9-坏果包赔,11-闪电退款,12-24小时发货,13-48小时发货,17-顺丰包邮,18-只换不修,1可定制化,29-预约配送,1000001-正品发票,1000002-送货入户并安装 + ServTxt string `json:"serv_txt,omitempty"` // 服务分 + ShareRate int `json:"share_rate,omitempty"` // 招商分成服务费比例,千分比 + SubsidyAmount int `json:"subsidy_amount,omitempty"` // 优势渠道专属商品补贴金额,单位为分。针对优质渠道的补贴活动,指定优势渠道可通过推广该商品获取相应补贴。补贴活动入口:[进宝网站-官方活动-千万补贴],报名入口:https://jinbao.pinduoduo.com/ten-million-subsidy/entry + SubsidyDuoAmountTenMillion int `json:"subsidy_duo_amount_ten_million,omitempty"` // 千万补贴给渠道的收入补贴,不允许直接给下级代理展示,单位为分 + UnifiedTags []string `json:"unified_tags,omitempty"` // 优惠标签列表,包括:"X元券","比全网低X元","服务费","精选素材","近30天低价","同款低价","同款好评","同款热销","旗舰店","一降到底","招商优选","商家优选","好价再降X元","全站销量XX","实时热销榜第X名","实时好评榜第X名","额外补X元"等 + VideoUrls []string `json:"video_urls,omitempty"` // 商品视频url + ZsDuoId int `json:"zs_duo_id,omitempty"` // 招商团长id + GoodsId int64 `json:"goods_id"` + CategoryId int64 `json:"category_id"` + CategoryName string `json:"category_name"` + } `json:"goods_details"` + } `json:"goods_detail_response"` +} + +// GoodsDetail 多多进宝商品详情查询 https://jinbao.pinduoduo.com/third-party/api-detail?apiName=pdd.ddk.goods.detail +func (app *App) GoodsDetail(notMustParams ...Params) (body []byte, err error) { + // 参数 + params := NewParamsWithType("pdd.ddk.goods.detail", notMustParams...) + // 请求 + body, err = app.request(params) + return +} diff --git a/service/pinduoduo/pdd.ddk.goods.pid.generate.go b/service/pinduoduo/pdd.ddk.goods.pid.generate.go new file mode 100644 index 00000000..8a89cfb6 --- /dev/null +++ b/service/pinduoduo/pdd.ddk.goods.pid.generate.go @@ -0,0 +1,23 @@ +package pinduoduo + +// GoodsPidGenerateResult 返回参数 +type GoodsPidGenerateResult struct { + PIdGenerateResponse struct { + PIdList []struct { + CreateTime int `json:"create_time,omitempty"` // 推广位创建时间 + PidName string `json:"pid_name,omitempty"` // 推广位名称 + PId string `json:"p_id,omitempty"` // 调用方推广位ID + MediaId int `json:"media_id,omitempty"` // 媒体id + } `json:"p_id_list"` + RemainPidCount int `json:"remain_pid_count"` // PID剩余数量 + } `json:"p_id_generate_response"` +} + +// GoodsPidGenerate 创建多多进宝推广位 https://jinbao.pinduoduo.com/third-party/api-detail?apiName=pdd.ddk.goods.pid.generate +func (app *App) GoodsPidGenerate(notMustParams ...Params) (body []byte, err error) { + // 参数 + params := NewParamsWithType("pdd.ddk.goods.pid.generate", notMustParams...) + // 请求 + body, err = app.request(params) + return +} diff --git a/service/pinduoduo/pdd.ddk.goods.promotion.url.generate.go b/service/pinduoduo/pdd.ddk.goods.promotion.url.generate.go new file mode 100644 index 00000000..94bd54da --- /dev/null +++ b/service/pinduoduo/pdd.ddk.goods.promotion.url.generate.go @@ -0,0 +1,43 @@ +package pinduoduo + +// GoodsPromotionUrlGenerateResult 返回参数 +type GoodsPromotionUrlGenerateResult struct { + GoodsPromotionUrlGenerateResponse struct { + GoodsPromotionUrlList []struct { + MobileShortUrl string `json:"mobile_short_url,omitempty"` // 对应出参mobile_url的短链接,与mobile_url功能一致。 + MobileUrl string `json:"mobile_url,omitempty"` // 使用此推广链接,用户安装微信的情况下,默认拉起拼多多福利券微信小程序,否则唤起H5页面 + QqAppInfo struct { + AppId string `json:"app_id,omitempty"` // 拼多多小程序id + BannerUrl string `json:"banner_url,omitempty"` // Banner图 + Desc string `json:"desc,omitempty"` // 描述 + PagePath string `json:"page_path,omitempty"` // 小程序path值 + QqAppIconUrl string `json:"qq_app_icon_url,omitempty"` // 小程序icon + SourceDisplayName string `json:"source_display_name,omitempty"` // 来源名 + Title string `json:"title,omitempty"` // 小程序标题 + UserName string `json:"user_name,omitempty"` // 用户名 + } `json:"qq_app_info"` + SchemaUrl string `json:"schema_url,omitempty"` // 使用此推广链接,用户安装拼多多APP的情况下会唤起APP(需客户端支持schema跳转协议) + ShortUrl string `json:"short_url,omitempty"` // 对应出参url的短链接,与url功能一致 + Url string `json:"url,omitempty"` // 普通推广长链接,唤起H5页面 + WeAppInfo struct { + AppId string `json:"app_id,omitempty"` // 小程序id + BannerUrl string `json:"banner_url,omitempty"` // Banner图 + Desc string `json:"desc,omitempty"` // 描述 + PagePath string `json:"page_path,omitempty"` // 小程序path值 + SourceDisplayName string `json:"source_display_name,omitempty"` // 来源名 + Title string `json:"title,omitempty"` // 小程序标题 + UserName string `json:"user_name,omitempty"` // 用户名 + WeAppIconUrl string `json:"we_app_icon_url,omitempty"` // 小程序图片 + } `json:"we_app_info"` + } `json:"goods_promotion_url_list"` + } `json:"goods_promotion_url_generate_response"` +} + +// GoodsPromotionUrlGenerate 多多进宝推广链接生成 https://jinbao.pinduoduo.com/third-party/api-detail?apiName=pdd.ddk.goods.promotion.url.generate +func (app *App) GoodsPromotionUrlGenerate(notMustParams ...Params) (body []byte, err error) { + // 参数 + params := NewParamsWithType("pdd.ddk.goods.promotion.url.generate", notMustParams...) + // 请求 + body, err = app.request(params) + return +} diff --git a/service/pinduoduo/pdd.ddk.goods.recommend.get.go b/service/pinduoduo/pdd.ddk.goods.recommend.get.go new file mode 100644 index 00000000..a1b8ddb1 --- /dev/null +++ b/service/pinduoduo/pdd.ddk.goods.recommend.get.go @@ -0,0 +1,72 @@ +package pinduoduo + +// GoodsRecommendGetResult 返回参数 +type GoodsRecommendGetResult struct { + GoodsBasicDetailResponse struct { + List []struct { + ActivityPromotionRate int `json:"activity_promotion_rate"` + ActivityTags []int `json:"activity_tags"` + BrandName string `json:"brand_name"` + CashGiftAmount int `json:"cash_gift_amount"` + CatId string `json:"cat_id"` + CatIds []int `json:"cat_ids"` + CouponDiscount int64 `json:"coupon_discount"` + CouponEndTime int `json:"coupon_end_time"` + CouponMinOrderAmount int `json:"coupon_min_order_amount"` + CouponPrice int `json:"coupon_price"` + CouponRemainQuantity int `json:"coupon_remain_quantity"` + CouponStartTime int `json:"coupon_start_time"` + CouponTotalQuantity int `json:"coupon_total_quantity"` + CreateAt int `json:"create_at"` + DescTxt string `json:"desc_txt"` + ExtraCouponAmount int `json:"extra_coupon_amount"` + GoodsDesc string `json:"goods_desc"` + GoodsImageUrl string `json:"goods_image_url"` + GoodsLabels []int `json:"goods_labels"` + GoodsName string `json:"goods_name"` + GoodsRate int `json:"goods_rate"` + GoodsSign string `json:"goods_sign"` + GoodsThumbnailUrl string `json:"goods_thumbnail_url"` + GoodsType int `json:"goods_type"` + HasCoupon bool `json:"has_coupon"` + HasMaterial bool `json:"has_material"` + LgstTxt string `json:"lgst_txt"` + MallId int64 `json:"mall_id"` + MallName string `json:"mall_name"` + MarketFee int `json:"market_fee"` + MerchantType string `json:"merchant_type"` + MinGroupPrice int64 `json:"min_group_price"` + MinNormalPrice int `json:"min_normal_price"` + OptId string `json:"opt_id"` + OptIds []int `json:"opt_ids"` + OptName string `json:"opt_name"` + PredictPromotionRate int `json:"predict_promotion_rate"` + PromotionRate int64 `json:"promotion_rate"` + QrCodeImageUrl string `json:"qr_code_image_url"` + RealtimeSalesTip string `json:"realtime_sales_tip"` + SalesTip string `json:"sales_tip"` + SearchId string `json:"search_id"` + ServTxt string `json:"serv_txt"` + ShareDesc string `json:"share_desc"` + ShareRate int `json:"share_rate"` + SubsidyAmount int `json:"subsidy_amount"` + SubsidyDuoAmountTenMillion int `json:"subsidy_duo_amount_ten_million"` + UnifiedTags []string `json:"unified_tags"` + GoodsId int64 `json:"goods_id"` + CategoryId string `json:"category_id"` + CategoryName string `json:"category_name"` + } `json:"list"` + ListId string `json:"list_id"` + SearchId string `json:"search_id"` + Total int `json:"total"` + } `json:"goods_basic_detail_response"` +} + +// GoodsRecommendGet 多多进宝商品推荐API https://jinbao.pinduoduo.com/third-party/api-detail?apiName=pdd.ddk.goods.recommend.get +func (app *App) GoodsRecommendGet(notMustParams ...Params) (body []byte, err error) { + // 参数 + params := NewParamsWithType("pdd.ddk.goods.recommend.get", notMustParams...) + // 请求 + body, err = app.request(params) + return +} diff --git a/service/pinduoduo/pdd.ddk.goods.search.go b/service/pinduoduo/pdd.ddk.goods.search.go new file mode 100644 index 00000000..9010c441 --- /dev/null +++ b/service/pinduoduo/pdd.ddk.goods.search.go @@ -0,0 +1,85 @@ +package pinduoduo + +type GoodsSearchResult struct { + GoodsSearchResponse struct { + GoodsList []struct { + ActivityPromotionRate int `json:"activity_promotion_rate"` + ActivityTags []int `json:"activity_tags"` + ActivityType int `json:"activity_type"` + BrandName string `json:"brand_name"` + CashGiftAmount int `json:"cash_gift_amount"` + CatIds []int `json:"cat_ids"` + CltCpnBatchSn string `json:"clt_cpn_batch_sn"` + CltCpnDiscount int `json:"clt_cpn_discount"` + CltCpnEndTime int `json:"clt_cpn_end_time"` + CltCpnMinAmt int `json:"clt_cpn_min_amt"` + CltCpnQuantity int `json:"clt_cpn_quantity"` + CltCpnRemainQuantity int `json:"clt_cpn_remain_quantity"` + CltCpnStartTime int `json:"clt_cpn_start_time"` + CouponDiscount int64 `json:"coupon_discount"` + CouponEndTime int `json:"coupon_end_time"` + CouponMinOrderAmount int `json:"coupon_min_order_amount"` + CouponRemainQuantity int `json:"coupon_remain_quantity"` + CouponStartTime int `json:"coupon_start_time"` + CouponTotalQuantity int `json:"coupon_total_quantity"` + CreateAt int `json:"create_at"` + DescTxt string `json:"desc_txt"` + ExtraCouponAmount int `json:"extra_coupon_amount"` + GoodsDesc string `json:"goods_desc"` + GoodsImageUrl string `json:"goods_image_url"` + GoodsLabels []int `json:"goods_labels"` + GoodsName string `json:"goods_name"` + GoodsSign string `json:"goods_sign"` + GoodsThumbnailUrl string `json:"goods_thumbnail_url"` + HasCoupon bool `json:"has_coupon"` + HasMallCoupon bool `json:"has_mall_coupon"` + HasMaterial bool `json:"has_material"` + LgstTxt string `json:"lgst_txt"` + MallCouponDiscountPct int `json:"mall_coupon_discount_pct"` + MallCouponEndTime int `json:"mall_coupon_end_time"` + MallCouponId int `json:"mall_coupon_id"` + MallCouponMaxDiscountAmount int `json:"mall_coupon_max_discount_amount"` + MallCouponMinOrderAmount int `json:"mall_coupon_min_order_amount"` + MallCouponRemainQuantity int `json:"mall_coupon_remain_quantity"` + MallCouponStartTime int `json:"mall_coupon_start_time"` + MallCouponTotalQuantity int `json:"mall_coupon_total_quantity"` + MallCps int `json:"mall_cps"` + MallId int64 `json:"mall_id"` + MallName string `json:"mall_name"` + MerchantType int `json:"merchant_type"` + MinGroupPrice int64 `json:"min_group_price"` + MinNormalPrice int `json:"min_normal_price"` + OnlySceneAuth bool `json:"only_scene_auth"` + OptId int `json:"opt_id"` + OptIds []int `json:"opt_ids"` + OptName string `json:"opt_name"` + PlanType int `json:"plan_type"` + PredictPromotionRate int `json:"predict_promotion_rate"` + PromotionRate int64 `json:"promotion_rate"` + SalesTip string `json:"sales_tip"` + SearchId string `json:"search_id"` + ServTxt string `json:"serv_txt"` + ServiceTags []int `json:"service_tags"` + ShareRate int `json:"share_rate"` + SubsidyAmount int `json:"subsidy_amount"` + SubsidyDuoAmountTenMillion int `json:"subsidy_duo_amount_ten_million"` + UnifiedTags []string `json:"unified_tags"` + ZsDuoId int `json:"zs_duo_id"` + GoodsId int64 `json:"goods_id"` + CategoryId int64 `json:"category_id"` + CategoryName string `json:"category_name"` + } `json:"goods_list"` + ListId string `json:"list_id"` + SearchId string `json:"search_id"` + TotalCount int `json:"total_count"` + } `json:"goods_search_response"` +} + +// GoodsSearch 多多进宝商品查询 https://jinbao.pinduoduo.com/third-party/api-detail?apiName=pdd.ddk.goods.search +func (app *App) GoodsSearch(notMustParams ...Params) (body []byte, err error) { + // 参数 + params := NewParamsWithType("pdd.ddk.goods.search", notMustParams...) + // 请求 + body, err = app.request(params) + return +} diff --git a/service/pinduoduo/pdd.ddk.order.list.increment.get.go b/service/pinduoduo/pdd.ddk.order.list.increment.get.go new file mode 100644 index 00000000..e459c4ef --- /dev/null +++ b/service/pinduoduo/pdd.ddk.order.list.increment.get.go @@ -0,0 +1,62 @@ +package pinduoduo + +type OrderListIncrementGetResult struct { + OrderListGetResponse struct { + TotalCount int `json:"total_count"` + OrderList []struct { + SepMarketFee int `json:"sep_market_fee"` + GoodsPrice int64 `json:"goods_price"` + SepDuoId int `json:"sep_duo_id"` + PromotionRate int64 `json:"promotion_rate"` + Type int `json:"type"` + SubsidyDuoAmountLevel int `json:"subsidy_duo_amount_level"` + CatIds []int `json:"cat_ids"` + OrderStatus int `json:"order_status"` + OrderCreateTime int `json:"order_create_time"` + IsDirect int `json:"is_direct"` + OrderGroupSuccessTime int `json:"order_group_success_time"` + MallId int `json:"mall_id"` + OrderAmount int64 `json:"order_amount"` + PriceCompareStatus int `json:"price_compare_status"` + OrderModifyAt int `json:"order_modify_at"` + AuthDuoId int `json:"auth_duo_id"` + CpaNew int `json:"cpa_new"` + GoodsName string `json:"goods_name"` + BatchNo string `json:"batch_no"` + RedPacketType int `json:"red_packet_type"` + GoodsQuantity int `json:"goods_quantity"` + FailReason string `json:"fail_reason,omitempty"` + GoodsId int64 `json:"goods_id"` + SepParameters string `json:"sep_parameters"` + SepRate int `json:"sep_rate"` + SubsidyType int `json:"subsidy_type"` + CustomParameters string `json:"custom_parameters"` + GoodsThumbnailUrl string `json:"goods_thumbnail_url"` + ShareRate int `json:"share_rate"` + PromotionAmount int64 `json:"promotion_amount"` + OrderPayTime int64 `json:"order_pay_time"` + OrderReceiveTime int64 `json:"order_receive_time"` + OrderSettleTime int64 `json:"order_settle_time"` + ActivityTags []int `json:"activity_tags"` + GroupId int64 `json:"group_id"` + SepPid string `json:"sep_pid"` + OrderStatusDesc string `json:"order_status_desc"` + ShareAmount int `json:"share_amount"` + OrderId string `json:"order_id"` + GoodsSign string `json:"goods_sign"` + OrderSn string `json:"order_sn"` + OrderVerifyTime int64 `json:"order_verify_time"` + PId string `json:"p_id"` + ZsDuoId int `json:"zs_duo_id"` + } `json:"order_list"` + RequestId string `json:"request_id"` + } `json:"order_list_get_response"` +} + +func (app *App) OrderListIncrementGet(notMustParams ...Params) (body []byte, err error) { + // 参数 + params := NewParamsWithType("pdd.ddk.order.list.increment.get", notMustParams...) + // 请求 + body, err = app.request(params) + return +} diff --git a/service/pinduoduo/pdd.ddk.resource.url.gen.go b/service/pinduoduo/pdd.ddk.resource.url.gen.go new file mode 100644 index 00000000..b3f7a607 --- /dev/null +++ b/service/pinduoduo/pdd.ddk.resource.url.gen.go @@ -0,0 +1,35 @@ +package pinduoduo + +// ResourceUrlGenResult 返回参数 +type ResourceUrlGenResult struct { + ResourceUrlResponse struct { + MultiUrlList struct { + ShortUrl string `json:"short_url"` // 频道推广短链接 + Url string `json:"url"` // 频道推广长链接 + } `json:"multi_url_list"` // 多人团链接 + Sign string `json:"sign,omitempty"` // sign + SingleUrlList struct { + ShortUrl string `json:"short_url"` // 频道推广短链接 + Url string `json:"url"` // 频道推广长链接 + } `json:"single_url_list"` // 单人团链接 + WeAppInfo struct { + AppId string `json:"app_id"` // 小程序id + BannerUrl string `json:"banner_url"` // Banner图 + Desc string `json:"desc"` // 描述 + PagePath string `json:"page_path"` // 小程序path值 + SourceDisplayName string `json:"source_display_name"` // 来源名 + Title string `json:"title"` // 小程序标题 + UserName string `json:"user_name"` // 用户名 + WeAppIconUrl string `json:"we_app_icon_url"` // 小程序icon + } `json:"we_app_info"` // 拼多多福利券微信小程序信息 + } `json:"resource_url_response"` +} + +// ResourceUrlGen 创建多多进宝推广位 https://jinbao.pinduoduo.com/third-party/api-detail?apiName=pdd.ddk.goods.pid.generate +func (app *App) ResourceUrlGen(notMustParams ...Params) (body []byte, err error) { + // 参数 + params := NewParamsWithType("pdd.ddk.resource.url.gen", notMustParams...) + // 请求 + body, err = app.request(params) + return +} diff --git a/service/pinduoduo/pdd.ddk.rp.prom.url.generate.go b/service/pinduoduo/pdd.ddk.rp.prom.url.generate.go new file mode 100644 index 00000000..e7fa797b --- /dev/null +++ b/service/pinduoduo/pdd.ddk.rp.prom.url.generate.go @@ -0,0 +1,51 @@ +package pinduoduo + +// RpPromUrlGenerateResult 返回参数 +type RpPromUrlGenerateResult struct { + RpPromotionUrlGenerateResponse struct { + ResourceList []struct { + Desc string `json:"desc"` // 活动描述 + Url string `json:"url"` // 活动地址 + } `json:"resource_list"` + UrlList []struct { + MobileShortUrl string `json:"mobile_short_url"` // 推广移动短链接,对应出参mobile_url的短链接,与mobile_url功能一致。 + MobileUrl string `json:"mobile_url"` // 推广移动链接,用户安装拼多多APP的情况下会唤起APP,否则唤起H5页面 + MultiGroupMobileShortUrl string `json:"multi_group_mobile_short_url"` // 推广多人团移动短链接 + MultiGroupMobileUrl string `json:"multi_group_mobile_url"` // 推广多人团移动链接,用户安装拼多多APP的情况下会唤起APP,否则唤起H5页面 + MultiGroupShortUrl string `json:"multi_group_short_url"` // 推广多人团短链接 + MultiGroupUrl string `json:"multi_group_url"` // 推广多人团链接,唤起H5页面 + QqAppInfo struct { + AppId string `json:"app_id"` // 拼多多小程序id + BannerUrl string `json:"banner_url"` // Banner图 + Desc string `json:"desc"` // 描述 + PagePath string `json:"page_path"` // 小程序path值 + QqAppIconUrl string `json:"qq_app_icon_url"` // 小程序icon + SourceDisplayName string `json:"source_display_name"` // 来源名 + Title string `json:"title"` // 小程序标题 + UserName string `json:"user_name"` // 用户名 + } `json:"qq_app_info"` // qq小程序信息 + SchemaUrl string `json:"schema_url"` // schema链接,用户安装拼多多APP的情况下会唤起APP(需客户端支持schema跳转协议) + ShortUrl string `json:"short_url"` // 推广短链接,对应出参url的短链接,与url功能一致 + Url string `json:"url"` // 普通推广长链接,唤起H5页面 + WeAppInfo struct { + AppId string `json:"app_id"` // 小程序id + BannerUrl string `json:"banner_url"` // Banner图 + Desc string `json:"desc"` // 描述 + PagePath string `json:"page_path"` // 小程序path值 + SourceDisplayName string `json:"source_display_name"` // 来源名 + Title string `json:"title"` // 小程序标题 + UserName string `json:"user_name"` // 用户名 + WeAppIconUrl string `json:"we_app_icon_url"` // 小程序icon + } `json:"we_app_info"` // 拼多多福利券微信小程序信息 + } `json:"url_list"` + } `json:"rp_promotion_url_generate_response"` +} + +// RpPromUrlGenerate 生成营销工具推广链接 https://jinbao.pinduoduo.com/third-party/api-detail?apiName=pdd.ddk.rp.prom.url.generate +func (app *App) RpPromUrlGenerate(notMustParams ...Params) (body []byte, err error) { + // 参数 + params := NewParamsWithType("pdd.ddk.rp.prom.url.generate", notMustParams...) + // 请求 + body, err = app.request(params) + return +} diff --git a/service/pinduoduo/pdd.goods.cats.get.go b/service/pinduoduo/pdd.goods.cats.get.go new file mode 100644 index 00000000..3b82cf70 --- /dev/null +++ b/service/pinduoduo/pdd.goods.cats.get.go @@ -0,0 +1,24 @@ +package pinduoduo + +// GoodsCatsGetResult 返回参数 +type GoodsCatsGetResult struct { + GoodsCatsGetResponse struct { + GoodsCatsList []struct { + CatId int `json:"cat_id"` // 商品类目ID + CatName string `json:"cat_name"` // 商品类目名称 + Level int `json:"level"` // 类目层级,1-一级类目,2-二级类目,3-三级类目,4-四级类目 + ParentCatID int `json:"parent_cat_id"` // id所属父类目ID,其中,parent_id=0时为顶级节点 + } `json:"goods_cats_list"` + } `json:"goods_cats_get_response"` +} + +// GoodsCatsGet 商品标准类目接口 https://open.pinduoduo.com/application/document/api?id=pdd.goods.cats.get +func (app *App) GoodsCatsGet(parentOptId int) (body []byte, err error) { + // 参数 + param := NewParams() + param.Set("parent_cat_id", parentOptId) + params := NewParamsWithType("pdd.goods.cats.get", param) + // 请求 + body, err = app.request(params) + return +} diff --git a/service/pinduoduo/pdd.goods.opt.get.go b/service/pinduoduo/pdd.goods.opt.get.go new file mode 100644 index 00000000..168fae78 --- /dev/null +++ b/service/pinduoduo/pdd.goods.opt.get.go @@ -0,0 +1,24 @@ +package pinduoduo + +// GoodsOptGetResult 返回参数 +type GoodsOptGetResult struct { + GoodsOptGetResponse struct { + GoodsOptList []struct { + Level int `json:"level"` // 层级,1-一级,2-二级,3-三级,4-四级 + OptId int `json:"opt_id"` // 商品标签ID + OptName string `json:"opt_name"` // 商品标签名 + ParentOptId int `json:"parent_opt_id"` // id所属父ID,其中,parent_id=0时为顶级节点 + } `json:"goods_opt_list"` + } `json:"goods_opt_get_response"` +} + +// GoodsOptGet 查询商品标签列表 https://open.pinduoduo.com/application/document/api?id=pdd.goods.opt.get +func (app *App) GoodsOptGet(parentOptId int) (body []byte, err error) { + // 参数 + param := NewParams() + param.Set("parent_opt_id", parentOptId) + params := NewParamsWithType("pdd.goods.opt.get", param) + // 请求 + body, err = app.request(params) + return +} diff --git a/service/pinduoduo/pinduoduo.go b/service/pinduoduo/pinduoduo.go deleted file mode 100644 index cf4596dd..00000000 --- a/service/pinduoduo/pinduoduo.go +++ /dev/null @@ -1,95 +0,0 @@ -package pinduoduo - -import ( - "bytes" - "crypto/md5" - "encoding/hex" - "github.com/bitly/go-simplejson" - "github.com/dtapps/go-library/utils/goparams" - "io" - "io/ioutil" - "net/http" - "net/url" - "sort" - "strconv" - "strings" - "time" -) - -const api = "https://gw-api.pinduoduo.com/api/router" - -// Parameter 参数 -type Parameter map[string]interface{} - -// ParameterEncode 参数 -type ParameterEncode []string - -// PinDuoDuo 公共请求参数 -type PinDuoDuo struct { - ClientId string //必填 POP分配给应用的client_id - ClientSecret string //必填 POP分配给应用的client_secret -} - -func (d *PinDuoDuo) Send(method string, param Parameter) (*simplejson.Json, error) { - // 处理数据 - param["type"] = method - param.setRequestData(d) - // 请求 - resp, err := http.Post(api, "application/x-www-form-urlencoded;charset=utf-8", strings.NewReader(param.getRequestData())) - if err != nil { - return nil, err - } - defer resp.Body.Close() - // 返回结果 - body, _ := ioutil.ReadAll(resp.Body) - respJson, err := simplejson.NewJson(body) - if err != nil { - return nil, err - } - return respJson, nil -} - -// 签名数据 -func sign(params Parameter, clientSecret string) string { - // 参数按照参数名的字典升序排列 - var keys []string - for k := range params { - keys = append(keys, k) - } - sort.Strings(keys) - // 拼接参数 - query := bytes.NewBufferString(clientSecret) - for _, k := range keys { - query.WriteString(k) - query.WriteString(goparams.GetParamsString(params[k])) - } - query.WriteString(clientSecret) - // MD5加密 - h := md5.New() - io.Copy(h, query) - // 把二进制转化为大写的十六进制 - return strings.ToUpper(hex.EncodeToString(h.Sum(nil))) -} - -// 设置请求数据 -func (p Parameter) setRequestData(d *PinDuoDuo) { - hh, _ := time.ParseDuration("8h") - loc := time.Now().UTC().Add(hh) - p["timestamp"] = strconv.FormatInt(loc.Unix(), 10) - p["client_id"] = d.ClientId - p["data_type"] = "JSON" - p["version"] = "v1" - // 设置签名 - p["sign"] = sign(p, d.ClientSecret) -} - -// 获取请求数据 -func (p Parameter) getRequestData() string { - // 公共参数 - args := url.Values{} - // 请求参数 - for key, val := range p { - args.Set(key, goparams.GetParamsString(val)) - } - return args.Encode() -} diff --git a/service/pinduoduo/type/type.go b/service/pinduoduo/type/type.go deleted file mode 100644 index 70b3fd9f..00000000 --- a/service/pinduoduo/type/type.go +++ /dev/null @@ -1,7 +0,0 @@ -package _type - -const ( - GoodsPidGenerate = "pdd.ddk.goods.pid.generate" - GoodsSearch = "pdd.ddk.goods.search" // 多多进宝商品查询 https://jinbao.pinduoduo.com/third-party/api-detail?apiName=pdd.ddk.goods.search - GoodsDetail = "pdd.ddk.goods.detail" // 多多进宝商品详情查询 https://jinbao.pinduoduo.com/third-party/api-detail?apiName=pdd.ddk.goods.detail -)