diff --git a/platformapi/ebaiapi/shop_sku.go b/platformapi/ebaiapi/shop_sku.go index 386ceb9c..8431158a 100644 --- a/platformapi/ebaiapi/shop_sku.go +++ b/platformapi/ebaiapi/shop_sku.go @@ -5,8 +5,6 @@ import ( "regexp" "strings" - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/utils" ) @@ -103,16 +101,16 @@ type PageDataInfo struct { List []*SkuInfo `json:"List"` } -type ShopSkuPriceUpdateResponseItem struct { +type BatchOpSkuResult struct { SkuID int64 `json:"sku_id"` - Price int `json:"price"` + Price int `json:"price,omitempty"` ErrorNo int `json:"error_no,omitempty"` ErrorMsg string `json:"error_msg,omitempty"` } -type ShopSkuPriceUpdateResponse struct { - FailedList []*ShopSkuPriceUpdateResponseItem `json:"failed_list"` - SuccessList []*ShopSkuPriceUpdateResponseItem `json:"success_list"` +type BatchOpResult struct { + FailedList []*BatchOpSkuResult `json:"failed_list"` + SuccessList []*BatchOpSkuResult `json:"success_list"` } const ( @@ -334,44 +332,69 @@ func strIDs2Str(strIDs []string) (str string) { return strings.Join(strIDs, ",") } -func handleShopSkuBatchResult(result *ResponseResult) (failedSkuIDs []int64, err error) { +// 之前的处理方法 +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(matchList[1]), &failedMap); err == nil && len(failedMap) > 0 { + 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 { - failedSkuIDs = append(failedSkuIDs, utils.Str2Int64WithDefault(vStr, 0)) + skuID = utils.Str2Int64WithDefault(vStr, 0) } else { - failedSkuIDs = append(failedSkuIDs, utils.Interface2Int64WithDefault(v, 0)) + skuID = utils.Interface2Int64WithDefault(v, 0) } + opResult.FailedList = append(opResult.FailedList, &BatchOpSkuResult{ + SkuID: skuID, + }) } } } } - return failedSkuIDs, err + return opResult, err } +func handleShopSkuBatchErr(err error) (opResult *BatchOpResult) { + if errMsg := utils.GetErrMsg(err); errMsg != "" { + var data interface{} + if err2 := utils.UnmarshalUseNumber([]byte(errMsg), &data); err2 == nil { + utils.Map2StructByJson(data, &opResult, true) + } + } + return opResult +} + +// 门店商品批量修改可售,价格,库存的API,在2019/07/26之前,除了SkuPriceUpdateBatch外,其它API在部分失败时会返回成功, +// 失败信息在data中,但2019/07/26之后,行为与SkuPriceUpdateBatch一致了,即完全成功时,返回成功,没有失败成功明细, +// 部分失败时,返回失败,详情在error中, +// 另外需要注意的是SkuPriceUpdateBatch的失败明细中的skuID是int64,但其它几个是string... + // 文档上说支持custom_sku_id,但实际好像只支持skuid -func (a *API) SkuDelete(shopID string, skuIDs []int64, customSkuDs []string) (failedSkuIDs []int64, err error) { +func (a *API) SkuDelete(shopID string, skuIDs []int64, customSkuDs []string) (opResult *BatchOpResult, err error) { params := genSkuIDParams(intIDs2Str(skuIDs), strIDs2Str(customSkuDs), "") params[KeyShopID] = shopID result, err := a.AccessAPI("sku.delete", params) if err == nil { - failedSkuIDs, err = handleShopSkuBatchResult(result) + opResult, err = handleShopSkuBatchResult(result) + } else { + opResult = handleShopSkuBatchErr(err) } - return failedSkuIDs, err + return opResult, err } -func (a *API) SkuOnline(shopID string, skuIDs []int64, customSkuDs, upcs []string) (failedSkuIDs []int64, err error) { +func (a *API) SkuOnline(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.AccessAPI("sku.online", params) if err == nil { - failedSkuIDs, err = handleShopSkuBatchResult(result) + opResult, err = handleShopSkuBatchResult(result) + } else { + opResult = handleShopSkuBatchErr(err) } - return failedSkuIDs, err + return opResult, err } func (a *API) SkuOnlineOne(shopID string, skuID int64, customSkuID, upc string) (err error) { @@ -381,14 +404,16 @@ func (a *API) SkuOnlineOne(shopID string, skuID int64, customSkuID, upc string) return err } -func (a *API) SkuOffline(shopID string, skuIDs []int64, customSkuDs, upcs []string) (failedSkuIDs []int64, err error) { +func (a *API) SkuOffline(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.AccessAPI("sku.offline", params) if err == nil { - failedSkuIDs, err = handleShopSkuBatchResult(result) + opResult, err = handleShopSkuBatchResult(result) + } else { + opResult = handleShopSkuBatchErr(err) } - return failedSkuIDs, err + return opResult, err } func (a *API) SkuOfflineOne(shopID string, skuID int64, customSkuID, upc string) (err error) { @@ -398,21 +423,18 @@ func (a *API) SkuOfflineOne(shopID string, skuID int64, customSkuID, upc string) return err } -// 此函数在部分失败时,会返回错误,全部成功时不会返回明细,其它ShopSku批处理操作的的则在部分失败时会返回成功 -func (a *API) SkuPriceUpdateBatch(shopID string, priceList ShopSkuInfoList, skuIDType int) (updateResponse *ShopSkuPriceUpdateResponse, err error) { +func (a *API) SkuPriceUpdateBatch(shopID string, priceList ShopSkuInfoList, skuIDType int) (opResult *BatchOpResult, err error) { params := map[string]interface{}{ KeyShopID: shopID, priceUpdateKeyIDMap[skuIDType]: priceList.PriceString(skuIDType), } - _, err = a.AccessAPI("sku.price.update.batch", params) - if err != nil { - // 文档上说的详情在data中,但其实是在error中... - if errExt, ok := err.(*utils.ErrorWithCode); ok { - baseapi.SugarLogger.Debug(errExt.ErrMsg()) - utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &updateResponse) - } + result, err := a.AccessAPI("sku.price.update.batch", params) + if err == nil { + opResult, err = handleShopSkuBatchResult(result) + } else { + opResult = handleShopSkuBatchErr(err) } - return updateResponse, err + return opResult, err } func (a *API) SkuPriceUpdateOne(shopID string, priceInfo *ShopSkuInfo) (err error) { @@ -425,16 +447,18 @@ func (a *API) SkuPriceUpdateOne(shopID string, priceInfo *ShopSkuInfo) (err erro return err } -func (a *API) SkuStockUpdateBatch(shopID string, stockList ShopSkuInfoList, skuIDType int) (failedSkuIDs []int64, err error) { +func (a *API) SkuStockUpdateBatch(shopID string, stockList ShopSkuInfoList, skuIDType int) (opResult *BatchOpResult, err error) { params := map[string]interface{}{ KeyShopID: shopID, stockUpdateKeyIDMap[skuIDType]: stockList.PriceString(skuIDType), } result, err := a.AccessAPI("sku.stock.update.batch", params) if err == nil { - failedSkuIDs, err = handleShopSkuBatchResult(result) + opResult, err = handleShopSkuBatchResult(result) + } else { + opResult = handleShopSkuBatchErr(err) } - return failedSkuIDs, err + return opResult, err } func (a *API) SkuStockUpdateOne(shopID string, stockInfo *ShopSkuInfo) (err error) { @@ -522,7 +546,7 @@ func IsErrSkuExist(err error) (isExist bool) { } func IsErrSkuNotExist(err error) (isExist bool) { - return utils.IsErrMatch(err, "1", []string{"sku_id与shop_id不匹配", "SKU不存在或者已经被删除"}) + return utils.IsErrMatch(err, "1", []string{"sku_id与shop_id不匹配", "SKU不存在或者已经被删除", "商品不存在"}) } func (a *API) GetEbaiSkuIDFromCustomID(shopID, customSkuID string) (ebaiSkuID int64) { diff --git a/platformapi/ebaiapi/shop_sku_test.go b/platformapi/ebaiapi/shop_sku_test.go index 59fe0403..c21b816d 100644 --- a/platformapi/ebaiapi/shop_sku_test.go +++ b/platformapi/ebaiapi/shop_sku_test.go @@ -115,19 +115,45 @@ func TestSkuShopCategoryMap(t *testing.T) { } func TestSkuDelete(t *testing.T) { - failedSkuIDs, err := api.SkuDelete(testShopID, []int64{12345678, 12423432}, nil) - if err != nil { - // t.Fatal(err) + const ( + notExistSkuID = 12345678 + existSkuID = 156406677407848 + ) + opResult, err := api.SkuDelete(testShopID, []int64{notExistSkuID}, nil) + t.Log(utils.Format4Output(opResult, false)) + if err == nil { + t.Log("应该要报错") } - t.Log(utils.Format4Output(failedSkuIDs, false)) -} - -func TestSkuOnline(t *testing.T) { - failedSkuIDs, err := api.SkuOnline(testShopID, []int64{156369111807787, 12345678, 12423432}, nil, nil) + if opResult == nil || len(opResult.FailedList) != 1 || opResult.FailedList[0].SkuID != notExistSkuID { + t.Logf("错误结果中应该要包含:%d", notExistSkuID) + } + opResult, err = api.SkuDelete(testShopID, []int64{existSkuID}, nil) + t.Log(utils.Format4Output(opResult, false)) if err != nil { t.Fatal(err) } - t.Log(utils.Format4Output(failedSkuIDs, false)) + if opResult == nil || len(opResult.SuccessList) != 1 || opResult.SuccessList[0].SkuID != existSkuID { + t.Logf("成功结果中应该要包含:%d", existSkuID) + } +} + +func TestSkuOnline(t *testing.T) { + const ( + notExistSkuID = 12345678 + existSkuID = 156406688807623 + ) + + opResult, err := api.SkuOnline(testShopID, []int64{notExistSkuID, existSkuID}, nil, nil) + t.Log(utils.Format4Output(opResult, false)) + if err == nil { + t.Log("应该要报错") + } + if opResult == nil || len(opResult.FailedList) != 1 || opResult.FailedList[0].SkuID != notExistSkuID { + t.Logf("错误结果中应该要包含:%d", notExistSkuID) + } + if opResult == nil || len(opResult.SuccessList) != 1 || opResult.SuccessList[0].SkuID != existSkuID { + t.Logf("成功结果中应该要包含:%d", existSkuID) + } } func TestSkuOnlineOne(t *testing.T) { @@ -138,15 +164,15 @@ func TestSkuOnlineOne(t *testing.T) { } func TestSkuOffline(t *testing.T) { - failedSkuIDs, err := api.SkuOffline(testShopID, []int64{156291398007698, 12345678, 12423432}, nil, nil) + opResult, err := api.SkuOffline(testShopID, []int64{1564049914071288, 156389470507185}, nil, nil) + t.Log(utils.Format4Output(opResult, false)) if err != nil { t.Fatal(err) } - t.Log(utils.Format4Output(failedSkuIDs, false)) } func TestSkuPriceUpdateBatch(t *testing.T) { - failedSkuIDs, err := api.SkuPriceUpdateBatch(testShopID, ShopSkuInfoList{ + opResult, err := api.SkuPriceUpdateBatch(testShopID, ShopSkuInfoList{ &ShopSkuInfo{ SkuID: 156369111807787, SalePrice: 100, @@ -160,14 +186,17 @@ func TestSkuPriceUpdateBatch(t *testing.T) { SalePrice: 100, }, }, SkuIDTypeSkuID) - if err != nil { - t.Fatal(err) + t.Log(utils.Format4Output(opResult, false)) + if err == nil { + t.Fatal("应该要报错才对") + } + if len(opResult.FailedList) != 3 { + t.Fatal("错误列表不正确") } - t.Log(utils.Format4Output(failedSkuIDs, false)) } func TestSkuStockUpdateBatch(t *testing.T) { - failedSkuIDs, err := api.SkuStockUpdateBatch(testShopID, ShopSkuInfoList{ + opResult, err := api.SkuStockUpdateBatch(testShopID, ShopSkuInfoList{ &ShopSkuInfo{ SkuID: 156291398007698, Stock: 2, @@ -181,10 +210,13 @@ func TestSkuStockUpdateBatch(t *testing.T) { Stock: 2, }, }, SkuIDTypeSkuID) - if err != nil { - t.Fatal(err) + t.Log(utils.Format4Output(opResult, false)) + if err == nil { + t.Fatal("应该要报错才对") + } + if len(opResult.FailedList) != 3 { + t.Fatal("错误列表不正确") } - t.Log(utils.Format4Output(failedSkuIDs, false)) } func TestGetEbaiCatIDFromName(t *testing.T) { diff --git a/utils/errorwithcode.go b/utils/errorwithcode.go index 055869c5..7f1c0da6 100644 --- a/utils/errorwithcode.go +++ b/utils/errorwithcode.go @@ -79,3 +79,10 @@ func IsErrMatch(err error, strCode string, strList []string) (isMatch bool) { } return isMatch } + +func GetErrMsg(err error) (errMsg string) { + if errExt, ok := err.(*ErrorWithCode); ok { + errMsg = errExt.ErrMsg() + } + return errMsg +}