京东商城api
This commit is contained in:
@@ -181,8 +181,8 @@ type WaybillReceiveParam struct {
|
||||
// SiteType int `json:"siteType"` //否 无 站点类型
|
||||
// SiteID int `json:"siteId"` //否 无 站点编码
|
||||
// SiteName string `json:"siteName"` //否 无 站点名称
|
||||
// ReceiveTel string `json:"receiveTel"` //否 无 收件人电话
|
||||
// ReceiveMobile string `json:"receiveMobile"` //否 无 收件人手机号(收件人电话、手机至少有一个不为空)
|
||||
ReceiveTel string `json:"receiveTel"` //否 无 收件人电话
|
||||
ReceiveMobile string `json:"receiveMobile"` //否 无 收件人手机号(收件人电话、手机至少有一个不为空)
|
||||
// Postcode string `json:"postcode"` //否 100000 收件人邮编,长度:6
|
||||
PackageCount int `json:"packageCount"` //是 无 包裹数(大于0,小于1000)
|
||||
Weight int `json:"weight"` //是 2.5 重量(单位:kg,保留小数点后两位)
|
||||
|
||||
108
platformapi/jdshopapi/jdshopapi.go
Normal file
108
platformapi/jdshopapi/jdshopapi.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package jdshopapi
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/baseapi"
|
||||
"git.rosy.net.cn/baseapi/platformapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
prodURL = "https://api.jd.com/routerjson"
|
||||
sigKey = "sign"
|
||||
)
|
||||
|
||||
type API struct {
|
||||
platformapi.APICookie
|
||||
|
||||
accessToken string
|
||||
appKey string
|
||||
appSecret string
|
||||
client *http.Client
|
||||
config *platformapi.APIConfig
|
||||
}
|
||||
|
||||
type UniteResp struct {
|
||||
Num int `json:"num"`
|
||||
IsSuccess bool `json:"is_success"`
|
||||
ErrorCode string `json:"error_code"`
|
||||
ErrorMsgCn string `json:"error_msg_cn"`
|
||||
ErrorMsg string `json:"error_msg"`
|
||||
}
|
||||
|
||||
func New(accessToken, appKey, appSecret string, config ...*platformapi.APIConfig) *API {
|
||||
curConfig := platformapi.DefAPIConfig
|
||||
if len(config) > 0 {
|
||||
curConfig = *config[0]
|
||||
}
|
||||
return &API{
|
||||
accessToken: accessToken,
|
||||
appKey: appKey,
|
||||
appSecret: appSecret,
|
||||
client: &http.Client{Timeout: curConfig.ClientTimeout},
|
||||
config: &curConfig,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) signParam(params map[string]interface{}) (sig string) {
|
||||
var valueList []string
|
||||
for k, v := range params {
|
||||
if k != sigKey {
|
||||
if str := fmt.Sprint(v); str != "" {
|
||||
valueList = append(valueList, fmt.Sprintf("%s%s", k, str))
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Sort(sort.StringSlice(valueList))
|
||||
valueList = append(valueList, fmt.Sprintf("%s", a.appSecret))
|
||||
var valueList2 = make([]string, len(valueList)+1)
|
||||
at := copy(valueList2, valueList[:0])
|
||||
at += copy(valueList2[at:], []string{a.appSecret})
|
||||
copy(valueList2[at:], valueList[0:])
|
||||
sig = strings.Join(valueList2, "")
|
||||
binSig := md5.Sum([]byte(sig))
|
||||
sig = fmt.Sprintf("%X", binSig)
|
||||
return sig
|
||||
}
|
||||
|
||||
func (a *API) AccessAPI(action string, url string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
|
||||
params := make(map[string]interface{})
|
||||
params["access_token"] = a.accessToken
|
||||
params["app_key"] = a.appKey
|
||||
params["timestamp"] = utils.Time2Str(time.Now())
|
||||
params["method"] = action
|
||||
params["v"] = "2.0"
|
||||
params = utils.MergeMaps(params, bizParams)
|
||||
signStr := a.signParam(params)
|
||||
params["sign"] = signStr
|
||||
fullURL := utils.GenerateGetURL(url, "", nil)
|
||||
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||||
func() *http.Request {
|
||||
request, _ := http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode()))
|
||||
request.Header.Set("charset", "UTF-8")
|
||||
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
return request
|
||||
},
|
||||
a.config,
|
||||
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
|
||||
if jsonResult1 == nil {
|
||||
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
|
||||
}
|
||||
if err == nil {
|
||||
if jsonResult1["error_response"] != nil {
|
||||
errLevel = platformapi.ErrLevelGeneralFail
|
||||
err = utils.NewErrorCode(jsonResult1["error_response"].(map[string]interface{})["zh_desc"].(string), jsonResult1["error_response"].(map[string]interface{})["code"].(string))
|
||||
baseapi.SugarLogger.Debugf("jdeclp AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true))
|
||||
}
|
||||
retVal = jsonResult1
|
||||
}
|
||||
return errLevel, err
|
||||
})
|
||||
return retVal, err
|
||||
}
|
||||
19
platformapi/jdshopapi/jxshopapi_test.go
Normal file
19
platformapi/jdshopapi/jxshopapi_test.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package jdshopapi
|
||||
|
||||
import (
|
||||
"git.rosy.net.cn/baseapi"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
api *API
|
||||
sugarLogger *zap.SugaredLogger
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger, _ := zap.NewDevelopment()
|
||||
sugarLogger = logger.Sugar()
|
||||
baseapi.Init(sugarLogger)
|
||||
api = New("da8db492e20149e494afaf5607e1d6654zgi", "E1D746D42474D5F1F1A10CECE75D99F6", "efa7e1d1a22640fa990e6cf164b28608")
|
||||
api.SetCookie("thor", "80FAF09E9A09B6E618A68057BDFCFCB81C821714A15F3E8682FBAD9605C6284CE3D573A97D5021559891D214CDCCFA4A90F8254643B0A60E168F976FF8C3D2E5ACB0F3DB2ABFBC0A2E4EE6297EC49919CAE5CBBD6A686F1F7370B6ABD7AE8BE70DD216650EC9AAD79928DAC85CFA2D9BC581BA085F0D45C613A99F13F25AA3B24372930D5BB7CEBF685AF34698EBFD92")
|
||||
}
|
||||
52
platformapi/jdshopapi/sku.go
Normal file
52
platformapi/jdshopapi/sku.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package jdshopapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
)
|
||||
|
||||
type FindShopCategoriesResult struct {
|
||||
CID int64 `json:"cid"` //123456 分类编号
|
||||
VenderID int `json:"vender_id"` //123456 商家编号
|
||||
ShopID int `json:"shop_id"` // 123456 店铺编号
|
||||
ParentCID int64 `json:"parent_cid"` //123456 父分类编号
|
||||
OrderNo int `json:"order_no"` //1 分类排序
|
||||
Name string `json:"name"` //分类1 分类名称
|
||||
IsOpen bool `json:"is_open"` //false 是否展开子分类(false,不展开;true,展开)
|
||||
IsHomeShow bool `json:"is_home_show"` //false 是否在首页展示分类(false,前台不展示,true前台展示
|
||||
Status int `json:"status"` // 1 状态(1:删除 1:正常)
|
||||
CreateTime int64 `json:"create_time"` //1394089643000 创建时间
|
||||
ModifyTime int64 `json:"modify_time"` // 修改时间。每修改一次此值都会发生变化。
|
||||
}
|
||||
|
||||
//查询商家所有的店内分类
|
||||
//https://open.jd.com/home/home#/doc/api?apiCateId=88&apiId=2801&apiName=jingdong.vender.shopcategory.findShopCategoriesByVenderId
|
||||
func (a *API) FindShopCategories() (findShopCategoriesResult []*FindShopCategoriesResult, err error) {
|
||||
result, err := a.AccessAPI("jingdong.vender.shopcategory.findShopCategoriesByVenderId", prodURL, nil)
|
||||
if err == nil {
|
||||
utils.Map2StructByJson(result["jingdong_vender_shopcategory_findShopCategoriesByVenderId_responce"].(map[string]interface{})["shopCategoryResult"].(map[string]interface{})["shop_category_list"], &findShopCategoriesResult, false)
|
||||
}
|
||||
return findShopCategoriesResult, err
|
||||
}
|
||||
|
||||
//删除店内分类
|
||||
//https://open.jd.com/home/home#/doc/api?apiCateId=88&apiId=3031&apiName=jingdong.vender.shopcategory.deleteShopCategoryByVenderIdAndCid
|
||||
func (a *API) DeleteShopCategory(cid int64) (uniteResp *UniteResp, err error) {
|
||||
result, err := a.AccessAPI("jingdong.vender.shopcategory.deleteShopCategoryByVenderIdAndCid", prodURL, map[string]interface{}{
|
||||
"cid": cid,
|
||||
})
|
||||
if err == nil {
|
||||
utils.Map2StructByJson(result["jingdong_vender_shopcategory_deleteShopCategoryByVenderIdAndCid_responce"].(map[string]interface{})["shopCategoryResult"], &uniteResp, false)
|
||||
if !uniteResp.IsSuccess {
|
||||
return nil, fmt.Errorf(uniteResp.ErrorMsgCn)
|
||||
}
|
||||
}
|
||||
return uniteResp, err
|
||||
}
|
||||
|
||||
//京东商城发布商品(创建商品?)
|
||||
//https://open.jd.com/home/home#/doc/api?apiCateId=48&apiId=1379&apiName=jingdong.ware.write.add
|
||||
func (a *API) CreateSkuName() (err error) {
|
||||
return err
|
||||
}
|
||||
23
platformapi/jdshopapi/sku_test.go
Normal file
23
platformapi/jdshopapi/sku_test.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package jdshopapi
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
)
|
||||
|
||||
func TestFindShopCategories(t *testing.T) {
|
||||
result, err := api.FindShopCategories()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(utils.Format4Output(result, false))
|
||||
}
|
||||
|
||||
func TestDeleteShopCategory(t *testing.T) {
|
||||
result, err := api.DeleteShopCategory(14439186)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(utils.Format4Output(result, false))
|
||||
}
|
||||
61
platformapi/jdshopapi/store_page.go
Normal file
61
platformapi/jdshopapi/store_page.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package jdshopapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"git.rosy.net.cn/baseapi"
|
||||
"git.rosy.net.cn/baseapi/platformapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
)
|
||||
|
||||
func (a *API) AccessStorePage(fullURL string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
|
||||
if a.GetCookieCount() == 0 {
|
||||
return nil, fmt.Errorf("需要设置Store Cookie才能使用此方法")
|
||||
}
|
||||
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||||
func() *http.Request {
|
||||
request, _ := http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(bizParams).Encode()))
|
||||
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
a.FillRequestCookies(request)
|
||||
return request
|
||||
},
|
||||
a.config,
|
||||
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
|
||||
if jsonResult1 == nil {
|
||||
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
|
||||
}
|
||||
if err == nil {
|
||||
if jsonResult1["error_response"] != nil {
|
||||
errLevel = platformapi.ErrLevelGeneralFail
|
||||
err = utils.NewErrorCode(jsonResult1["error_response"].(map[string]interface{})["zh_desc"].(string), jsonResult1["error_response"].(map[string]interface{})["code"].(string))
|
||||
baseapi.SugarLogger.Debugf("jdeclp AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true))
|
||||
}
|
||||
retVal = jsonResult1
|
||||
}
|
||||
return errLevel, err
|
||||
})
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
type CreateShopCategoryParam struct {
|
||||
HomeShow int `json:"homeShow"`
|
||||
ID int `json:"id"`
|
||||
Open string `json:"open"`
|
||||
OrderNo int `json:"orderNo"`
|
||||
ParentID string `json:"parentId"`
|
||||
Title string `json:"title"`
|
||||
Type int `json:"type"`
|
||||
}
|
||||
|
||||
//京东商城创建或修改店内分类
|
||||
//https://seller.shop.jd.com/vendershop/vendershop_shopCategory.action#
|
||||
func (a *API) CreateShopCategory(createShopCategoryParam []*CreateShopCategoryParam) (err error) {
|
||||
result, _ := json.MarshalIndent(createShopCategoryParam, "", "")
|
||||
_, err = a.AccessStorePage("https://seller.shop.jd.com/vendershop/vendershop_doShopCategory.action", map[string]interface{}{
|
||||
"categoryJson": string(result),
|
||||
})
|
||||
return err
|
||||
}
|
||||
20
platformapi/jdshopapi/store_page_test.go
Normal file
20
platformapi/jdshopapi/store_page_test.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package jdshopapi
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCreateShopCategory(t *testing.T) {
|
||||
var CreateShopCategoryParams = []*CreateShopCategoryParam{
|
||||
&CreateShopCategoryParam{
|
||||
HomeShow: 0,
|
||||
ID: 0,
|
||||
Open: "",
|
||||
OrderNo: 0,
|
||||
ParentID: "",
|
||||
Title: "测试1",
|
||||
Type: 3,
|
||||
},
|
||||
}
|
||||
api.CreateShopCategory(CreateShopCategoryParams)
|
||||
}
|
||||
Reference in New Issue
Block a user