From 73a5f7241e1d2d8ca0786a7d938de8cbffe1c2ff Mon Sep 17 00:00:00 2001 From: gazebo Date: Wed, 26 Sep 2018 22:30:19 +0800 Subject: [PATCH] - sync sku to ebai, still have bugs. --- business/model/dao/dao.go | 4 +- business/model/dao/dao_bz.go | 27 ++ business/model/model.go | 2 + business/model/store_sku.go | 6 +- business/partner/purchase/ebai/store_sku.go | 363 +++++++++++++----- .../partner/purchase/ebai/store_sku_test.go | 55 +++ 6 files changed, 349 insertions(+), 108 deletions(-) create mode 100644 business/partner/purchase/ebai/store_sku_test.go diff --git a/business/model/dao/dao.go b/business/model/dao/dao.go index e5b15d224..92909fb99 100644 --- a/business/model/dao/dao.go +++ b/business/model/dao/dao.go @@ -105,9 +105,9 @@ func GetEntity(db *DaoDB, item interface{}, cols ...string) (err error) { if db == nil { db = GetDB() } - err = utils.CallFuncLogError(func() error { + err = utils.CallFuncLogErrorIgnore(func() error { return db.db.Read(item, cols...) - }, reflect.TypeOf(item).Name()) + }, reflect.TypeOf(item).Name(), orm.ErrNoRows) return err } diff --git a/business/model/dao/dao_bz.go b/business/model/dao/dao_bz.go index 7e01c6d8c..1f6827215 100644 --- a/business/model/dao/dao_bz.go +++ b/business/model/dao/dao_bz.go @@ -8,6 +8,7 @@ import ( "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/globals" + "github.com/astaxie/beego/orm" ) // 这里面的函数要求实体是IDCUDL的,即含有ID, UpdatedAt, LastOperator, DeletedAt字段 @@ -110,3 +111,29 @@ func DeleteEntityLogically(db *DaoDB, item interface{}, kvs map[string]interface model.FieldDeletedAt: time.Now(), }), userName, conditions) } + +func AddStoreCategoryMap(db *DaoDB, storeID, categoryID int, vendorID int, vendorCategoryID string, status int8, userName string) (err error) { + storeCat := &model.StoreSkuCategoryMap{ + StoreID: storeID, + CategoryID: categoryID, + } + if err = GetEntity(db, storeCat, model.FieldStoreID, model.FieldCategoryID); err != nil && err != orm.ErrNoRows { + return err + } + if vendorID == model.VendorIDEBAI { + if vendorCategoryID != "" { + storeCat.EbaiID = utils.Str2Int64(vendorCategoryID) + } + storeCat.EbaiSyncStatus = status + } else { + panic("unsupported vendor") + } + if storeCat.ID == 0 { + WrapAddIDCULDEntity(storeCat, userName) + err = CreateEntity(db, storeCat) + } else { + WrapUpdateULEntity(storeCat, userName) + _, err = UpdateEntity(db, storeCat) + } + return err +} diff --git a/business/model/model.go b/business/model/model.go index cfdf73662..a3b5ffb58 100644 --- a/business/model/model.go +++ b/business/model/model.go @@ -23,6 +23,8 @@ const ( FieldNameID = "NameID" FieldPlaceCode = "PlaceCode" + FieldCategoryID = "CategoryID" + FieldJdID = "JdID" FieldElmID = "ElmID" FieldEbaiID = "EbaiID" diff --git a/business/model/store_sku.go b/business/model/store_sku.go index 61414d4aa..bda90a321 100644 --- a/business/model/store_sku.go +++ b/business/model/store_sku.go @@ -9,8 +9,8 @@ const ( type StoreSkuCategoryMap struct { ModelIDCULD - StoreID int `orm:"column(store_id)"` - SkuCategoryID int `orm:"column(sku_category_id)"` + StoreID int `orm:"column(store_id)"` + CategoryID int `orm:"column(category_id)"` ElmID int64 `orm:"column(elm_id);index"` EbaiID int64 `orm:"column(ebai_id);index"` @@ -21,7 +21,7 @@ type StoreSkuCategoryMap struct { func (*StoreSkuCategoryMap) TableUnique() [][]string { return [][]string{ - []string{"StoreID", "SkuCategoryID", "DeletedAt"}, + []string{"StoreID", "CategoryID", "DeletedAt"}, } } diff --git a/business/partner/purchase/ebai/store_sku.go b/business/partner/purchase/ebai/store_sku.go index a5f9b2d07..c126f7b1f 100644 --- a/business/partner/purchase/ebai/store_sku.go +++ b/business/partner/purchase/ebai/store_sku.go @@ -1,6 +1,9 @@ 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" @@ -11,6 +14,10 @@ import ( "git.rosy.net.cn/jx-callback/globals/api" ) +const ( + MaxPageSize = 100 +) + type tStoreSkuFullInfo struct { model.StoreSkuBind @@ -27,30 +34,39 @@ type tStoreSkuFullInfo struct { Img string `orm:"size(255)" json:"img"` PlaceStr string - CatName string `orm:"size(255)"` - EbaiCategoryID int64 `orm:"column(ebai_category_id)" json:"ebaiCategoryID"` // 这个是指对应的饿百商品类别 + CatName string `orm:"size(255)"` CatID int `orm:"column(cat_id)"` CatEbaiID int64 `orm:"column(cat_ebai_id)"` CatEbaiSyncStatus int CatLevel int - ParentCatName string `orm:"size(255)"` - ParentCatID int `orm:"column(parent_cat_id)"` - ParentCatEbaiID int64 `orm:"column(parent_cat_ebai_id)"` - ParentCatEbaiSyncStatus int - ParentCatLevel int + ParentCatID int `orm:"column(parent_cat_id)"` + ParentCatEbaiID int64 `orm:"column(parent_cat_ebai_id)"` - EbaiCat1ID string `orm:"column(ebai_cat1_id)"` - EbaiCat2ID string `orm:"column(ebai_cat2_id)"` - EbaiCat3ID string `orm:"column(ebai_cat3_id)"` + EbaiCat1ID int64 `orm:"column(ebai_cat1_id)"` + EbaiCat2ID int64 `orm:"column(ebai_cat2_id)"` + EbaiCat3ID int64 `orm:"column(ebai_cat3_id)"` +} + +type tStoreCatInfo struct { + model.StoreSkuCategoryMap + CatID int `orm:"column(cat_id)"` + Name string + ParentID int `orm:"column(parent_id)"` + Level int + Type int + Seq int + + ParentEbaiID int64 `orm:"column(parent_ebai_id)"` + Children map[string]*tStoreCatInfo `orm:"-"` } var ( - defCatMap = map[int]string{ - 1: "151301831158987", - 2: "15347484581335", - 3: "15347484581339", + defCatMap = map[int]int64{ + 1: 151301831158987, + 2: 15347484581335, + 3: 15347484581339, } ) @@ -65,23 +81,25 @@ func (p *PurchaseHandler) SyncStoreSkus(db *dao.DaoDB, storeIDs []int, skuIDs [] } func (p *PurchaseHandler) syncOneStoreSkus(db *dao.DaoDB, storeID int, skuIDs []int, isForce bool, userName string) (err error) { + if err = p.syncOneStoreCategoriesFromRemote2Local(db, storeID, userName); err != nil { + return err + } sql := ` SELECT t1.*, t2.spec_quality, t2.spec_unit, t2.weight, t2.status sku_status, t3.prefix, t3.name, t3.comment, t3.is_global, t3.unit, t3.img, - t4.name cat_name, t4.ebai_category_id, - t4.id cat_id, t4.level cat_level, t5.ebai_id cat_ebai_id, t5.ebai_sync_status cat_ebai_sync_status, - t4p.name parent_cat_name, - t4p.id parent_cat_id, t4p.level parent_cat_level, t5p.ebai_id parent_cat_ebai_id, t5p.ebai_sync_status parent_cat_ebai_sync_status, - cat1.vendor_category_id ebai_cat1_id, cat2.vendor_category_id ebai_cat2_id, cat2.parent_id ebai_cat3_id + t4.name cat_name, + t4.id cat_id, t4.level cat_level, t5.ebai_id cat_ebai_id, + t4p.id parent_cat_id, t5p.ebai_id parent_cat_ebai_id, t5p.ebai_sync_status parent_cat_ebai_sync_status, + cat1.vendor_category_id ebai_cat3_id, cat2.vendor_category_id ebai_cat2_id, cat2.parent_id ebai_cat1_id FROM store_sku_bind t1 JOIN sku t2 ON t1.sku_id = t2.id JOIN sku_name t3 ON t2.name_id = t3.id JOIN sku_category t4 ON t3.category_id = t4.id JOIN sku_category t4p ON t4p.id = t4.parent_id - LEFT JOIN store_sku_category_map t5 ON t5.store_id = t1.store_id AND t5.sku_category_id = t4.id - LEFT JOIN store_sku_category_map t5p ON t5p.store_id = t1.store_id AND t5p.sku_category_id = t4p.id + LEFT JOIN store_sku_category_map t5 ON t5.store_id = t1.store_id AND t5.category_id = t4.id + LEFT JOIN store_sku_category_map t5p ON t5p.store_id = t1.store_id AND t5p.category_id = t4p.id - LEFT JOIN sku_vendor_category cat1 ON t3.category_id = cat1.vendor_category_id AND cat1.vendor_id = ? + LEFT JOIN sku_vendor_category cat1 ON t4.ebai_category_id = cat1.vendor_category_id AND cat1.vendor_id = ? LEFT JOIN sku_vendor_category cat2 ON cat1.parent_id = cat2.vendor_category_id AND cat1.vendor_id = ? WHERE t1.store_id = ? AND (t1.ebai_sync_status <> 0) @@ -98,83 +116,49 @@ func (p *PurchaseHandler) syncOneStoreSkus(db *dao.DaoDB, storeID int, skuIDs [] strStoreID := utils.Int2Str(storeID) var storeSkuInfoList []*tStoreSkuFullInfo if err = dao.GetRows(db, &storeSkuInfoList, sql, sqlParams...); err == nil { - globals.SugarLogger.Debug(utils.Format4Output(storeSkuInfoList, false)) - level1CatList2Add := make(map[string]interface{}) - level2CatList2Add := make(map[string]interface{}) + // globals.SugarLogger.Debug(utils.Format4Output(storeSkuInfoList, false)) + catList2Add := make(map[int]int) for _, storeSku := range storeSkuInfoList { if storeSku.EbaiSyncStatus&model.SyncFlagNewMask != 0 { if storeSku.ParentCatEbaiID == 0 { - level1CatList2Add[utils.Int2Str(storeSku.ParentCatID)] = map[string]interface{}{ - ebaiapi.KeyShopID: strStoreID, - "parent_category_id": 0, - "name": utils.FilterMb4(storeSku.ParentCatName), - "shop_custom_id": utils.Int2Str(storeSku.ParentCatID), - "rank": storeSku.ParentCatLevel + 1, // 饿百是从1开始 - } + catList2Add[storeSku.ParentCatID] = 1 + } + if storeSku.CatEbaiID == 0 { + catList2Add[storeSku.CatID] = 1 } } } - globals.SugarLogger.Debug(utils.Format4Output(level1CatList2Add, false)) - level1CatList := utils.MapKV2List(level1CatList2Add) - task := tasksch.RunTask("syncOneStoreSkus level1 cat", false, nil, 0, 1, userName, func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - cat := batchItemList[0].(map[string]interface{}) - globals.SugarLogger.Debug(strStoreID, 0, cat["name"].(string), cat["rank"].(int), cat["shop_custom_id"].(string)) - ebaiCatID, err2 := api.EbaiAPI.ShopCategoryCreate(strStoreID, 0, cat["name"].(string), cat["rank"].(int), cat["shop_custom_id"].(string)) - if err = err2; err == nil { - cat["category_id"] = ebaiCatID - return nil, nil + for k := range catList2Add { + if err = dao.AddStoreCategoryMap(db, storeID, k, model.VendorIDEBAI, "", model.SyncFlagNewMask, userName); err != nil { + return err } - return nil, err - }, level1CatList) - if _, err = task.GetResult(0); err == nil { - for _, storeSku := range storeSkuInfoList { - if storeSku.EbaiSyncStatus&model.SyncFlagNewMask != 0 { - if storeSku.CatEbaiID == 0 { - level2CatList2Add[utils.Int2Str(storeSku.CatID)] = map[string]interface{}{ - ebaiapi.KeyShopID: strStoreID, - "parent_category_id": level1CatList2Add[utils.Int2Str(storeSku.ParentCatID)].(map[string]interface{})["category_id"], - "name": utils.FilterMb4(storeSku.CatName), - "shop_custom_id": utils.Int2Str(storeSku.CatID), - "rank": storeSku.CatLevel + 1, // 饿百是从1开始 - } + } + if err = p.syncOneStoreCategoriesFromLocal2Remote(db, storeID, userName); err != nil { + return err + } + if err = dao.GetRows(db, &storeSkuInfoList, sql, sqlParams...); err == nil { + task := tasksch.RunTask("syncOneStoreSkus skus", false, nil, 0, 1, userName, func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + storeSku := batchItemList[0].(*tStoreSkuFullInfo) + updateFields := []string{model.FieldEbaiSyncStatus} + if storeSku.EbaiSyncStatus&model.SyncFlagDeletedMask != 0 { + err = api.EbaiAPI.SkuDelete(strStoreID, utils.Int64ToStr(storeSku.EbaiID)) + } else if storeSku.EbaiSyncStatus&model.SyncFlagNewMask != 0 { + // globals.SugarLogger.Debug(utils.Format4Output(genSkuParamsFromStoreSkuInfo(storeSku), false)) + if storeSku.EbaiID, err = api.EbaiAPI.SkuCreate(strStoreID, storeSku.SkuID, genSkuParamsFromStoreSkuInfo(storeSku)); err == nil { + // todo 创建SKU后马上绑定分类,会失败,待解决 + err = api.EbaiAPI.SkuShopCategoryMap(strStoreID, storeSku.EbaiID, utils.Int64ToStr(storeSku.CatEbaiID)) + updateFields = append(updateFields, model.FieldEbaiID) } + } else if storeSku.EbaiSyncStatus&model.SyncFlagModifiedMask != 0 { + _, err = api.EbaiAPI.SkuUpdate(strStoreID, storeSku.EbaiID, genSkuParamsFromStoreSkuInfo(storeSku)) } - } - level2CatList := utils.MapKV2List(level1CatList2Add) - task = tasksch.RunTask("syncOneStoreSkus level2 cat", false, nil, 0, 1, userName, func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - cat := batchItemList[0].(map[string]interface{}) - ebaiCatID, err2 := api.EbaiAPI.ShopCategoryCreate(strStoreID, 0, cat["name"].(string), cat["rank"].(int), cat["shop_custom_id"].(string)) - if err = err2; err == nil { - cat["category_id"] = ebaiCatID - return nil, nil + if err == nil { + storeSku.EbaiSyncStatus = 0 + _, err = dao.UpdateEntity(nil, &storeSku.StoreSkuBind, updateFields...) } return nil, err - }, level2CatList) - if _, err = task.GetResult(0); err == nil { - task = tasksch.RunTask("syncOneStoreSkus skus", false, nil, 0, 1, userName, func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeSku := batchItemList[0].(*tStoreSkuFullInfo) - if storeSku.ParentCatEbaiID == 0 { - storeSku.ParentCatEbaiID = level1CatList2Add[utils.Int2Str(storeSku.ParentCatID)].(map[string]interface{})["category_id"].(int64) - } - if storeSku.CatEbaiID == 0 { - storeSku.CatEbaiID = level1CatList2Add[utils.Int2Str(storeSku.CatID)].(map[string]interface{})["category_id"].(int64) - } - updateFields := []string{model.FieldEbaiSyncStatus} - if storeSku.EbaiSyncStatus&model.SyncFlagDeletedMask != 0 { - err = api.EbaiAPI.SkuDelete(strStoreID, utils.Int64ToStr(storeSku.EbaiID)) - } else if storeSku.EbaiSyncStatus&model.SyncFlagNewMask != 0 { - storeSku.EbaiID, err = api.EbaiAPI.SkuCreate(strStoreID, storeSku.SkuID, genSkuParamsFromStoreSkuInfo(storeSku)) - updateFields = append(updateFields, model.FieldEbaiID) - } else if storeSku.EbaiSyncStatus&model.SyncFlagModifiedMask != 0 { - _, err = api.EbaiAPI.SkuUpdate(strStoreID, genSkuParamsFromStoreSkuInfo(storeSku)) - } - if err == nil { - _, err = dao.UpdateEntity(nil, &storeSku.StoreSkuBind, updateFields...) - } - return nil, err - }, storeSkuInfoList) - _, err = task.GetResult(0) - } + }, storeSkuInfoList) + _, err = task.GetResult(0) } } return err @@ -189,33 +173,103 @@ func (p *PurchaseHandler) SyncStoreCategories(db *dao.DaoDB, storeIDs []int, cat // JOIN sku t2 ON t1.sku_id = t2.skuIDs // JOIN sku_name t3 ON t2.name_id = t3.id // JOIN sku_category t4 ON t3.category_id = t4.id - // LEFT JOIN store_sku_category_map t5 ON t5.store_id = t1.store_id AND t5.sku_category_id = t4.id + // LEFT JOIN store_sku_category_map t5 ON t5.store_id = t1.store_id AND t5.category_id = t4.id // WHERE t1.store_id = ? AND (t1.ebai_sync_status <> 0 // ` return err } -func (p *PurchaseHandler) syncOneStoreCategory(db *dao.DaoDB, storeIDs []int, catIDs []int) (err error) { - return err -} - func (p *PurchaseHandler) ReadStoreCategories(storeID int) (cats []*model.SkuCategory, err error) { - return cats, err + return nil, err } func (p *PurchaseHandler) ReadStoreSku(storeID, skuID int) (skuNameExt *model.SkuNameExt, err error) { return skuNameExt, err } +func (p *PurchaseHandler) GetAllRemoteSkus(storeID int) (skus []map[string]interface{}, err error) { + page1, err := api.EbaiAPI.SkuList(utils.Int2Str(storeID), utils.Params2Map("pagesize", MaxPageSize)) + skus = append(skus, page1.List...) + if err == nil { + if page1.Pages > 1 { + pages := make([]int, page1.Pages-1) + for i := 2; i <= page1.Pages; i++ { + pages[i-2] = i + } + task := tasksch.RunTask("GetAllRemoteSkus", false, nil, 0, 1, "", func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + callParams := map[string]interface{}{ + "pagesize": MaxPageSize, + "page": batchItemList[0], + } + pageSku, err2 := api.EbaiAPI.SkuList(utils.Int2Str(storeID), callParams) + if err2 == nil { + return pageSku.List, err2 + } + globals.SugarLogger.Debug(utils.Format4Output(callParams, false)) + return nil, err2 + }, pages) + result, err2 := task.GetResult(0) + if err = err2; err == nil { + for _, v := range result { + skus = append(skus, v.(map[string]interface{})) + } + } + } + } + return skus, err +} + +func (p *PurchaseHandler) DeleteRemoteSkus(storeID int, vendorSkuIDs []string) (err error) { + if vendorSkuIDs == nil { + result, err2 := p.GetAllRemoteSkus(storeID) + if err = err2; err == nil { + vendorSkuIDs = make([]string, len(result)) + for k, v := range result { + vendorSkuIDs[k] = utils.Interface2String(v["sku_id"]) + } + } + } + task := tasksch.RunTask("DeleteRemoteSkus", false, nil, 0, 100, "", func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + strList := make([]string, len(batchItemList)) + for k, v := range batchItemList { + strList[k] = v.(string) + } + return nil, api.EbaiAPI.SkuDelete(utils.Int2Str(storeID), strings.Join(strList, ",")) + }, vendorSkuIDs) + _, err = task.GetResult(0) + return err +} + +func (p *PurchaseHandler) DeleteRemoteCategories(storeID int, vendorCatIDs []int64) (err error) { + strStoreID := utils.Int2Str(storeID) + if vendorCatIDs == nil { + result, err2 := api.EbaiAPI.ShopCategoryGet(strStoreID) + if err = err2; err == nil { + vendorCatIDs = make([]int64, len(result)) + for k, v := range result { + vendorCatIDs[k] = v.CategoryID + } + } + } + task := tasksch.RunTask("DeleteRemoteCategories", false, nil, 0, 1, "", func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + return nil, api.EbaiAPI.ShopCategoryDelete(strStoreID, batchItemList[0].(int64)) + }, vendorCatIDs) + _, err = task.GetResult(0) + return err +} + +/////////// func genSkuParamsFromStoreSkuInfo(storeSku *tStoreSkuFullInfo) map[string]interface{} { return map[string]interface{}{ - "name": jxutils.ComposeSkuName(storeSku.Prefix, storeSku.Name, storeSku.Comment, storeSku.Unit, storeSku.SpecQuality, storeSku.SpecUnit, 0), - "status": jxSkuStatus2Ebai(jxutils.MergeSkuStatus(storeSku.SkuStatus, storeSku.Status)), - "left_num": ebaiapi.MaxLeftNum, - "sale_price": storeSku.Price, - "cat1": getEbaiCat(storeSku.EbaiCat1ID, 1), - "cat2": getEbaiCat(storeSku.EbaiCat2ID, 2), - "cat3": getEbaiCat(storeSku.EbaiCat3ID, 3), + "name": jxutils.ComposeSkuName(storeSku.Prefix, storeSku.Name, storeSku.Comment, storeSku.Unit, storeSku.SpecQuality, storeSku.SpecUnit, 0), + "status": jxSkuStatus2Ebai(jxutils.MergeSkuStatus(storeSku.SkuStatus, storeSku.Status)), + "left_num": ebaiapi.MaxLeftNum, + "sale_price": storeSku.Price, + "market_price": storeSku.Price, + "cat1_id": getEbaiCat(storeSku.EbaiCat1ID, 1), + "cat2_id": getEbaiCat(storeSku.EbaiCat2ID, 2), + "cat3_id": getEbaiCat(storeSku.EbaiCat3ID, 3), + "weight": storeSku.Weight, "photos": []map[string]interface{}{ map[string]interface{}{ "is_master": true, @@ -232,9 +286,112 @@ func jxSkuStatus2Ebai(status int) int { return ebaiapi.SkuStatusOnline } -func getEbaiCat(catID string, level int) string { - if catID == "" { +func getEbaiCat(catID int64, level int) int64 { + if catID == 0 { return defCatMap[level] } return catID } + +// 从饿百同步分类信息到本地 +func (p *PurchaseHandler) syncOneStoreCategoriesFromRemote2Local(db *dao.DaoDB, storeID int, userName string) (err error) { + sql := ` + SELECT t2.*, t1.id cat_id, t1.name, t1.parent_id, t1.level, t1.type, t1.seq + FROM sku_category t1 + LEFT JOIN store_sku_category_map t2 ON t1.id = t2.category_id AND t2.store_id = ? AND (t2.deleted_at = ?) + WHERE t1.deleted_at = ? + ORDER BY t1.level + ` + var catList []*tStoreCatInfo + if err = dao.GetRows(db, &catList, sql, storeID, utils.DefaultTimeValue, utils.DefaultTimeValue); err == nil { + cat1Map := map[string]*tStoreCatInfo{} + for _, v := range catList { + v.Name = utils.FilterMb4(v.Name) + if v.Level == 1 { + cat1 := cat1Map[v.Name] + if cat1 == nil { + cat1Map[v.Name] = v + cat1Map[utils.Int2Str(v.CatID)] = v + v.Children = make(map[string]*tStoreCatInfo) + } + } else { + cat1 := cat1Map[utils.Int2Str(v.ParentID)] + if cat1 == nil { + panic(fmt.Sprintf("can not find category, id:%d", v.ParentID)) + } + cat1.Children[v.Name] = v + } + } + if result, err := api.EbaiAPI.ShopCategoryGet(utils.Int2Str(storeID)); err == nil { + for _, v := range result { + jxCat := cat1Map[v.Name] + if jxCat == nil { // 远程有,本地没有,非法类别 + + } else { + if jxCat.EbaiID != v.CategoryID || utils.Int2Str(jxCat.CatID) != v.ShopCustomID { + if jxCat.ID == 0 { // 远程有,本门店没有 + globals.SugarLogger.Debug(jxCat.CatID) + err = dao.AddStoreCategoryMap(db, storeID, jxCat.CatID, model.VendorIDEBAI, utils.Int64ToStr(v.CategoryID), model.SyncFlagModifiedMask, userName) + } else { // 远程有,本门店有,但ID信息不一致 + err = dao.AddStoreCategoryMap(db, storeID, jxCat.CatID, model.VendorIDEBAI, utils.Int64ToStr(v.CategoryID), model.SyncFlagModifiedMask, userName) + } + } else { // 两边都有,且信息一致 + + } + } + if err != nil { + return err + } + } + } + } + return err +} + +// 从本地同步分类信息到饿百 +// 测试过程中出现过,父分类创建成功后马上创建子分类会报没有父分类错 +func (p *PurchaseHandler) syncOneStoreCategoriesFromLocal2Remote(db *dao.DaoDB, storeID int, userName string) (err error) { + for level := 1; level <= 2; level++ { + sql := ` + SELECT t2.*, t1.name, t1.parent_id, t1.level, t1.type, t1.seq, t2p.ebai_id parent_ebai_id + FROM sku_category t1 + LEFT JOIN sku_category t1p ON t1.parent_id = t1p.id + JOIN store_sku_category_map t2 ON t1.id = t2.category_id AND t2.store_id = ? AND t2.ebai_sync_status <> 0 + LEFT JOIN store_sku_category_map t2p ON t1p.id = t2p.category_id AND t2p.store_id = ? + WHERE t1.level = ? + ` + var catList []*tStoreCatInfo + sqlParams := []interface{}{ + storeID, + storeID, + level, + } + if err = dao.GetRows(db, &catList, sql, sqlParams...); err == nil { + strStoreID := utils.Int2Str(storeID) + task := tasksch.RunTask("syncOneStoreCategoriesFromLocal2Remote", false, nil, 0, 1, userName, func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + updateFields := []string{model.FieldEbaiSyncStatus} + catInfo := batchItemList[0].(*tStoreCatInfo) + // globals.SugarLogger.Debug(utils.Format4Output(catInfo, false)) + db2 := dao.GetDB() + if catInfo.EbaiSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除 + err = api.EbaiAPI.ShopCategoryDelete(strStoreID, catInfo.EbaiID) + } else if catInfo.EbaiSyncStatus&model.SyncFlagNewMask != 0 { // 新增 + ebaiID, err2 := api.EbaiAPI.ShopCategoryCreate(strStoreID, catInfo.ParentEbaiID, utils.FilterMb4(catInfo.Name), int(catInfo.Seq+1), utils.Int2Str(catInfo.ID)) + if err = err2; err == nil { + catInfo.EbaiID = ebaiID + updateFields = append(updateFields, model.FieldEbaiID) + } + } else if catInfo.EbaiSyncStatus&model.SyncFlagModifiedMask != 0 { // 修改 + err = api.EbaiAPI.ShopCategoryUpdate(strStoreID, catInfo.EbaiID, utils.FilterMb4(catInfo.Name), int(catInfo.Seq+1), utils.Int2Str(catInfo.ID)) + } + if err == nil { + catInfo.EbaiSyncStatus = 0 + _, err = dao.UpdateEntity(db2, &catInfo.StoreSkuCategoryMap, updateFields...) + } + return nil, err + }, catList) + _, err = task.GetResult(0) + } + } + return err +} diff --git a/business/partner/purchase/ebai/store_sku_test.go b/business/partner/purchase/ebai/store_sku_test.go new file mode 100644 index 000000000..07a6b5bf5 --- /dev/null +++ b/business/partner/purchase/ebai/store_sku_test.go @@ -0,0 +1,55 @@ +package ebai + +import ( + "testing" + + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/model/dao" +) + +func TestSyncStoreSkus(t *testing.T) { + db := dao.GetDB() + err := new(PurchaseHandler).SyncStoreSkus(db, []int{100077}, []int{7}, false, "autotest") + if err != nil { + t.Fatal(err.Error()) + } +} + +func TestSyncOneStoreCategoriesFromRemote2Local(t *testing.T) { + db := dao.GetDB() + err := new(PurchaseHandler).syncOneStoreCategoriesFromRemote2Local(db, 100077, "autotest") + if err != nil { + t.Fatal(err.Error()) + } +} + +func TestSyncOneStoreCategoriesFromLocal2Remote(t *testing.T) { + db := dao.GetDB() + err := new(PurchaseHandler).syncOneStoreCategoriesFromLocal2Remote(db, 100077, "autotest") + if err != nil { + t.Fatal(err.Error()) + } +} + +func TestGetAllRemoteSkus(t *testing.T) { + result, err := new(PurchaseHandler).GetAllRemoteSkus(100077) + if err != nil { + t.Fatal(err.Error()) + } else { + t.Log(utils.Format4Output(result, false)) + } +} + +func TestDeleteRemoteSkus(t *testing.T) { + err := new(PurchaseHandler).DeleteRemoteSkus(100077, nil) + if err != nil { + t.Fatal(err.Error()) + } +} + +func TestDeleteRemoteCategories(t *testing.T) { + err := new(PurchaseHandler).DeleteRemoteCategories(100077, nil) + if err != nil { + t.Fatal(err.Error()) + } +}