- jd.FullSyncStoreSkus
- refactor mtwm.SyncLocalStoreCategory
This commit is contained in:
@@ -89,6 +89,9 @@ type IPurchasePlatformHandler interface {
|
||||
SyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error)
|
||||
RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error)
|
||||
|
||||
// !!!注意,此操作会先清除门店已有的商品,一般用于初始化,小心使用
|
||||
FullSyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error)
|
||||
|
||||
GetVendorID() int
|
||||
}
|
||||
|
||||
@@ -114,13 +117,8 @@ type IMultipleStoresHandler interface {
|
||||
type ISingleStoreHandler interface {
|
||||
IPurchasePlatformHandler
|
||||
SyncStoreCategory(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync bool) (hint string, err error)
|
||||
ReadStoreCategories(storeID int) (cats []*model.SkuCategory, err error)
|
||||
|
||||
ReadStoreSku(storeID, skuID int) (skuNameExt *model.SkuNameExt, err error)
|
||||
RefreshStoresAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool, storeIDs []int) (hint string, err error)
|
||||
|
||||
// !!!注意,此操作会先清除门店已有的商品,一般用于初始化,小心使用
|
||||
FullSyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error)
|
||||
}
|
||||
|
||||
type IDeliveryPlatformHandler interface {
|
||||
|
||||
@@ -243,14 +243,6 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
||||
return rootTask.ID, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) ReadStoreCategories(storeID int) (cats []*model.SkuCategory, err error) {
|
||||
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))
|
||||
if err == nil {
|
||||
|
||||
@@ -3,19 +3,11 @@ package elm
|
||||
import (
|
||||
"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"
|
||||
)
|
||||
|
||||
func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync bool) (hint string, err error) {
|
||||
return "", nil
|
||||
}
|
||||
func (p *PurchaseHandler) ReadStoreCategories(storeID int) (cats []*model.SkuCategory, err error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) ReadStoreSku(storeID, skuID int) (skuNameExt *model.SkuNameExt, err error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
return hint, err
|
||||
|
||||
@@ -132,3 +132,111 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
||||
}
|
||||
return task.ID, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
globals.SugarLogger.Debugf("jd FullSyncStoreSkus, storeID:%d", storeID)
|
||||
db := dao.GetDB()
|
||||
_, err = dao.SetStoreSkuSyncStatus(ctx, db, model.VendorIDJD, storeID, nil, model.SyncFlagModifiedMask|model.SyncFlagPriceMask|model.SyncFlagSaleMask)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
skus, err := dao.GetFullStoreSkus(db, model.VendorIDJD, storeID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return p.syncStoreSkus(ctx, parentTask, db, storeID, skus, isAsync, isContinueWhenError)
|
||||
}
|
||||
|
||||
// todo 之后应该与SyncStoreSkus合并
|
||||
func (p *PurchaseHandler) syncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, db *dao.DaoDB, storeID int, skus []*dao.StoreSkuSyncInfo, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
globals.SugarLogger.Debugf("jd syncStoreSkus, storeID:%d, len(skus):%d", storeID, len(skus))
|
||||
if len(skus) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJD)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
stationNo := storeDetail.VendorStoreID
|
||||
task := tasksch.NewParallelTask("SyncStoresSkus京东", tasksch.NewParallelConfig().SetBatchSize(jdapi.MaxStoreSkuBatchSize).SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
var skuPriceInfoList []*jdapi.SkuPriceInfo
|
||||
var skuVendibilityList []*jdapi.StockVendibility
|
||||
var skuStockList []*jdapi.SkuStock
|
||||
var batchSkuIDs []int
|
||||
for _, v := range batchItemList {
|
||||
storeSku := v.(*dao.StoreSkuSyncInfo)
|
||||
alreadyAddStock := false
|
||||
if storeSku.SkuSyncStatus&model.SyncFlagChangedMask != 0 || storeSku.BindID == 0 {
|
||||
if storeSku.BindID != 0 {
|
||||
batchSkuIDs = append(batchSkuIDs, storeSku.BindID)
|
||||
}
|
||||
if storeSku.SkuSyncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask) != 0 || storeSku.BindID == 0 { // 关注或取消关注
|
||||
stock := &jdapi.SkuStock{
|
||||
OutSkuId: utils.Int2Str(storeSku.ID),
|
||||
StockQty: model.MaxStoreSkuStockQty,
|
||||
}
|
||||
if storeSku.DeletedAt != utils.DefaultTimeValue || storeSku.BindID == 0 {
|
||||
stock.StockQty = 0
|
||||
} else {
|
||||
alreadyAddStock = true
|
||||
}
|
||||
if stock.StockQty != 0 || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) {
|
||||
skuStockList = append(skuStockList, stock)
|
||||
}
|
||||
}
|
||||
if storeSku.SkuSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 {
|
||||
skuPriceInfoList = append(skuPriceInfoList, &jdapi.SkuPriceInfo{
|
||||
OutSkuId: utils.Int2Str(storeSku.ID),
|
||||
Price: jxutils.CaculateSkuVendorPrice(int(storeSku.Price), int(storeDetail.PricePercentage)),
|
||||
})
|
||||
}
|
||||
if storeSku.SkuSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 {
|
||||
vendibility := &jdapi.StockVendibility{
|
||||
OutSkuId: utils.Int2Str(storeSku.ID),
|
||||
DoSale: true,
|
||||
}
|
||||
if storeSku.Status != model.StoreSkuBindStatusNormal {
|
||||
vendibility.DoSale = false
|
||||
} else if !alreadyAddStock { // 如果是设置可售则自动将库存加满
|
||||
stock := &jdapi.SkuStock{
|
||||
OutSkuId: utils.Int2Str(storeSku.ID),
|
||||
StockQty: model.MaxStoreSkuStockQty,
|
||||
}
|
||||
skuStockList = append(skuStockList, stock)
|
||||
}
|
||||
if vendibility.DoSale || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) {
|
||||
skuVendibilityList = append(skuVendibilityList, vendibility)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// globals.SugarLogger.Debug(utils.Format4Output(skuVendibilityList, false), utils.Format4Output(skuPriceInfoList, false), utils.Format4Output(skuStockList, false))
|
||||
if globals.EnableStoreWrite {
|
||||
// todo 以下可以优化为并行操作
|
||||
if len(skuVendibilityList) > 0 {
|
||||
_, err = api.JdAPI.BatchUpdateVendibility("", stationNo, skuVendibilityList, ctx.GetUserName())
|
||||
}
|
||||
if err == nil && len(skuPriceInfoList) > 0 {
|
||||
_, err = api.JdAPI.UpdateVendorStationPrice("", stationNo, skuPriceInfoList)
|
||||
}
|
||||
if err == nil && len(skuStockList) > 0 {
|
||||
_, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, skuStockList, ctx.GetUserName())
|
||||
}
|
||||
}
|
||||
if err == nil && len(batchSkuIDs) > 0 {
|
||||
db := dao.GetDB() // 多线程问题
|
||||
sql := `
|
||||
UPDATE store_sku_bind t1
|
||||
SET t1.jd_sync_status = 0
|
||||
WHERE t1.id IN (` + dao.GenQuestionMarks(len(batchSkuIDs)) + ")"
|
||||
_, err = dao.ExecuteSQL(db, sql, batchSkuIDs)
|
||||
}
|
||||
return nil, err
|
||||
}, skus)
|
||||
ctx.SetTaskOrAddChild(task, parentTask)
|
||||
task.Run()
|
||||
if !isAsync {
|
||||
_, err = task.GetResult(0)
|
||||
}
|
||||
return task.ID, err
|
||||
}
|
||||
|
||||
@@ -86,10 +86,6 @@ func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask t
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) ReadStoreCategories(storeID int) (cats []*model.SkuCategory, err error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// 此函数根据门店商品信息重建分类信息
|
||||
// 远程有,本地无, --> 删除远程
|
||||
// 远程有,本地有,映射无, --> 添加关联
|
||||
@@ -110,17 +106,10 @@ func (p *PurchaseHandler) SyncLocalStoreCategory(ctx *jxcontext.Context, db *dao
|
||||
return "", err
|
||||
}
|
||||
for _, cat := range localCats {
|
||||
catID := cat.VendorCatID
|
||||
if catID == "" {
|
||||
catID = cat.Name
|
||||
}
|
||||
parentCatID := cat.ParentVendorCatID
|
||||
if parentCatID == "" {
|
||||
parentCatID = cat.ParentCatName
|
||||
}
|
||||
catMap[i][parentCatID+"/"+catID] = cat
|
||||
catMap[i][cat.ParentCatName+"/"+cat.Name] = cat
|
||||
}
|
||||
}
|
||||
identityCatMap := make(map[int]int) // 这里面表示远程有,本地有,且完全相同,可擦掉本地的修改标记
|
||||
if isCheckRemote {
|
||||
strStoreID := utils.Int2Str(storeID)
|
||||
remoteCats, err := api.MtwmAPI.RetailCatList(utils.Int2Str(storeID))
|
||||
@@ -141,7 +130,7 @@ func (p *PurchaseHandler) SyncLocalStoreCategory(ctx *jxcontext.Context, db *dao
|
||||
if localCat.MapID == 0 { // 本地映射没有
|
||||
localCat.MapID = -1 // 表示远程有同名的
|
||||
} else { // 本地映射有
|
||||
localCat.MapID = -2 // 表示不处理
|
||||
identityCatMap[localCat.MapID] = 1
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -174,13 +163,24 @@ func (p *PurchaseHandler) SyncLocalStoreCategory(ctx *jxcontext.Context, db *dao
|
||||
if err = dao.CreateEntity(db, catMap); err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else if v.MapID != -2 {
|
||||
} else if isCheckRemote {
|
||||
catMap := &model.StoreSkuCategoryMap{
|
||||
MtwmSyncStatus: model.SyncFlagNewMask,
|
||||
}
|
||||
updateFields := []string{
|
||||
model.FieldUpdatedAt,
|
||||
model.FieldLastOperator,
|
||||
model.FieldMtwmSyncStatus,
|
||||
}
|
||||
if identityCatMap[v.MapID] == 1 { // 如果一样,则要刷新ID(对于MTWM其实就是名字)
|
||||
catMap.MtwmID = v.Name
|
||||
catMap.MtwmSyncStatus = 0
|
||||
updateFields = append(updateFields, model.FieldMtwmID)
|
||||
}
|
||||
catMap.ID = v.MapID
|
||||
num++
|
||||
if _, err = dao.UpdateEntity(db, catMap, "MtwmSyncStatus"); err != nil {
|
||||
dao.WrapUpdateULEntity(catMap, ctx.GetUserName())
|
||||
if _, err = dao.UpdateEntity(db, catMap, updateFields...); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
@@ -201,10 +201,6 @@ func TranverseRemoteCatList(parentCatName string, remoteCats []*mtwmapi.RetailCa
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) ReadStoreSku(storeID, skuID int) (skuNameExt *model.SkuNameExt, err error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// hint,如果是异步,返回的是任务ID,如果是同步,返回是本次需要同步的目录数
|
||||
func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
db := dao.GetDB()
|
||||
@@ -224,8 +220,14 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
||||
if hint != "0" {
|
||||
return "", errors.New("同步门店商品所需目录失败")
|
||||
}
|
||||
|
||||
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDMTWM)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
skus, err := dao.GetStoreSkus(db, model.VendorIDMTWM, storeID, skuIDs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// globals.SugarLogger.Debug(utils.Format4Output(skus, false))
|
||||
strStoreID := utils.Int2Str(storeID)
|
||||
rootTask := tasksch.NewParallelTask("美团外卖SyncStoreSkus", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(rootTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
@@ -241,7 +243,7 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
||||
foodData[mtwmapi.KeyAppFoodCode] = utils.Int2Str(skuItem.ID)
|
||||
foodData["name"] = jxutils.ComposeSkuName(skuItem.Prefix, skuItem.Name, skuItem.Comment, skuItem.Unit, skuItem.SpecQuality, skuItem.SpecUnit, 30)
|
||||
foodData["description"] = skuItem.Comment
|
||||
foodData["price"] = jxutils.IntPrice2Standard(skuItem.Price)
|
||||
foodData["price"] = jxutils.CaculateSkuVendorPrice(int(skuItem.Price), int(storeDetail.PricePercentage))
|
||||
foodData["min_order_count"] = 1
|
||||
foodData["unit"] = skuItem.Unit
|
||||
foodData["box_num"] = 0
|
||||
@@ -307,7 +309,7 @@ func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask t
|
||||
case 3:
|
||||
_, err = p.SyncStoreCategory(ctx, rootTask, storeID, false)
|
||||
case 4:
|
||||
_, err = p.SyncStoreSkus(ctx, rootTask, storeID, nil, true, isContinueWhenError)
|
||||
// _, err = p.SyncStoreSkus(ctx, rootTask, storeID, nil, true, isContinueWhenError)
|
||||
}
|
||||
return nil, err
|
||||
}, 5)
|
||||
|
||||
Reference in New Issue
Block a user