diff --git a/platformapi/jdapi/jdapi.go b/platformapi/jdapi/jdapi.go index 8a5f0299..8d60820b 100644 --- a/platformapi/jdapi/jdapi.go +++ b/platformapi/jdapi/jdapi.go @@ -173,17 +173,7 @@ func (a *API) AccessAPI(apiStr string, jdParams map[string]interface{}) (retVal return retVal, err } -func (a *API) AccessAPINoPage(apiStr string, jdParams map[string]interface{}, keyToRemove, keyToKeep []string) (interface{}, error) { - jsonResult, err := a.AccessAPI(apiStr, jdParams) - if err != nil { - return nil, err - } - - var data map[string]interface{} - if err := utils.UnmarshalUseNumber([]byte(jsonResult["data"].(string)), &data); err != nil { - return nil, platformapi.ErrResponseDataFormatWrong - } - +func normalNoPageResultParser(data map[string]interface{}) (interface{}, error) { innerCode := "" for _, innerCodeKey := range innerCodeKeys { if innerCode2, ok := data[innerCodeKey]; ok { @@ -191,21 +181,41 @@ func (a *API) AccessAPINoPage(apiStr string, jdParams map[string]interface{}, ke break } } - + if innerCode == "" { + panic(fmt.Sprintf("can not find innerCode, data:%v", data)) + } if _, ok := innerCodeOKCodes[innerCode]; ok { for _, innerDataKey := range noPageInnerDataKeys { if innerData, ok := data[innerDataKey]; ok { - return utils.DictKeysMan(innerData, keyToRemove, keyToKeep), nil + return innerData, nil } } - baseapi.SugarLogger.Errorf("can not find inner data, data:%v", jsonResult) - return nil, platformapi.ErrResponseDataFormatWrong - } else { - return nil, utils.NewErrorCode(getErrMsgFromData(data), innerCode, 1) + panic(fmt.Sprintf("can not find inner data, data:%v", data)) + // return nil, platformapi.ErrResponseDataFormatWrong } + return nil, utils.NewErrorCode(getErrMsgFromData(data), innerCode, 1) } -func NormalHavePageResultParser(data map[string]interface{}, totalCount int) ([]interface{}, int, error) { +func (a *API) AccessAPINoPage(apiStr string, jdParams map[string]interface{}, keyToRemove, keyToKeep []string, resultParser func(data map[string]interface{}) (interface{}, error)) (interface{}, error) { + if resultParser == nil { + resultParser = normalNoPageResultParser + } + jsonResult, err := a.AccessAPI(apiStr, jdParams) + if err != nil { + return nil, err + } + var data map[string]interface{} + if err := utils.UnmarshalUseNumber([]byte(jsonResult["data"].(string)), &data); err != nil { + return nil, platformapi.ErrResponseDataFormatWrong + } + result, err := resultParser(data) + if err == nil { + return utils.DictKeysMan(result, keyToRemove, keyToKeep), nil + } + return result, err +} + +func normalHavePageResultParser(data map[string]interface{}, totalCount int) ([]interface{}, int, error) { var result map[string]interface{} var retVal []interface{} @@ -237,8 +247,9 @@ func NormalHavePageResultParser(data map[string]interface{}, totalCount int) ([] for _, inner2ResultKey := range havePageInner2DataKeys { if inner2Result, ok := result[inner2ResultKey]; ok { - - if inner2ResultStr, ok := inner2Result.(string); ok { + if inner2Result == nil { + retVal = nil + } else if inner2ResultStr, ok := inner2Result.(string); ok { err := utils.UnmarshalUseNumber([]byte(inner2ResultStr), &retVal) if err != nil { return nil, 0, platformapi.ErrResponseDataFormatWrong @@ -246,7 +257,6 @@ func NormalHavePageResultParser(data map[string]interface{}, totalCount int) ([] } else { retVal = inner2Result.([]interface{}) } - return retVal, totalCount, nil } } @@ -254,9 +264,9 @@ func NormalHavePageResultParser(data map[string]interface{}, totalCount int) ([] return nil, 0, platformapi.ErrResponseDataFormatWrong } -func (a *API) AccessAPIHavePage(apiStr string, jdParams map[string]interface{}, keyToRemove, keyToKeep []string, pageResultParser PageResultParser) ([]interface{}, error) { +func (a *API) AccessAPIHavePage(apiStr string, jdParams map[string]interface{}, keyToRemove, keyToKeep []string, pageResultParser PageResultParser) ([]interface{}, int, error) { if pageResultParser == nil { - pageResultParser = NormalHavePageResultParser + pageResultParser = normalHavePageResultParser } localJdParams := make(map[string]interface{}) @@ -269,10 +279,10 @@ func (a *API) AccessAPIHavePage(apiStr string, jdParams map[string]interface{}, totalCount := 0 pageNo := AllPage pageSize := DefaultPageSize - if tempPageNo, ok := localJdParams["pageNo"]; ok { + if tempPageNo, ok := localJdParams[KeyPageNo]; ok { pageNo = tempPageNo.(int) } - if tempPageSize, ok := localJdParams["pageSize"]; ok { + if tempPageSize, ok := localJdParams[KeyPageSize]; ok { pageSize = tempPageSize.(int) } @@ -283,25 +293,25 @@ func (a *API) AccessAPIHavePage(apiStr string, jdParams map[string]interface{}, retVal := make([]interface{}, 0) for { - localJdParams["pageNo"] = curPage - localJdParams["pageSize"] = pageSize + localJdParams[KeyPageNo] = curPage + localJdParams[KeyPageSize] = pageSize jsonResult, err := a.AccessAPI(apiStr, localJdParams) if err != nil { - return nil, err + return nil, totalCount, err } var data map[string]interface{} if err := utils.UnmarshalUseNumber([]byte(jsonResult["data"].(string)), &data); err != nil { - return nil, platformapi.ErrResponseDataFormatWrong + return nil, totalCount, platformapi.ErrResponseDataFormatWrong } innerCode := forceInnerCode2Str(data["code"]) if innerCode != "0" && innerCode != "200" { - return nil, utils.NewErrorCode(getErrMsgFromData(data), innerCode, 1) + return nil, totalCount, utils.NewErrorCode(getErrMsgFromData(data), innerCode, 1) } inResult, totalCount2, err := pageResultParser(data, totalCount) if err != nil { - return nil, err + return nil, totalCount, err } totalCount = totalCount2 @@ -313,8 +323,7 @@ func (a *API) AccessAPIHavePage(apiStr string, jdParams map[string]interface{}, } curPage++ } - - return retVal, nil + return retVal, totalCount, nil } func forceInnerCode2Str(innerCode interface{}) string { diff --git a/platformapi/jdapi/jdapi_test.go b/platformapi/jdapi/jdapi_test.go index c5194fba..43e4a356 100644 --- a/platformapi/jdapi/jdapi_test.go +++ b/platformapi/jdapi/jdapi_test.go @@ -45,7 +45,7 @@ func TestAccessAPI(t *testing.T) { } func TestAccessAPINoPage(t *testing.T) { - result, err := jdapi.AccessAPINoPage("address/allcities", nil, []string{"yn"}, nil) + result, err := jdapi.AccessAPINoPage("address/allcities", nil, []string{"yn"}, nil, nil) if err != nil { t.Fatalf("TestAccessAPINoPage return error:%v", err) } @@ -67,12 +67,12 @@ func TestAccessAPIHavePage(t *testing.T) { "pageNo": 1, "pageSize": 20, } - skuInfo, err := jdapi.AccessAPIHavePage("pms/querySkuInfos", jdParams, nil, []string{"skuName", "skuId"}, nil) + skuInfo, totalCount, err := jdapi.AccessAPIHavePage("pms/querySkuInfos", jdParams, nil, []string{"skuName", "skuId"}, nil) if err != nil { t.Fatalf("AccessAPIHavePage return error:%v", err) } - if len(skuInfo) == 0 { + if len(skuInfo) == 0 || totalCount == 0 { t.Fatal("sku info is empty") } oneSku := skuInfo[0].(map[string]interface{}) @@ -102,12 +102,12 @@ func TestOrderQuery(t *testing.T) { jdParams := map[string]interface{}{ "orderId": "813344594000041", } - result, err := jdapi.OrderQuery(jdParams) + result, totalCount, err := jdapi.OrderQuery(jdParams) if err != nil { t.Fatalf("OrderQuery return error:%v", err) } - if len(result) == 0 { + if len(result) == 0 || totalCount == 0 { t.Fatal("OrderQuery return empty data") } buyerCityOk := false diff --git a/platformapi/jdapi/order.go b/platformapi/jdapi/order.go index 5b8e43b7..07744447 100644 --- a/platformapi/jdapi/order.go +++ b/platformapi/jdapi/order.go @@ -55,19 +55,18 @@ var ( ErrCanNotFindOrder = errors.New("can not find order") ) -func (a API) OrderQuery(jdParams map[string]interface{}) (retVal []interface{}, err error) { - retVal, err = a.AccessAPIHavePage("order/es/query", jdParams, nil, nil, nil) - return +func (a *API) OrderQuery(jdParams map[string]interface{}) (retVal []interface{}, totalCount int, err error) { + return a.AccessAPIHavePage("order/es/query", jdParams, nil, nil, nil) } // orderFreightMoney 基础运费 // tips 商家承担小费 // merchantPaymentDistanceFreightMoney 取件服务费(开票)(正向单展示远距离运费;售后单则展示达达售后运费) // orderBaseFreightMoney ? -func (a API) QuerySingleOrder(orderId string) (map[string]interface{}, error) { +func (a *API) QuerySingleOrder(orderId string) (map[string]interface{}, error) { jdParams := make(map[string]interface{}) jdParams["orderId"] = orderId - result, err := a.AccessAPIHavePage("order/es/query", jdParams, nil, nil, nil) + result, _, err := a.AccessAPIHavePage("order/es/query", jdParams, nil, nil, nil) if err != nil { return nil, err } @@ -77,7 +76,7 @@ func (a API) QuerySingleOrder(orderId string) (map[string]interface{}, error) { return result[0].(map[string]interface{}), nil } -func (a API) LegacyQuerySingleOrder(orderId string) (map[string]interface{}, error) { +func (a *API) LegacyQuerySingleOrder(orderId string) (map[string]interface{}, error) { jdParams := make(map[string]interface{}) jdParams["orderId"] = orderId @@ -98,62 +97,62 @@ func (a API) LegacyQuerySingleOrder(orderId string) (map[string]interface{}, err return result, nil } -func (a API) OrderAcceptOperate(orderId string, isAgreed bool, userName string) (interface{}, error) { +func (a *API) OrderAcceptOperate(orderId string, isAgreed bool, userName string) (interface{}, error) { jdParams := map[string]interface{}{ "orderId": orderId, "isAgreed": utils.Bool2String(isAgreed), "operator": utils.GetAPIOperator(userName), } - return a.AccessAPINoPage("ocs/orderAcceptOperate", jdParams, nil, nil) + return a.AccessAPINoPage("ocs/orderAcceptOperate", jdParams, nil, nil, nil) } // 拣货完成且众包配送接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=ed93745b86c6487eaaea5f55a84785ac -func (a API) OrderJDZBDelivery(orderId string, userName string) (interface{}, error) { +func (a *API) OrderJDZBDelivery(orderId string, userName string) (interface{}, error) { jdParams := map[string]interface{}{ "orderId": orderId, "operator": utils.GetAPIOperator(userName), } - return a.AccessAPINoPage("bm/open/api/order/OrderJDZBDelivery", jdParams, nil, nil) + return a.AccessAPINoPage("bm/open/api/order/OrderJDZBDelivery", jdParams, nil, nil, nil) } // 订单达达配送转商家自送接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=e7b4950164754eecac7ea87278c2b071 -func (a API) ModifySellerDelivery(orderId string, userName string) (interface{}, error) { +func (a *API) ModifySellerDelivery(orderId string, userName string) (interface{}, error) { jdParams := map[string]interface{}{ "orderId": orderId, "updatePin": utils.GetAPIOperator(userName), } - return a.AccessAPINoPage("order/modifySellerDelivery", jdParams, nil, nil) + return a.AccessAPINoPage("order/modifySellerDelivery", jdParams, nil, nil, nil) } // 拣货完成且商家自送接口(这个接口是商家本身配置为自送模式下才能调用的接口,如果启用了达达配送,是不能调用的) // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=0e08e71a45dc48b6a337e06a852ac33a -func (a API) OrderSerllerDelivery(orderId string, userName string) (interface{}, error) { +func (a *API) OrderSerllerDelivery(orderId string, userName string) (interface{}, error) { jdParams := map[string]interface{}{ "orderId": orderId, "operator": utils.GetAPIOperator(userName), } - return a.AccessAPINoPage("bm/open/api/order/OrderSerllerDelivery", jdParams, nil, nil) + return a.AccessAPINoPage("bm/open/api/order/OrderSerllerDelivery", jdParams, nil, nil, nil) } // 商家自送,订单妥投接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=ecc80f06d35141979f4841f345001f74 -func (a API) DeliveryEndOrder(orderId string, userName string) (interface{}, error) { +func (a *API) DeliveryEndOrder(orderId string, userName string) (interface{}, error) { jdParams := map[string]interface{}{ "orderId": orderId, "operPin": utils.GetAPIOperator(userName), "operTime": utils.GetCurTimeStr(), } - return a.AccessAPINoPage("ocs/deliveryEndOrder", jdParams, nil, nil) + return a.AccessAPINoPage("ocs/deliveryEndOrder", jdParams, nil, nil, nil) } //订单金额拆分接口 -func (a API) QueryOassBussMoney(orderId string) ([]interface{}, error) { +func (a *API) QueryOassBussMoney(orderId string) ([]interface{}, error) { jdParams := map[string]interface{}{ "orderId": orderId, } - result, err := a.AccessAPINoPage("oassBussService/queryOassBussMoney", jdParams, nil, nil) + result, err := a.AccessAPINoPage("oassBussService/queryOassBussMoney", jdParams, nil, nil, nil) if err != nil { return nil, err } diff --git a/platformapi/jdapi/product.go b/platformapi/jdapi/product.go new file mode 100644 index 00000000..75243766 --- /dev/null +++ b/platformapi/jdapi/product.go @@ -0,0 +1,347 @@ +package jdapi + +import "git.rosy.net.cn/baseapi/utils" + +const ( + KeyBrandId = "brandId" + KeyBrandName = "brandName" + KeyBrandStatus = "brandStatus" + KeyCategoryId = "categoryId" + KeyChildIds = "childIds" + KeyFields = "fields" + KeyFixedStatus = "fixedStatus" + KeyHandleStatus = "handleStatus" + KeyHeight = "height" + KeyID = "id" + KeyImages = "images" + KeyImgType = "imgType" + KeyIfViewDesc = "ifViewDesc" + KeyIsFilterDel = "isFilterDel" + KeyIsSale = "isSale" + KeyKeyValue = "keyValue" + KeyLength = "length" + KeyLiquidStatue = "liquidStatue" + KeyOutSkuId = "outSkuId" + KeyPID = "pid" + KeyProductDesc = "productDesc" + KeyPageNo = "pageNo" + KeyPageSize = "pageSize" + KeyPrefixKey = "prefixKey" + KeyPrefixKeyId = "prefixKeyId" + KeyPreKeyEndTime = "preKeyEndTime" + KeyPreKeyStartTime = "preKeyStartTime" + KeyPrescripition = "prescripition" + KeyShopCategoryLevel = "shopCategoryLevel" + KeyShopCategoryName = "shopCategoryName" + KeyShopCategories = "shopCategories" + KeySellCities = "sellCities" + KeySlogan = "slogan" + KeySloganEndTime = "sloganEndTime" + KeySloganStartTime = "sloganStartTime" + KeySort = "sort" + KeySkuId = "skuId" + KeySkuName = "skuName" + KeySkuPrice = "skuPrice" + KeyStoreId = "storeId" + KeySystemFixedStatus = "systemFixedStatus" + KeyTransportAttribute = "transportAttribute" + KeyUpcCode = "upcCode" + KeyWeight = "weight" +) + +type SkuIDPair struct { + SkuId int `json:"skuId"` + OutSkuId string `json:"outSkuId"` +} + +type BrandInfo struct { + ID int `json:"id"` + BrandName string `json:"brandName"` + BrandStatus int `json:"brandStatus"` +} + +type IDKeyValuePair struct { + ID string `json:"_id"` + KeyValue string `json:"keyValue"` +} + +type ProductStatus struct { + Synchronized bool `json:"synchronized"` + EsEntity map[string]interface{} `json:"esEntity"` + ProductEntity map[string]interface{} `json:"productEntity"` +} + +// 分页查询商品品牌信息接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=1ca07a3e767649a7a44fc6ea7e9ed8dd +func (a *API) QueryPageBrandInfo(pageNo, pageSize, brandId int, brandName string) (brandList []*BrandInfo, totalCount int, err error) { + if pageNo <= 0 { + pageNo = 1 + } + if pageSize == 0 { + pageSize = 50 + } + params := map[string]interface{}{ + KeyPageNo: pageNo, // pageNo好像必须要有值,否则一直不返回 + KeyPageSize: pageSize, + KeyFields: []string{ + "BRAND_ID", + "BRAND_NAME", + "BRAND_STATUS", + }, + } + if brandId != 0 { + params[KeyBrandId] = brandId + } + if brandName == "" { + params[KeyBrandName] = brandName + } + + result, totalCount, err := a.AccessAPIHavePage("pms/queryPageBrandInfo", params, nil, nil, nil) + if err == nil { + brandList = make([]*BrandInfo, len(result)) + for index, v := range result { + mapData := v.(map[string]interface{}) + brandList[index] = &BrandInfo{ + ID: int(utils.MustInterface2Int64(mapData[KeyID])), + BrandName: utils.Interface2String(mapData[KeyBrandName]), + BrandStatus: int(utils.MustInterface2Int64(mapData[KeyBrandStatus])), + } + } + return brandList, totalCount, nil + } + return nil, 0, err +} + +// 获取京东到家类目信息接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=d287d326124d42c090cff03c16385706 +func (a *API) QueryChildCategoriesForOP(pid int) (catList []map[string]interface{}, err error) { + result, err := a.AccessAPINoPage("api/queryChildCategoriesForOP", utils.Params2Map("fields", []string{ + "ID", + "PID", + "CATEGORY_NAME", + "CATEGORY_LEVEL", + "CATEGORY_STATUS", + "FULLPATH", + }, "id", pid), nil, nil, nil) + if err == nil { + return utils.Slice2MapSlice(result.([]interface{})), nil + } + return nil, err +} + +// 新增商家店内分类信息接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=de26f24a62aa47a49e5ab7579d638cb3 +func (a *API) AddShopCategory(pid int, shopCategoryName string, shopCategoryLevel, sort int, userName string) (catId string, err error) { + params := map[string]interface{}{ + KeyPID: pid, + KeyShopCategoryName: shopCategoryName, + KeyShopCategoryLevel: shopCategoryLevel, + KeySort: sort, + "createPin": utils.GetAPIOperator(userName), + } + result, err := a.AccessAPINoPage("pms/addShopCategory", params, nil, nil, nil) + if err == nil { + return result.(string), nil + } + return "", err +} + +// 查询商家店内分类信息接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=964f2d248a7e42b196be2ab35b4e93b4 +func (a *API) QueryCategoriesByOrgCode() (catList []map[string]interface{}, err error) { + result, err := a.AccessAPINoPage("pms/queryCategoriesByOrgCode", utils.Params2Map("fields", []string{ + "ID", + "PID", + "SHOP_CATEGORY_NAME", + "SORT", + }), nil, nil, nil) + if err == nil { + return utils.Slice2MapSlice(result.([]interface{})), nil + } + return nil, err +} + +// 修改商家店内分类信息接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=1de278c670b64da492f676ab78d62f73 +func (a *API) UpdateShopCategory(id int, shopCategoryName string) error { + params := map[string]interface{}{ + KeyID: id, + KeyShopCategoryName: shopCategoryName, + } + _, err := a.AccessAPINoPage("pms/updateShopCategory", params, nil, nil, nil) + return err +} + +// 修改商家店内分类顺序接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=2a8267602e814be9828f0c7ce307b872 +func (a *API) ChangeShopCategoryOrder(pid int, childIds []int) error { + params := map[string]interface{}{ + KeyPID: pid, + KeyChildIds: childIds, + } + _, err := a.AccessAPINoPage("pms/changeShopCategoryOrder", params, nil, nil, nil) + return err +} + +// 删除商家店内分类接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=c17b96e9fe254b2a8574f6d1bc0c1667 +func (a *API) DelShopCategory(id int) error { + _, err := a.AccessAPINoPage("pms/delShopCategory", utils.Params2Map(KeyID, id), nil, nil, nil) + return err +} + +// 新增商品信息接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=dfe6a5ca73fa421da1c9f969b848113e +func (a *API) AddSku(outSkuId string, cagtegoryId int, shopCategories []int, brandId int, skuName string, skuPrice int, weight float32, images []string, fixedStatus int, isSale bool, addParams map[string]interface{}) (skuId string, err error) { + fixedParams := map[string]interface{}{ + KeyOutSkuId: outSkuId, + KeyCategoryId: cagtegoryId, + KeyShopCategories: shopCategories, + KeyBrandId: brandId, + KeySkuName: skuName, + KeySkuPrice: skuPrice, + KeyWeight: weight, + KeyImages: images, + KeyFixedStatus: fixedStatus, + KeyIsSale: isSale, + } + result, err := a.AccessAPINoPage("pms/sku/addSku", utils.MergeMaps(fixedParams, addParams), nil, nil, nil) + if err == nil { + return result.(string), nil + } + return "", err +} + +// 根据商家商品编码修改商品信息接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=290bdb0ea8a44e10b86b05591254ad68 +func (a *API) UpdateSku(outSkuId string, params map[string]interface{}) (skuId string, err error) { + result, err := a.AccessAPINoPage("pms/sku/updateSku", utils.MergeMaps(params, utils.Params2Map("outSkuId", outSkuId)), nil, nil, nil) + if err == nil { + return result.(string), nil + } + return "", err +} + +// 根据到家商品编码批量更新商家商品编码接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=4155d29bbdf649b69c67473b705ce7e7 +func (a *API) BatchUpdateOutSkuId(skuInfoList []*SkuIDPair) (retVal interface{}, err error) { + result, err := a.AccessAPINoPage("pms/sku/batchUpdateOutSkuId", utils.Params2Map("skuInfoList", skuInfoList), nil, nil, nil) + if err == nil { + return result, nil + } + return nil, err +} + +// 查询商家已上传商品信息列表接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=e433b95f74524dab91718432c0358977 +// pageNo 从1开始 +func (a *API) QuerySkuInfos(skuName string, skuId, pageNo, pageSize int, isFilterDel bool) (retVal []map[string]interface{}, totalCount int, err error) { + if pageNo <= 0 { + pageNo = 1 + } + if pageSize == 0 { + pageSize = 50 + } + params := map[string]interface{}{ + KeyPageNo: pageNo, // pageNo好像必须要有值,否则一直不返回 + KeyPageSize: pageSize, + } + if skuName != "" { + params[KeySkuName] = skuName + } + if skuId != 0 { + params[KeySkuId] = skuId + } + if isFilterDel { + params[KeyIsFilterDel] = "1" + } else { + params[KeyIsFilterDel] = "0" + } + result, totalCount, err := a.AccessAPIHavePage("pms/querySkuInfos", params, nil, nil, nil) + if err == nil { + return utils.Slice2MapSlice(result), totalCount, nil + } + return nil, 0, err +} + +// 查询商品图片处理结果接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=17506653e03542f9a49023711780c30d +func (a *API) QueryListBySkuIds(skuIds []int, addParams map[string]interface{}) (retVal []map[string]interface{}, err error) { + result, err := a.AccessAPINoPage("order/queryListBySkuIds", utils.MergeMaps(addParams, utils.Params2Map("skuIds", skuIds)), nil, nil, nil) + if err == nil { + return utils.Slice2MapSlice(result.([]interface{})), nil + } + return nil, err + +} + +// 分页查询京东到家商品前缀库接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=2195b87baf0c4783bb1a4fda35aea7d1 +func (a *API) QueryKeyWordDicInfo(pageNo, pageSize int, keyValue string) (values []*IDKeyValuePair, totalCount int, err error) { + if pageNo <= 0 { + pageNo = 1 + } + if pageSize == 0 { + pageSize = 50 + } + params := map[string]interface{}{ + KeyPageNo: pageNo, // pageNo好像必须要有值,否则一直不返回 + KeyPageSize: pageSize, + KeyFields: []string{ + "ID", + "KEYVALUE", + }, + } + if keyValue != "" { + params[KeyKeyValue] = keyValue + } + + result, totalCount, err := a.AccessAPIHavePage("pms/queryKeyWordDicInfo", params, nil, nil, nil) + if err == nil { + values = make([]*IDKeyValuePair, len(result)) + for index, v := range result { + mapData := v.(map[string]interface{}) + values[index] = &IDKeyValuePair{ + ID: utils.Interface2String(mapData["_id"]), + KeyValue: utils.Interface2String(mapData[KeyKeyValue]), + } + } + return values, totalCount, nil + } + return nil, 0, err +} + +// 商家商品状态同步接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=5e29d6c9317847e58b8cbcc70702fd52 +func (a *API) SyncProduct(storeId, skuId string) (retVal bool, err error) { + result, err := a.AccessAPINoPage("search/syncProduct", utils.Params2Map(KeyStoreId, storeId, KeySkuId, skuId), nil, nil, func(data map[string]interface{}) (interface{}, error) { + status := utils.MustInterface2Int64(data["status"]) + if status == 200 { + return data["synchronized"].(bool), nil + } + return nil, utils.NewErrorIntCode(data["message"].(string), int(status)) + }) + if err == nil { + return result.(bool), nil + } + return false, err +} + +func (a *API) GetProductStatus(storeId, skuId string) (retVal *ProductStatus, err error) { + result, err := a.AccessAPINoPage("search/getProductStatus", utils.Params2Map(KeyStoreId, storeId, KeySkuId, skuId), nil, nil, func(data map[string]interface{}) (interface{}, error) { + status := utils.MustInterface2Int64(data["status"]) + if status == 200 { + return &ProductStatus{ + Synchronized: data["synchronized"].(bool), + EsEntity: data["esEntity"].(map[string]interface{}), + ProductEntity: data["productEntity"].(map[string]interface{}), + }, nil + } + return nil, utils.NewErrorIntCode(data["message"].(string), int(status)) + }) + if err == nil { + return result.(*ProductStatus), nil + } + return nil, err + +} diff --git a/platformapi/jdapi/product_test.go b/platformapi/jdapi/product_test.go new file mode 100644 index 00000000..6c56ab89 --- /dev/null +++ b/platformapi/jdapi/product_test.go @@ -0,0 +1,126 @@ +package jdapi + +import ( + "testing" + + "git.rosy.net.cn/baseapi" +) + +func TestQueryPageBrandInfo(t *testing.T) { + result, _, err := jdapi.QueryPageBrandInfo(0, 0, 0, "") + if err != nil { + t.Fatal(err) + } + if len(result) == 0 { + t.Fatal("QueryPageBrandInfo brand list is empty!") + } + // baseapi.SugarLogger.Debug(result[0]) +} + +func TestQueryCategoriesByOrgCode(t *testing.T) { + result, err := jdapi.QueryCategoriesByOrgCode() + if err != nil { + t.Fatal(err) + } + if len(result) == 0 { + t.Fatal("QueryCategoriesByOrgCode category list is empty!") + } +} + +func TestQueryChildCategoriesForOP(t *testing.T) { + result, err := jdapi.QueryChildCategoriesForOP(0) + if err != nil { + t.Fatal(err) + } + if len(result) == 0 { + t.Fatal("QueryChildCategoriesForOP jd category list is empty!") + } +} + +func TestBatchUpdateOutSkuId(t *testing.T) { + // result, err := jdapi.BatchUpdateOutSkuId([]*SkuIDPair{ + // &SkuIDPair{ + // SkuId: 2012286955, + // OutSkuId: "1", + // }, + // &SkuIDPair{ + // SkuId: 2012286956, + // OutSkuId: "2", + // }, + // &SkuIDPair{ + // SkuId: 2012286957, + // OutSkuId: "3", + // }, + // }) + // baseapi.SugarLogger.Debug(result, err) +} + +func TestQuerySkuInfos(t *testing.T) { + pageSize := 20 + result, totalCount, err := jdapi.QuerySkuInfos("", 0, 0, pageSize, true) + if err != nil { + t.Fatal(err) + } + if len(result) != pageSize || totalCount == 0 { + baseapi.SugarLogger.Debug(result) + t.Fatalf("QuerySkuInfos result size is not same as requested:%d", pageSize) + } +} + +func TestQueryListBySkuIds(t *testing.T) { + ids := []int{ + 2018806493, + 2018805873, + } + result, err := jdapi.QueryListBySkuIds(ids, nil) + if err != nil { + t.Fatal(err) + } + if len(result) != len(ids) { + baseapi.SugarLogger.Debug(result) + t.Fatalf("QueryListBySkuIds result size is not same as requested:%d", len(ids)) + } +} + +func TestQueryKeyWordDicInfo(t *testing.T) { + result, totalCount, err := jdapi.QueryKeyWordDicInfo(0, 0, "") + if err != nil { + t.Fatal(err) + } + if len(result) == 0 || totalCount == 0 { + t.Fatalf("QueryKeyWordDicInfo size is wrong") + } + // baseapi.SugarLogger.Debug(result[0], totalCount) +} + +func TestSyncProduct(t *testing.T) { + result, err := jdapi.SyncProduct("11732425", "2015717812") + if err != nil { + t.Fatal(err) + } + baseapi.SugarLogger.Debug(result) + result, err = jdapi.SyncProduct("wrongstoreid", "2015717812") + if err == nil { + t.Fatal("SyncProduct should return error") + } + result, err = jdapi.SyncProduct("11732425", "wrongskuid") + if err == nil { + t.Fatal("SyncProduct should return error") + } +} + +func TestGetProductStatust(t *testing.T) { + result, err := jdapi.GetProductStatus("11732425", "2015717812") + if err != nil || result == nil { + t.Fatal(err) + } + // baseapi.SugarLogger.Debug(result) + result, err = jdapi.GetProductStatus("wrongstoreid", "2015717812") + if err == nil { + t.Fatal("GetProductStatus should return error") + } + result, err = jdapi.GetProductStatus("11732425", "wrongskuid") + if err == nil { + t.Fatal("GetProductStatus should return error") + } +} diff --git a/platformapi/jdapi/store.go b/platformapi/jdapi/store.go index 657daba8..33a3f2b4 100644 --- a/platformapi/jdapi/store.go +++ b/platformapi/jdapi/store.go @@ -1,12 +1,43 @@ package jdapi +// todo 没有删除门店的方法? import ( "git.rosy.net.cn/baseapi/utils" ) +const ( + KeyStationName = "stationName" + KeyOutSystemId = "outSystemId" + KeyPhone = "phone" + KeyMobile = "mobile" + KeyCity = "city" + KeyCounty = "county" + KeyStationAddress = "stationAddress" + KeyOperator = "operator" + KeyServiceTimeStart1 = "serviceTimeStart1" + KeyServiceTimeEnd1 = "serviceTimeEnd1" + KeyServiceTimeStart2 = "serviceTimeStart2" + KeyServiceTimeEnd2 = "serviceTimeEnd2" + KeyLng = "lng" + KeyLat = "lat" + KeyDeliveryRangeType = "deliveryRangeType" + KeyCoordinateType = "coordinateType" + KeyDeliveryRangeRadius = "deliveryRangeRadius" + KeyCoordinatePoints = "coordinatePoints" + KeyCloseStatus = "closeStatus" + KeyStoreNotice = "storeNotice" + KeyStandByPhone = "standByPhone" +) + +type CreateShopResult struct { + DeliveryRangeType int `json:"deliveryRangeType"` + CoordinatePoints string `json:"coordinatePoints"` +} + +// 获取门店编码列表接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=138426aa19b54c48ae8464af1ca3b681 -func (a API) GetStationsByVenderId() ([]string, error) { - result, err := a.AccessAPINoPage("store/getStationsByVenderId", nil, nil, nil) +func (a *API) GetStationsByVenderId() ([]string, error) { + result, err := a.AccessAPINoPage("store/getStationsByVenderId", nil, nil, nil, nil) if err == nil { result2 := result.([]interface{}) retVal := make([]string, len(result2)) @@ -18,59 +49,95 @@ func (a API) GetStationsByVenderId() ([]string, error) { return nil, err } +// 新增不带资质的门店信息接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=93acef27c3aa4d8286d5c8c26b493629 +func (a *API) CreateStore(stationName, phone string, city, county int, stationAddress, userName string, serviceTimeStart1, serviceTimeEnd1 int, lng, lat float64, deliveryRangeType, coordinateType int, standByPhone string, addParams map[string]interface{}) (*CreateShopResult, error) { + params := map[string]interface{}{ + KeyStationName: stationName, + KeyPhone: phone, + KeyCity: city, + KeyCounty: county, + KeyStationAddress: stationAddress, + KeyOperator: utils.GetAPIOperator(userName), + KeyServiceTimeStart1: serviceTimeStart1, + KeyServiceTimeEnd2: serviceTimeEnd1, + KeyLng: lng, + KeyLat: lat, + KeyDeliveryRangeType: deliveryRangeType, + KeyCoordinateType: coordinateType, + KeyStandByPhone: standByPhone, + } + result, err := a.AccessAPINoPage("store/createStore", utils.MergeMaps(params, addParams), nil, nil, nil) + if err == nil { + result2 := result.(map[string]interface{}) + retVal := &CreateShopResult{ + DeliveryRangeType: int(utils.MustInterface2Int64(result2["deliveryRangeType"])), + CoordinatePoints: utils.Interface2String(result2["coordinatePoints"]), + } + return retVal, nil + } + return nil, err +} + +// 根据到家门店编码查询门店基本信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=4c48e347027146d5a103e851055cb1a7 -func (a API) GetStoreInfoByStationNo(storeNo string) (map[string]interface{}, error) { - result, err := a.AccessAPINoPage("storeapi/getStoreInfoByStationNo", utils.Params2Map("StoreNo", storeNo), nil, nil) +func (a *API) GetStoreInfoByStationNo(storeNo string) (map[string]interface{}, error) { + result, err := a.AccessAPINoPage("storeapi/getStoreInfoByStationNo", utils.Params2Map("StoreNo", storeNo), nil, nil, nil) if err == nil { return result.(map[string]interface{}), nil } return nil, err } +// 修改门店基础信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=2600369a456446f0921e918f3d15e96a -func (a API) UpdateStoreInfo4Open(storeNo, operator string, addParams map[string]interface{}) (string, error) { +func (a *API) UpdateStoreInfo4Open(storeNo, userName string, addParams map[string]interface{}) (string, error) { jdParams := map[string]interface{}{ "stationNo": storeNo, - "operator": operator, + "operator": utils.GetAPIOperator(userName), } for k, v := range addParams { jdParams[k] = v } - result, err := a.AccessAPINoPage("store/updateStoreInfo4Open", jdParams, nil, nil) + result, err := a.AccessAPINoPage("store/updateStoreInfo4Open", jdParams, nil, nil, nil) if err == nil { return result.(string), nil } return "", err } -func (a API) GetCommentByOrderId(orderId int64) (map[string]interface{}, error) { +// 根据订单号查询商家门店评价信息接口 +// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=bd23397725bb4e74b69e2f2fa1c88d43 +func (a *API) GetCommentByOrderId(orderId int64) (map[string]interface{}, error) { jdParams := map[string]interface{}{ "orderId": orderId, } - result, err := a.AccessAPINoPage("commentOutApi/getCommentByOrderId", jdParams, nil, nil) + result, err := a.AccessAPINoPage("commentOutApi/getCommentByOrderId", jdParams, nil, nil, nil) if err != nil { return nil, err } return result.(map[string]interface{}), nil } +// 商家门店评价信息回复接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=ea0b466a7fa8489b813e8b197efca2d4? -func (a API) OrgReplyComment(orderID int64, storeID, content, replayPin string) (string, error) { +func (a *API) OrgReplyComment(orderID int64, storeID, content, replayPin string) (string, error) { jdParams := map[string]interface{}{ "orderId": orderID, "storeId": storeID, "content": content, "replyPin": replayPin, } - result, err := a.AccessAPINoPage("commentOutApi/orgReplyComment", jdParams, nil, nil) + result, err := a.AccessAPINoPage("commentOutApi/orgReplyComment", jdParams, nil, nil, nil) if err != nil { return "", err } return result.(string), nil } +// 根据到家门店编码修改商家自动接单接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=194&apiid=5df446bb5ff14413965b8d702718dc48 -func (a API) UpdateStoreConfig4Open(stationNo string, isAutoOrder bool) (bool, error) { +func (a *API) UpdateStoreConfig4Open(stationNo string, isAutoOrder bool) (bool, error) { jdParams := map[string]interface{}{ "stationNo": stationNo, } @@ -80,7 +147,7 @@ func (a API) UpdateStoreConfig4Open(stationNo string, isAutoOrder bool) (bool, e } else { jdParams["isAutoOrder"] = 1 } - result, err := a.AccessAPINoPage("store/updateStoreConfig4Open", jdParams, nil, nil) + result, err := a.AccessAPINoPage("store/updateStoreConfig4Open", jdParams, nil, nil, nil) if err != nil { return false, err } diff --git a/utils/typeconv.go b/utils/typeconv.go index f7e3bb2a..6ff16a30 100644 --- a/utils/typeconv.go +++ b/utils/typeconv.go @@ -93,6 +93,14 @@ func Interface2String(data interface{}) string { return data.(string) } +func Slice2MapSlice(data []interface{}) []map[string]interface{} { + retVal := make([]map[string]interface{}, len(data)) + for k, v := range data { + retVal[k] = v.(map[string]interface{}) + } + return retVal +} + // func Bool2String(value bool) string { if value {