- PruneMissingStoreSkus也会删除本地不存在的远程分类
This commit is contained in:
@@ -61,7 +61,7 @@ func SyncStorCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendor
|
|||||||
rootTask := tasksch.NewSeqTask(fmt.Sprintf("%s SyncStoreCategory step1", model.VendorChineseNames[vendorID]), ctx,
|
rootTask := tasksch.NewSeqTask(fmt.Sprintf("%s SyncStoreCategory step1", model.VendorChineseNames[vendorID]), ctx,
|
||||||
func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
level := step + 1
|
level := step + 1
|
||||||
catList, err := dao.GetStoreCategories(db, vendorID, storeID, level)
|
catList, err := dao.GetDirtyStoreCategories(db, vendorID, storeID, level)
|
||||||
if len(catList) > 0 {
|
if len(catList) > 0 {
|
||||||
num += len(catList)
|
num += len(catList)
|
||||||
task := tasksch.NewParallelTask(fmt.Sprintf("%s SyncStoreCategory step2, level=%d", model.VendorChineseNames[vendorID], level),
|
task := tasksch.NewParallelTask(fmt.Sprintf("%s SyncStoreCategory step2, level=%d", model.VendorChineseNames[vendorID], level),
|
||||||
@@ -546,26 +546,39 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除京西没有,平台有的商品
|
func checkRemoteCatExist(localCatMap map[string]*dao.SkuStoreCatInfo, catList []*partner.BareCategoryInfo) (cat2Delete []*partner.BareCategoryInfo) {
|
||||||
|
for _, v := range catList {
|
||||||
|
if localCatMap[v.VendorCatID] == nil {
|
||||||
|
cat2Delete = append(cat2Delete, v)
|
||||||
|
}
|
||||||
|
cat2Delete = append(cat2Delete, checkRemoteCatExist(localCatMap, v.Children)...)
|
||||||
|
}
|
||||||
|
return cat2Delete
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除京西没有,平台有的商品与商家分类
|
||||||
func PruneMissingStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func PruneMissingStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler)
|
handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler)
|
||||||
if handler == nil {
|
if handler == nil {
|
||||||
return "", fmt.Errorf("平台:%s不支持此操作", model.VendorChineseNames[vendorID])
|
return "", fmt.Errorf("平台:%s不支持此操作", model.VendorChineseNames[vendorID])
|
||||||
}
|
}
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
localSkuList, err := dao.GetStoreSkus2(db, vendorID, storeID, nil, false)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
localSkuMap := make(map[int]*dao.StoreSkuSyncInfo)
|
|
||||||
for _, v := range localSkuList {
|
|
||||||
localSkuMap[v.SkuID] = v
|
|
||||||
}
|
|
||||||
var sku2Delete []*partner.StoreSkuInfo
|
var sku2Delete []*partner.StoreSkuInfo
|
||||||
|
var cat2Delete []*partner.BareCategoryInfo
|
||||||
task := tasksch.NewSeqTask(fmt.Sprintf("清除平台:%s上多余的门店商品", model.VendorChineseNames[vendorID]), ctx,
|
task := tasksch.NewSeqTask(fmt.Sprintf("清除平台:%s上多余的门店商品", model.VendorChineseNames[vendorID]), ctx,
|
||||||
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
switch step {
|
switch step {
|
||||||
case 0:
|
case 0:
|
||||||
|
localSkuList, err := dao.GetStoreSkus2(db, vendorID, storeID, nil, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
localSkuMap := make(map[int]*dao.StoreSkuSyncInfo)
|
||||||
|
for _, v := range localSkuList {
|
||||||
|
localSkuMap[v.SkuID] = v
|
||||||
|
}
|
||||||
|
|
||||||
remoteSkuList, err2 := handler.GetStoreSkusFullInfo(ctx, task, storeID, vendorStoreID, nil)
|
remoteSkuList, err2 := handler.GetStoreSkusFullInfo(ctx, task, storeID, vendorStoreID, nil)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
for _, v := range remoteSkuList {
|
for _, v := range remoteSkuList {
|
||||||
@@ -577,7 +590,6 @@ func PruneMissingStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, ven
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
localSkuMap = nil
|
|
||||||
case 1:
|
case 1:
|
||||||
if len(sku2Delete) > 0 {
|
if len(sku2Delete) > 0 {
|
||||||
_, err = putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
|
_, err = putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
|
||||||
@@ -585,9 +597,47 @@ func PruneMissingStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, ven
|
|||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}, ctx, parentTask, sku2Delete, handler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus), isContinueWhenError)
|
}, ctx, parentTask, sku2Delete, handler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus), isContinueWhenError)
|
||||||
}
|
}
|
||||||
|
sku2Delete = nil
|
||||||
|
case 2:
|
||||||
|
localCatList, err := dao.GetStoreCategories(db, vendorID, storeID, 0, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
localCatMap := make(map[string]*dao.SkuStoreCatInfo)
|
||||||
|
for _, v := range localCatList {
|
||||||
|
localCatMap[v.VendorCatID] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteCatList, err2 := handler.GetStoreAllCategories(ctx, storeID, vendorStoreID)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
cat2Delete = checkRemoteCatExist(localCatMap, remoteCatList)
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
if len(cat2Delete) > 0 {
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
level := 2 - i
|
||||||
|
var levelCat2Delete []*partner.BareCategoryInfo
|
||||||
|
for _, v := range cat2Delete {
|
||||||
|
if v.Level == level {
|
||||||
|
levelCat2Delete = append(levelCat2Delete, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(levelCat2Delete) > 0 {
|
||||||
|
task4Delete := tasksch.NewParallelTask(fmt.Sprintf("删除本地不存在的远程分类,level:%d", level), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
cat := batchItemList[0].(*partner.BareCategoryInfo)
|
||||||
|
err = handler.DeleteStoreCategory(ctx, storeID, vendorStoreID, cat.VendorCatID)
|
||||||
|
return nil, err
|
||||||
|
}, levelCat2Delete)
|
||||||
|
tasksch.HandleTask(task4Delete, task, true).Run()
|
||||||
|
_, err = task4Delete.GetResult(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cat2Delete = nil
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}, 2)
|
}, 4)
|
||||||
tasksch.HandleTask(task, parentTask, true).Run()
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
if isAsync {
|
if isAsync {
|
||||||
hint = task.GetID()
|
hint = task.GetID()
|
||||||
|
|||||||
@@ -1 +1,32 @@
|
|||||||
package cms
|
package cms
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"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/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner/putils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFreeBatchStoreSkuInfo(t *testing.T) {
|
||||||
|
var sku2Delete []*partner.StoreSkuInfo
|
||||||
|
for i := 0; i < 123; i++ {
|
||||||
|
sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{
|
||||||
|
SkuID: i + 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := jxcontext.AdminCtx
|
||||||
|
var parentTask tasksch.ITask
|
||||||
|
isContinueWhenError := true
|
||||||
|
handler, _ := partner.GetPurchasePlatformFromVendorID(model.VendorIDEBAI).(partner.ISingleStoreStoreSkuHandler)
|
||||||
|
_, err := putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
|
||||||
|
t.Log(len(batchedStoreSkuList))
|
||||||
|
return nil, 0, err
|
||||||
|
}, ctx, parentTask, sku2Delete, handler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus), isContinueWhenError)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -156,9 +156,9 @@ func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int
|
|||||||
|
|
||||||
// 单门店模式厂商适用
|
// 单门店模式厂商适用
|
||||||
// 单纯的从已经创建的store_sku_category_map中,得到相关的同步信息
|
// 单纯的从已经创建的store_sku_category_map中,得到相关的同步信息
|
||||||
func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats []*SkuStoreCatInfo, err error) {
|
func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int, isDirty bool) (cats []*SkuStoreCatInfo, err error) {
|
||||||
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
sql := fmt.Sprintf(`
|
sql := `
|
||||||
SELECT t4.*,
|
SELECT t4.*,
|
||||||
t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status store_cat_sync_status,
|
t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status store_cat_sync_status,
|
||||||
t4p.name parent_cat_name,
|
t4p.name parent_cat_name,
|
||||||
@@ -167,14 +167,32 @@ func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats []*Sk
|
|||||||
JOIN sku_category t4 ON t5.category_id = t4.id AND t4.deleted_at = ?
|
JOIN sku_category t4 ON t5.category_id = t4.id AND t4.deleted_at = ?
|
||||||
LEFT JOIN sku_category t4p ON t4.parent_id = t4p.id
|
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 t5.store_id = t5p.store_id AND t5p.deleted_at = ?
|
LEFT JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5.store_id = t5p.store_id AND t5p.deleted_at = ?
|
||||||
WHERE t5.store_id = ? AND t4.level = ? AND t5.%s_sync_status <> 0 AND t5.deleted_at = ?
|
WHERE t5.store_id = ? AND t5.deleted_at = ?`
|
||||||
`, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix)
|
fieldPrefixParams := []interface{}{fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix}
|
||||||
if err = GetRows(db, &cats, sql, utils.DefaultTimeValue, utils.DefaultTimeValue, storeID, level, utils.DefaultTimeValue); err != nil {
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
storeID,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
if isDirty {
|
||||||
|
sql += " AND t5.%s_sync_status <> 0"
|
||||||
|
fieldPrefixParams = append(fieldPrefixParams, fieldPrefix)
|
||||||
|
}
|
||||||
|
if level > 0 {
|
||||||
|
sql += " AND t4.level = ?"
|
||||||
|
sqlParams = append(sqlParams, level)
|
||||||
|
}
|
||||||
|
if err = GetRows(db, &cats, fmt.Sprintf(sql, fieldPrefixParams...), sqlParams...); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return cats, err
|
return cats, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDirtyStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats []*SkuStoreCatInfo, err error) {
|
||||||
|
return GetStoreCategories(db, vendorID, storeID, level, true)
|
||||||
|
}
|
||||||
|
|
||||||
// 以store_sku_bind为基础来做同步,正常情况下使用
|
// 以store_sku_bind为基础来做同步,正常情况下使用
|
||||||
// !!! 此函数不要将store_sku_bind中的vendor_price取出来放到StoreSkuSyncInfo.VendorPrice中,因为之后会依赖这个VendorPrice进行重算
|
// !!! 此函数不要将store_sku_bind中的vendor_price取出来放到StoreSkuSyncInfo.VendorPrice中,因为之后会依赖这个VendorPrice进行重算
|
||||||
// 单多门店模式厂商通用
|
// 单多门店模式厂商通用
|
||||||
|
|||||||
Reference in New Issue
Block a user