diff --git a/platformapi/ebaiapi/common.go b/platformapi/ebaiapi/common.go new file mode 100644 index 00000000..49de80ec --- /dev/null +++ b/platformapi/ebaiapi/common.go @@ -0,0 +1,32 @@ +package ebaiapi + +import ( + "git.rosy.net.cn/baseapi/utils" +) + +type CityInfo struct { + ID int `json:"city_id"` + Name string `json:"city_name"` + ParentID int `json:"parent_id"` + IsOpen int `json:"is_open"` + Level int `json:"level"` +} + +func (a *API) CommonShopCities(parentID int) (cityList []*CityInfo, err error) { + result, err := a.AccessAPI("common.shopcities", utils.Params2Map("pid", parentID)) + if err == nil { + cityMapList := utils.Slice2MapSlice(result.Data.([]interface{})) + // baseapi.SugarLogger.Debug(utils.Format4Output(cityMapList, false)) + cityList = make([]*CityInfo, len(cityMapList)) + for k, v := range cityMapList { + cityList[k] = &CityInfo{ + ID: int(utils.Str2Int64(utils.Interface2String(v["city_id"]))), + Name: utils.Interface2String(v["city_name"]), + ParentID: int(utils.Str2Int64(utils.Interface2String(v["parent_id"]))), + IsOpen: int(utils.Str2Int64(utils.Interface2String(v["is_open"]))), + } + } + return cityList, nil + } + return nil, err +} diff --git a/platformapi/ebaiapi/common_test.go b/platformapi/ebaiapi/common_test.go new file mode 100644 index 00000000..4e28ef5f --- /dev/null +++ b/platformapi/ebaiapi/common_test.go @@ -0,0 +1,16 @@ +package ebaiapi + +import ( + "testing" + + "git.rosy.net.cn/baseapi/utils" +) + +func TestCommonShopCities(t *testing.T) { + result, err := api.CommonShopCities(0) + if err != nil { + t.Fatal(err) + } else { + t.Log(utils.Format4Output(result, false)) + } +} diff --git a/platformapi/ebaiapi/ebaiapi.go b/platformapi/ebaiapi/ebaiapi.go index eb97766f..eb673fd7 100644 --- a/platformapi/ebaiapi/ebaiapi.go +++ b/platformapi/ebaiapi/ebaiapi.go @@ -101,6 +101,9 @@ func (a *API) AccessAPI(cmd string, body map[string]interface{}) (retVal *Respon return platformapi.ErrLevelSuccess, nil } newErr := utils.NewErrorIntCode(retVal.Error, retVal.ErrNo) + if newErr.IntCode() == 20212 { + return platformapi.ErrLevelExceedLimit, newErr + } return platformapi.ErrLevelCodeIsNotOK, newErr }) return retVal, err diff --git a/platformapi/ebaiapi/ebaiapi_test.go b/platformapi/ebaiapi/ebaiapi_test.go index 9ba4e2f9..0bde63e1 100644 --- a/platformapi/ebaiapi/ebaiapi_test.go +++ b/platformapi/ebaiapi/ebaiapi_test.go @@ -11,7 +11,7 @@ import ( const ( testShopBaiduID = 2233043816 - testShopID = "test_708706_63032" + testShopID = "100077" ) var ( diff --git a/platformapi/ebaiapi/shop.go b/platformapi/ebaiapi/shop.go index 3bd3531a..89993e06 100644 --- a/platformapi/ebaiapi/shop.go +++ b/platformapi/ebaiapi/shop.go @@ -59,7 +59,7 @@ type ShopInfo struct { OrderStatusPush int `json:"order_status_push"` } -func (a *API) genParams(shopID string, baiduShopID int64) map[string]interface{} { +func (a *API) genShopIDParams(shopID string, baiduShopID int64) map[string]interface{} { if shopID == "" && baiduShopID == 0 || shopID != "" && baiduShopID != 0 { panic("shopID and baiduShopID can not all be empty or all not be empty") } @@ -102,8 +102,16 @@ func (a *API) ShopList( /*orderPush, orderStatusPush, status, */ sysStatus int) return nil, err } +func (a *API) ShopCreate(params map[string]interface{}) (baiduShopID int64, err error) { + result, err := a.AccessAPI("shop.create", params) + if err == nil { + return utils.MustInterface2Int64(result.Data.(map[string]interface{})[KeyBaiduShopID]), nil + } + return 0, err +} + func (a *API) ShopGet(shopID string, baiduShopID int64) (shop map[string]interface{}, err error) { - params := a.genParams(shopID, baiduShopID) + params := a.genShopIDParams(shopID, baiduShopID) result, err := a.AccessAPI("shop.get", params) if err == nil { return result.Data.(map[string]interface{}), nil @@ -120,7 +128,7 @@ func (a *API) ShopUpdate(params map[string]interface{}) (err error) { } func (a *API) ShopBusStatusGet(shopID string, baiduShopID int64, platformFlag string) (busStatus int, err error) { - params := a.genParams(shopID, baiduShopID) + params := a.genShopIDParams(shopID, baiduShopID) params["platformFlag"] = platformFlag result, err := a.AccessAPI("shop.busstatus.get", params) if err == nil { @@ -139,7 +147,7 @@ func (a *API) ShopIDBatchUpdate(baiduShopIDs []string, shopIDs []string) (err er } func (a *API) ShopOnline(shopID string, baiduShopID int64) (err error) { - params := a.genParams(shopID, baiduShopID) + params := a.genShopIDParams(shopID, baiduShopID) _, err = a.AccessAPI("shop.open", params) if err == nil { return nil @@ -148,7 +156,7 @@ func (a *API) ShopOnline(shopID string, baiduShopID int64) (err error) { } func (a *API) ShopOffline(shopID string, baiduShopID int64) (err error) { - params := a.genParams(shopID, baiduShopID) + params := a.genShopIDParams(shopID, baiduShopID) _, err = a.AccessAPI("shop.offline", params) if err == nil { return nil @@ -157,7 +165,7 @@ func (a *API) ShopOffline(shopID string, baiduShopID int64) (err error) { } func (a *API) ShopClose(shopID string, baiduShopID int64) (err error) { - params := a.genParams(shopID, baiduShopID) + params := a.genShopIDParams(shopID, baiduShopID) _, err = a.AccessAPI("shop.close", params) if err == nil { return nil diff --git a/platformapi/ebaiapi/shop_sku.go b/platformapi/ebaiapi/shop_sku.go new file mode 100644 index 00000000..c4f90668 --- /dev/null +++ b/platformapi/ebaiapi/shop_sku.go @@ -0,0 +1,152 @@ +package ebaiapi + +import ( + "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/utils" +) + +const ( + SkuStatusOnline = 1 + SkuStatusOffline = 0 +) + +const ( + MaxLeftNum = 9999 + DefUPC = 12345678 +) + +type CategoryInfo struct { + CategoryID int64 `json:"category_id"` + ShopCustomID string `json:"shop_custom_id"` + Name string `json:"name"` + Rank int `json:"rank"` // 店内分类独有 + Children []*CategoryInfo `json:"children"` + Level int +} + +type PageDataInfo struct { + Total int + Page int + Pages int + List []map[string]interface{} +} + +// category相关的函数,shop_custom_id可重 + +func (a *API) ShopCategoryCreate(shopID string, parentID int64, name string, rank int, shopCustomID string) (catID int64, err error) { + result, err := a.AccessAPI("sku.shop.category.create", map[string]interface{}{ + KeyShopID: shopID, + "parent_category_id": parentID, + "name": name, + "rank": rank, + "shop_custom_id": shopCustomID, + }) + if err == nil { + return utils.Str2Int64(utils.Interface2String(result.Data.(map[string]interface{})["category_id"])), nil + } + return 0, err +} + +func (a *API) ShopCategoryGet(shopID string) (cats []*CategoryInfo, err error) { + result, err := a.AccessAPI("sku.shop.category.get", utils.Params2Map(KeyShopID, shopID)) + if err == nil { + baseapi.SugarLogger.Debug(result) + cats := interface2CatList(result.Data.(map[string]interface{})["categorys"], 1) + return cats, nil + } + return nil, err +} + +func (a *API) ShopCategoryUpdate(shopID string, categoryID int64, name string, rank int, shopCustomID string) (err error) { + _, err = a.AccessAPI("sku.shop.category.update", map[string]interface{}{ + KeyShopID: shopID, + "category_id": categoryID, + "name": name, + "rank": rank, + "shop_custom_id": shopCustomID, + }) + if errWithCode, ok := err.(*utils.ErrorWithCode); ok { + if errWithCode.Level() == 0 && errWithCode.IntCode() == 1 { //忽略同名错误 + err = nil + } + } + return err +} + +func (a *API) ShopCategoryDelete(shopID string, categoryID int64) (err error) { + _, err = a.AccessAPI("sku.shop.category.delete", map[string]interface{}{ + KeyShopID: shopID, + "category_id": categoryID, + }) + return err +} + +func (a *API) SkuGetItemsByCategoryId(shopID string, categoryID int64) (skus []map[string]interface{}, err error) { + result, err := a.AccessAPI("sku.getItemsByCategoryId", map[string]interface{}{ + KeyShopID: shopID, + "category_id": categoryID, + }) + if err == nil { + return utils.Slice2MapSlice(result.Data.([]interface{})), nil + } + return nil, err +} + +func (a *API) SkuList(shopID string, params map[string]interface{}) (skuInfo *PageDataInfo, err error) { + defParams := map[string]interface{}{ + KeyShopID: shopID, + } + result, err := a.AccessAPI("sku.list", utils.MergeMaps(params, defParams)) + if err == nil { + data := result.Data.(map[string]interface{}) + return &PageDataInfo{ + Total: int(utils.MustInterface2Int64(data["total"])), + Page: int(utils.MustInterface2Int64(data["page"])), + Pages: int(utils.MustInterface2Int64(data["pages"])), + List: utils.Slice2MapSlice(data["list"].([]interface{})), + }, nil + } + return nil, err +} + +func (a *API) SkuCreate(shopID string, params map[string]interface{}) (skuID int64, err error) { + defParams := map[string]interface{}{ + KeyShopID: shopID, + } + if params["upc"] == nil { + defParams["upc"] = DefUPC + } + if params["brand_id"] == nil { + defParams["brand_id"] = 0 + } + result, err := a.AccessAPI("sku.create", utils.MergeMaps(params, defParams)) + if err == nil { + return utils.MustInterface2Int64(result.Data.(map[string]interface{})["sku_id"]), nil + } + return 0, err +} + +// +func interface2CatList(data interface{}, level int) (cats []*CategoryInfo) { + maps, ok := data.([]interface{}) + if ok { + cats = make([]*CategoryInfo, len(maps)) + for index, v := range maps { + cats[index] = interface2Cat(v, level) + } + } + return cats +} + +func interface2Cat(data interface{}, level int) (cat *CategoryInfo) { + catMap := data.(map[string]interface{}) + cat = &CategoryInfo{ + CategoryID: utils.MustInterface2Int64(catMap["category_id"]), + ShopCustomID: utils.Interface2String(catMap["shop_custom_id"]), + Name: utils.Interface2String(catMap["name"]), + Rank: int(utils.MustInterface2Int64(catMap["rank"])), + Children: interface2CatList(catMap["children"], level+1), + Level: level, + } + return cat +} diff --git a/platformapi/ebaiapi/shop_sku_test.go b/platformapi/ebaiapi/shop_sku_test.go new file mode 100644 index 00000000..ac0e5d88 --- /dev/null +++ b/platformapi/ebaiapi/shop_sku_test.go @@ -0,0 +1,73 @@ +package ebaiapi + +import ( + "testing" + + "git.rosy.net.cn/baseapi/utils" +) + +func TestShopCategoryCreate(t *testing.T) { + result, err := api.ShopCategoryCreate(testShopID, 0, "绿色蔬菜", 16, "16") + if err != nil { + t.Fatal(err) + } else { + t.Log(utils.Format4Output(result, false)) + } +} + +func TestShopCategoryGet(t *testing.T) { + result, err := api.ShopCategoryGet(testShopID) + if err != nil { + t.Fatal(err) + } else { + t.Log(utils.Format4Output(result, false)) + } +} + +func TestShopCategoryUpdate(t *testing.T) { + err := api.ShopCategoryUpdate(testShopID, 153760204017121, "水果2", 2, "2") + if err != nil { + t.Fatal(err) + } +} + +func TestShopCategoryDelete(t *testing.T) { + err := api.ShopCategoryDelete(testShopID, 153760195017120) + if err != nil { + t.Fatal(err) + } +} + +func TestSkuGetItemsByCategoryId(t *testing.T) { + result, err := api.SkuGetItemsByCategoryId(testShopID, 0) + if err != nil { + t.Fatal(err) + } else { + t.Log(utils.Format4Output(result, false)) + } +} + +func TestSkuList(t *testing.T) { + result, err := api.SkuList(testShopID, nil) + if err != nil { + t.Fatal(err) + } else { + t.Log(utils.Format4Output(result, false)) + } +} + +func TestSkuCreate(t *testing.T) { + result, err := api.SkuCreate(testShopID, map[string]interface{}{ + "name": "测试商品", + "status": SkuStatusOnline, + "left_num": MaxLeftNum, + "sale_price": 100, + "market_price": 100, + "custom_sku_id": 1, + }) + if err != nil { + t.Fatal(err) + } else { + t.Log(utils.Format4Output(result, false)) + } +} diff --git a/platformapi/ebaiapi/shop_test.go b/platformapi/ebaiapi/shop_test.go index 92064bfa..03dd4d88 100644 --- a/platformapi/ebaiapi/shop_test.go +++ b/platformapi/ebaiapi/shop_test.go @@ -15,6 +15,16 @@ func TestShopList(t *testing.T) { } } +func TestShopCreate(t *testing.T) { + + // result, err := api.ShopCreate("", testShopBaiduID) + // if err != nil { + // t.Fatal(err) + // } else { + // t.Log(utils.Format4Output(result, false)) + // } +} + func TestShopGet(t *testing.T) { result, err := api.ShopGet("", testShopBaiduID) if err != nil { diff --git a/platformapi/ebaiapi/sku.go b/platformapi/ebaiapi/sku.go new file mode 100644 index 00000000..534b6a63 --- /dev/null +++ b/platformapi/ebaiapi/sku.go @@ -0,0 +1,15 @@ +package ebaiapi + +import "git.rosy.net.cn/baseapi/utils" + +func (a *API) SkuCategoryList(keyword string, depth int, parentID int64) (cats []interface{}, err error) { + result, err := a.AccessAPI("sku.category.list", map[string]interface{}{ + "keyword": keyword, + "depth": depth, + "parent_id": parentID, + }) + if err == nil { + return utils.Interface2Slice(result.Data), nil + } + return nil, err +} diff --git a/platformapi/ebaiapi/sku_test.go b/platformapi/ebaiapi/sku_test.go new file mode 100644 index 00000000..46d40620 --- /dev/null +++ b/platformapi/ebaiapi/sku_test.go @@ -0,0 +1,16 @@ +package ebaiapi + +import ( + "testing" + + "git.rosy.net.cn/baseapi/utils" +) + +func TestSkuCategoryList(t *testing.T) { + result, err := api.SkuCategoryList("", 1, 0) + if err != nil { + t.Fatal(err) + } else { + t.Log(utils.Format4Output(result, false)) + } +} diff --git a/platformapi/jdapi/sku.go b/platformapi/jdapi/sku.go index f5d005aa..2a28130b 100644 --- a/platformapi/jdapi/sku.go +++ b/platformapi/jdapi/sku.go @@ -211,6 +211,7 @@ func (a *API) ChangeShopCategoryOrder(pid int64, childIds []int64) error { // 删除商家店内分类接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=c17b96e9fe254b2a8574f6d1bc0c1667 +// 删除一个不存在的分类,好像不会报错 func (a *API) DelShopCategory(id int64) error { _, err := a.AccessAPINoPage("pms/delShopCategory", utils.Params2Map(KeyID, id), nil, nil, nullResultParser) return err diff --git a/platformapi/platformapi.go b/platformapi/platformapi.go index 0e8d474b..0d4e6496 100644 --- a/platformapi/platformapi.go +++ b/platformapi/platformapi.go @@ -6,16 +6,16 @@ import ( "net/http" "time" - "github.com/fatih/structs" - "git.rosy.net.cn/baseapi" + "github.com/fatih/structs" ) const ( DefClientTimeout = 10 * time.Second DefSleepSecondWhenExceedLimit = 6 * time.Second + DefRandSlice = 10 DefMaxRecoverableRetryCount = 3 - DefMaxExceedLimitRetryCount = 10 + DefMaxExceedLimitRetryCount = 12 ) type APIRetryConfig struct {