package ebai import ( "fmt" "strings" "git.rosy.net.cn/baseapi/platformapi/ebaiapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" ) const ( minBatchSize = 5 // 使用batch相关的API最少的处理数量,因为饿百批处理API的调用频率限制得更低 ) // 门店分类 func (p *PurchaseHandler) ReadStoreCategory(ctx *jxcontext.Context, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) { remoteCats, err := api.EbaiAPI.ShopCategoryGet(vendorStoreID) if err == nil { cats = convertVendorCatList(remoteCats) } return cats, err } func convertVendorCatList(remoteCats []*ebaiapi.CategoryInfo) (cats []*partner.BareCategoryInfo) { for _, rCat := range remoteCats { cat := &partner.BareCategoryInfo{ VendorCatID: utils.Int64ToStr(rCat.CategoryID), Name: rCat.Name, Level: rCat.Level, Seq: jxCatSeq2Ebai(rCat.Rank), Children: convertVendorCatList(rCat.Children), } cats = append(cats, cat) } return cats } func (p *PurchaseHandler) CreateStoreSkuCategory(ctx *jxcontext.Context, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { var vendorCatID int64 if globals.EnableEbaiStoreWrite { vendorCatID, err = api.EbaiAPI.ShopCategoryCreate(vendorStoreID, utils.Str2Int64WithDefault(storeCat.ParentVendorCatID, 0), storeCat.Name, jxCatSeq2Ebai(storeCat.Seq)) } else { vendorCatID = jxutils.GenFakeID() } storeCat.VendorCatID = utils.Int64ToStr(vendorCatID) return err } func (p *PurchaseHandler) UpdateStoreSkuCategory(ctx *jxcontext.Context, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { if globals.EnableEbaiStoreWrite { err = api.EbaiAPI.ShopCategoryUpdate(vendorStoreID, utils.Str2Int64WithDefault(storeCat.VendorCatID, 0), storeCat.Name, jxCatSeq2Ebai(storeCat.Seq)) } return err } func (p *PurchaseHandler) DeleteStoreSkuCategory(ctx *jxcontext.Context, vendorStoreID, vendorCatID string) (err error) { if globals.EnableEbaiStoreWrite { err = api.EbaiAPI.ShopCategoryDelete(vendorStoreID, utils.Str2Int64WithDefault(vendorCatID, 0)) } return err } // 门店商品 // 多门店平台不需要实现这个接口 func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (err error) { storeSku := storeSkuList[0] if globals.EnableEbaiStoreWrite { _, err = api.EbaiAPI.SkuUpdate(vendorStoreID, utils.Str2Int64(storeSku.VendorSkuID), genSkuParamsFromStoreSkuInfo2(storeSku)) } return err } // 通用 func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) int { return 1 } // 对于多门店平台来说,storeSkuList中只有SkuID与VendorSkuID有意义 func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (err error) { storeSku := storeSkuList[0] var vendorSkuID int64 if globals.EnableEbaiStoreWrite { vendorSkuID, err = api.EbaiAPI.SkuCreate(vendorStoreID, storeSku.SkuID, genSkuParamsFromStoreSkuInfo2(storeSku)) } else { vendorSkuID = jxutils.GenFakeID() } storeSku.VendorSkuID = utils.Int64ToStr(vendorSkuID) return err } func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.BareStoreSkuInfo) (err error) { if globals.EnableEbaiStoreWrite { err = api.EbaiAPI.SkuDelete(vendorStoreID, strings.Join(partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDList(), ",")) } return err } func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.BareStoreSkuInfo) (err error) { var validSkus, invalidSkus []string for _, storeSku := range storeSkuList { if storeSku.Status == model.SkuStatusNormal { validSkus = append(validSkus, storeSku.VendorSkuID) } else { invalidSkus = append(invalidSkus, storeSku.VendorSkuID) } } if globals.EnableEbaiStoreWrite { if len(invalidSkus) > minBatchSize { err = api.EbaiAPI.SkuOffline(utils.Int2Str(storeID), strings.Join(invalidSkus, ",")) } else if len(invalidSkus) > 0 { for _, v := range invalidSkus { if err = api.EbaiAPI.SkuOfflineOne(utils.Int2Str(storeID), utils.Str2Int64(v), "", ""); err != nil { break } } } if err == nil { if len(validSkus) > minBatchSize { err = api.EbaiAPI.SkuOnline(utils.Int2Str(storeID), strings.Join(validSkus, ",")) } else if len(validSkus) > 0 { for _, v := range invalidSkus { if err = api.EbaiAPI.SkuOnlineOne(utils.Int2Str(storeID), utils.Str2Int64(v), "", ""); err != nil { break } } } } } return err } func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.BareStoreSkuInfo) (err error) { skuPriceList := make([]string, len(storeSkuList)) for k, v := range storeSkuList { skuPriceList[k] = fmt.Sprintf("%s:%d", v.VendorSkuID, v.Price) } if globals.EnableEbaiStoreWrite { if len(skuPriceList) > minBatchSize { err = api.EbaiAPI.SkuPriceUpdateBatch(utils.Int2Str(storeID), strings.Join(skuPriceList, ";"), "", "") } else { for _, v := range skuPriceList { if err = api.EbaiAPI.SkuPriceUpdateOne(utils.Int2Str(storeID), v, "", ""); err != nil { break } } } } return err } func genSkuParamsFromStoreSkuInfo2(storeSku *dao.StoreSkuSyncInfo) (params map[string]interface{}) { params = map[string]interface{}{ "name": storeSku.Name, "left_num": model.MaxStoreSkuStockQty, "category_id": utils.Str2Int64(storeSku.VendorCatID), "predict_cat": 0, // 不使用推荐类目 "cat1_id": getEbaiCat(storeSku.VendorVendorCatID3, 1), "cat2_id": getEbaiCat(storeSku.VendorVendorCatID2, 2), "cat3_id": getEbaiCat(storeSku.VendorVendorCatID, 3), "weight": storeSku.Weight, "photos": []map[string]interface{}{ map[string]interface{}{ "is_master": true, "url": storeSku.Img, }, }, } if storeSku.DescImg != "" { params["rtf"] = storeSku.DescImg } if storeSku.StoreSkuSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 { params["sale_price"] = storeSku.Price params["market_price"] = storeSku.Price } if storeSku.StoreSkuSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 { params["status"] = jxSkuStatus2Ebai(storeSku.StoreSkuStatus) } // todo 饿百如果给的UPC是空要报错,但如果我要删除UPC怎么弄? if storeSku.Upc != "" { params["upc"] = storeSku.Upc } return params } func (p *PurchaseHandler) GetStoreSkusInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.BareStoreSkuInfo) (outStoreSkuList []*partner.BareStoreSkuInfo, err error) { vendorSkuIDIntList := partner.BareStoreSkuInfoList(inStoreSkuList).GetVendorSkuIDIntList() var vendorSkuList []*ebaiapi.SkuInfo if len(vendorSkuIDIntList) > 1 { task := tasksch.NewParallelTask("获取饿百平台门店商品信息", nil, ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { vendorSkuID := batchItemList[0].(int64) skuInfo, err := api.EbaiAPI.SkuList(utils.Int2Str(storeID), &ebaiapi.SkuListParams{ SkuID: vendorSkuID, }) if err == nil { vendorSkuList = skuInfo.List return skuInfo.List, nil } return nil, err }, vendorSkuIDIntList) tasksch.HandleTask(task, parentTask, false).Run() _, err = task.GetResult(0) } else if len(vendorSkuIDIntList) == 1 { skuInfo, err2 := api.EbaiAPI.SkuList(utils.Int2Str(storeID), &ebaiapi.SkuListParams{ SkuID: vendorSkuIDIntList[0], }) if err = err2; err == nil { vendorSkuList = skuInfo.List } } else { return nil, nil } if err == nil { storeSkuMap := make(map[int64]*partner.BareStoreSkuInfo) for _, v := range inStoreSkuList { storeSkuMap[utils.Str2Int64(v.VendorSkuID)] = v } for _, skuInfo := range vendorSkuList { storeSku := storeSkuMap[skuInfo.SkuID] globals.SugarLogger.Debug(utils.Format4Output(storeSku, false)) outStoreSkuList = append(outStoreSkuList, storeSku) storeSku.Price = skuInfo.SalePrice storeSku.Status = ebaiSkuStatus2Jx(skuInfo.Status) } } return outStoreSkuList, err } func ebaiSkuStatus2Jx(ebaiSkuStatus int) (jxSkuStatus int) { if ebaiSkuStatus == ebaiapi.SkuStatusOnline { jxSkuStatus = model.SkuStatusNormal } else if ebaiSkuStatus == ebaiapi.SkuStatusOffline { jxSkuStatus = model.SkuStatusDontSale } else if ebaiSkuStatus == ebaiapi.SkuStatusOnline { jxSkuStatus = model.SkuStatusDeleted } return jxSkuStatus }