diff --git a/business/jxstore/cms/system_store_sku.go b/business/jxstore/cms/system_store_sku.go index 00dce9bcd..08e2a0c23 100644 --- a/business/jxstore/cms/system_store_sku.go +++ b/business/jxstore/cms/system_store_sku.go @@ -1,7 +1,14 @@ package cms import ( + "fmt" + "git.rosy.net.cn/baseapi/platformapi/ebaiapi" + "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" "time" "git.rosy.net.cn/baseapi/platformapi/mtwmapi" @@ -11,193 +18,220 @@ import ( // CopyOnStoreSkuToOther 将一个美团门店分类和商品复制到另一个门店 func CopyOnStoreSkuToOther(ctx *jxcontext.Context, fromStoreId, toStoreId string, vendorId int, isAsync bool, offSet int) (hint string, err error) { - return "", err - //var ( - // db = dao.GetDB() - //) - // - //fromStoreDetail, _ := dao.GetStoreDetailByVendorStoreID(db, fromStoreId, vendorId, "") - //if fromStoreDetail == nil { - // return "", fmt.Errorf("%s,平台门店id未获取到", fromStoreId) - //} - //if fromStoreDetail.VendorOrgCode == globals.Mtwm2Code { - // fromAPI := partner.CurAPIManager.GetAPI(vendorId, fromStoreDetail.VendorOrgCode).(*mtwmapi.API) - // fromAPI.SetToken(fromStoreDetail.MtwmToken) - //} else { - // switch vendorId { - // case model.VendorIDMTWM: - // fromAPI = partner.CurAPIManager.GetAPI(vendorId, fromStoreDetail.VendorOrgCode).(*mtwmapi.API) - // case model.VendorIDEBAI: - // fromAPI = partner.CurAPIManager.GetAPI(vendorId, fromStoreDetail.VendorOrgCode).(*ebaiapi.API) - // } - //} - // - //toStoreDetail, _ := dao.GetStoreDetailByVendorStoreID(db, toStoreId, vendorId, "") - //if toStoreDetail == nil { - // return "", fmt.Errorf("%s,平台门店id未获取到", fromStoreId) - //} - //if toStoreDetail.VendorOrgCode == globals.Mtwm2Code { - // toAPI := partner.CurAPIManager.GetAPI(vendorId, toStoreDetail.VendorOrgCode).(*mtwmapi.API) - // toAPI.SetToken(fromStoreDetail.MtwmToken) - //} - // - //apiObj := partner.CurAPIManager.GetAPI(vendorId, appOrgCode).(*mtwmapi.API) - //if appOrgCode == globals.Mtwm2Code { - // var storeDetail *dao.StoreDetail - // if storeID != 0 { - // storeDetail, _ = dao.GetStoreDetail(db, storeID, vendorId, appOrgCode) - // } else if vendorStoreID != "" { - // storeDetail, _ = dao.GetStoreDetailByVendorStoreID(db, vendorStoreID, vendorId, appOrgCode) - // } - // if storeDetail != nil { - // apiObj.SetToken(storeDetail.MtwmToken) - // } - //} - // - //// 门店api加载 - //toStore, err := dao.GetStoreDetailByVendorStoreID(db, toStoreId, vendorId, "") - //if err != nil { - // return "", err - //} - //toApi := mtwmapi.New(beego.AppConfig.DefaultString("mtwmAppID2", ""), beego.AppConfig.DefaultString("mtwmSecret2", ""), beego.AppConfig.DefaultString("mtwmCallbackURL2", ""), "") - //toApi.SetToken(toStore.MtwmToken) - // - //fromStore, err := dao.GetStoreDetailByVendorStoreID(db, fromStoreId, vendorId, "") - //if err != nil { - // return "", err - //} - //fromApi := mtwmapi.New(beego.AppConfig.DefaultString("mtwmAppID2", ""), beego.AppConfig.DefaultString("mtwmSecret2", ""), beego.AppConfig.DefaultString("mtwmCallbackURL2", ""), "") - //fromApi.SetToken(fromStore.MtwmToken) - // - //taskName := fmt.Sprintf("将平台门店[%s],分类和商品复制到[%s]", fromStoreId, toStoreId) - //config := tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(false) - //work := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // step := batchItemList[0].(int) - // switch step { - // // case 1: - // // 1.加载门店商品,删除商品.当分类下没有商品时.删除分类 - // // errs := LoadingStoreSkuList(ctx, toApi, toStore.VendorStoreID) - // //if errs != nil && len(errs) > 0 { - // // return nil, errs[0] - // //} - // case 1: - // handler, _ := partner.GetPurchasePlatformFromVendorID(vendorId).(partner.ISingleStoreStoreSkuHandler) - // if handler == nil { - // return nil, fmt.Errorf(model.VendorChineseNames[vendorId] + ":不存在此平台") - // } - // fromCategory, err := handler.GetStoreAllCategories(ctx, fromStore.ID, fromStore.VendorStoreID) - // - // // 同步分类 - // fromCategoryList, err := fromApi.RetailCatList(utils.Int2Str(fromVendorStoreId)) - // //globals.SugarLogger.Debugf("err ============ %v", err) - // //for _, v := range fromCategoryList { - // // categoryErr := toApi.RetailCatUpdate(toStore.VendorStoreID, v.Name, &mtwmapi.Param4UpdateCat{ - // // CategoryCode: v.Code, - // // Sequence: v.Sequence, - // // }) - // // if categoryErr != nil { - // // globals.SugarLogger.Debugf("err := RetailCatUpdate : %v", categoryErr) - // // } - // // if v.Children != nil && len(v.Children) != 0 { - // // for _, c := range v.Children { - // // if err3 := toApi.RetailCatUpdate(toStore.VendorStoreID, v.Name, &mtwmapi.Param4UpdateCat{ - // // CategoryNameOrigin: v.Name, - // // //CategoryCodeOrigin: v.Code, - // // //CategoryCode: v.Code, - // // SecondaryCategoryCode: c.Code, - // // SecondaryCategoryName: c.Name, - // // Sequence: c.Sequence, - // // }); err3 != nil { - // // globals.SugarLogger.Debugf("err := RetailCatUpdate Children : %v", err3) - // // } - // // } - // // } - // //} - // - // case 2: - // i := offSet - // for { - // // 同步商品 - // fromFoodList, err1 := fromApi.RetailListAll(fromStoreId, i) - // if len(fromFoodList) == 0 || fromFoodList == nil { - // return nil, fmt.Errorf("fromFoodList 为空 %s ,i:= %d", utils.Format4Output(err1, false), i) - // } - // - // if err := BatchInitData(ctx, fromFoodList, toApi, toStore.VendorStoreID, i); err != nil { - // globals.SugarLogger.Debugf("BatchInitData : %s", utils.Format4Output(err, false)) - // } - // if len(fromFoodList) < 100 { - // break - // } - // i++ - // } - // - // } - // return - //} - //task := tasksch.NewParallelTask(taskName, config, ctx, work, []int{1, 2}) - //tasksch.HandleTask(task, nil, true).Run() - //if !isAsync { - // _, err = task.GetResult(0) - // hint = "1" - //} else { - // hint = task.ID - //} - //return hint, err -} + var ( + db = dao.GetDB() + ) -func LoadingStoreSkuList(ctx *jxcontext.Context, api *mtwmapi.API, poiCode string) (err []error) { - foodList, err1 := api.RetailListAll(poiCode, 0) - if err1 != nil { - return append(err, err1) + // 门店api加载 + toStore, err := dao.GetStoreDetailByVendorStoreID(db, toStoreId, vendorId, "") + if err != nil { + return "", err } - i := 0 - for _, v := range foodList { - err1 := api.RetailDelete(ctx.GetTrackInfo(), poiCode, v.AppFoodCode) - if err1 != nil { - err = append(err, err1) - } - if i%40 == 0 { - time.Sleep(200 * time.Millisecond) - } - i++ + fromStore, err := dao.GetStoreDetailByVendorStoreID(db, fromStoreId, vendorId, "") + if err != nil { + return "", err } - return + switch vendorId { + case model.VendorIDMTWM: + return CopyMtToMT(ctx, fromStore, toStore, isAsync, offSet) + case model.VendorIDEBAI: + return CopyEBaiToEBai(ctx, fromStore, toStore, isAsync) + default: + return "", fmt.Errorf("暂时还不支持") + } } -type Skus struct { - AvailableTimes struct { - Friday string `json:"friday"` - Monday string `json:"monday"` - Saturday string `json:"saturday"` - Sunday string `json:"sunday"` - Thursday string `json:"thursday"` - Tuesday string `json:"tuesday"` - Wednesday string `json:"wednesday"` - } `json:"available_times"` - BoxNum string `json:"box_num"` - BoxPrice string `json:"box_price"` - IsSellFlag int `json:"isSellFlag"` - LadderBoxNum string `json:"ladder_box_num"` - LadderBoxPrice string `json:"ladder_box_price"` - LimitOpenSyncStockNow bool `json:"limit_open_sync_stock_now"` - LocationCode string `json:"location_code"` - MinOrderCount string `json:"min_order_count"` - Price string `json:"price"` - SkuId string `json:"sku_id"` - Spec string `json:"spec"` - Stock string `json:"stock"` - Unit string `json:"unit"` - Upc string `json:"upc"` - Weight string `json:"weight"` - WeightForUnit string `json:"weight_for_unit"` - WeightUnit string `json:"weight_unit"` +// CopyEBaiToEBai 饿了么商品复制到饿了么 +func CopyEBaiToEBai(ctx *jxcontext.Context, fromStore, toStore *dao.StoreDetail, isAsync bool) (hint string, err error) { + VendorCategoryIDMap := make(map[int64]int64, 0) + api := api.EbaiAPI + taskName := fmt.Sprintf("将饿了么平台门店[%s],分类和商品复制到[%s]", fromStore.VendorStoreID, toStore.VendorStoreID) + config := tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(false) + work := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + step := batchItemList[0].(int) + switch step { + case 1: + // 1.加载门店商品,删除商品.当分类下没有商品时.删除分类 + //errs := LoadingStoreSkuList(ctx, toApi, toStore.VendorStoreID) + // errs := LoadingStoreSkuList(ctx, toApi, toStore.VendorStoreID) + //if errs != nil && len(errs) > 0 { + // return nil, errs[0] + //} + case 2: + // 同步分类 + fromCategoryList, err := api.ShopCategoryGet(utils.Int2Str(fromStore.ID)) + if err != nil { + return nil, err + } + for _, v := range fromCategoryList { + parentID, categoryErr := api.ShopCategoryCreate(utils.Int2Str(toStore.ID), 0, v.Name, v.Rank) + if categoryErr != nil { + globals.SugarLogger.Debugf("err := RetailCatUpdate : %v", categoryErr) + continue + } + VendorCategoryIDMap[v.CategoryID] = parentID + if v.Children != nil && len(v.Children) != 0 { + for _, c := range v.Children { + childrenCateId, err := api.ShopCategoryCreate(utils.Int2Str(toStore.ID), parentID, c.Name, c.Rank) + if err != nil { + globals.SugarLogger.Debugf("err := RetailCatUpdate Children : %v", err) + continue + } + VendorCategoryIDMap[v.CategoryID] = childrenCateId + } + } + } + globals.SugarLogger.Debugf("======VendorCategoryIDMap := %s", utils.Format4Output(VendorCategoryIDMap, false)) + case 3: + i := 0 + for { + // 同步商品 + fromFoodList, err1 := api.SkuList(utils.Int2Str(fromStore.ID), &ebaiapi.SkuListParams{}) + if len(fromFoodList.List) == 0 || fromFoodList == nil { + return nil, fmt.Errorf("fromFoodList 为空 %s ,i:= %d", utils.Format4Output(err1, false), i) + } + + if err = BatchInitSkuEBai2EBai(ctx, fromFoodList.List, api, utils.Int2Str(toStore.ID), VendorCategoryIDMap); err != nil { + globals.SugarLogger.Debugf("BatchInitData : %s", utils.Format4Output(err, false)) + } + i = fromFoodList.SkuIdOffset + } + + } + return + } + task := tasksch.NewParallelTask(taskName, config, ctx, work, []int{1, 2, 3}) + tasksch.HandleTask(task, nil, true).Run() + if !isAsync { + _, err = task.GetResult(0) + hint = "1" + } else { + hint = task.ID + } + return hint, err } -// BatchInitData 批量创建商品 -func BatchInitData(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, toApi *mtwmapi.API, vendorStoreID string, i int) error { +// BatchInitSkuEBai2EBai 批量创建商品 +func BatchInitSkuEBai2EBai(ctx *jxcontext.Context, fromSku []*ebaiapi.SkuInfo, toApi *ebaiapi.API, storeID string, VendorCategoryIDMap map[int64]int64) error { + for _, storeSku := range fromSku { + params := map[string]interface{}{ + "left_num": model.MaxStoreSkuStockQty, + "weight": storeSku.Weight, + "photos": storeSku.Photos, + "preparation_time": storeSku.PreparationTime, + } + params["upc"] = storeSku.Upc + params["name"] = storeSku.Name + params["cat3_id"] = VendorCategoryIDMap[int64(storeSku.CateId2)] + params["category_id"] = VendorCategoryIDMap[int64(storeSku.CateId)] + params["rtf"] = storeSku.Rtf + params["process_type"] = storeSku.ProcessType + params["process_detail"] = storeSku.ProcessDetail + params["sale_price"] = storeSku.SalePrice + params["status"] = storeSku.Status + params["minimum"] = storeSku.Minimum + params["seven_days_no_reason"] = storeSku.SevenDaysNoReason + if len(storeSku.SkuProperty) != model.NO { + params["sku_property"] = storeSku.SkuProperty + } + customSkuID := storeSku.CustomSkuID + if customSkuID == "" { + customSkuID = utils.Int64ToStr(storeSku.SkuId) + } + _, err := toApi.SkuCreate(ctx.GetTrackInfo(), storeID, utils.Str2Int64(storeSku.CustomSkuID), params) + if err != nil { + globals.SugarLogger.Debugf("错误商品id: %d,商品名称:%s, %v", storeSku.SkuId, storeSku.Name, err) + } + } + + return nil +} + +// CopyMtToMT 美团商品复制到美团 +func CopyMtToMT(ctx *jxcontext.Context, fromStore, toStore *dao.StoreDetail, isAsync bool, offSet int) (hint string, err error) { + fromAPI := partner.CurAPIManager.GetAPI(model.VendorIDMTWM, fromStore.VendorOrgCode).(*mtwmapi.API) + if fromStore.VendorOrgCode == globals.Mtwm2Code { + fromAPI.SetToken(fromStore.MtwmToken) + } + + toAPI := partner.CurAPIManager.GetAPI(model.VendorIDMTWM, toStore.VendorOrgCode).(*mtwmapi.API) + if toStore.VendorOrgCode == globals.Mtwm2Code { + toAPI.SetToken(toStore.MtwmToken) + } + + taskName := fmt.Sprintf("将美团平台门店[%s],分类和商品复制到[%s]", fromStore.VendorStoreID, toStore.VendorStoreID) + config := tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(false) + work := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + step := batchItemList[0].(int) + switch step { + case 1: + // 1.加载门店商品,删除商品.当分类下没有商品时.删除分类 + //errs := LoadingStoreSkuList(ctx, toApi, toStore.VendorStoreID) + // errs := LoadingStoreSkuList(ctx, toApi, toStore.VendorStoreID) + //if errs != nil && len(errs) > 0 { + // return nil, errs[0] + //} + case 2: + // 同步分类 + fromCategoryList, _ := fromAPI.RetailCatList(fromStore.VendorStoreID) + for _, v := range fromCategoryList { + categoryErr := toAPI.RetailCatUpdate(toStore.VendorStoreID, v.Name, &mtwmapi.Param4UpdateCat{ + CategoryCode: v.Code, + Sequence: v.Sequence, + }) + if categoryErr != nil { + globals.SugarLogger.Debugf("err := RetailCatUpdate : %v", categoryErr) + } + if v.Children != nil && len(v.Children) != 0 { + for _, c := range v.Children { + if err3 := toAPI.RetailCatUpdate(toStore.VendorStoreID, v.Name, &mtwmapi.Param4UpdateCat{ + CategoryNameOrigin: v.Name, + SecondaryCategoryCode: c.Code, + SecondaryCategoryName: c.Name, + Sequence: c.Sequence, + }); err3 != nil { + globals.SugarLogger.Debugf("err := RetailCatUpdate Children : %v", err3) + } + } + } + } + + case 3: + i := offSet + for { + // 同步商品 + fromFoodList, err1 := fromAPI.RetailListAll(fromStore.VendorStoreID, i) + if len(fromFoodList) == 0 || fromFoodList == nil { + return nil, fmt.Errorf("fromFoodList 为空 %s ,i:= %d", utils.Format4Output(err1, false), i) + } + + if err = BatchInitSkuMT2MT(ctx, fromFoodList, toAPI, toStore.VendorStoreID, i); err != nil { + globals.SugarLogger.Debugf("BatchInitData : %s", utils.Format4Output(err, false)) + } + if len(fromFoodList) < 100 { + break + } + i++ + } + + } + return + } + task := tasksch.NewParallelTask(taskName, config, ctx, work, []int{1, 2, 3}) + tasksch.HandleTask(task, nil, true).Run() + if !isAsync { + _, err = task.GetResult(0) + hint = "1" + } else { + hint = task.ID + } + return hint, err +} + +// BatchInitSkuMT2MT 批量创建商品 +func BatchInitSkuMT2MT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, toApi *mtwmapi.API, vendorStoreID string, i int) error { foodDataList := make([]map[string]interface{}, len(fromSku)) for i, storeSku := range fromSku { foodData := make(map[string]interface{}) diff --git a/business/partner/purchase/ebai/store_sku2.go b/business/partner/purchase/ebai/store_sku2.go index 5e4c19959..0377e4f08 100644 --- a/business/partner/purchase/ebai/store_sku2.go +++ b/business/partner/purchase/ebai/store_sku2.go @@ -627,12 +627,12 @@ func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTas func vendorSku2Jx(vendorSku *ebaiapi.SkuInfo) (skuName *partner.SkuNameInfo) { prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(vendorSku.Name) - weight := vendorSku.Weight + weight := utils.Str2Int(vendorSku.Weight) if weight <= 0 { weight = jxutils.FormatSkuWeight(specQuality, specUnit) } skuID := int(utils.Str2Int64WithDefault(vendorSku.CustomSkuID, 0)) - vendorSkuID := utils.Int64ToStr(vendorSku.SkuID) + vendorSkuID := utils.Int64ToStr(vendorSku.SkuId) skuName = &partner.SkuNameInfo{ NameID: skuID, VendorNameID: vendorSkuID, @@ -648,8 +648,8 @@ func vendorSku2Jx(vendorSku *ebaiapi.SkuInfo) (skuName *partner.SkuNameInfo) { SkuID: skuID, Stock: vendorSku.LeftNum, - VendorPrice: vendorSku.SalePrice, - Status: ebaiSkuStatus2Jx(vendorSku.Status), + VendorPrice: int64(vendorSku.SalePrice), + Status: ebaiSkuStatus2Jx(utils.Str2Int(vendorSku.Status)), }, SkuName: vendorSku.Name, Comment: comment, @@ -660,7 +660,7 @@ func vendorSku2Jx(vendorSku *ebaiapi.SkuInfo) (skuName *partner.SkuNameInfo) { }, } for _, v := range vendorSku.Photos { - skuName.PictureList = append(skuName.PictureList, v.URL) + skuName.PictureList = append(skuName.PictureList, v.Url) } // todo, 看起来饿百只返回了最低一级的商家分类信息 for _, v := range vendorSku.CustomCatList { diff --git a/controllers/cms_store_sku.go b/controllers/cms_store_sku.go index 01a125d97..2759aef21 100644 --- a/controllers/cms_store_sku.go +++ b/controllers/cms_store_sku.go @@ -1057,7 +1057,7 @@ func (c *StoreSkuController) CopyMtToJd() { // @router /CopyMtToMt [post] func (c *StoreSkuController) CopyMtToMt() { c.callCopyMtToMt(func(params *tStoreSkuCopyMtToMtParams) (retVal interface{}, errCode string, err error) { - //retVal, err = cms.CopyOnStoreSkuToOther(params.Ctx, params.FromStoreID, params.ToStoreID, false, params.OffSet) + retVal, err = cms.CopyOnStoreSkuToOther(params.Ctx, params.FromStoreID, params.ToStoreID, params.VendorID, false, params.OffSet) return retVal, errCode, err }) }