From 875959d4b70171fb80e3e1075bb72e02f059abc5 Mon Sep 17 00:00:00 2001 From: gazebo Date: Mon, 26 Nov 2018 17:34:14 +0800 Subject: [PATCH] - mtwm category sync ok. --- business/model/dao/store_sku.go | 22 +- business/partner/purchase/mtwm/store_sku.go | 195 +++++++++++++++--- .../partner/purchase/mtwm/store_sku_test.go | 22 ++ 3 files changed, 199 insertions(+), 40 deletions(-) diff --git a/business/model/dao/store_sku.go b/business/model/dao/store_sku.go index 2cbe936b1..8437e826a 100644 --- a/business/model/dao/store_sku.go +++ b/business/model/dao/store_sku.go @@ -9,12 +9,12 @@ import ( type SkuStoreCatInfo struct { model.SkuCategory - CatID int `orm:"column(cat_id)"` // 这个主要用于判断是否有store_sku_category_map + MapID int `orm:"column(map_id)"` // 这个主要用于判断是否有store_sku_category_map VendorCatID string `orm:"column(vendor_cat_id)"` CatSyncStatus int8 ParentCatName string - ParentCatID int `orm:"column(parent_cat_id)"` // 这个主要用于判断是否有父store_sku_category_map + ParentMapID int `orm:"column(parent_map_id)"` // 这个主要用于判断是否有父store_sku_category_map ParentVendorCatID string `orm:"column(parent_vendor_cat_id)"` ParentCatSyncStatus int8 } @@ -32,19 +32,19 @@ type StoreCatSyncInfo struct { func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int) (cats []*SkuStoreCatInfo, err error) { sql := ` - SELECT DISTINCT t4.*, t5.category_id cat_id, t5.%s_id vendor_cat_id, t5.%s_sync_status cat_sync_status, t4p.name parent_cat_name, t5p.category_id parent_cat_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status + SELECT DISTINCT t4.*, t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status cat_sync_status, t4p.name parent_cat_name, t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status FROM store_sku_bind t1 JOIN sku t2 ON t1.sku_id = t2.id JOIN sku_name t3 ON t2.name_id = t3.id ` if level == 2 { sql += ` - JOIN sku_category t4 ON (t3.category_id = t4.id OR t2.category_id = t4.id) + JOIN sku_category t4 ON (t3.category_id = t4.id OR t2.category_id = t4.id) AND t4.level = 2 ` } else { sql += ` - JOIN sku_category t4c ON (t3.category_id = t4c.id OR t2.category_id = t4c.id) - JOIN sku_category t4 ON t4.id = t4c.parent_id + LEFT JOIN sku_category t4c ON (t3.category_id = t4c.id OR t2.category_id = t4c.id) + JOIN sku_category t4 ON (t4.id = t4c.parent_id OR (t3.category_id = t4.id OR t2.category_id = t4.id)) AND t4.level = 1 ` } sql += ` @@ -54,9 +54,9 @@ func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int WHERE t1.store_id = ? ` sqlParams := []interface{}{ + utils.DefaultTimeValue, + utils.DefaultTimeValue, storeID, - utils.DefaultTimeValue, - utils.DefaultTimeValue, } if len(skuIDs) > 0 { sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" @@ -76,9 +76,9 @@ func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats []*St SELECT t5.*, t4.name cat_name, t4.seq, t4p.name parent_cat_name, t5p.category_id parent_cat_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status FROM store_sku_category_map t5 JOIN sku_category t4 ON t5.category_id = t4.id - JOIN sku_category t4p ON t4.parent_id = t4p.id - JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5p.deleted_at = ? - WHERE t5.store_id = ? AND t5.level = ? AND t5.%s_sync_status <> 0 + LEFT JOIN sku_category t4p ON t4.parent_id = t4p.id + LEFT JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5p.deleted_at = ? + WHERE t5.store_id = ? AND t4.level = ? AND t5.%s_sync_status <> 0 `, filedPrefix, filedPrefix, filedPrefix) if err = GetRows(db, &cats, sql, utils.DefaultTimeValue, storeID, level); err != nil { return nil, err diff --git a/business/partner/purchase/mtwm/store_sku.go b/business/partner/purchase/mtwm/store_sku.go index ea2ce2dc6..2da75b5e3 100644 --- a/business/partner/purchase/mtwm/store_sku.go +++ b/business/partner/purchase/mtwm/store_sku.go @@ -1,6 +1,7 @@ package mtwm import ( + "git.rosy.net.cn/baseapi/platformapi/mtwmapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" @@ -20,6 +21,7 @@ func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask t task := tasksch.NewParallelTask("mtwm SyncStoreCategory2", nil, userName, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { updateFields := []string{dao.GetSyncStatusStructField(model.VendorNames[model.VendorIDMTWM])} catInfo := batchItemList[0].(*dao.StoreCatSyncInfo) + globals.SugarLogger.Debug(globals.EnableStoreWrite, " ", globals.EnableMtwmStoreWrite) if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { if catInfo.MtwmSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除 err = api.MtwmAPI.RetailCatDelete(strStoreID, catInfo.MtwmID) @@ -71,51 +73,109 @@ func (p *PurchaseHandler) ReadStoreCategories(storeID int) (cats []*model.SkuCat return nil, nil } -func (p *PurchaseHandler) SyncLocalStoreCategory(db *dao.DaoDB, storeID int, userName string) (err error) { - remoteCats, err := api.MtwmAPI.RetailCatList(utils.Int2Str(storeID)) - if err == nil { - return err - } +// 此函数根据门店商品信息重建分类信息 +// 远程有,本地无, --> 删除远程 +// 远程有,本地有,映射无, --> 添加关联 +// 远程有,本地有,映射有, --> 不处理 +// 远程无,本地有,映射无, --> 添加本地 +// 远程无,本地有,映射有, --> 同步标记改为新增 +func (p *PurchaseHandler) SyncLocalStoreCategory(ctx *jxcontext.Context, db *dao.DaoDB, storeID int, isCheckRemote, isAsync bool) (hint string, err error) { if db == nil { db = dao.GetDB() } - catMap := make(map[string]*dao.StoreCatSyncInfo) + catMap := make([]map[string]*dao.SkuStoreCatInfo, 2) for i := 0; i < 2; i++ { - localCats, err := dao.GetStoreCategories(db, model.VendorIDMTWM, storeID, i+1) + catMap[i] = make(map[string]*dao.SkuStoreCatInfo) + localCats, err := dao.GetSkusCategories(db, model.VendorIDMTWM, storeID, nil, i+1) + // globals.SugarLogger.Debug(utils.Format4Output(localCats, false)) if err != nil { - return err + return "", err } for _, cat := range localCats { - cat.StoreSkuCategoryMap.MtwmSyncStatus = model.SyncFlagNewMask - catMap[cat.ParentVendorCatID+"/"+cat.MtwmID] = cat - } - } - strStoreID := utils.Int2Str(storeID) - - processRemoteCat := func(catName, parentCatName string) (err error) { - localCat := catMap[parentCatName+"/"+catName] - if localCat == nil { - if err = api.MtwmAPI.RetailCatDelete(strStoreID, catName); err != nil { - return err + catID := cat.VendorCatID + if catID == "" { + catID = cat.Name } - } else { - // localCat.StoreSkuCategoryMap.MtwmSyncStatus = model.SyncFlagModifiedMask + parentCatID := cat.ParentVendorCatID + if parentCatID == "" { + parentCatID = cat.ParentCatName + } + catMap[i][parentCatID+"/"+catID] = cat } - return nil } + if isCheckRemote { + strStoreID := utils.Int2Str(storeID) + remoteCats, err := api.MtwmAPI.RetailCatList(utils.Int2Str(storeID)) + if err != nil { + return "", err + } + if err = TranverseRemoteCatList("", remoteCats, func(level int, parentCatName, catName string) (err error) { + localCat := catMap[level-1][parentCatName+"/"+catName] + // globals.SugarLogger.Debug(parentCatName, " ", catName, " ", localCat) + if localCat == nil { // 本地分类就没有这个名字,直接删除 + globals.SugarLogger.Debug(parentCatName, " ", catName, " ", localCat, strStoreID) + if err = api.MtwmAPI.RetailCatDelete(strStoreID, catName); err != nil { + return err + } + } else { // 本地分类有这个名字 + if localCat.MapID == 0 { // 本地映射没有 + localCat.MapID = -1 // 表示远程有同名的 + } else { // 本地映射有 + localCat.MapID = -2 // 表示不处理 + } + } + return nil + }); err != nil { + return "", err + } + } + dao.Begin(db) + defer func() { + dao.Rollback(db) + }() + for i := 0; i < 2; i++ { + for _, v := range catMap[i] { + if v.MapID == -1 || v.MapID == 0 { // 本地缺失 + mtwmSyncStatus := int8(model.SyncFlagNewMask) + if v.MapID == -1 { // 远程有同名的,只是简单增加一条本地记录关联 + mtwmSyncStatus = 0 + } + catMap := &model.StoreSkuCategoryMap{ + StoreID: storeID, + CategoryID: v.ID, + MtwmID: v.Name, + MtwmSyncStatus: mtwmSyncStatus, + EbaiSyncStatus: model.SyncFlagNewMask, + ElmSyncStatus: model.SyncFlagNewMask, + } + dao.WrapAddIDCULDEntity(catMap, ctx.GetUserName()) + if err = dao.CreateEntity(db, catMap); err != nil { + return "", err + } + } else if v.MapID != -2 { + catMap := &model.StoreSkuCategoryMap{ + MtwmSyncStatus: model.SyncFlagNewMask, + } + catMap.ID = v.MapID + if _, err = dao.UpdateEntity(db, catMap, "MtwmSyncStatus"); err != nil { + return "", err + } + } + } + } + dao.Commit(db) + return "", err +} +func TranverseRemoteCatList(parentCatName string, remoteCats []*mtwmapi.RetailCategoryInfo, handler func(level int, parentCatName, catName string) error) (err error) { for _, remoteCat := range remoteCats { name := utils.Interface2String(remoteCat.Name) - if err = processRemoteCat("", name); err != nil { + TranverseRemoteCatList(name, remoteCat.Children, handler) + if err = handler(remoteCat.Level, parentCatName, name); err != nil { return err } - for _, subRemoteCat := range remoteCat.Children { - if err = processRemoteCat(name, utils.Interface2String(subRemoteCat.Name)); err != nil { - return err - } - } } - return err + return nil } func (p *PurchaseHandler) ReadStoreSku(storeID, skuID int) (skuNameExt *model.SkuNameExt, err error) { @@ -133,3 +193,80 @@ func (p *PurchaseHandler) RefreshStoresAllSkusID(ctx *jxcontext.Context, parentT func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error) { return hint, 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["app_food_code"]) + } + } + } + strStoreID := utils.Int2Str(storeID) + task := tasksch.NewParallelTask("mtwm DeleteRemoteSkus", nil, "", func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { + err = api.MtwmAPI.RetailDelete(strStoreID, batchItemList[0].(string)) + } + return nil, err + }, vendorSkuIDs) + task.Run() + _, err = task.GetResult(0) + return err +} + +func (p *PurchaseHandler) GetAllRemoteSkus(storeID int) (skus []map[string]interface{}, err error) { + strStoreID := utils.Int2Str(storeID) + for { + result, err := api.MtwmAPI.RetailList(strStoreID, len(skus), mtwmapi.GeneralMaxLimit) + if err != nil { + return nil, err + } + skus = append(skus, result...) + if len(result) < mtwmapi.GeneralMaxLimit { + break + } + } + return skus, err +} + +func (p *PurchaseHandler) DeleteRemoteCategories(storeID int, vendorCatIDs []string) (err error) { + strStoreID := utils.Int2Str(storeID) + vendorCatIDs2 := make([]string, 0) + if vendorCatIDs == nil { + result, err := api.MtwmAPI.RetailCatList(strStoreID) + if err != nil { + return err + } + vendorCatIDs = make([]string, len(result)) + for k, v := range result { + vendorCatIDs[k] = v.Name + for _, v2 := range v.Children { + vendorCatIDs2 = append(vendorCatIDs2, v2.Name) + } + } + } + rootTask := tasksch.NewSeqTask("mtwm DeleteRemoteCategories", "", func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + var catIDs []string + if step == 0 { + catIDs = vendorCatIDs2 + } else { + catIDs = vendorCatIDs + } + if len(catIDs) > 0 { + task := tasksch.NewParallelTask("mtwm DeleteRemoteCategories paralle", nil, "", func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { + err = api.MtwmAPI.RetailCatDelete(strStoreID, batchItemList[0].(string)) + } + return nil, err + }, catIDs) + rootTask.AddChild(task).Run() + _, err = task.GetResult(0) + } + return nil, err + }, 2) + rootTask.Run() + _, err = rootTask.GetResult(0) + return err +} diff --git a/business/partner/purchase/mtwm/store_sku_test.go b/business/partner/purchase/mtwm/store_sku_test.go index 2da7b38a4..204874541 100644 --- a/business/partner/purchase/mtwm/store_sku_test.go +++ b/business/partner/purchase/mtwm/store_sku_test.go @@ -15,3 +15,25 @@ func TestSyncStoreCategory(t *testing.T) { } t.Log(utils.Format4Output(store, false)) } + +func TestSyncLocalStoreCategory(t *testing.T) { + store, err := new(PurchaseHandler).SyncLocalStoreCategory(jxcontext.AdminCtx, nil, 100077, true, false) + if err != nil { + t.Fatal(err) + } + t.Log(utils.Format4Output(store, false)) +} + +func TestDeleteRemoteSkus(t *testing.T) { + err := new(PurchaseHandler).DeleteRemoteSkus(100077, nil) + if err != nil { + t.Fatal(err) + } +} + +func TestDeleteRemoteCategories(t *testing.T) { + err := new(PurchaseHandler).DeleteRemoteCategories(100077, nil) + if err != nil { + t.Fatal(err) + } +}