package jdapi import ( "regexp" "strings" "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" KeyOutSpuId = "outSuperId" KeySpuName = "superName" KeySkuMainInfo = "skuMainInfo" 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" ) const ( FakeKeySpecAttr = "specAttr" ) const ( MaxBatchSize4BatchUpdateOutSkuId = 50 MaxPageSize4QuerySku = 50 MaxSkuIDsCount4QueryListBySkuIds = 25 ) const ( SkuFixedStatusOnline = 1 // 上架 SkuFixedStatusOffline = 2 // 下架 SkuFixedStatusDeleted = 4 // 删除 ) const ( CreateSpuResultSuccess = 1 CreateSpuResultInProgress = 2 CreateSpuResultFailed = 3 ) const ( IsFilterDelTrue = "0" // 0代表不查已删除商品 ) const ( MaxSkuNameCharCount = 45 // skuname最长字符数 SaleAttrIDBase = 1001 SaleAttrValueIDBase = 10 ) const ( ImgTypeMain = 1 // 商品图片 ImgTypeDetail = 2 // 详情图片 ) type SkuIDPair struct { SkuId int64 `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"` } // 这个类型商家店内分类与到家分类共用, type CategoryInfo struct { Id int64 `json:"id"` ParentId int64 `json:"pid"` Name string `json:"categoryName"` Level int `json:"categoryLevel"` Sort int `json:"sort"` // 店内分类独有 Status int `json:"status"` // 到家分类独有 FullPath string `json:"fullPath"` // 到家分类独有 } type CreateByUpcParam struct { UniqueUpc string `json:"uniqueCode"` // 商品UPC码 OutSku string `json:"outSku"` // 商家商品编码,商家系统中唯一编码,限1-35字符,与到家商品编码一对一对应 JdPrice string `json:"jdPrice"` // 商家商品价格(单位:元),用于初始商品门店价格,所有的商品门店价格都会初始化成该值。后续修改商品门店价格需要通过价格类接口修改。 ShopCategoryID int64 `json:"shopCategoryId"` // 商家店内分类编码,店内分类编码通过查询商家店内分类信息接口获取 IsSale bool `json:"isSale"` // 门店商品可售状态,true为可售,false为不可售,默认为可售。 } type CreateByUpcPair struct { Upc string SkuId int64 } type QuerySkuParam struct { SkuName string `json:"skuName,omitempty"` UpcCode string `json:"upcCode,omitempty"` SkuID int64 `json:"skuId,omitempty"` IsFilterDel string `json:"isFilterDel,omitempty"` // 是否查询出已删除的上传商品(0代表不查已删除商品,不填则查出全部商品) PageNo int `json:"pageNo,omitempty"` PageSize int `json:"pageSize,omitempty"` } type SkuMain struct { SuperID int64 `json:"superId"` SkuID int64 `json:"skuId"` OutSkuID string `json:"outSkuId"` CategoryID int64 `json:"categoryId"` BrandID int64 `json:"brandId"` ShopCategories []int64 `json:"shopCategories"` SkuName string `json:"skuName"` Slogan string `json:"slogan"` FixedStatus int `json:"fixedStatus"` // 商家商品上下架状态(1:上架;2:下架;4:删除;) FixedUpTime string `json:"fixedUpTime"` OrgCode int `json:"orgCode"` SellCities []int64 `json:"sellCities"` SkuPrice int `json:"skuPrice"` Weight float64 `json:"weight"` } type QueryListBySkuIdsParam struct { SkuIDs []int64 `json:"skuIds"` ImgType int `json:"imgType,omitempty"` HandleStatus []int `json:"handleStatus,omitempty"` } type ImgHandleQueryResult struct { ID string `json:"id"` SkuID int64 `json:"skuId"` IsMain int `json:"isMain"` ImgType int `json:"imgType"` SourceImgURL string `json:"sourceImgUrl"` SkuImgSort int `json:"skuImgSort"` HandleStatus int `json:"handleStatus"` HandleStatusStr string `json:"handleStatusStr"` HandleRemark string `json:"handleRemark"` HandleErrLog string `json:"handleErrLog"` } var ( skuExistReg = regexp.MustCompile(`商家skuId已存在:(\d+)`) ) // 分页查询商品品牌信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=1ca07a3e767649a7a44fc6ea7e9ed8dd func (a *API) QueryPageBrandInfo(pageNo, pageSize int, brandId int64, 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 int64) (catList []*CategoryInfo, 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 interface2CatList(result, 1, func(data interface{}, level int) (cat *CategoryInfo) { mapData, ok := data.(map[string]interface{}) if ok { cat = &CategoryInfo{ Id: utils.MustInterface2Int64(mapData["id"]), ParentId: utils.MustInterface2Int64(mapData["pid"]), Name: utils.Interface2String(mapData["categoryName"]), Level: int(utils.MustInterface2Int64(mapData["categoryLevel"])), Status: int(utils.MustInterface2Int64(mapData["categoryStatus"])), FullPath: utils.Interface2String(mapData["fullPath"]), } } return cat }), nil } return nil, err } // 新增商家店内分类信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=de26f24a62aa47a49e5ab7579d638cb3 func (a *API) AddShopCategory(pid int64, shopCategoryName string, shopCategoryLevel, sort int, userName string) (catId string, err error) { params := map[string]interface{}{ KeyPID: pid, KeyShopCategoryName: shopCategoryName, } if shopCategoryLevel > 0 { params[KeyShopCategoryLevel] = shopCategoryLevel } if sort >= 0 { params[KeySort] = sort } if userName != "" { params["createPin"] = utils.GetAPIOperator(userName) } result, err := a.AccessAPINoPage("pms/addShopCategory", params, nil, nil, nil) if err == nil { return (result.(map[string]interface{}))["id"].(string), nil } return "", err } // 查询商家店内分类信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=964f2d248a7e42b196be2ab35b4e93b4 func (a *API) QueryCategoriesByOrgCode() (catList []*CategoryInfo, err error) { result, err := a.AccessAPINoPage("pms/queryCategoriesByOrgCode", utils.Params2Map("fields", []string{ "ID", "PID", "SHOP_CATEGORY_NAME", "SHOP_CATEGORY_LEVEL", "SORT", }), nil, nil, nil) if err == nil { return interface2CatList(result, 1, nil), nil } return nil, err } // 修改商家店内分类信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=1de278c670b64da492f676ab78d62f73 func (a *API) UpdateShopCategory(id int64, shopCategoryName string) error { params := map[string]interface{}{ KeyID: id, KeyShopCategoryName: shopCategoryName, } _, err := a.AccessAPINoPage("pms/updateShopCategory", params, nil, nil, nullResultParser) return err } // 修改商家店内分类顺序接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=2a8267602e814be9828f0c7ce307b872 func (a *API) ChangeShopCategoryOrder(pid int64, childIds []int64) error { params := map[string]interface{}{ KeyPID: pid, KeyChildIds: childIds, } _, err := a.AccessAPINoPage("pms/changeShopCategoryOrder", params, nil, nil, nullResultParser) return err } // 删除商家店内分类接口 // 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 } // 新增商品信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=dfe6a5ca73fa421da1c9f969b848113e func (a *API) AddSku(outSkuId string, cagtegoryId int, shopCategories []int64, 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.(map[string]interface{}))["skuId"].(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.(map[string]interface{}))["skuId"].(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(queryParam *QuerySkuParam) (skuList []*SkuMain, totalCount int, err error) { if queryParam.PageNo <= 0 { queryParam.PageNo = 1 } if queryParam.PageSize == 0 { queryParam.PageSize = MaxPageSize4QuerySku } result, totalCount, err := a.AccessAPIHavePage("pms/querySkuInfos", utils.Struct2MapByJson(queryParam), nil, nil, nil) if err == nil { err = JdMap2StructByJson(result, &skuList, false) } return skuList, totalCount, err } // 查询商品图片处理结果接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=17506653e03542f9a49023711780c30d func (a *API) QueryListBySkuIds(queryParam *QueryListBySkuIdsParam) (imgList []*ImgHandleQueryResult, err error) { result, err := a.AccessAPINoPage("order/queryListBySkuIds", utils.Struct2MapByJson(queryParam), nil, nil, nil) if err == nil { err = JdMap2StructByJson(result, &imgList, false) } return imgList, 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, genNoPageResultParser("status", "message", "synchronized", "200")) if err == nil { return result.(bool), nil } return false, err } // 商家商品状态检查接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=a348122182ef459982cae1280407ff17 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 } // 新增SPU信息接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=e30936da75294e55bcfdabb92c3815bc func (a *API) AddSpu(outSpuId string, cagtegoryId int, shopCategories []int64, brandId int, spuName string, images []string, fixedStatus int, addParams map[string]interface{}, skus []map[string]interface{}) (spuId int64, skuPairs []*SkuIDPair, err error) { attrList := []string{} for k, v := range skus { attr := v[FakeKeySpecAttr].(string) //getSkuAttr(v[KeyWeight].(float32)) attrList = append(attrList, attr) skus[k] = utils.MergeMaps(map[string]interface{}{ "saleAttrValues": genAttrMapList(attr), }, v) delete(skus[k], FakeKeySpecAttr) } fixedParams := map[string]interface{}{ KeyOutSpuId: outSpuId, KeyCategoryId: cagtegoryId, KeyShopCategories: shopCategories, KeyBrandId: brandId, KeySpuName: spuName, KeyImages: images, KeyFixedStatus: fixedStatus, KeySkuMainInfo: skus, KeyProductDesc: spuName, // todo "saleAttrRelationInfoList": []map[string]interface{}{ map[string]interface{}{ "saleAttrName": "规格", "saleAttrValueNameList": attrList, }, }, } result, err := a.AccessAPINoPage("pms/addSpu", utils.MergeMaps(fixedParams, addParams), nil, nil, nil) if err == nil { resultMap := result.(map[string]interface{}) skuMainParterResponseList := resultMap["skuMainParterResponseList"].([]interface{}) skuPairs = make([]*SkuIDPair, len(skuMainParterResponseList)) for k, v := range skuMainParterResponseList { v2 := v.(map[string]interface{}) skuPairs[k] = &SkuIDPair{ OutSkuId: v2["outSkuId"].(string), SkuId: utils.Str2Int64(v2["skuId"].(string)), } } return utils.MustInterface2Int64(resultMap["superId"]), skuPairs, nil } return 0, nil, err } // 追加新的SKU到指定的SPU接口 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=cffb839b06f042b28d6397b6bd4f2676 func (a *API) AppendSku(outSpuId string, outSkuId string, skuName string, skuPrice int, weight float32, images []string, fixedStatus int, isSale bool, specAttr string, addParams map[string]interface{}) (skuID int64, err error) { attr := specAttr //getSkuAttr(weight) if err = a.AppendSpuSaleAttr(outSpuId, utils.Int2Str(SaleAttrIDBase), attr); err != nil { return 0, err } fixedParams := map[string]interface{}{ KeyOutSpuId: outSpuId, KeyOutSkuId: outSkuId, KeySkuName: skuName, KeySkuPrice: skuPrice, KeyWeight: weight, KeyImages: images, KeyFixedStatus: fixedStatus, KeyIsSale: isSale, "saleAttrValues": genAttrMapList(attr), } result, err := a.AccessAPINoPage("pms/appendSku", utils.MergeMaps(fixedParams, addParams), nil, nil, nil) if err == nil { resultMap := result.(map[string]interface{}) skuMainParterResponseList := resultMap["skuMainParterResponseList"].([]interface{}) return utils.Str2Int64(skuMainParterResponseList[0].(map[string]interface{})["skuId"].(string)), nil } return 0, err } // 更新SPU基础信息,不可以更新销售属性 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=3816c5eadc5d4f268f760cac14483ec0 func (a *API) UpdateSpu(outSpuId string, params map[string]interface{}) (err error) { _, err = a.AccessAPINoPage("pms/updateSpu", utils.MergeMaps(params, utils.Params2Map(KeyOutSpuId, outSpuId)), nil, nil, nil) return err } // 更新SPU下指定SKU的基础信息 // https://opendj.jd.com/staticnew/widgets/resources.html?groupid=180&apiid=8be2b5d153044179a13089e7f19e24e6 func (a *API) UpdateSkuBaseInfo(outSpuId, outSkuId string, params map[string]interface{}) (err error) { _, err = a.AccessAPINoPage("pms/updateSkuBaseInfo", utils.MergeMaps(params, utils.Params2Map(KeyOutSpuId, outSpuId, KeyOutSkuId, outSkuId)), nil, nil, nil) return err } func (a *API) GetSkuSaleAttrName() (saleAttrNameList []string, err error) { result, err := a.AccessAPINoPage("pms/getSkuSaleAttrName", nil, nil, nil, nil) if err == nil { return utils.Slice2StringSlice(result.([]interface{})), nil } return nil, err } func (a *API) AppendSpuSaleAttr(outSpuId, attrName, attrNewValue string) (err error) { _, err = a.AccessAPINoPage("pms/appendSpuSaleAttr", map[string]interface{}{ KeyOutSpuId: outSpuId, "saleAttrId": attrName, "saleAttrValueName": attrNewValue, }, nil, nil, nil) return err } func (a *API) GetSpuSaleAttr(outSpuId string) (attrList []map[string]interface{}, err error) { result, err := a.AccessAPINoPage("pms/getSpuSaleAttr", map[string]interface{}{ KeyOutSpuId: outSpuId, }, nil, nil, nil) if err == nil { return utils.Slice2MapSlice(result.([]interface{})), nil } return nil, err } func (a *API) BatchAddSku(batchSkuRequestList []*CreateByUpcParam) (pairs []*CreateByUpcPair, err error) { result, err := a.AccessAPINoPage("PmsSkuMainService/batchAddSku", map[string]interface{}{ "batchSkuRequestList": batchSkuRequestList, }, nil, nil, genNoPageResultParser("code", "result", "detail", "0")) if err == nil { // globals.SugarLogger.Debug(utils.Format4Output(result, false)) // todo 这个API在找不到UPC创建失败时,code也是0,底层不能判断失败 if result2, ok := result.([]interface{}); ok && len(result2) > 0 { detail := utils.Slice2MapSlice(result2) pairs = make([]*CreateByUpcPair, len(detail)) for k, v := range detail { pairs[k] = &CreateByUpcPair{ Upc: utils.Interface2String(v["uniqueCode"]), SkuId: utils.MustInterface2Int64(v["skuId"]), } } return pairs, nil } else { return nil, utils.NewErrorIntCode("BatchAddSku失败", -1) } } return nil, err } func (a *API) GetSpuStatus(outSpuId string) (resultStatus int, err error) { result, err := a.AccessAPINoPage("pms/getSpuStatus", map[string]interface{}{ "outSuperId": outSpuId, }, nil, nil, nil) if err == nil { return int(utils.MustInterface2Int64(result.(map[string]interface{})["status"])), nil } return 0, err } func (a *API) UpdateSpuSaleAttr(outSpuId, saleAttrId, saleAttrName, saleAttrValueId, saleAttrValueName string) (err error) { apiParams := map[string]interface{}{ "outSuperId": outSpuId, "saleAttrId": saleAttrId, "saleAttrValueId": saleAttrValueId, } if saleAttrName != "" { apiParams["saleAttrName"] = saleAttrName } if saleAttrValueName != "" { apiParams["saleAttrValueName"] = saleAttrValueName } _, err = a.AccessAPINoPage("pms/updateSpuSaleAttr", apiParams, nil, nil, nil) return err } /////////////////////////// // 私有辅助函数 func interface2Cat(data interface{}, level int) (cat *CategoryInfo) { mapData, ok := data.(map[string]interface{}) if ok { cat = &CategoryInfo{ Id: utils.MustInterface2Int64(mapData["id"]), ParentId: utils.MustInterface2Int64(mapData["pid"]), Name: utils.Interface2String(mapData["shopCategoryName"]), Level: int(utils.Interface2Int64WithDefault(mapData["shopCategoryLevel"], 0)), Sort: int(utils.MustInterface2Int64(mapData["sort"])), } } return cat } func interface2CatList(data interface{}, level int, interface2CatHandler func(data interface{}, level int) (cat *CategoryInfo)) (cats []*CategoryInfo) { if interface2CatHandler == nil { interface2CatHandler = interface2Cat } maps, ok := data.([]interface{}) if ok { cats = make([]*CategoryInfo, len(maps)) for index, v := range maps { cats[index] = interface2CatHandler(v, level) } } return cats } // func getSkuAttr(weight float32) (attr string) { // attr = fmt.Sprintf("约%dg", int(math.Round(float64(weight*1000)))) // return attr // } func genAttrMapList(kgAttr string) (attrList []map[string]interface{}) { return []map[string]interface{}{ map[string]interface{}{ "saleAttrName": "规格", "saleAttrValueName": kgAttr, }, } } func GetJdSkuIDFromError(err error) int64 { if err2, ok := err.(*utils.ErrorWithCode); ok && err2.IntCode() == 11001 && strings.Index(err2.ErrMsg(), "商家skuId已存在") >= 0 { searchResult := skuExistReg.FindStringSubmatch(err2.ErrMsg()) if searchResult != nil && len(searchResult[1]) > 0 { return utils.Str2Int64(searchResult[1]) } } return 0 }