632 lines
20 KiB
Go
632 lines
20 KiB
Go
package ebaiapi
|
||
|
||
import (
|
||
"fmt"
|
||
"regexp"
|
||
"strings"
|
||
|
||
"gitrosy.jxc4.com/baseapi/utils"
|
||
)
|
||
|
||
const (
|
||
SkuStatusOnline = 1 // 为上架
|
||
SkuStatusOffline = 0 // 为下架
|
||
SkuStatusDeleted = 2 // 为删除
|
||
)
|
||
|
||
const (
|
||
UPCTypeStandard = 1
|
||
UPCTypePrivate = 0
|
||
)
|
||
const (
|
||
MaxLeftNum = 99999
|
||
MaxSkuNameByteCount = 100 // skuname的最大字节数,注意不是字符数,超长饿百会报错:{"data":"","errno":20200,"error":"invalid param:[name]...
|
||
|
||
MaxStoreSkuBatchSize = 100 // sku.offline, sku.online, sku.price.update.batch和sku.stock.update.batch这些批量操作的最大值
|
||
MaxSkuCatRank = 100000 // 商品排序优先级 ,最小值为1,最大值为100000,rank值较大的优先展示
|
||
MaxCatCatRank = 100000 // 自定义分类排序优先级 ,最小值为1,最大值为100000,rank值较大的优先展示
|
||
MaxSkuListPageSize = 100 //获取数量,1-100,默认20
|
||
|
||
MaxCategoryNameLen = 12 // 商家分类名最大长度
|
||
)
|
||
|
||
var (
|
||
shopSkuBatchFailedSkuReg = regexp.MustCompile(`请核查以下sku:(\{.*\})`)
|
||
|
||
skuExistMsgList = []string{"商品已存在", "shop sku exist", "已被使用,请更换"}
|
||
skuNotExistMsgList = []string{"sku_id与shop_id不匹配", "SKU不存在或者已经被删除", "商品不存在"}
|
||
)
|
||
|
||
type CategoryInfo struct {
|
||
CategoryID int64 `json:"category_id"`
|
||
Name string `json:"name"`
|
||
Rank int `json:"rank"` // 店内分类独有
|
||
Children []*CategoryInfo `json:"children"`
|
||
Level int `json:"level"`
|
||
}
|
||
|
||
type SkuListParams struct {
|
||
Page int `json:"page,omitempty"`
|
||
PageSize int `json:"pagesize,omitempty"`
|
||
Upc string `json:"upc,omitempty"`
|
||
SkuID int64 `json:"sku_id,omitempty"`
|
||
CustomSkuID string `json:"custom_sku_id,omitempty"`
|
||
//UpcType int `json:"upc_type,omitempty"`
|
||
GetUncate int `json:"get_uncate,omitempty"`
|
||
Delete int `json:"delete,omitempty"`
|
||
Enabled int `json:"enabled,omitempty"`
|
||
StartTime int `json:"start_time,omitempty"`
|
||
EndTime int `json:"end_time,omitempty"`
|
||
SkuIdOffset int `json:"sku_id_offset,omitempty"`
|
||
}
|
||
|
||
type SkuPhotoInfo struct {
|
||
IsMaster int `json:"is_master"`
|
||
URL string `json:"url"`
|
||
}
|
||
|
||
type SkuCustomCatInfo struct {
|
||
CustomCatID string `json:"custom_cat_id"`
|
||
CustomCatName string `json:"custom_cat_name"`
|
||
}
|
||
|
||
type SkuInfo struct {
|
||
CateId int `json:"cate_id"`
|
||
CateId1 int `json:"cate_id1"`
|
||
CateId2 int `json:"cate_id2"`
|
||
CateName string `json:"cate_name"`
|
||
CateName1 string `json:"cate_name1"`
|
||
CateName2 string `json:"cate_name2"`
|
||
CustomCatIds string `json:"custom_cat_ids"`
|
||
CustomSkuId string `json:"custom_sku_id"`
|
||
DurationSaleFlag bool `json:"duration_sale_flag"`
|
||
IsInActivity int `json:"is_in_activity"`
|
||
ItemId int64 `json:"item_id"`
|
||
LeftNum int `json:"left_num"`
|
||
MarketPrice int `json:"market_price"`
|
||
Minimum int `json:"minimum"`
|
||
Name string `json:"name"`
|
||
NeedIce string `json:"need_ice"`
|
||
PackageFlag bool `json:"package_flag"`
|
||
Photos []struct {
|
||
IsMaster int `json:"is_master"`
|
||
Url string `json:"url"`
|
||
} `json:"photos"`
|
||
PreminusWeight int `json:"preminus_weight"`
|
||
PreparationTime int `json:"preparation_time"`
|
||
PrescriptionType string `json:"prescription_type"`
|
||
ProcessDetail []interface{} `json:"process_detail"`
|
||
ProcessType int `json:"process_type"`
|
||
ProductionAddr1 string `json:"production_addr1"`
|
||
ProductionAddr2 string `json:"production_addr2"`
|
||
ProductionAddr3 string `json:"production_addr3"`
|
||
Rtf string `json:"rtf"`
|
||
SalePrice int `json:"sale_price"`
|
||
SaleStep int `json:"sale_step"`
|
||
SaleUnit string `json:"sale_unit"`
|
||
SevenDaysNoReason bool `json:"seven_days_no_reason"`
|
||
SkuId int64 `json:"sku_id"`
|
||
SkuProperty []interface{} `json:"sku_property"`
|
||
Status string `json:"status"`
|
||
Summary string `json:"summary"`
|
||
Upc string `json:"upc"`
|
||
UpcType int `json:"upc_type"`
|
||
Weight string `json:"weight"`
|
||
WeightFlag int `json:"weight_flag"`
|
||
|
||
CustomCatIDs string `json:"custom_cat_ids"`
|
||
CustomCatList []*SkuCustomCatInfo `json:"custom_cat_list"`
|
||
CustomSkuID string `json:"custom_sku_id"`
|
||
ShelfNumber string `json:"shelf_number"`
|
||
UpdateTime string `json:"update_time"`
|
||
}
|
||
|
||
type PageDataInfo struct {
|
||
Total int `json:"Total"`
|
||
Page int `json:"Page"`
|
||
Pages int `json:"Pages"`
|
||
SkuIdOffset int `json:"sku_id_offset"`
|
||
List []*SkuInfo `json:"List"`
|
||
}
|
||
|
||
type BatchOpSkuResult struct {
|
||
SkuID int64 `json:"sku_id"`
|
||
Price int `json:"price,omitempty"`
|
||
ErrorNo int `json:"error_no,omitempty"`
|
||
ErrorMsg string `json:"error_msg,omitempty"`
|
||
}
|
||
|
||
type BatchOpResult struct {
|
||
FailedList []*BatchOpSkuResult `json:"failed_list"`
|
||
SuccessList []*BatchOpSkuResult `json:"success_list"`
|
||
}
|
||
|
||
const (
|
||
SkuIDTypeUnknown = 0
|
||
SkuIDTypeSkuID = 1
|
||
SkuIDTypeCustomSkuID = 2
|
||
SkuIDTypeUpc = 3
|
||
)
|
||
|
||
var (
|
||
priceUpdateKeyIDMap = map[int]string{
|
||
SkuIDTypeSkuID: "skuid_price",
|
||
SkuIDTypeCustomSkuID: "custom_sku_id",
|
||
SkuIDTypeUpc: "upc_price",
|
||
}
|
||
stockUpdateKeyIDMap = map[int]string{
|
||
SkuIDTypeSkuID: "skuid_stocks",
|
||
SkuIDTypeCustomSkuID: "custom_sku_id",
|
||
SkuIDTypeUpc: "upc_stocks",
|
||
}
|
||
)
|
||
|
||
type ShopSkuInfo struct {
|
||
SkuID int64
|
||
CustomSkuID string
|
||
Upc string
|
||
|
||
SalePrice int64
|
||
MarketPrice int64
|
||
Stock int
|
||
}
|
||
|
||
type ShopSkuInfoList []*ShopSkuInfo
|
||
|
||
func (v *ShopSkuInfo) GuessIDType() int {
|
||
if v.SkuID > 0 {
|
||
return SkuIDTypeSkuID
|
||
} else if v.CustomSkuID != "" {
|
||
return SkuIDTypeCustomSkuID
|
||
}
|
||
return SkuIDTypeUpc
|
||
}
|
||
|
||
func (v *ShopSkuInfo) ToSkuID(skuIDType int) (str string) {
|
||
if skuIDType == SkuIDTypeUnknown {
|
||
skuIDType = v.GuessIDType()
|
||
}
|
||
if skuIDType == SkuIDTypeSkuID {
|
||
str = utils.Int64ToStr(v.SkuID)
|
||
} else if skuIDType == SkuIDTypeCustomSkuID {
|
||
str = v.CustomSkuID
|
||
} else {
|
||
str = v.Upc
|
||
}
|
||
return str
|
||
}
|
||
|
||
func (v *ShopSkuInfo) PriceString(skuIDType int) (str string) {
|
||
str = v.ToSkuID(skuIDType) + ":" + utils.Int64ToStr(v.SalePrice)
|
||
if v.MarketPrice > 0 {
|
||
str += "," + utils.Int64ToStr(v.MarketPrice)
|
||
}
|
||
return str
|
||
}
|
||
|
||
func (v *ShopSkuInfo) StockString(skuIDType int) (str string) {
|
||
str = v.ToSkuID(skuIDType) + ":" + utils.Int2Str(v.Stock)
|
||
return str
|
||
}
|
||
|
||
func (l ShopSkuInfoList) PriceString(skuIDType int) (str string) {
|
||
if len(l) > 0 {
|
||
strList := make([]string, len(l))
|
||
for k, v := range l {
|
||
strList[k] = v.PriceString(skuIDType)
|
||
}
|
||
str = strings.Join(strList, ";")
|
||
}
|
||
return str
|
||
}
|
||
|
||
func (l ShopSkuInfoList) StockString(skuIDType int) (str string) {
|
||
if len(l) > 0 {
|
||
strList := make([]string, len(l))
|
||
for k, v := range l {
|
||
strList[k] = v.StockString(skuIDType)
|
||
}
|
||
str = strings.Join(strList, ";")
|
||
}
|
||
return str
|
||
}
|
||
|
||
func genSkuIDParams(skuIDstr string, customSkuID, upc string) map[string]interface{} {
|
||
params := map[string]interface{}{}
|
||
if skuIDstr != "" {
|
||
params[KeySkuID] = skuIDstr
|
||
} else if customSkuID != "" {
|
||
params[KeyCustomSkuID] = customSkuID
|
||
} else if upc != "" {
|
||
params[KeyUPC] = upc
|
||
} else {
|
||
panic("skuID, customSkuID and upc are all no value!")
|
||
}
|
||
return params
|
||
}
|
||
|
||
// category相关的函数,shop_custom_id可重
|
||
func (a *API) ShopCategoryCreate(shopID string, parentID int64, name string, rank int) (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,
|
||
})
|
||
if err == nil {
|
||
if result.Data != nil {
|
||
return utils.Interface2Int64WithDefault((result.Data.(map[string]interface{})["category_id"]), 0), nil
|
||
}
|
||
}
|
||
if err != nil && strings.Contains(err.Error(), "新增的店内分类已存在") {
|
||
errStr := err.Error()
|
||
startIndex := strings.Index(errStr, "(")
|
||
endIndex := strings.Index(errStr, ")")
|
||
return utils.Str2Int64(errStr[startIndex+3 : endIndex]), 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 {
|
||
if inMap, ok := result.Data.(map[string]interface{}); ok {
|
||
cats := interface2CatList(inMap["categorys"], 1)
|
||
return cats, nil
|
||
}
|
||
}
|
||
return nil, err
|
||
}
|
||
|
||
func (a *API) ShopCategoryUpdate(shopID string, categoryID int64, name string, rank int) (err error) {
|
||
_, err = a.AccessAPI("sku.shop.category.update", map[string]interface{}{
|
||
KeyShopID: shopID,
|
||
"category_id": categoryID,
|
||
"name": name,
|
||
"rank": rank,
|
||
})
|
||
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 *SkuListParams) (skuInfo *PageDataInfo, err error) {
|
||
params.PageSize = 100
|
||
paramMap := utils.Struct2FlatMap(params)
|
||
paramMap[KeyShopID] = shopID
|
||
paramMap["include_cate_info"] = 1
|
||
result, err := a.AccessAPI("sku.list", paramMap)
|
||
if err == nil {
|
||
err = utils.Map2StructByJson(result.Data, &skuInfo, true)
|
||
}
|
||
return skuInfo, err
|
||
}
|
||
|
||
// 饿百商品名可以相同,不会报错
|
||
func (a *API) SkuCreate(trackInfo, shopID string, customSkuID int64, params map[string]interface{}) (skuID int64, err error) {
|
||
defParams := map[string]interface{}{
|
||
KeyShopID: shopID,
|
||
KeyCustomSkuID: customSkuID,
|
||
}
|
||
if utils.IsNil(params["upc"]) {
|
||
params["upc"] = "upc-" + utils.Int2Str(int(customSkuID))
|
||
}
|
||
/*if params["brand_id"] == nil {
|
||
defParams["brand_id"] = 0
|
||
}
|
||
if params["brand_name"] == nil {
|
||
defParams["brand_name"] = "无" // 很狗血的是,你还必须填个无才行。。。
|
||
}*/
|
||
params = utils.MergeMaps(params, defParams)
|
||
result, err := a.AccessAPI2("sku.create", params, trackInfo)
|
||
if err == nil && result.Data != nil {
|
||
return utils.Interface2Int64WithDefault(result.Data.(map[string]interface{})[KeySkuID], 0), nil
|
||
} else if err != nil && strings.Contains(err.Error(), "商品已存在") {
|
||
skuIDStr := err.Error()
|
||
start := strings.LastIndex(skuIDStr, "sku_id")
|
||
end := strings.Index(skuIDStr, "level")
|
||
return utils.Str2Int64(skuIDStr[start+7 : end-1]), nil
|
||
}
|
||
|
||
return 0, err
|
||
}
|
||
|
||
func (a *API) SkuUpdate(trackInfo, shopID string, ebaiSkuID int64, params map[string]interface{}) (skuID int64, err error) {
|
||
defParams := map[string]interface{}{
|
||
KeyShopID: shopID,
|
||
KeySkuID: ebaiSkuID,
|
||
}
|
||
result, err := a.AccessAPI2("sku.update", utils.MergeMaps(params, defParams), trackInfo)
|
||
if err == nil {
|
||
return utils.Interface2Int64WithDefault(result.Data.(map[string]interface{})[KeySkuID], 0), nil
|
||
}
|
||
return 0, err
|
||
}
|
||
|
||
func intIDs2Str(intIDs []int64) (str string) {
|
||
return strings.Join(utils.Int64Slice2String(intIDs), ",")
|
||
}
|
||
|
||
func strIDs2Str(strIDs []string) (str string) {
|
||
return strings.Join(strIDs, ",")
|
||
}
|
||
|
||
// 之前的处理方法
|
||
func handleShopSkuBatchResult(result *ResponseResult) (opResult *BatchOpResult, err error) {
|
||
if dataStr, ok := result.Data.(string); ok && dataStr != "" {
|
||
matchList := shopSkuBatchFailedSkuReg.FindStringSubmatch(dataStr)
|
||
if len(matchList) == 2 {
|
||
var failedMap map[string]interface{}
|
||
if err = utils.UnmarshalUseNumber([]byte(dataStr), &failedMap); err == nil && len(failedMap) > 0 {
|
||
opResult = &BatchOpResult{}
|
||
for _, v := range failedMap {
|
||
var skuID int64
|
||
if vStr, ok := v.(string); ok {
|
||
skuID = utils.Str2Int64WithDefault(vStr, 0)
|
||
} else {
|
||
skuID = utils.Interface2Int64WithDefault(v, 0)
|
||
}
|
||
opResult.FailedList = append(opResult.FailedList, &BatchOpSkuResult{
|
||
SkuID: skuID,
|
||
})
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return opResult, err
|
||
}
|
||
|
||
func handleShopSkuBatchErr(err error) (opResult *BatchOpResult, outErr error) {
|
||
outErr = err
|
||
if errExt, ok := err.(*utils.ErrorWithCode); ok {
|
||
if errExt.ErrMsg() != "" {
|
||
var data interface{}
|
||
if err2 := utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &data); err2 == nil {
|
||
if err2 = utils.Map2StructByJson(data, &opResult, true); err2 == nil {
|
||
// 将以\u表示的字符串标准化,并去掉成功的
|
||
errExt.SetErrMsg(string(utils.MustMarshal(opResult.FailedList)))
|
||
outErr = errExt
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return opResult, outErr
|
||
}
|
||
|
||
// 门店商品批量修改可售,价格,库存的API,在2019/07/26之前,除了SkuPriceUpdateBatch外,其它API在部分失败时会返回成功,
|
||
// 失败信息在data中,但2019/07/26之后,行为与SkuPriceUpdateBatch一致了,即完全成功时,返回成功,没有失败成功明细,
|
||
// 部分失败时,返回失败,详情在error中,
|
||
// 另外需要注意的是SkuPriceUpdateBatch的失败明细中的skuID是int64,但其它几个是string...
|
||
|
||
// 文档上说支持custom_sku_id,但实际好像只支持skuid
|
||
// 饿百删除商品后,还要等待5分钟后才会归档商品,才会真正删除生效
|
||
func (a *API) SkuDelete(trackInfo, shopID string, skuIDs []int64, customSkuDs []string) (opResult *BatchOpResult, err error) {
|
||
params := genSkuIDParams(intIDs2Str(skuIDs), strIDs2Str(customSkuDs), "")
|
||
params[KeyShopID] = shopID
|
||
result, err := a.AccessAPI2("sku.delete", params, trackInfo)
|
||
if err == nil {
|
||
opResult, err = handleShopSkuBatchResult(result)
|
||
} else {
|
||
opResult, err = handleShopSkuBatchErr(err)
|
||
}
|
||
return opResult, err
|
||
}
|
||
|
||
func (a *API) SkuOnline(trackInfo, shopID string, skuIDs []int64, customSkuDs, upcs []string) (opResult *BatchOpResult, err error) {
|
||
params := genSkuIDParams(intIDs2Str(skuIDs), strIDs2Str(customSkuDs), strIDs2Str(upcs))
|
||
params[KeyShopID] = shopID
|
||
result, err := a.AccessAPI2("sku.online", params, trackInfo)
|
||
if err == nil {
|
||
opResult, err = handleShopSkuBatchResult(result)
|
||
} else {
|
||
opResult, err = handleShopSkuBatchErr(err)
|
||
}
|
||
return opResult, err
|
||
}
|
||
|
||
func (a *API) SkuOnlineOne(trackInfo, shopID string, skuID int64, customSkuID, upc string) (err error) {
|
||
params := genSkuIDParams(utils.Int64ToStrNoZero(skuID), customSkuID, upc)
|
||
params[KeyShopID] = shopID
|
||
_, err = a.AccessAPI2("sku.online.one", params, trackInfo)
|
||
return err
|
||
}
|
||
|
||
func (a *API) SkuOffline(trackInfo, shopID string, skuIDs []int64, customSkuDs, upcs []string) (opResult *BatchOpResult, err error) {
|
||
params := genSkuIDParams(intIDs2Str(skuIDs), strIDs2Str(customSkuDs), strIDs2Str(upcs))
|
||
params[KeyShopID] = shopID
|
||
result, err := a.AccessAPI2("sku.offline", params, trackInfo)
|
||
if err == nil {
|
||
opResult, err = handleShopSkuBatchResult(result)
|
||
} else {
|
||
opResult, err = handleShopSkuBatchErr(err)
|
||
}
|
||
return opResult, err
|
||
}
|
||
|
||
func (a *API) SkuOfflineOne(trackInfo, shopID string, skuID int64, customSkuID, upc string) (err error) {
|
||
params := genSkuIDParams(utils.Int64ToStrNoZero(skuID), customSkuID, upc)
|
||
params[KeyShopID] = shopID
|
||
_, err = a.AccessAPI2("sku.offline.one", params, trackInfo)
|
||
return err
|
||
}
|
||
|
||
func (a *API) SkuPriceUpdateBatch(trackInfo, shopID string, priceList ShopSkuInfoList, skuIDType int) (opResult *BatchOpResult, err error) {
|
||
params := map[string]interface{}{
|
||
KeyShopID: shopID,
|
||
priceUpdateKeyIDMap[skuIDType]: priceList.PriceString(skuIDType),
|
||
}
|
||
result, err := a.AccessAPI2("sku.price.update.batch", params, trackInfo)
|
||
if err == nil {
|
||
opResult, err = handleShopSkuBatchResult(result)
|
||
} else {
|
||
opResult, err = handleShopSkuBatchErr(err)
|
||
}
|
||
return opResult, err
|
||
}
|
||
|
||
func (a *API) SkuPriceUpdateOne(trackInfo, shopID string, priceInfo *ShopSkuInfo) (opResult *BatchOpResult, err error) {
|
||
skuIDType := priceInfo.GuessIDType()
|
||
params := map[string]interface{}{
|
||
KeyShopID: shopID,
|
||
priceUpdateKeyIDMap[skuIDType]: priceInfo.PriceString(skuIDType),
|
||
}
|
||
_, err = a.AccessAPI2("sku.price.update.one", params, trackInfo)
|
||
return opResult, err
|
||
}
|
||
|
||
func (a *API) SkuStockUpdateBatch(trackInfo, shopID string, stockList ShopSkuInfoList, skuIDType int) (opResult *BatchOpResult, err error) {
|
||
params := map[string]interface{}{
|
||
KeyShopID: shopID,
|
||
stockUpdateKeyIDMap[skuIDType]: stockList.StockString(skuIDType),
|
||
}
|
||
result, err := a.AccessAPI2("sku.stock.update.batch", params, trackInfo)
|
||
if err == nil {
|
||
opResult, err = handleShopSkuBatchResult(result)
|
||
} else {
|
||
opResult, err = handleShopSkuBatchErr(err)
|
||
}
|
||
return opResult, err
|
||
}
|
||
|
||
func (a *API) SkuStockUpdateOne(trackInfo, shopID string, stockInfo *ShopSkuInfo) (err error) {
|
||
skuIDType := stockInfo.GuessIDType()
|
||
params := map[string]interface{}{
|
||
KeyShopID: shopID,
|
||
stockUpdateKeyIDMap[skuIDType]: stockInfo.StockString(skuIDType),
|
||
}
|
||
_, err = a.AccessAPI2("sku.stock.update.one", params, trackInfo)
|
||
return err
|
||
}
|
||
|
||
func (a *API) SkuShopCategoryMap(shopID string, skuID int64, customSkuID string, categoryID int64, rank int) (err error) {
|
||
params := map[string]interface{}{
|
||
KeyShopID: shopID,
|
||
KeyCategoryID: categoryID,
|
||
}
|
||
if skuID > 0 {
|
||
params[KeySkuID] = skuID
|
||
} else {
|
||
params[KeyCustomSkuID] = customSkuID
|
||
}
|
||
if rank > 0 {
|
||
params["rank"] = rank
|
||
}
|
||
_, err = a.AccessAPI("sku.shop.category.map", params)
|
||
return err
|
||
}
|
||
|
||
// 饿百的这个API有点怪,虽然有shopID参数,但返回的链接可以跨店使用
|
||
func (a *API) SkuUploadRTF(shopID, rtfDetail string) (rtfURL string, err error) {
|
||
params := map[string]interface{}{
|
||
KeyShopID: shopID,
|
||
"rtf_detail": rtfDetail,
|
||
}
|
||
result, err := a.AccessAPI("sku.uploadrtf", params)
|
||
if err == nil {
|
||
rtfURL = utils.Interface2String(result.Data.(map[string]interface{})["url"])
|
||
}
|
||
return rtfURL, err
|
||
}
|
||
|
||
func BuildRFTFromImgs(imgList ...string) string {
|
||
imgList2 := make([]string, len(imgList))
|
||
for index, img := range imgList {
|
||
imgList2[index] = fmt.Sprintf(`<img align="absmiddle" src="%s" alt="%s" />`, img, img)
|
||
}
|
||
return strings.Join(imgList2, "\n")
|
||
}
|
||
|
||
//
|
||
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"]),
|
||
Name: utils.Interface2String(catMap["name"]),
|
||
Rank: int(utils.MustInterface2Int64(catMap["rank"])),
|
||
Children: interface2CatList(catMap["children"], level+1),
|
||
Level: level,
|
||
}
|
||
return cat
|
||
}
|
||
|
||
func IsErrCategoryExist(err error) (isExist bool) {
|
||
return utils.IsErrMatch(err, "1", []string{"商户已存在该自定义分类"})
|
||
}
|
||
|
||
func IsErrCategoryNotExist(err error) (isNotExist bool) {
|
||
return utils.IsErrMatch(err, "", []string{"不存在该自定义分类ID", "商户不存在该自定义分类"})
|
||
}
|
||
|
||
func IsErrSkuExist(err error) (isExist bool) {
|
||
return utils.IsErrMatch(err, "1", skuExistMsgList)
|
||
}
|
||
|
||
func IsErrSkuNotExist(err error) (isExist bool) {
|
||
return utils.IsErrMatch(err, "1", skuNotExistMsgList)
|
||
}
|
||
|
||
func IsMsgSkuExist(msg string) bool {
|
||
return utils.IsErrMsgMatch(msg, skuExistMsgList)
|
||
}
|
||
|
||
func IsMsgSkuNotExist(msg string) bool {
|
||
return utils.IsErrMsgMatch(msg, skuNotExistMsgList)
|
||
}
|
||
|
||
func (a *API) GetEbaiSkuIDFromCustomID(shopID, customSkuID string) (ebaiSkuID int64) {
|
||
if skuInfo, err2 := a.SkuList(shopID, &SkuListParams{
|
||
CustomSkuID: customSkuID,
|
||
}); err2 == nil && skuInfo != nil && len(skuInfo.List) > 0 {
|
||
ebaiSkuID = skuInfo.List[0].SkuId
|
||
}
|
||
return ebaiSkuID
|
||
}
|
||
|
||
func (a *API) GetEbaiCatIDFromName(shopID, catName string) (ebaiCatID int64) {
|
||
if catList, err2 := a.ShopCategoryGet(shopID); err2 == nil {
|
||
for _, v := range catList {
|
||
if v.Name == catName {
|
||
ebaiCatID = v.CategoryID
|
||
break
|
||
}
|
||
for _, v2 := range v.Children {
|
||
if v2.Name == catName {
|
||
ebaiCatID = v2.CategoryID
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return ebaiCatID
|
||
}
|