From 25ac631c5c7703b9bc15b2626c1b425de8889834 Mon Sep 17 00:00:00 2001 From: gazebo Date: Fri, 22 Mar 2019 15:04:28 +0800 Subject: [PATCH] - refactor jxcontent and tasksch (remove dependency from jxcontent to tasksch) - send dingding msg to user when async task finished --- business/auth2/auth2.go | 4 + business/jxstore/cms/message.go | 2 +- business/jxstore/cms/store.go | 64 +-- business/jxstore/cms/sync.go | 267 +++++----- business/jxstore/cms/user2.go | 2 +- business/jxstore/financial/financial.go | 78 +-- business/jxstore/initdata/initdata.go | 173 +++--- business/jxstore/promotion/jd_promotion.go | 155 +++--- business/jxstore/promotion/promotion.go | 32 +- business/jxstore/tempop/tempop.go | 493 +++++++++--------- business/jxutils/jxcontext/jxcontext.go | 52 +- business/jxutils/msg/msg.go | 24 + business/jxutils/tasksch/parallel_task.go | 16 +- .../jxutils/tasksch/parallel_task_test.go | 70 +-- business/jxutils/tasksch/sequence_task.go | 5 +- .../jxutils/tasksch/sequence_task_test.go | 59 ++- business/jxutils/tasksch/task.go | 39 +- business/model/dao/dao_auth2.go | 15 + business/model/dao/dao_user2.go | 15 - business/partner/purchase/ebai/common.go | 40 +- business/partner/purchase/ebai/order.go | 22 +- business/partner/purchase/ebai/store.go | 63 +-- business/partner/purchase/ebai/store_sku.go | 329 ++++++------ .../partner/purchase/ebai/store_sku_test.go | 2 +- business/partner/purchase/jd/sku.go | 67 +-- business/partner/purchase/jd/store.go | 55 +- business/partner/purchase/jd/store_sku.go | 298 +++++------ business/partner/purchase/mtwm/store_sku.go | 329 ++++++------ .../partner/purchase/weimob/wsc/store_sku.go | 241 ++++----- conf/app.conf | 2 + globals/api/api.go | 2 +- 31 files changed, 1527 insertions(+), 1488 deletions(-) create mode 100644 business/jxutils/msg/msg.go diff --git a/business/auth2/auth2.go b/business/auth2/auth2.go index 324e7324b..490ff4cf3 100644 --- a/business/auth2/auth2.go +++ b/business/auth2/auth2.go @@ -387,3 +387,7 @@ func DisableUser(userID, operatorUserName string) (err error) { } return err } + +func GetUserBindAuthInfo(userID string) (authList []*model.AuthBind, err error) { + return dao.GetUserBindAuthInfo(dao.GetDB(), userID) +} diff --git a/business/jxstore/cms/message.go b/business/jxstore/cms/message.go index 7361598e9..5bf65bc11 100644 --- a/business/jxstore/cms/message.go +++ b/business/jxstore/cms/message.go @@ -41,7 +41,7 @@ func SendStoreMessage(ctx *jxcontext.Context, title, content string, storeIDs [] } dao.Commit(db) - rootTask := tasksch.NewParallelTask("SendStoreMessage", nil, ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + rootTask := tasksch.NewParallelTask("SendStoreMessage", nil, ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { db := dao.GetDB() msgStatus := batchItemList[0].(*model.MessageStatus) if err = weixinmsg.NotifyStoreMessage(msgStatus.StoreID, msgStatus.MessageID, msgStatus.ID, msg.Title, msg.Content); err == nil { diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go index 398ad9680..ba8a59256 100644 --- a/business/jxstore/cms/store.go +++ b/business/jxstore/cms/store.go @@ -750,40 +750,40 @@ func RefreshMissingDadaStores(ctx *jxcontext.Context, storeID int, isAsync, isCo if err != nil { return "", err } - task := tasksch.NewParallelTask("RefreshMissingDadaStores", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeDetail := batchItemList[0].(*dao.StoreDetail2) - _, err = api.DadaAPI.ShopDetail(utils.Int2Str(storeDetail.ID)) - if err != nil { - if codeErr, ok := err.(*utils.ErrorWithCode); ok && codeErr.IntCode() == dadaapi.ResponseCodeShopNotExist { - _, err = api.DadaAPI.ShopAdd(utils.Int2Str(storeDetail.ID), composeDadaStoreName(storeDetail), dadaapi.BusinessTypeConvStore, storeDetail.CityName, - storeDetail.DistrictName, storeDetail.Address, jxutils.IntCoordinate2Standard(storeDetail.Lng), jxutils.IntCoordinate2Standard(storeDetail.Lat), - storeDetail.Tel1, storeDetail.Tel1, nil) + task := tasksch.NewParallelTask("RefreshMissingDadaStores", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + storeDetail := batchItemList[0].(*dao.StoreDetail2) + _, err = api.DadaAPI.ShopDetail(utils.Int2Str(storeDetail.ID)) + if err != nil { + if codeErr, ok := err.(*utils.ErrorWithCode); ok && codeErr.IntCode() == dadaapi.ResponseCodeShopNotExist { + _, err = api.DadaAPI.ShopAdd(utils.Int2Str(storeDetail.ID), composeDadaStoreName(storeDetail), dadaapi.BusinessTypeConvStore, storeDetail.CityName, + storeDetail.DistrictName, storeDetail.Address, jxutils.IntCoordinate2Standard(storeDetail.Lng), jxutils.IntCoordinate2Standard(storeDetail.Lat), + storeDetail.Tel1, storeDetail.Tel1, nil) + } + } else { + params := map[string]interface{}{ + "station_name": composeDadaStoreName(storeDetail), + "business": dadaapi.BusinessTypeConvStore, + "city_name": storeDetail.CityName, + "area_name": storeDetail.DistrictName, + "station_address": storeDetail.Address, + "lng": jxutils.IntCoordinate2Standard(storeDetail.Lng), + "lat": jxutils.IntCoordinate2Standard(storeDetail.Lat), + "contact_name": storeDetail.Tel1, + "phone": storeDetail.Tel1, + } + err = api.DadaAPI.ShopUpdate(utils.Int2Str(storeDetail.ID), params) } - } else { - params := map[string]interface{}{ - "station_name": composeDadaStoreName(storeDetail), - "business": dadaapi.BusinessTypeConvStore, - "city_name": storeDetail.CityName, - "area_name": storeDetail.DistrictName, - "station_address": storeDetail.Address, - "lng": jxutils.IntCoordinate2Standard(storeDetail.Lng), - "lat": jxutils.IntCoordinate2Standard(storeDetail.Lat), - "contact_name": storeDetail.Tel1, - "phone": storeDetail.Tel1, + if err == nil { + db := dao.GetDB() + _, err = AddStoreCourierMap(ctx, db, storeDetail.ID, model.VendorIDDada, &model.StoreCourierMap{ + VendorStoreID: utils.Int2Str(storeDetail.ID), + Status: model.StoreStatusOpened, + }) } - err = api.DadaAPI.ShopUpdate(utils.Int2Str(storeDetail.ID), params) - } - if err == nil { - db := dao.GetDB() - _, err = AddStoreCourierMap(ctx, db, storeDetail.ID, model.VendorIDDada, &model.StoreCourierMap{ - VendorStoreID: utils.Int2Str(storeDetail.ID), - Status: model.StoreStatusOpened, - }) - } - return nil, err - }, storeList) - ctx.SetTaskOrAddChild(task, nil) - tasksch.ManageTask(task).Run() + return nil, err + }, storeList) + tasksch.HandleTask(task, nil, true).Run() hint = task.ID if !isAsync { _, err = task.GetResult(0) diff --git a/business/jxstore/cms/sync.go b/business/jxstore/cms/sync.go index a5fa53a65..592bd56ec 100644 --- a/business/jxstore/cms/sync.go +++ b/business/jxstore/cms/sync.go @@ -130,29 +130,29 @@ func (v *VendorSync) GetSingleStoreHandler(vendorID int) partner.ISingleStoreHan func (v *VendorSync) syncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, multiStoresHandler partner.IMultipleStoresHandler, db *dao.DaoDB, cats []*model.SkuCategory, userName string) (err error) { syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[multiStoresHandler.GetVendorID()]) - task := tasksch.NewParallelTask("syncCategories", nil, userName, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - cat := batchItemList[0].(*model.SkuCategory) - updateFields := []string{syncStatusFieldName} - syncStatus := jxutils.GetObjFieldByName(cat, syncStatusFieldName).(int8) - if (syncStatus & model.SyncFlagDeletedMask) != 0 { //删除 - err = multiStoresHandler.DeleteCategory(db, cat, userName) - } else if (syncStatus & model.SyncFlagNewMask) != 0 { // 新增 - err = multiStoresHandler.CreateCategory(db, cat, userName) - updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[multiStoresHandler.GetVendorID()])) - } else if (syncStatus & model.SyncFlagModifiedMask) != 0 { // 修改 - err = multiStoresHandler.UpdateCategory(db, cat, userName) - if intErr, ok := err.(*utils.ErrorWithCode); ok && intErr.IntCode() == -3 { - err = nil + task := tasksch.NewParallelTask("syncCategories", nil, ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { + cat := batchItemList[0].(*model.SkuCategory) + updateFields := []string{syncStatusFieldName} + syncStatus := jxutils.GetObjFieldByName(cat, syncStatusFieldName).(int8) + if (syncStatus & model.SyncFlagDeletedMask) != 0 { //删除 + err = multiStoresHandler.DeleteCategory(db, cat, userName) + } else if (syncStatus & model.SyncFlagNewMask) != 0 { // 新增 + err = multiStoresHandler.CreateCategory(db, cat, userName) + updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[multiStoresHandler.GetVendorID()])) + } else if (syncStatus & model.SyncFlagModifiedMask) != 0 { // 修改 + err = multiStoresHandler.UpdateCategory(db, cat, userName) + if intErr, ok := err.(*utils.ErrorWithCode); ok && intErr.IntCode() == -3 { + err = nil + } } - } - if err == nil { - jxutils.SetObjFieldByName(cat, syncStatusFieldName, int8(0)) - _, err = dao.UpdateEntity(db, cat, updateFields...) - } - return nil, err - }, cats) - ctx.SetTaskOrAddChild(task, parentTask) - task.Run() + if err == nil { + jxutils.SetObjFieldByName(cat, syncStatusFieldName, int8(0)) + _, err = dao.UpdateEntity(db, cat, updateFields...) + } + return nil, err + }, cats) + tasksch.HandleTask(task, parentTask, false).Run() _, err = task.GetResult(0) return err } @@ -212,14 +212,15 @@ func (v *VendorSync) SyncStore(ctx *jxcontext.Context, db *dao.DaoDB, vendorID, loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) handler := v.GetStoreHandler(loopMapInfo.VendorID) if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("SyncStore loop store %s", model.VendorChineseNames[loopMapInfo.VendorID]), nil, ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - if err = handler.UpdateStore(db, storeMap.StoreID, userName); err == nil { - storeMap.SyncStatus = 0 - _, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus) - } - return nil, err - }, loopMapInfo.StoreMapList) + loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("SyncStore loop store %s", model.VendorChineseNames[loopMapInfo.VendorID]), nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + storeMap := batchItemList[0].(*model.StoreMap) + if err = handler.UpdateStore(db, storeMap.StoreID, userName); err == nil { + storeMap.SyncStatus = 0 + _, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus) + } + return nil, err + }, loopMapInfo.StoreMapList) t.AddChild(loopStoreTask).Run() _, err = loopStoreTask.GetResult(0) return nil, err @@ -262,51 +263,52 @@ func (v *VendorSync) SyncSku(ctx *jxcontext.Context, db *dao.DaoDB, nameID, skuI err := dao.GetRows(db, &skuNameList, sql, sqlParams...) if err == nil && len(skuNameList) > 0 { // todo 同一skuName下的sku顺序处理的原因是京东SPU特殊类型必须要序列化同步才能正常处理, db可能会有多线程问题 - task := tasksch.NewParallelTask("SyncSku loop sku", tasksch.NewParallelConfig().SetParallelCount(10).SetIsContinueWhenError(isContinueWhenError), userName, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - skuName := batchItemList[0].(*model.SkuName) - var skuList []*model.Sku - if err = dao.GetRows(db, &skuList, fmt.Sprintf(` + task := tasksch.NewParallelTask("SyncSku loop sku", tasksch.NewParallelConfig().SetParallelCount(10).SetIsContinueWhenError(isContinueWhenError), ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { + skuName := batchItemList[0].(*model.SkuName) + var skuList []*model.Sku + if err = dao.GetRows(db, &skuList, fmt.Sprintf(` SELECT * FROM sku WHERE name_id = ? AND %s_sync_status <> 0 ORDER BY IF(spec_unit IN('kg', 'L'), 1000, 1) * spec_quality `, dbField), skuName.ID); err == nil && len(skuList) > 0 { - for _, sku := range skuList { - syncStatus := jxutils.GetObjFieldByName(sku, syncStatusFieldName).(int8) - if (skuID == -1 || skuID == sku.ID) && (syncStatus != 0) { - updateFields := []string{syncStatusFieldName} - if syncStatus&model.SyncFlagDeletedMask != 0 { // 删除 - err = multiStoresHandler.DeleteSku(db, sku, userName) - } else if syncStatus&model.SyncFlagNewMask != 0 { // 新增 - if err = multiStoresHandler.CreateSku(db, sku, userName); err == nil { - var tmpStruct struct { - MaxIndex int + for _, sku := range skuList { + syncStatus := jxutils.GetObjFieldByName(sku, syncStatusFieldName).(int8) + if (skuID == -1 || skuID == sku.ID) && (syncStatus != 0) { + updateFields := []string{syncStatusFieldName} + if syncStatus&model.SyncFlagDeletedMask != 0 { // 删除 + err = multiStoresHandler.DeleteSku(db, sku, userName) + } else if syncStatus&model.SyncFlagNewMask != 0 { // 新增 + if err = multiStoresHandler.CreateSku(db, sku, userName); err == nil { + var tmpStruct struct { + MaxIndex int + } + // todo hard code 得到京东spu中sku的顺序(以方便以后修改销售属性),这个必须要每次重新从数据库取 + if dao.GetRow(db, &tmpStruct, "SELECT MAX(sku_index) max_index FROM sku WHERE name_id = ? AND jd_id > 0 AND jd_id < 4024012631406 ", sku.NameID) == nil { + sku.SkuIndex = tmpStruct.MaxIndex + 1 + updateFields = append(updateFields, "SkuIndex") + } + updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[multiStoresHandler.GetVendorID()])) } - // todo hard code 得到京东spu中sku的顺序(以方便以后修改销售属性),这个必须要每次重新从数据库取 - if dao.GetRow(db, &tmpStruct, "SELECT MAX(sku_index) max_index FROM sku WHERE name_id = ? AND jd_id > 0 AND jd_id < 4024012631406 ", sku.NameID) == nil { - sku.SkuIndex = tmpStruct.MaxIndex + 1 - updateFields = append(updateFields, "SkuIndex") - } - updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[multiStoresHandler.GetVendorID()])) + } else if syncStatus&model.SyncFlagModifiedMask != 0 { // 修改 + err = multiStoresHandler.UpdateSku(db, sku, userName) } - } else if syncStatus&model.SyncFlagModifiedMask != 0 { // 修改 - err = multiStoresHandler.UpdateSku(db, sku, userName) - } - if err == nil { - jxutils.SetObjFieldByName(sku, syncStatusFieldName, int8(0)) - if _, err = dao.UpdateEntity(db, sku, updateFields...); err != nil { - break + if err == nil { + jxutils.SetObjFieldByName(sku, syncStatusFieldName, int8(0)) + if _, err = dao.UpdateEntity(db, sku, updateFields...); err != nil { + break + } } } } } - } - if err == nil { - jxutils.SetObjFieldByName(skuName, syncStatusFieldName, int8(0)) - _, err = dao.UpdateEntity(db, skuName, syncStatusFieldName) - } - return nil, err - }, skuNameList) + if err == nil { + jxutils.SetObjFieldByName(skuName, syncStatusFieldName, int8(0)) + _, err = dao.UpdateEntity(db, skuName, syncStatusFieldName) + } + return nil, err + }, skuNameList) t.AddChild(task).Run() _, err = task.GetResult(0) } @@ -320,11 +322,12 @@ func (v *VendorSync) SyncStoresCategory(ctx *jxcontext.Context, db *dao.DaoDB, v loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) if handler := v.GetSingleStoreHandler(loopMapInfo.VendorID); handler != nil { if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewSeqTask("SyncStoresCategory loop stores", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - storeID := loopMapInfo.StoreMapList[step].StoreID - _, err = handler.SyncStoreCategory(ctx, task, storeID, false) - return nil, err - }, len(loopMapInfo.StoreMapList)) + loopStoreTask := tasksch.NewSeqTask("SyncStoresCategory loop stores", ctx, + func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + storeID := loopMapInfo.StoreMapList[step].StoreID + _, err = handler.SyncStoreCategory(ctx, task, storeID, false) + return nil, err + }, len(loopMapInfo.StoreMapList)) t.AddChild(loopStoreTask).Run() _, err = loopStoreTask.GetResult(0) return nil, err @@ -342,16 +345,17 @@ func (v *VendorSync) SyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendo loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil { if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewSeqTask("SyncStoresSkus相同平台循环门店", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - storeID := loopMapInfo.StoreMapList[step].StoreID - if _, err = handler.SyncStoreSkus(ctx, task, storeID, skuIDs, false, isContinueWhenError); err != nil { - globals.SugarLogger.Debugf("SyncStoresSkus failed1 store:%d failed with error:%v", storeID, err) - if isContinueWhenError { - err = nil + loopStoreTask := tasksch.NewSeqTask("SyncStoresSkus相同平台循环门店", ctx, + func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + storeID := loopMapInfo.StoreMapList[step].StoreID + if _, err = handler.SyncStoreSkus(ctx, task, storeID, skuIDs, false, isContinueWhenError); err != nil { + globals.SugarLogger.Debugf("SyncStoresSkus failed1 store:%d failed with error:%v", storeID, err) + if isContinueWhenError { + err = nil + } } - } - return nil, err - }, len(loopMapInfo.StoreMapList)) + return nil, err + }, len(loopMapInfo.StoreMapList)) t.AddChild(loopStoreTask).Run() _, err = loopStoreTask.GetResult(0) return nil, err @@ -368,11 +372,12 @@ func (v *VendorSync) FullSyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, v loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil { if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewSeqTask("FullSyncStoresSkus相同平台循环门店", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - storeID := loopMapInfo.StoreMapList[step].StoreID - _, err = handler.FullSyncStoreSkus(ctx, task, storeID, false, isContinueWhenError) - return nil, err - }, len(loopMapInfo.StoreMapList)) + loopStoreTask := tasksch.NewSeqTask("FullSyncStoresSkus相同平台循环门店", ctx, + func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + storeID := loopMapInfo.StoreMapList[step].StoreID + _, err = handler.FullSyncStoreSkus(ctx, task, storeID, false, isContinueWhenError) + return nil, err + }, len(loopMapInfo.StoreMapList)) t.AddChild(loopStoreTask).Run() _, err = loopStoreTask.GetResult(0) return nil, err @@ -389,11 +394,12 @@ func (v *VendorSync) DeleteRemoteStoreSkus(ctx *jxcontext.Context, db *dao.DaoDB loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil { if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewSeqTask("DeleteRemoteStoreSkus相同平台循环门店", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - storeID := loopMapInfo.StoreMapList[step].StoreID - _, err = handler.DeleteRemoteStoreSkus(ctx, task, storeID, false, isContinueWhenError) - return nil, err - }, len(loopMapInfo.StoreMapList)) + loopStoreTask := tasksch.NewSeqTask("DeleteRemoteStoreSkus相同平台循环门店", ctx, + func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + storeID := loopMapInfo.StoreMapList[step].StoreID + _, err = handler.DeleteRemoteStoreSkus(ctx, task, storeID, false, isContinueWhenError) + return nil, err + }, len(loopMapInfo.StoreMapList)) t.AddChild(loopStoreTask).Run() _, err = loopStoreTask.GetResult(0) return nil, err @@ -443,9 +449,8 @@ func (v *VendorSync) LoopStoresMap(ctx *jxcontext.Context, db *dao.DaoDB, taskNa } index++ } - task := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx.GetUserName(), handler, loopInfoList) - ctx.SetTaskOrAddChild(task, nil) - tasksch.ManageTask(task).Run() + task := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, handler, loopInfoList) + tasksch.HandleTask(task, nil, true).Run() if !isAsync { _, err = task.GetResult(0) } @@ -453,62 +458,28 @@ func (v *VendorSync) LoopStoresMap(ctx *jxcontext.Context, db *dao.DaoDB, taskNa } func (v *VendorSync) LoopMultiStoresVendors(ctx *jxcontext.Context, db *dao.DaoDB, taskName string, isAsync bool, userName string, handler tasksch.WorkFunc) (hint string, err error) { - task := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), userName, handler, v.MultiStoreVendorIDs) - ctx.SetTaskOrAddChild(task, nil) - tasksch.ManageTask(task).Run() + task := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, handler, v.MultiStoreVendorIDs) + tasksch.HandleTask(task, nil, true).Run() if !isAsync { _, err = task.GetResult(0) } return task.ID, makeSyncError(err) } -// func (v *VendorSync) LoopStoreVendors(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, taskName string, isAsync bool, userName string, handler tasksch.WorkFunc) (hint string, err error) { -// if taskName == "" { -// taskName = "LoopStoreVendors" -// } -// var vendorIDMap map[int]int -// if len(vendorIDs) != 0 { -// vendorIDMap = make(map[int]int) -// for _, v := range vendorIDs { -// vendorIDMap[v] = 1 -// } -// } -// allHandlers := make([]int, len(v.MultiStoreVendorIDs)+len(v.SingleStoreVendorIDs)) -// copy(allHandlers, v.MultiStoreVendorIDs) -// copy(allHandlers[len(v.MultiStoreVendorIDs):], v.SingleStoreVendorIDs) -// if vendorIDMap != nil { -// count := 0 -// for _, v := range allHandlers { -// if vendorIDMap[v] == 1 { -// allHandlers[count] = v -// count++ -// } -// } -// allHandlers = allHandlers[:count] -// } -// task := tasksch.NewParallelTask(taskName, nil, userName, handler, allHandlers) -// ctx.SetTaskOrAddChild(task, nil) -// tasksch.ManageTask(task).Run() -// if !isAsync { -// _, err = task.GetResult(0) -// } -// return task.ID, err -// } - func (v *VendorSync) RefreshAllSkusID(ctx *jxcontext.Context, isAsync bool, vendorIDs []int, storeIDs []int) (hint string, err error) { - task := tasksch.NewParallelTask("RefreshAllSkusID", nil, ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorID := batchItemList[0].(int) - if handler := v.GetStoreHandler(vendorID); handler != nil { - if multiHandler, ok := handler.(partner.IMultipleStoresHandler); ok { - _, err = multiHandler.RefreshAllSkusID(ctx, task, false) - } else if singleHandler, ok := handler.(partner.ISingleStoreHandler); ok { - _, err = singleHandler.RefreshStoresAllSkusID(ctx, task, false, storeIDs) + task := tasksch.NewParallelTask("RefreshAllSkusID", nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + vendorID := batchItemList[0].(int) + if handler := v.GetStoreHandler(vendorID); handler != nil { + if multiHandler, ok := handler.(partner.IMultipleStoresHandler); ok { + _, err = multiHandler.RefreshAllSkusID(ctx, task, false) + } else if singleHandler, ok := handler.(partner.ISingleStoreHandler); ok { + _, err = singleHandler.RefreshStoresAllSkusID(ctx, task, false, storeIDs) + } } - } - return nil, err - }, vendorIDs) - ctx.SetTaskOrAddChild(task, nil) - tasksch.ManageTask(task).Run() + return nil, err + }, vendorIDs) + tasksch.HandleTask(task, nil, true).Run() if !isAsync { _, err = task.GetResult(0) } @@ -516,15 +487,15 @@ func (v *VendorSync) RefreshAllSkusID(ctx *jxcontext.Context, isAsync bool, vend } func (v *VendorSync) RefreshAllStoresID(ctx *jxcontext.Context, isAsync bool, vendorIDs []int) (hint string, err error) { - task := tasksch.NewParallelTask("RefreshAllStoresID", nil, ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorID := batchItemList[0].(int) - if handler := v.GetStoreHandler(vendorID); handler != nil { - _, err = handler.RefreshAllStoresID(ctx, task, false) - } - return nil, err - }, vendorIDs) - ctx.SetTaskOrAddChild(task, nil) - tasksch.ManageTask(task).Run() + task := tasksch.NewParallelTask("RefreshAllStoresID", nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + vendorID := batchItemList[0].(int) + if handler := v.GetStoreHandler(vendorID); handler != nil { + _, err = handler.RefreshAllStoresID(ctx, task, false) + } + return nil, err + }, vendorIDs) + tasksch.HandleTask(task, nil, true).Run() if !isAsync { _, err = task.GetResult(0) } diff --git a/business/jxstore/cms/user2.go b/business/jxstore/cms/user2.go index a84d0480e..a729c5292 100644 --- a/business/jxstore/cms/user2.go +++ b/business/jxstore/cms/user2.go @@ -100,7 +100,7 @@ func RegisterUser(user *model.User, mobileVerifyCode string, inAuthInfo *auth2.A func GetUserBindAuthInfo(ctx *jxcontext.Context) (authList []*model.AuthBind, err error) { authInfo, err := ctx.GetV2AuthInfo() if err == nil { - return dao.GetUserBindAuthInfo(dao.GetDB(), authInfo.GetID()) + return auth2.GetUserBindAuthInfo(authInfo.GetID()) } return nil, err } diff --git a/business/jxstore/financial/financial.go b/business/jxstore/financial/financial.go index 69c4228be..abb4c908c 100644 --- a/business/jxstore/financial/financial.go +++ b/business/jxstore/financial/financial.go @@ -52,51 +52,51 @@ func SendFilesToStores(ctx *jxcontext.Context, files []*multipart.FileHeader, ti } upToken := putPolicy.UploadToken(api.QiniuAPI) cfg := &storage.Config{} - task := tasksch.NewParallelTask("SendFilesToStores", tasksch.NewParallelConfig().SetIsContinueWhenError(true), userName, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - fileInfo := batchItemList[0].(*tUploadFileInfo) - fileHeader := fileInfo.FileHeader - storeID := fileInfo.StoreID - file, err := fileHeader.Open() - globals.SugarLogger.Debugf("SendFilesToStores upload file:%s", fileHeader.Filename) - if err == nil { - ret := storage.PutRet{} - key := "storeBill_" + utils.Int2Str(storeID) + "_" + strings.ToLower(utils.GetUUID()) + path.Ext(fileHeader.Filename) - formUploader := storage.NewFormUploader(cfg) - for i := 0; i < 3; i++ { - if err = formUploader.Put(context.Background(), &ret, upToken, key, file, fileHeader.Size, nil); err == nil { - break - } - } - file.Close() + task := tasksch.NewParallelTask("SendFilesToStores", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + fileInfo := batchItemList[0].(*tUploadFileInfo) + fileHeader := fileInfo.FileHeader + storeID := fileInfo.StoreID + file, err := fileHeader.Open() + globals.SugarLogger.Debugf("SendFilesToStores upload file:%s", fileHeader.Filename) if err == nil { - db := dao.GetDB() - billRec := &legacymodel.StoreBill{ - Date: time.Now(), - Url: jxutils.ComposeQiniuResURL(ret.Key), - StoreId: storeID, - BillName: fileHeader.Filename, - ShopName: shopName, - BillTitle: title, - } - if err = dao.CreateEntity(db, billRec); err == nil { - err = weixinmsg.NotifySaleBill(storeID, title, shopName, "http://www.jxc4.com/billshow/?path="+billRec.Url) - if err != nil { - globals.SugarLogger.Infof("SendFilesToStores NotifySaleBill file:%s error:%v", fileHeader.Filename, err) + ret := storage.PutRet{} + key := "storeBill_" + utils.Int2Str(storeID) + "_" + strings.ToLower(utils.GetUUID()) + path.Ext(fileHeader.Filename) + formUploader := storage.NewFormUploader(cfg) + for i := 0; i < 3; i++ { + if err = formUploader.Put(context.Background(), &ret, upToken, key, file, fileHeader.Size, nil); err == nil { + break + } + } + file.Close() + if err == nil { + db := dao.GetDB() + billRec := &legacymodel.StoreBill{ + Date: time.Now(), + Url: jxutils.ComposeQiniuResURL(ret.Key), + StoreId: storeID, + BillName: fileHeader.Filename, + ShopName: shopName, + BillTitle: title, + } + if err = dao.CreateEntity(db, billRec); err == nil { + err = weixinmsg.NotifySaleBill(storeID, title, shopName, "http://www.jxc4.com/billshow/?path="+billRec.Url) + if err != nil { + globals.SugarLogger.Infof("SendFilesToStores NotifySaleBill file:%s error:%v", fileHeader.Filename, err) + } + err = nil // 忽略微信发送错误 + } else { + globals.SugarLogger.Warnf("SendFilesToStores CreateEntity file:%s error:%v", fileHeader.Filename, err) } - err = nil // 忽略微信发送错误 } else { - globals.SugarLogger.Warnf("SendFilesToStores CreateEntity file:%s error:%v", fileHeader.Filename, err) + globals.SugarLogger.Warnf("SendFilesToStores file:%s failed with error:%v", fileHeader.Filename, err) } } else { - globals.SugarLogger.Warnf("SendFilesToStores file:%s failed with error:%v", fileHeader.Filename, err) + globals.SugarLogger.Warnf("SendFilesToStores open file:%s failed with error:%v", fileHeader.Filename, err) } - } else { - globals.SugarLogger.Warnf("SendFilesToStores open file:%s failed with error:%v", fileHeader.Filename, err) - } - return retVal, err - }, fileList) - ctx.SetTaskOrAddChild(task, nil) - tasksch.ManageTask(task).Run() + return retVal, err + }, fileList) + tasksch.HandleTask(task, nil, true).Run() hint = task.ID if !isAsync { _, err = task.GetResult(0) diff --git a/business/jxstore/initdata/initdata.go b/business/jxstore/initdata/initdata.go index 1821a5721..3f216dc9f 100644 --- a/business/jxstore/initdata/initdata.go +++ b/business/jxstore/initdata/initdata.go @@ -147,22 +147,23 @@ func InitSkuName(ctx *jxcontext.Context, isForce, isAsync, isContinueWhenError b return "", err } - task := tasksch.NewParallelTask("InitSkuName calculate md5", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - skuName := batchItemList[0].(*model.SkuName) - if skuName.ImgHashCode == "" || isForce { - response, err := http.Get(skuName.Img) - if err == nil { - defer response.Body.Close() - data, err2 := ioutil.ReadAll(response.Body) - if err = err2; err == nil { - skuName.ImgHashCode = fmt.Sprintf("%X", md5.Sum(data)) - db := dao.GetDB() - _, err = dao.UpdateEntity(db, skuName, "ImgHashCode") + task := tasksch.NewParallelTask("InitSkuName calculate md5", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + skuName := batchItemList[0].(*model.SkuName) + if skuName.ImgHashCode == "" || isForce { + response, err := http.Get(skuName.Img) + if err == nil { + defer response.Body.Close() + data, err2 := ioutil.ReadAll(response.Body) + if err = err2; err == nil { + skuName.ImgHashCode = fmt.Sprintf("%X", md5.Sum(data)) + db := dao.GetDB() + _, err = dao.UpdateEntity(db, skuName, "ImgHashCode") + } } } - } - return nil, err - }, skuNameList) + return nil, err + }, skuNameList) tasksch.ManageTask(task).Run() if !isAsync { _, err = task.GetResult(0) @@ -207,17 +208,18 @@ func UploadWeimobImg4SkuName(ctx *jxcontext.Context, nameIDs []int, isAsync, isC if err != nil { return "", err } - rootTask := tasksch.NewParallelTask("UploadWeimobImg4SkuName", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - skuName := batchItemList[0].(*model.SkuName) - if skuName.Img != "" && skuName.ImgWeimob == "" { - if globals.EnableWscStoreWrite { - if skuName.ImgWeimob, err = api.WeimobAPI.UploadImgByURL(skuName.Img, ""); err == nil { - _, err = dao.UpdateEntity(db, skuName, "ImgWeimob") + rootTask := tasksch.NewParallelTask("UploadWeimobImg4SkuName", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + skuName := batchItemList[0].(*model.SkuName) + if skuName.Img != "" && skuName.ImgWeimob == "" { + if globals.EnableWscStoreWrite { + if skuName.ImgWeimob, err = api.WeimobAPI.UploadImgByURL(skuName.Img, ""); err == nil { + _, err = dao.UpdateEntity(db, skuName, "ImgWeimob") + } } } - } - return nil, err - }, skuNameList) + return nil, err + }, skuNameList) tasksch.ManageTask(rootTask).Run() if !isAsync { @@ -350,76 +352,77 @@ func BuildSkuFromEbaiStore(ctx *jxcontext.Context, baiduShopID int64, isAsync, i } cfg := &storage.Config{} upToken := putPolicy.UploadToken(api.QiniuAPI) - rootTask := tasksch.NewSeqTask("BuildSkuFromEbaiStore", ctx.GetUserName(), func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - var catID string - cat := skuCatList[step] - skuNameExtList := allSkuInfo2[cat] - catID, err = addShopCategory(0, cat.Name, int(cat.Level), cat.Seq, ctx.GetUserName()) - if err == nil { - shopCategories := []int64{utils.Str2Int64(catID)} - for _, skuNameExt := range skuNameExtList { - var imgContent []byte - skuNameExt.CategoryID = cat.ID - skuNameExt.Img = strings.Replace(skuNameExt.Img, "https://", "http://", 1) - if imgContent, _, err = jxutils.DownloadFileByURL(skuNameExt.Img); err != nil { - globals.SugarLogger.Infof("download pic %s failed with error:%v", skuNameExt.Img, err) - if !isContinueWhenError { - return nil, err - } - err = nil - continue - } - formUploader := storage.NewFormUploader(cfg) - ret := storage.PutRet{} - key := jxutils.GenPicFileName(".jpeg") - for i := 0; i < 3; i++ { - if err = formUploader.Put(context.Background(), &ret, upToken, key, bytes.NewReader(imgContent), int64(len(imgContent)), nil); err == nil { - break - } - } - if err != nil { - globals.SugarLogger.Infof("upload pic %s failed with error:%v", skuNameExt.Img, err) - if !isContinueWhenError { - return nil, err - } - err = nil - continue - } - qiniuImgURL := "http://image.jxc4.com/" + key + "?imageMogr2/thumbnail/x800/gravity/Center/crop/800x800" - for _, sku := range skuNameExt.Skus { - jdCatID := 22410 // 其他国产水果 - if cat.Name == "进口水果" { - jdCatID = 20342 // 其他进口水果 - } - price := sku.LinkID - sku.LinkID = 0 - skuName := jxutils.ComposeSkuName(skuNameExt.Prefix, skuNameExt.Name, sku.Comment, skuNameExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameLen) - fixedStatus := 1 - if sku.Status != model.SkuStatusNormal { - fixedStatus = 2 - } - var vendorSkuID string - vendorSkuID, err = addSku(utils.Int2Str(startOutSkuID), jdCatID, shopCategories, jd.DefBrandID, skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{qiniuImgURL}, fixedStatus, true, nil) - if err == nil { - globals.SugarLogger.Debugf("vendorSkuID=%s", vendorSkuID) - } else { - globals.SugarLogger.Infof("create %s failed with error:%v", skuName, err) + rootTask := tasksch.NewSeqTask("BuildSkuFromEbaiStore", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + var catID string + cat := skuCatList[step] + skuNameExtList := allSkuInfo2[cat] + catID, err = addShopCategory(0, cat.Name, int(cat.Level), cat.Seq, ctx.GetUserName()) + if err == nil { + shopCategories := []int64{utils.Str2Int64(catID)} + for _, skuNameExt := range skuNameExtList { + var imgContent []byte + skuNameExt.CategoryID = cat.ID + skuNameExt.Img = strings.Replace(skuNameExt.Img, "https://", "http://", 1) + if imgContent, _, err = jxutils.DownloadFileByURL(skuNameExt.Img); err != nil { + globals.SugarLogger.Infof("download pic %s failed with error:%v", skuNameExt.Img, err) if !isContinueWhenError { return nil, err } err = nil + continue + } + formUploader := storage.NewFormUploader(cfg) + ret := storage.PutRet{} + key := jxutils.GenPicFileName(".jpeg") + for i := 0; i < 3; i++ { + if err = formUploader.Put(context.Background(), &ret, upToken, key, bytes.NewReader(imgContent), int64(len(imgContent)), nil); err == nil { + break + } + } + if err != nil { + globals.SugarLogger.Infof("upload pic %s failed with error:%v", skuNameExt.Img, err) + if !isContinueWhenError { + return nil, err + } + err = nil + continue + } + qiniuImgURL := "http://image.jxc4.com/" + key + "?imageMogr2/thumbnail/x800/gravity/Center/crop/800x800" + for _, sku := range skuNameExt.Skus { + jdCatID := 22410 // 其他国产水果 + if cat.Name == "进口水果" { + jdCatID = 20342 // 其他进口水果 + } + price := sku.LinkID + sku.LinkID = 0 + skuName := jxutils.ComposeSkuName(skuNameExt.Prefix, skuNameExt.Name, sku.Comment, skuNameExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameLen) + fixedStatus := 1 + if sku.Status != model.SkuStatusNormal { + fixedStatus = 2 + } + var vendorSkuID string + vendorSkuID, err = addSku(utils.Int2Str(startOutSkuID), jdCatID, shopCategories, jd.DefBrandID, skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{qiniuImgURL}, fixedStatus, true, nil) + if err == nil { + globals.SugarLogger.Debugf("vendorSkuID=%s", vendorSkuID) + } else { + globals.SugarLogger.Infof("create %s failed with error:%v", skuName, err) + if !isContinueWhenError { + return nil, err + } + err = nil + } + // fmt.Printf("%s,[%s]%s-%f-%s, %s, %s\n", cat.Name, skuNameExt.Prefix, skuNameExt.Name, skuNameExt.SpecQuality, skuNameExt.SpecUnit, qiniuImgURL, skuName) + startOutSkuID++ + // rootTask.Cancel() + // return nil, nil } - // fmt.Printf("%s,[%s]%s-%f-%s, %s, %s\n", cat.Name, skuNameExt.Prefix, skuNameExt.Name, skuNameExt.SpecQuality, skuNameExt.SpecUnit, qiniuImgURL, skuName) - startOutSkuID++ - // rootTask.Cancel() - // return nil, nil } + } else { + return nil, err } - } else { return nil, err - } - return nil, err - }, len(skuCatList)) + }, len(skuCatList)) tasksch.ManageTask(rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) diff --git a/business/jxstore/promotion/jd_promotion.go b/business/jxstore/promotion/jd_promotion.go index 1043fbc7e..4423c119b 100644 --- a/business/jxstore/promotion/jd_promotion.go +++ b/business/jxstore/promotion/jd_promotion.go @@ -424,64 +424,66 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW } dao.Commit(db) - rootTask := tasksch.NewSeqTask("CreateJdPromotion", userName, func(task *tasksch.SeqTask, step int, params2 ...interface{}) (result interface{}, err error) { - if step == 0 { - task1 := tasksch.NewParallelTask("CreateJdPromotion update sku price", nil, userName, func(t *tasksch.ParallelTask, batchItemList []interface{}, params2 ...interface{}) (retVal interface{}, err error) { - storeID := batchItemList[0].(int) - modifyPricesList := jxutils.SplitSlice(modifyPricesList[storeID], jdapi.MaxStoreSkuBatchSize) - for _, modifyPrices := range modifyPricesList { - modifyPrices2 := make([]*jdapi.SkuPriceInfo, len(modifyPrices)) - for k, v := range modifyPrices { - modifyPrices2[k] = v.(*jdapi.SkuPriceInfo) - } - if globals.EnableStoreWrite { - if _, err = api.JdAPI.UpdateVendorStationPrice(utils.Int2Str(storeID), "", modifyPrices2); err != nil { - return nil, err + rootTask := tasksch.NewSeqTask("CreateJdPromotion", ctx, + func(task *tasksch.SeqTask, step int, params2 ...interface{}) (result interface{}, err error) { + if step == 0 { + task1 := tasksch.NewParallelTask("CreateJdPromotion update sku price", nil, ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params2 ...interface{}) (retVal interface{}, err error) { + storeID := batchItemList[0].(int) + modifyPricesList := jxutils.SplitSlice(modifyPricesList[storeID], jdapi.MaxStoreSkuBatchSize) + for _, modifyPrices := range modifyPricesList { + modifyPrices2 := make([]*jdapi.SkuPriceInfo, len(modifyPrices)) + for k, v := range modifyPrices { + modifyPrices2[k] = v.(*jdapi.SkuPriceInfo) + } + if globals.EnableStoreWrite { + if _, err = api.JdAPI.UpdateVendorStationPrice(utils.Int2Str(storeID), "", modifyPrices2); err != nil { + return nil, err + } + } } + return nil, nil + }, jxStoreIDs) + task.AddChild(task1).Run() + _, err = task1.GetResult(0) + } else if step == 1 { + err = promotionHandler.CreatePromotionRules(infoId, "", limitDevice, limitPin, limitCount, limitDaily) + } else if step == 2 { + task2 := tasksch.NewParallelTask("CreateJdPromotion CreatePromotionSku", tasksch.NewParallelConfig().SetBatchSize(MaxPromotionSkuCount).SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params2 ...interface{}) (retVal interface{}, err error) { + skus := make([]map[string]interface{}, len(batchItemList)) + for k, v := range batchItemList { + skus[k] = v.(map[string]interface{}) + } + _, err = promotionHandler.CreatePromotionSku(infoId, "", skus) + return nil, err + }, promotionPrices) + task.AddChild(task2).Run() + _, err = task2.GetResult(0) + if isContinueWhenError && err != nil { // todo isContinueWhenError为true时,强制忽略此步的错误 + err = nil + } + } else if step == 3 { + err = promotionHandler.ConfirmPromotion(infoId, "") + if err == nil { + db := dao.GetDB() + if _, err = dao.UpdateEntityLogically(db, promotion, map[string]interface{}{ + model.FieldStatus: model.PromotionStatusRemoteCreated, + }, ctx.GetUserName(), nil); err == nil { + RefreshJdPromotionLockStatus(ctx, promotion.ID) } } - return nil, nil - }, jxStoreIDs) - task.AddChild(task1).Run() - _, err = task1.GetResult(0) - } else if step == 1 { - err = promotionHandler.CreatePromotionRules(infoId, "", limitDevice, limitPin, limitCount, limitDaily) - } else if step == 2 { - task2 := tasksch.NewParallelTask("CreateJdPromotion CreatePromotionSku", tasksch.NewParallelConfig().SetBatchSize(MaxPromotionSkuCount).SetIsContinueWhenError(isContinueWhenError), userName, func(task *tasksch.ParallelTask, batchItemList []interface{}, params2 ...interface{}) (retVal interface{}, err error) { - skus := make([]map[string]interface{}, len(batchItemList)) - for k, v := range batchItemList { - skus[k] = v.(map[string]interface{}) - } - _, err = promotionHandler.CreatePromotionSku(infoId, "", skus) - return nil, err - }, promotionPrices) - task.AddChild(task2).Run() - _, err = task2.GetResult(0) - if isContinueWhenError && err != nil { // todo isContinueWhenError为true时,强制忽略此步的错误 - err = nil } - } else if step == 3 { - err = promotionHandler.ConfirmPromotion(infoId, "") - if err == nil { + if err != nil { db := dao.GetDB() - if _, err = dao.UpdateEntityLogically(db, promotion, map[string]interface{}{ - model.FieldStatus: model.PromotionStatusRemoteCreated, - }, ctx.GetUserName(), nil); err == nil { - RefreshJdPromotionLockStatus(ctx, promotion.ID) - } + dao.UpdateEntityLogically(db, promotion, map[string]interface{}{ + model.FieldStatus: model.PromotionStatusRemoteFailed, + model.FieldRemark: err.Error(), + }, ctx.GetUserName(), nil) } - } - if err != nil { - db := dao.GetDB() - dao.UpdateEntityLogically(db, promotion, map[string]interface{}{ - model.FieldStatus: model.PromotionStatusRemoteFailed, - model.FieldRemark: err.Error(), - }, ctx.GetUserName(), nil) - } - return nil, err - }, 4) - ctx.SetTaskOrAddChild(rootTask, nil) - tasksch.ManageTask(rootTask).Run() + return nil, err + }, 4) + tasksch.HandleTask(rootTask, nil, true).Run() if !isAsync { _, err = rootTask.GetResult(0) } @@ -745,32 +747,33 @@ func RefreshJdStoreSkuStock(promotionID int, skuIDs []int) (err error) { } globals.SugarLogger.Debugf("RefreshJdStoreSkuStock promotionID:%d, len(promotionItemList)=%d", promotionID, len(promotionItemList)) if len(promotionItemList) > 0 { - task := tasksch.NewParallelTask("RefreshJdStoreSkuStock", tasksch.NewParallelConfig().SetBatchSize(jdapi.MaxStoreSkuBatchSize).SetIsContinueWhenError(true), "schedule", func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - stockList := make([]*jdapi.SkuStock, 0) - stationNo := batchItemList[0].(*tPromotionItemInfo).JdStoreID - for _, v := range batchItemList { - promotionItem := v.(*tPromotionItemInfo) - if promotionItem.JdStoreID != stationNo { - // globals.SugarLogger.Debugf("RefreshJdStoreSkuStock BatchUpdateCurrentQtys stationNo:%s, stockList:%s", stationNo, utils.Format4Output(stockList, false)) - _, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, stockList, userName) - if err != nil { - globals.SugarLogger.Warnf("RefreshJdStoreSkuStock BatchUpdateCurrentQtys failed with error:%v", err) + task := tasksch.NewParallelTask("RefreshJdStoreSkuStock", tasksch.NewParallelConfig().SetBatchSize(jdapi.MaxStoreSkuBatchSize).SetIsContinueWhenError(true), jxcontext.AdminCtx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + stockList := make([]*jdapi.SkuStock, 0) + stationNo := batchItemList[0].(*tPromotionItemInfo).JdStoreID + for _, v := range batchItemList { + promotionItem := v.(*tPromotionItemInfo) + if promotionItem.JdStoreID != stationNo { + // globals.SugarLogger.Debugf("RefreshJdStoreSkuStock BatchUpdateCurrentQtys stationNo:%s, stockList:%s", stationNo, utils.Format4Output(stockList, false)) + _, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, stockList, userName) + if err != nil { + globals.SugarLogger.Warnf("RefreshJdStoreSkuStock BatchUpdateCurrentQtys failed with error:%v", err) + } + stockList = make([]*jdapi.SkuStock, 0) + stationNo = promotionItem.JdStoreID } - stockList = make([]*jdapi.SkuStock, 0) - stationNo = promotionItem.JdStoreID + stockList = append(stockList, &jdapi.SkuStock{ + OutSkuId: utils.Int2Str(promotionItem.SkuID), + StockQty: model.MaxStoreSkuStockQty, + }) } - stockList = append(stockList, &jdapi.SkuStock{ - OutSkuId: utils.Int2Str(promotionItem.SkuID), - StockQty: model.MaxStoreSkuStockQty, - }) - } - // globals.SugarLogger.Debugf("RefreshJdStoreSkuStock BatchUpdateCurrentQtys stationNo:%s, stockList:%s", stationNo, utils.Format4Output(stockList, false)) - _, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, stockList, userName) - if err != nil { - globals.SugarLogger.Warnf("RefreshJdStoreSkuStock BatchUpdateCurrentQtys failed with error:%v", err) - } - return nil, err - }, promotionItemList) + // globals.SugarLogger.Debugf("RefreshJdStoreSkuStock BatchUpdateCurrentQtys stationNo:%s, stockList:%s", stationNo, utils.Format4Output(stockList, false)) + _, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, stockList, userName) + if err != nil { + globals.SugarLogger.Warnf("RefreshJdStoreSkuStock BatchUpdateCurrentQtys failed with error:%v", err) + } + return nil, err + }, promotionItemList) task.Run() _, err = task.GetResult(0) } diff --git a/business/jxstore/promotion/promotion.go b/business/jxstore/promotion/promotion.go index a2af2dea4..a7aa37f1e 100644 --- a/business/jxstore/promotion/promotion.go +++ b/business/jxstore/promotion/promotion.go @@ -65,22 +65,22 @@ func SendAdvertingByGoodsOrder(ctx *jxcontext.Context, advertising string, days mobileNumbers = append(mobileNumbers, "18180948107") smsClient := aliyunsmsclient.New("http://dysmsapi.aliyuncs.com/") - task := tasksch.NewParallelTask("SendAdvertingByGoodsOrder", tasksch.NewParallelConfig().SetBatchSize(MaxBatchSize), userName, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - numbers := make([]string, len(batchItemList)) - for k, v := range batchItemList { - numbers[k] = v.(string) - } - numberStr := strings.Join(numbers, ",") - _, err = smsClient.Execute(globals.AliKey, globals.AliSecret, numberStr, "京西菜市", "SMS_109345355", string(utils.MustMarshal(map[string]interface{}{ - "code": "code", - }))) - if err != nil { - globals.SugarLogger.Infof("SendAdvertingByGoodsOrder numbers:%s failed with error:%v", numberStr, err) - } - return nil, err - }, mobileNumbers) - ctx.SetTaskOrAddChild(task, nil) - tasksch.ManageTask(task).Run() + task := tasksch.NewParallelTask("SendAdvertingByGoodsOrder", tasksch.NewParallelConfig().SetBatchSize(MaxBatchSize), ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + numbers := make([]string, len(batchItemList)) + for k, v := range batchItemList { + numbers[k] = v.(string) + } + numberStr := strings.Join(numbers, ",") + _, err = smsClient.Execute(globals.AliKey, globals.AliSecret, numberStr, "京西菜市", "SMS_109345355", string(utils.MustMarshal(map[string]interface{}{ + "code": "code", + }))) + if err != nil { + globals.SugarLogger.Infof("SendAdvertingByGoodsOrder numbers:%s failed with error:%v", numberStr, err) + } + return nil, err + }, mobileNumbers) + tasksch.HandleTask(task, nil, true).Run() if !isAsync { _, err = task.GetResult(0) diff --git a/business/jxstore/tempop/tempop.go b/business/jxstore/tempop/tempop.go index 5ef97d22a..fd036bcca 100644 --- a/business/jxstore/tempop/tempop.go +++ b/business/jxstore/tempop/tempop.go @@ -138,11 +138,12 @@ func Convert2JDSPU(ctx *jxcontext.Context, count int, isAsync, isContinueWhenErr if err = dao.GetRows(db, &skuNameList, sql, utils.DefaultTimeValue); err != nil { return "", err } - rootTask := tasksch.NewParallelTask("Convert2JDSPU", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - skuName := batchItemList[0].(*model.SkuName) - _, err = cms.CurVendorSync.SyncSku(ctx, db, skuName.ID, -1, false, isContinueWhenError, ctx.GetUserName()) - return nil, err - }, skuNameList) + rootTask := tasksch.NewParallelTask("Convert2JDSPU", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + skuName := batchItemList[0].(*model.SkuName) + _, err = cms.CurVendorSync.SyncSku(ctx, db, skuName.ID, -1, false, isContinueWhenError, ctx.GetUserName()) + return nil, err + }, skuNameList) tasksch.ManageTask(rootTask).Run() if !isAsync { @@ -283,8 +284,9 @@ func Change2JDSPU4Store(ctx *jxcontext.Context, storeIDs []int, step int, isAsyn func TransferLegacyJdOrder(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { sqlBatchCount := 1000 - rootTask := tasksch.NewSeqTask("TransferLegacyJdOrder", ctx.GetUserName(), func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - sql := ` + rootTask := tasksch.NewSeqTask("TransferLegacyJdOrder", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + sql := ` SELECT t1.* FROM jdorder t1 LEFT JOIN goods_order_original t2 ON t2.vendor_order_id = t1.vendor_order_id @@ -292,58 +294,59 @@ func TransferLegacyJdOrder(ctx *jxcontext.Context, isAsync, isContinueWhenError ORDER BY t1.orderstatustime LIMIT ? ` - db := dao.GetDB() - var jdOrderList []*legacymodel2.Jdorder - if err = dao.GetRows(db, &jdOrderList, sql, sqlBatchCount); err != nil { - return nil, err - } - if len(jdOrderList) > 0 { - task := tasksch.NewParallelTask("TransferLegacyJdOrder2", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetBatchSize(40), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - var orderDetailList []*model.GoodsOrderOriginal - for _, v := range batchItemList { - jdOrder := v.(*legacymodel2.Jdorder) - var detail map[string]interface{} - if err = utils.UnmarshalUseNumber([]byte(strings.Replace(strings.Replace(jdOrder.Data, "\n", "", -1), "\r", "", -1)), &detail); err != nil { - return nil, err - } - resultList := detail["result"].(map[string]interface{})["resultList"].([]interface{}) - if len(resultList) > 0 { - originalData := resultList[0].(map[string]interface{}) - orgCode := originalData["orgCode"].(string) - if orgCode == "320406" { - orderPurchaseTime := utils.Interface2String(originalData["orderPurchaseTime"]) - if orderPurchaseTime == "" { - globals.SugarLogger.Debugf("TransferLegacyJdOrder abnormal order:%s", jdOrder.VendorOrderID) - orderPurchaseTime = utils.Interface2String(originalData["orderStartTime"]) + db := dao.GetDB() + var jdOrderList []*legacymodel2.Jdorder + if err = dao.GetRows(db, &jdOrderList, sql, sqlBatchCount); err != nil { + return nil, err + } + if len(jdOrderList) > 0 { + task := tasksch.NewParallelTask("TransferLegacyJdOrder2", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetBatchSize(40), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + var orderDetailList []*model.GoodsOrderOriginal + for _, v := range batchItemList { + jdOrder := v.(*legacymodel2.Jdorder) + var detail map[string]interface{} + if err = utils.UnmarshalUseNumber([]byte(strings.Replace(strings.Replace(jdOrder.Data, "\n", "", -1), "\r", "", -1)), &detail); err != nil { + return nil, err } - if orderPurchaseTime != "" { - orderDetail := &model.GoodsOrderOriginal{ - VendorOrderID: jdOrder.VendorOrderID, - VendorID: model.VendorIDJD, - AccountNo: orgCode, - OrderCreatedAt: utils.Str2Time(orderPurchaseTime), - OriginalData: string(utils.MustMarshal(originalData)), + resultList := detail["result"].(map[string]interface{})["resultList"].([]interface{}) + if len(resultList) > 0 { + originalData := resultList[0].(map[string]interface{}) + orgCode := originalData["orgCode"].(string) + if orgCode == "320406" { + orderPurchaseTime := utils.Interface2String(originalData["orderPurchaseTime"]) + if orderPurchaseTime == "" { + globals.SugarLogger.Debugf("TransferLegacyJdOrder abnormal order:%s", jdOrder.VendorOrderID) + orderPurchaseTime = utils.Interface2String(originalData["orderStartTime"]) + } + if orderPurchaseTime != "" { + orderDetail := &model.GoodsOrderOriginal{ + VendorOrderID: jdOrder.VendorOrderID, + VendorID: model.VendorIDJD, + AccountNo: orgCode, + OrderCreatedAt: utils.Str2Time(orderPurchaseTime), + OriginalData: string(utils.MustMarshal(originalData)), + } + orderDetailList = append(orderDetailList, orderDetail) + } else { + globals.SugarLogger.Debugf("TransferLegacyJdOrder abnormal2 order:%s", jdOrder.VendorOrderID) + } } - orderDetailList = append(orderDetailList, orderDetail) - } else { - globals.SugarLogger.Debugf("TransferLegacyJdOrder abnormal2 order:%s", jdOrder.VendorOrderID) } } - } - } - if len(orderDetailList) > 0 { - err = dao.CreateMultiEntities(db, orderDetailList) - } - return nil, err - }, jdOrderList) - // rootTask.AddChild(task).Run() - task.Run() - _, err = task.GetResult(0) - } else { - rootTask.Cancel() - } - return nil, err - }, math.MaxInt32) + if len(orderDetailList) > 0 { + err = dao.CreateMultiEntities(db, orderDetailList) + } + return nil, err + }, jdOrderList) + // rootTask.AddChild(task).Run() + task.Run() + _, err = task.GetResult(0) + } else { + rootTask.Cancel() + } + return nil, err + }, math.MaxInt32) tasksch.ManageTask(rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) @@ -484,38 +487,39 @@ func PullJdOrder(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, is gapList[k] = k } - rootTask := tasksch.NewParallelTask("PullJdOrder", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(20), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - gapIndex := batchItemList[0].(int) - hourIndex := gapIndex * hourGap - subFromTime := fromTime.Add(time.Duration(hourIndex) * time.Hour) - subToTime := fromTime.Add(time.Duration(hourIndex+hourGap) * time.Hour) - if subToTime.Sub(toTime) > 0 { - subToTime = toTime - } - if true { //gapIndex < gapCount-1 { - subToTime = subToTime.Add(-1 * time.Second) // 减一秒 - } - commonParams := map[string]interface{}{ - jdapi.KeyPageSize: pageSize, - "orderPurchaseTime_begin": utils.Time2Str(subFromTime), - "orderPurchaseTime_end": utils.Time2Str(subToTime), - } - // globals.SugarLogger.Debugf("PullJdOrder, commonParams=%s", utils.Format4Output(commonParams, false)) - orderList, totalCount, err := api.JdAPI.OrderQuery(commonParams) - if err != nil { - return "", err - } - storeOrderList, err := api.JdAPI.GetStoreOrderInfoList(utils.Time2Str(subFromTime), utils.Time2Str(subToTime)) - if err != nil { - } - if err = saveJdOrderList(existJdIDMap, orderList, storeOrderList); err != nil { - return "", err - } - if false { - globals.SugarLogger.Debugf("subFromTime:%s, subToTime:%s, totalCount:%d, len(orderList):%d", utils.Time2Str(subFromTime), utils.Time2Str(subToTime), totalCount, len(orderList)) - } - return nil, err - }, gapList) + rootTask := tasksch.NewParallelTask("PullJdOrder", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(20), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + gapIndex := batchItemList[0].(int) + hourIndex := gapIndex * hourGap + subFromTime := fromTime.Add(time.Duration(hourIndex) * time.Hour) + subToTime := fromTime.Add(time.Duration(hourIndex+hourGap) * time.Hour) + if subToTime.Sub(toTime) > 0 { + subToTime = toTime + } + if true { //gapIndex < gapCount-1 { + subToTime = subToTime.Add(-1 * time.Second) // 减一秒 + } + commonParams := map[string]interface{}{ + jdapi.KeyPageSize: pageSize, + "orderPurchaseTime_begin": utils.Time2Str(subFromTime), + "orderPurchaseTime_end": utils.Time2Str(subToTime), + } + // globals.SugarLogger.Debugf("PullJdOrder, commonParams=%s", utils.Format4Output(commonParams, false)) + orderList, totalCount, err := api.JdAPI.OrderQuery(commonParams) + if err != nil { + return "", err + } + storeOrderList, err := api.JdAPI.GetStoreOrderInfoList(utils.Time2Str(subFromTime), utils.Time2Str(subToTime)) + if err != nil { + } + if err = saveJdOrderList(existJdIDMap, orderList, storeOrderList); err != nil { + return "", err + } + if false { + globals.SugarLogger.Debugf("subFromTime:%s, subToTime:%s, totalCount:%d, len(orderList):%d", utils.Time2Str(subFromTime), utils.Time2Str(subToTime), totalCount, len(orderList)) + } + return nil, err + }, gapList) tasksch.ManageTask(rootTask).Run() if !isAsync { @@ -562,17 +566,18 @@ func DeleteWrongSpu(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) ( if err = dao.GetRows(db, &skuNameList, sql, utils.DefaultTimeValue); err != nil { return "", err } - rootTask := tasksch.NewSeqTask("DeleteWrongSpu", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - mapData := map[string]interface{}{ - "name": skuNameList[step].Name, - } - _, err = cms.UpdateSkuName(ctx, skuNameList[step].ID, mapData, ctx.GetUserName()) - if err != nil { - globals.SugarLogger.Debugf("DeleteWrongSpu failed nameid:%d, name:%s, with error:%v", skuNameList[step].ID, skuNameList[step].Name, err) - err = nil // 强制忽略错误 - } - return nil, err - }, len(skuNameList)) + rootTask := tasksch.NewSeqTask("DeleteWrongSpu", ctx, + func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + mapData := map[string]interface{}{ + "name": skuNameList[step].Name, + } + _, err = cms.UpdateSkuName(ctx, skuNameList[step].ID, mapData, ctx.GetUserName()) + if err != nil { + globals.SugarLogger.Debugf("DeleteWrongSpu failed nameid:%d, name:%s, with error:%v", skuNameList[step].ID, skuNameList[step].Name, err) + err = nil // 强制忽略错误 + } + return nil, err + }, len(skuNameList)) tasksch.ManageTask(rootTask).Run() if !isAsync { @@ -590,8 +595,9 @@ type GoodsOrderOriginalEx struct { func CreateOrderFromOriginal(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { sqlBatchCount := 5000 - rootTask := tasksch.NewSeqTask("CreateOrderFromOriginal", ctx.GetUserName(), func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - sql := ` + rootTask := tasksch.NewSeqTask("CreateOrderFromOriginal", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + sql := ` SELECT t1.*, t3.order_status FROM goods_order_original t1 LEFT JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id @@ -599,58 +605,59 @@ func CreateOrderFromOriginal(ctx *jxcontext.Context, isAsync, isContinueWhenErro WHERE t2.id IS NULL LIMIT ?; ` - rawDB := orm.NewOrm() - db := dao.WrapDB(rawDB) - var orderList []*GoodsOrderOriginalEx - if err = dao.GetRows(db, &orderList, sql, sqlBatchCount); err != nil { - return nil, err - } - if len(orderList) > 0 { - task := tasksch.NewParallelTask("CreateOrderFromOriginal", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(1), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - orderOriginal := batchItemList[0].(*GoodsOrderOriginalEx) - globals.SugarLogger.Debugf("CreateOrderFromOriginal processing orderID:%s", orderOriginal.VendorOrderID) - if handler := partner.GetPurchasePlatformFromVendorID(orderOriginal.VendorID); handler != nil { - var detail map[string]interface{} - if err = utils.UnmarshalUseNumber([]byte(strings.Replace(strings.Replace(orderOriginal.OriginalData, "\n", "", -1), "\r", "", -1)), &detail); err != nil { - globals.SugarLogger.Debugf("CreateOrderFromOriginal abnormal orderID:%s, error:%v", orderOriginal.VendorOrderID, err) - return nil, err - } - order := handler.Map2Order(detail) - if order.Status < model.OrderStatusEndBegin { - if orderOriginal.OrderStatus == 3 { - order.Status = model.OrderStatusFinished - } else if orderOriginal.OrderStatus == 7 { - order.Status = model.OrderStatusCanceled - } else { - order2, err2 := handler.GetOrder(order.VendorOrderID) - if err = err2; err == nil { - order.Status = order2.Status - } else { - err = nil // ignore get status error - } - } - } - if err == nil { - rawDB := orm.NewOrm() - if _, err = orderman.FixedOrderManager.SaveOrder(order, false, rawDB); err != nil { - globals.SugarLogger.Debugf("CreateOrderFromOriginal abnormal orderID:%s, error:%v", orderOriginal.VendorOrderID, err) - } - } else { - globals.SugarLogger.Debugf("CreateOrderFromOriginal abnormal orderID:%s, error:%v", orderOriginal.VendorOrderID, err) - } - } else { - globals.SugarLogger.Debugf("CreateOrderFromOriginal abnormal orderID:%s", orderOriginal.VendorOrderID) - } + rawDB := orm.NewOrm() + db := dao.WrapDB(rawDB) + var orderList []*GoodsOrderOriginalEx + if err = dao.GetRows(db, &orderList, sql, sqlBatchCount); err != nil { return nil, err - }, orderList) - // rootTask.AddChild(task).Run() - task.Run() - _, err = task.GetResult(0) - } else { - rootTask.Cancel() - } - return nil, err - }, math.MaxInt32) + } + if len(orderList) > 0 { + task := tasksch.NewParallelTask("CreateOrderFromOriginal", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(1), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + orderOriginal := batchItemList[0].(*GoodsOrderOriginalEx) + globals.SugarLogger.Debugf("CreateOrderFromOriginal processing orderID:%s", orderOriginal.VendorOrderID) + if handler := partner.GetPurchasePlatformFromVendorID(orderOriginal.VendorID); handler != nil { + var detail map[string]interface{} + if err = utils.UnmarshalUseNumber([]byte(strings.Replace(strings.Replace(orderOriginal.OriginalData, "\n", "", -1), "\r", "", -1)), &detail); err != nil { + globals.SugarLogger.Debugf("CreateOrderFromOriginal abnormal orderID:%s, error:%v", orderOriginal.VendorOrderID, err) + return nil, err + } + order := handler.Map2Order(detail) + if order.Status < model.OrderStatusEndBegin { + if orderOriginal.OrderStatus == 3 { + order.Status = model.OrderStatusFinished + } else if orderOriginal.OrderStatus == 7 { + order.Status = model.OrderStatusCanceled + } else { + order2, err2 := handler.GetOrder(order.VendorOrderID) + if err = err2; err == nil { + order.Status = order2.Status + } else { + err = nil // ignore get status error + } + } + } + if err == nil { + rawDB := orm.NewOrm() + if _, err = orderman.FixedOrderManager.SaveOrder(order, false, rawDB); err != nil { + globals.SugarLogger.Debugf("CreateOrderFromOriginal abnormal orderID:%s, error:%v", orderOriginal.VendorOrderID, err) + } + } else { + globals.SugarLogger.Debugf("CreateOrderFromOriginal abnormal orderID:%s, error:%v", orderOriginal.VendorOrderID, err) + } + } else { + globals.SugarLogger.Debugf("CreateOrderFromOriginal abnormal orderID:%s", orderOriginal.VendorOrderID) + } + return nil, err + }, orderList) + // rootTask.AddChild(task).Run() + task.Run() + _, err = task.GetResult(0) + } else { + rootTask.Cancel() + } + return nil, err + }, math.MaxInt32) tasksch.ManageTask(rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) @@ -688,91 +695,93 @@ func TransformJdSpu2Sku(ctx *jxcontext.Context, skuNameIDs []int, count int, isA return "", fmt.Errorf("待转换的skuName为空") } batchSize := 40 - rootTask := tasksch.NewSeqTask("TransformJdSpu2Sku", ctx.GetUserName(), func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - var ( - locker sync.Mutex - skuIDs []int - ) - lastIndex := (step + 1) * batchSize - if lastIndex > len(skuNameList) { - lastIndex = len(skuNameList) - } - batchSkNameList := skuNameList[step*batchSize : lastIndex] - subTask := tasksch.NewParallelTask(fmt.Sprintf("TransformJdSpu2Sku:%d", step), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(subTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - skuName := batchItemList[0].(*model.SkuName) - if !jxutils.IsFakeID(skuName.JdID) { - sql = ` + rootTask := tasksch.NewSeqTask("TransformJdSpu2Sku", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + var ( + locker sync.Mutex + skuIDs []int + ) + lastIndex := (step + 1) * batchSize + if lastIndex > len(skuNameList) { + lastIndex = len(skuNameList) + } + batchSkNameList := skuNameList[step*batchSize : lastIndex] + subTask := tasksch.NewParallelTask(fmt.Sprintf("TransformJdSpu2Sku:%d", step), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(subTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + skuName := batchItemList[0].(*model.SkuName) + if !jxutils.IsFakeID(skuName.JdID) { + sql = ` SELECT * FROM sku WHERE name_id = ? AND deleted_at = ? AND status <> ?; ` - sqlParams := []interface{}{ - skuName.ID, - utils.DefaultTimeValue, - model.SkuStatusDeleted, - } - var skuList []*model.Sku - if err = dao.GetRows(db, &skuList, sql, sqlParams...); err != nil { - return "", err - } - globals.SugarLogger.Debugf("TransformJdSpu2Sku skuList:%s", utils.Format4Output(skuList, false)) - if len(skuList) > 0 { - for _, sku := range skuList { - locker.Lock() - skuIDs = append(skuIDs, sku.ID) - locker.Unlock() - if !jxutils.IsFakeID(sku.JdID) { - if globals.EnableStoreWrite { - if err = api.JdAPI.UpdateSkuBaseInfo(utils.Int2Str(skuName.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)); err != nil { - break + sqlParams := []interface{}{ + skuName.ID, + utils.DefaultTimeValue, + model.SkuStatusDeleted, + } + var skuList []*model.Sku + if err = dao.GetRows(db, &skuList, sql, sqlParams...); err != nil { + return "", err + } + globals.SugarLogger.Debugf("TransformJdSpu2Sku skuList:%s", utils.Format4Output(skuList, false)) + if len(skuList) > 0 { + for _, sku := range skuList { + locker.Lock() + skuIDs = append(skuIDs, sku.ID) + locker.Unlock() + if !jxutils.IsFakeID(sku.JdID) { + if globals.EnableStoreWrite { + if err = api.JdAPI.UpdateSkuBaseInfo(utils.Int2Str(skuName.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)); err != nil { + break + } + } } } } - } - } - if err == nil && globals.EnableStoreWrite { - if err = api.JdAPI.UpdateSpu(utils.Int2Str(skuName.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusOffline)); err == nil { - err = api.JdAPI.UpdateSpu(utils.Int2Str(skuName.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)) - } - } - if err == nil { - skuName.IsSpu = 0 - skuName.JdID = 0 - if _, err = dao.UpdateEntity(db, skuName, "IsSpu", "JdID"); err == nil { - sql := ` + if err == nil && globals.EnableStoreWrite { + if err = api.JdAPI.UpdateSpu(utils.Int2Str(skuName.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusOffline)); err == nil { + err = api.JdAPI.UpdateSpu(utils.Int2Str(skuName.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)) + } + } + if err == nil { + skuName.IsSpu = 0 + skuName.JdID = 0 + if _, err = dao.UpdateEntity(db, skuName, "IsSpu", "JdID"); err == nil { + sql := ` UPDATE sku t1 SET t1.jd_sync_status = ?, t1.jd_id = 0 WHERE t1.name_id = ? AND t1.deleted_at = ? AND t1.status <> ? ` - sqlParams := []interface{}{ - model.SyncFlagNewMask, - skuName.ID, - utils.DefaultTimeValue, - model.SkuStatusDeleted, - } - if _, err = dao.ExecuteSQL(db, sql, sqlParams...); err == nil { - _, err = cms.CurVendorSync.SyncSku(ctx, db, skuName.ID, -1, false, isContinueWhenError, ctx.GetUserName()) + sqlParams := []interface{}{ + model.SyncFlagNewMask, + skuName.ID, + utils.DefaultTimeValue, + model.SkuStatusDeleted, + } + if _, err = dao.ExecuteSQL(db, sql, sqlParams...); err == nil { + _, err = cms.CurVendorSync.SyncSku(ctx, db, skuName.ID, -1, false, isContinueWhenError, ctx.GetUserName()) + } + } } + } else { + globals.SugarLogger.Debugf("TransformJdSpu2Sku skuName:%d is fake", skuName.ID) + } + return nil, err + }, batchSkNameList) + rootTask.AddChild(subTask).Run() + if _, err = subTask.GetResult(0); err == nil { + if len(skuIDs) > 0 { + if _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDJD, -1, skuIDs, model.SyncFlagModifiedMask|model.SyncFlagPriceMask|model.SyncFlagSaleMask); err == nil { + time.Sleep(20 * time.Second) + _, err = cms.CurVendorSync.SyncStoresSkus(ctx, db, []int{model.VendorIDJD}, nil, skuIDs, false, isContinueWhenError) } } - } else { - globals.SugarLogger.Debugf("TransformJdSpu2Sku skuName:%d is fake", skuName.ID) } return nil, err - }, batchSkNameList) - rootTask.AddChild(subTask).Run() - if _, err = subTask.GetResult(0); err == nil { - if len(skuIDs) > 0 { - if _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDJD, -1, skuIDs, model.SyncFlagModifiedMask|model.SyncFlagPriceMask|model.SyncFlagSaleMask); err == nil { - time.Sleep(20 * time.Second) - _, err = cms.CurVendorSync.SyncStoresSkus(ctx, db, []int{model.VendorIDJD}, nil, skuIDs, false, isContinueWhenError) - } - } - } - return nil, err - }, (len(skuNameList)-1)/batchSize+1) + }, (len(skuNameList)-1)/batchSize+1) tasksch.ManageTask(rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) @@ -795,21 +804,22 @@ func ReProcessJdBadComment(ctx *jxcontext.Context, isForce, isAsync, isContinueW var commentList []*legacymodel.JxBadComments if err = dao.GetRows(db, &commentList, sql); err == nil { if len(commentList) > 0 { - rootTask := tasksch.NewParallelTask("ReProcessJdBadComment", nil, ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - badComment := batchItemList[0].(*legacymodel.JxBadComments) - comment1, _ := unmarshalCommentText(badComment.Msg) - comment2, _ := unmarshalCommentText(badComment.UpdatedMsg) - if len(comment1) > 0 { - badComment.Createtime = utils.Timestamp2Str(utils.MustInterface2Int64(comment1["createTime"].(map[string]interface{})["time"]) / 1000) - badComment.Msg = string(utils.MustMarshal(comment1)) - if len(comment2) > 0 { - badComment.Updatetime = utils.Timestamp2Str(utils.MustInterface2Int64(comment2["createTime"].(map[string]interface{})["time"]) / 1000) - badComment.UpdatedMsg = string(utils.MustMarshal(comment2)) + rootTask := tasksch.NewParallelTask("ReProcessJdBadComment", nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + badComment := batchItemList[0].(*legacymodel.JxBadComments) + comment1, _ := unmarshalCommentText(badComment.Msg) + comment2, _ := unmarshalCommentText(badComment.UpdatedMsg) + if len(comment1) > 0 { + badComment.Createtime = utils.Timestamp2Str(utils.MustInterface2Int64(comment1["createTime"].(map[string]interface{})["time"]) / 1000) + badComment.Msg = string(utils.MustMarshal(comment1)) + if len(comment2) > 0 { + badComment.Updatetime = utils.Timestamp2Str(utils.MustInterface2Int64(comment2["createTime"].(map[string]interface{})["time"]) / 1000) + badComment.UpdatedMsg = string(utils.MustMarshal(comment2)) + } + _, err = dao.UpdateEntity(db, badComment) } - _, err = dao.UpdateEntity(db, badComment) - } - return nil, err - }, commentList) + return nil, err + }, commentList) tasksch.ManageTask(rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) @@ -856,15 +866,16 @@ func RefreshEbaiBadComment(ctx *jxcontext.Context, fromTime, toTime time.Time, i } days := int(toTime.Sub(fromTime)/(24*time.Hour) + 1) globals.SugarLogger.Debugf("RefreshEbaiBadComment fromTime:%s, toTime:%s, days:%d", utils.Time2Str(fromTime), utils.Time2Str(toTime), days) - rootTask := tasksch.NewSeqTask("RefreshEbaiBadComment", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - batchFromTime := fromTime.Add(time.Duration(step) * 24 * time.Hour) - batchToTime := batchFromTime.Add(24*time.Hour - time.Second) - if batchToTime.Sub(toTime) > 0 { - batchToTime = toTime - } - err = ebai.CurPurchaseHandler.RefreshComment(batchFromTime, batchToTime) - return nil, err - }, days) + rootTask := tasksch.NewSeqTask("RefreshEbaiBadComment", ctx, + func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + batchFromTime := fromTime.Add(time.Duration(step) * 24 * time.Hour) + batchToTime := batchFromTime.Add(24*time.Hour - time.Second) + if batchToTime.Sub(toTime) > 0 { + batchToTime = toTime + } + err = ebai.CurPurchaseHandler.RefreshComment(batchFromTime, batchToTime) + return nil, err + }, days) tasksch.ManageTask(rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) diff --git a/business/jxutils/jxcontext/jxcontext.go b/business/jxutils/jxcontext/jxcontext.go index 0b03c4b2d..e1fff6e9a 100644 --- a/business/jxutils/jxcontext/jxcontext.go +++ b/business/jxutils/jxcontext/jxcontext.go @@ -3,12 +3,10 @@ package jxcontext import ( "errors" "net/http" - "sync" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/auth2" "git.rosy.net.cn/jx-callback/business/jxcallback/auth" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/globals" "github.com/astaxie/beego" @@ -21,14 +19,12 @@ type IAuther interface { } type Context struct { - rootTask tasksch.ITask token string accessUUID string userInfo IAuther //*auth.LoginInfo w http.ResponseWriter r *http.Request mapData map[interface{}]interface{} - locker sync.RWMutex } const ( @@ -43,9 +39,8 @@ func init() { AdminCtx = NewWithUserName(nil, model.AdminName, nil, nil) } -func NewWithUserName(rootTask tasksch.ITask, userName string, w http.ResponseWriter, r *http.Request) (ctx *Context) { +func NewWithUserName(notUsed interface{}, userName string, w http.ResponseWriter, r *http.Request) (ctx *Context) { ctx = &Context{ - rootTask: rootTask, token: userName, w: w, r: r, @@ -55,9 +50,8 @@ func NewWithUserName(rootTask tasksch.ITask, userName string, w http.ResponseWri return ctx } -func New(rootTask tasksch.ITask, token string, w http.ResponseWriter, r *http.Request) (ctx *Context, errCode string, err error) { +func New(notUsed interface{}, token string, w http.ResponseWriter, r *http.Request) (ctx *Context, errCode string, err error) { ctx = &Context{ - rootTask: rootTask, token: token, w: w, r: r, @@ -141,34 +135,6 @@ func (ctx *Context) GetV2AuthInfo() (authInfo *auth2.AuthInfo, err error) { return nil, auth2.ErrNeedV2Token } -func (ctx *Context) GetRootTask() tasksch.ITask { - ctx.locker.RLock() - defer ctx.locker.RUnlock() - - return ctx.rootTask -} - -func (ctx *Context) SetTaskOrAddChild(task tasksch.ITask, parentTask tasksch.ITask) bool { - if parentTask != nil { - parentTask.AddChild(task) - } else { - parentTask = task - } - ctx.locker.RLock() - if ctx.rootTask == nil { - ctx.locker.RUnlock() - - ctx.locker.Lock() - if ctx.rootTask == nil { - ctx.rootTask = parentTask - } - ctx.locker.Unlock() - return true - } - ctx.locker.RUnlock() - return false -} - func (ctx *Context) GetResponseWriter() http.ResponseWriter { return ctx.w } @@ -176,17 +142,3 @@ func (ctx *Context) GetResponseWriter() http.ResponseWriter { func (ctx *Context) GetRequest() *http.Request { return ctx.r } - -func (ctx *Context) SetValue(key, value interface{}) { - ctx.locker.Lock() - defer ctx.locker.Unlock() - - ctx.mapData[key] = value -} - -func (ctx *Context) GetValue(key interface{}) interface{} { - ctx.locker.RLock() - defer ctx.locker.RUnlock() - - return ctx.mapData[key] -} diff --git a/business/jxutils/msg/msg.go b/business/jxutils/msg/msg.go new file mode 100644 index 000000000..7436d8312 --- /dev/null +++ b/business/jxutils/msg/msg.go @@ -0,0 +1,24 @@ +package msg + +import ( + "git.rosy.net.cn/jx-callback/business/auth2" + "git.rosy.net.cn/jx-callback/business/auth2/authprovider/dingding" + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" +) + +func SendUserMessage(userID, title, content string) (err error) { + authList, err := auth2.GetUserBindAuthInfo(userID) + if err == nil { + for _, auth := range authList { + if auth.Type == dingding.AuthTypeStaff { + err = api.DingDingAPI.CorpAsyncSendSimple(auth.AuthID, content) + break + } + } + } + if err != nil { + globals.SugarLogger.Infof("SendUserMessage userID:%s, title:%s, content:%s failed with error:%v", userID, title, content, err) + } + return err +} diff --git a/business/jxutils/tasksch/parallel_task.go b/business/jxutils/tasksch/parallel_task.go index 8655b495f..e50944c3a 100644 --- a/business/jxutils/tasksch/parallel_task.go +++ b/business/jxutils/tasksch/parallel_task.go @@ -6,6 +6,7 @@ import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/globals" ) @@ -18,6 +19,8 @@ type WorkFunc func(task *ParallelTask, batchItemList []interface{}, params ...in type ResultHandlerFunc func(taskName string, result []interface{}, err error) type ParallelConfig struct { + // ParentTask ITask + // IsAsync bool ParallelCount int BatchSize int IsContinueWhenError bool @@ -41,9 +44,11 @@ var ( func NewParallelConfig() *ParallelConfig { return &ParallelConfig{ + // ParentTask: parentTask, + // IsAsync: false, + IsContinueWhenError: false, ParallelCount: DefParallelCount, BatchSize: 1, - IsContinueWhenError: false, ResultHandler: nil, } } @@ -63,12 +68,17 @@ func (c *ParallelConfig) SetIsContinueWhenError(isContinueWhenError bool) *Paral return c } +// func (c *ParallelConfig) SetIsAsync(isAsync bool) *ParallelConfig { +// c.IsAsync = isAsync +// return c +// } + func (c *ParallelConfig) SetResultHandler(resultHandler ResultHandlerFunc) *ParallelConfig { c.ResultHandler = resultHandler return c } -func NewParallelTask(taskName string, config *ParallelConfig, userName string, worker WorkFunc, itemList interface{}, params ...interface{}) *ParallelTask { +func NewParallelTask(taskName string, config *ParallelConfig, ctx *jxcontext.Context, worker WorkFunc, itemList interface{}, params ...interface{}) *ParallelTask { if config == nil { config = NewParallelConfig() } @@ -91,7 +101,7 @@ func NewParallelTask(taskName string, config *ParallelConfig, userName string, w worker: worker, jobList: jobList, } - task.Init(config.ParallelCount, config.BatchSize, config.IsContinueWhenError, params, taskName, userName, len(realItemList), jobListLen) + task.Init(config.ParallelCount, config.BatchSize, config.IsContinueWhenError, params, taskName, ctx, len(realItemList), jobListLen) return task } diff --git a/business/jxutils/tasksch/parallel_task_test.go b/business/jxutils/tasksch/parallel_task_test.go index 01b332c18..5343f560a 100644 --- a/business/jxutils/tasksch/parallel_task_test.go +++ b/business/jxutils/tasksch/parallel_task_test.go @@ -7,6 +7,7 @@ import ( "time" "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" ) func TestRunParallelTask(t *testing.T) { @@ -14,16 +15,17 @@ func TestRunParallelTask(t *testing.T) { for k := range itemList { itemList[k] = k } - task := NewParallelTask("test", NewParallelConfig().SetParallelCount(100).SetBatchSize(7), "autotest", func(task *ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - sleepSecond := rand.Intn(5) - t.Logf("sleep %d seconds", sleepSecond) - time.Sleep(time.Duration(sleepSecond) * time.Second) - retSlice := make([]string, len(batchItemList)) - for k := range retSlice { - retSlice[k] = "hello:" + utils.Int2Str(batchItemList[k].(int)*2) - } - return retSlice, nil - }, itemList, "a", "b", 1, 2) + task := NewParallelTask("test", NewParallelConfig().SetParallelCount(100).SetBatchSize(7), jxcontext.AdminCtx, + func(task *ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + sleepSecond := rand.Intn(5) + t.Logf("sleep %d seconds", sleepSecond) + time.Sleep(time.Duration(sleepSecond) * time.Second) + retSlice := make([]string, len(batchItemList)) + for k := range retSlice { + retSlice[k] = "hello:" + utils.Int2Str(batchItemList[k].(int)*2) + } + return retSlice, nil + }, itemList, "a", "b", 1, 2) task.Run() result, err := task.GetResult(1 * time.Microsecond) if err == nil || task.GetStatus() != TaskStatusWorking { @@ -45,16 +47,17 @@ func TestCancelParallelTask(t *testing.T) { for k := range itemList { itemList[k] = k } - task := NewParallelTask("test", NewParallelConfig().SetParallelCount(100).SetBatchSize(7), "autotest", func(task *ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - sleepSecond := rand.Intn(5) - fmt.Printf("sleep %d seconds\n", sleepSecond) - time.Sleep(time.Duration(sleepSecond) * time.Second) - retSlice := make([]string, len(batchItemList)) - for k := range retSlice { - retSlice[k] = "hello:" + utils.Int2Str(batchItemList[k].(int)*2) - } - return retSlice, nil - }, itemList, "a", "b", 1, 2) + task := NewParallelTask("test", NewParallelConfig().SetParallelCount(100).SetBatchSize(7), jxcontext.AdminCtx, + func(task *ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + sleepSecond := rand.Intn(5) + fmt.Printf("sleep %d seconds\n", sleepSecond) + time.Sleep(time.Duration(sleepSecond) * time.Second) + retSlice := make([]string, len(batchItemList)) + for k := range retSlice { + retSlice[k] = "hello:" + utils.Int2Str(batchItemList[k].(int)*2) + } + return retSlice, nil + }, itemList, "a", "b", 1, 2) task.Run() // time.Sleep(time.Second * 6) fmt.Printf("finishedItemCount:%d, finishedJobCount:%d\n", task.GetFinishedItemCount(), task.GetFinishedJobCount()) @@ -71,19 +74,20 @@ func TestRunParallelTaskPartialSuccess(t *testing.T) { for k := range itemList { itemList[k] = k } - task := NewParallelTask("test", NewParallelConfig().SetParallelCount(100).SetBatchSize(7).SetIsContinueWhenError(true), "autotest", func(task *ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - sleepSecond := rand.Intn(5) - t.Logf("sleep %d seconds", sleepSecond) - time.Sleep(time.Duration(sleepSecond) * time.Second) - retSlice := make([]string, len(batchItemList)) - for k := range retSlice { - retSlice[k] = "hello:" + utils.Int2Str(batchItemList[k].(int)*2) - } - if rand.Intn(2) == 1 { - return nil, fmt.Errorf("test:%d", batchItemList[0].(int)) - } - return retSlice, nil - }, itemList, "a", "b", 1, 2) + task := NewParallelTask("test", NewParallelConfig().SetParallelCount(100).SetBatchSize(7).SetIsContinueWhenError(true), jxcontext.AdminCtx, + func(task *ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + sleepSecond := rand.Intn(5) + t.Logf("sleep %d seconds", sleepSecond) + time.Sleep(time.Duration(sleepSecond) * time.Second) + retSlice := make([]string, len(batchItemList)) + for k := range retSlice { + retSlice[k] = "hello:" + utils.Int2Str(batchItemList[k].(int)*2) + } + if rand.Intn(2) == 1 { + return nil, fmt.Errorf("test:%d", batchItemList[0].(int)) + } + return retSlice, nil + }, itemList, "a", "b", 1, 2) task.Run() result, err := task.GetResult(1 * time.Microsecond) if err == nil || task.GetStatus() != TaskStatusWorking { diff --git a/business/jxutils/tasksch/sequence_task.go b/business/jxutils/tasksch/sequence_task.go index ae8903394..d747286a0 100644 --- a/business/jxutils/tasksch/sequence_task.go +++ b/business/jxutils/tasksch/sequence_task.go @@ -4,6 +4,7 @@ import ( "time" "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/globals" ) @@ -19,11 +20,11 @@ type SeqTask struct { worker SeqWorkFunc } -func NewSeqTask(taskName string, userName string, worker SeqWorkFunc, stepCount int, params ...interface{}) *SeqTask { +func NewSeqTask(taskName string, ctx *jxcontext.Context, worker SeqWorkFunc, stepCount int, params ...interface{}) *SeqTask { task := &SeqTask{ worker: worker, } - task.Init(1, 1, false, params, taskName, userName, stepCount, stepCount) + task.Init(1, 1, false, params, taskName, ctx, stepCount, stepCount) return task } diff --git a/business/jxutils/tasksch/sequence_task_test.go b/business/jxutils/tasksch/sequence_task_test.go index e28709d30..29fff37f3 100644 --- a/business/jxutils/tasksch/sequence_task_test.go +++ b/business/jxutils/tasksch/sequence_task_test.go @@ -7,38 +7,41 @@ import ( "time" "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" ) func TestRunSeqTask(t *testing.T) { var seqTask ITask - seqTask = NewSeqTask("TestSeqTask", "autotest", func(task *SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - fmt.Println("ONE") - task2 := NewParallelTask("hello", nil, "xjh", func(parallelTask *ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - i := batchItemList[0].(int) - time.Sleep(2 * time.Second) - fmt.Println(i * 2) - return nil, nil - }, []int{1, 2, 3}) - seqTask.AddChild(task2) - time.Sleep(time.Duration(rand.Intn(3)) * time.Second) - task2.Run() - case 1: - fmt.Println("TWO") - time.Sleep(time.Duration(rand.Intn(3)) * time.Second) - case 2: - fmt.Println("THREE") - time.Sleep(time.Duration(rand.Intn(3)) * time.Second) - case 3: - fmt.Println("FOUR") - time.Sleep(time.Duration(rand.Intn(3)) * time.Second) - case 4: - fmt.Println("FIVE") - time.Sleep(time.Duration(rand.Intn(3)) * time.Second) - } - return []string{"1"}, nil - }, 5) + seqTask = NewSeqTask("TestSeqTask", jxcontext.AdminCtx, + func(task *SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + fmt.Println("ONE") + task2 := NewParallelTask("hello", nil, jxcontext.AdminCtx, + func(parallelTask *ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + i := batchItemList[0].(int) + time.Sleep(2 * time.Second) + fmt.Println(i * 2) + return nil, nil + }, []int{1, 2, 3}) + seqTask.AddChild(task2) + time.Sleep(time.Duration(rand.Intn(3)) * time.Second) + task2.Run() + case 1: + fmt.Println("TWO") + time.Sleep(time.Duration(rand.Intn(3)) * time.Second) + case 2: + fmt.Println("THREE") + time.Sleep(time.Duration(rand.Intn(3)) * time.Second) + case 3: + fmt.Println("FOUR") + time.Sleep(time.Duration(rand.Intn(3)) * time.Second) + case 4: + fmt.Println("FIVE") + time.Sleep(time.Duration(rand.Intn(3)) * time.Second) + } + return []string{"1"}, nil + }, 5) seqTask.Run() time.Sleep(3 * time.Second) diff --git a/business/jxutils/tasksch/task.go b/business/jxutils/tasksch/task.go index a71b14aa7..ed1426dee 100644 --- a/business/jxutils/tasksch/task.go +++ b/business/jxutils/tasksch/task.go @@ -8,6 +8,8 @@ import ( "time" "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + "git.rosy.net.cn/jx-callback/business/jxutils/msg" "git.rosy.net.cn/jx-callback/globals" ) @@ -97,14 +99,17 @@ type BaseTask struct { Children TaskList `json:"children"` Err error `json:"err"` - detailErrMsgList []string `json:"-"` - finishChan chan int - C <-chan int `json:"-"` + detailErrMsgList []string + finishChan chan struct{} + C <-chan struct{} `json:"-"` params []interface{} quitChan chan int locker sync.RWMutex parent ITask + + ctx *jxcontext.Context + isGetResultCalled bool } func (s TaskList) Len() int { @@ -121,7 +126,7 @@ func (s TaskList) Swap(i, j int) { s[j] = tmp } -func (t *BaseTask) Init(parallelCount, batchSize int, isContinueWhenError bool, params []interface{}, name, userName string, totalItemCount, totalJobCount int) { +func (t *BaseTask) Init(parallelCount, batchSize int, isContinueWhenError bool, params []interface{}, name string, ctx *jxcontext.Context, totalItemCount, totalJobCount int) { t.ID = utils.GetUUID() t.ParallelCount = parallelCount t.BatchSize = batchSize @@ -129,13 +134,14 @@ func (t *BaseTask) Init(parallelCount, batchSize int, isContinueWhenError bool, t.params = params t.Name = name t.CreatedAt = time.Now() - t.CreatedBy = userName + t.ctx = ctx + t.CreatedBy = ctx.GetUserName() t.UpdatedAt = t.CreatedAt t.TerminatedAt = utils.DefaultTimeValue t.TotalItemCount = totalItemCount t.TotalJobCount = totalJobCount t.quitChan = make(chan int) - t.finishChan = make(chan int) + t.finishChan = make(chan struct{}) t.Status = TaskStatusWorking t.C = t.finishChan @@ -155,6 +161,7 @@ func (t *BaseTask) GetResult(duration time.Duration) (retVal []interface{}, err timer := time.NewTimer(duration) select { case <-t.finishChan: + t.isGetResultCalled = true timer.Stop() return t.Result, t.Err case <-timer.C: @@ -249,6 +256,14 @@ func AddChild(parentTask ITask, task ITask) ITask { return task } +func HandleTask(task, parentTask ITask, isMangeIt bool) ITask { + AddChild(task, parentTask) + if parentTask == nil && isMangeIt { + ManageTask(task) + } + return task +} + ///////// func (t *BaseTask) MarshalJSON() ([]byte, error) { @@ -280,6 +295,18 @@ func (t *BaseTask) run(taskHandler func()) { } close(t.finishChan) + time.Sleep(10 * time.Millisecond) // 等待GetResult中的isGetResultCalled赋值 + if !t.isGetResultCalled && t.parent == nil && len(GetTasks(t.ID, TaskStatusBegin, TaskStatusEnd, 24, "")) == 0 { + if authInfo, err := t.ctx.GetV2AuthInfo(); err == nil { // 这里应该是不管登录类型,直接以可能的方式发消息 + var content string + if t.Status == TaskStatusFinished { + content = fmt.Sprintf("你的异步任务[%s]执行成功完成", t.Name) + } else { + content = fmt.Sprintf("你的异步任务[%s]执行失败,%s", t.Name, t.Err.Error()) + } + msg.SendUserMessage(authInfo.UserID, "异步任务完成", content) + } + } }) } } diff --git a/business/model/dao/dao_auth2.go b/business/model/dao/dao_auth2.go index 1fa5bbac2..17241fe1f 100644 --- a/business/model/dao/dao_auth2.go +++ b/business/model/dao/dao_auth2.go @@ -52,3 +52,18 @@ func GetAuthBindsByAuthID2(db *DaoDB, authID2 string, typeList []string) (authBi err = GetRows(db, &authBinds, sql, sqlParams...) return authBinds, err } + +func GetUserBindAuthInfo(db *DaoDB, userID string) (authList []*model.AuthBind, err error) { + sql := ` + SELECT * + FROM auth_bind t1 + WHERE t1.deleted_at = ? AND t1.status = ? AND t1.user_id = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + model.UserStatusNormal, + userID, + } + err = GetRows(db, &authList, sql, sqlParams...) + return authList, err +} diff --git a/business/model/dao/dao_user2.go b/business/model/dao/dao_user2.go index 5852f4203..e963396f0 100644 --- a/business/model/dao/dao_user2.go +++ b/business/model/dao/dao_user2.go @@ -23,18 +23,3 @@ func GetUserByID(db *DaoDB, fieldName, fieldValue string) (user *model.User, err err = GetRow(db, &user, sql, sqlParams...) return user, err } - -func GetUserBindAuthInfo(db *DaoDB, userID string) (authList []*model.AuthBind, err error) { - sql := ` - SELECT * - FROM auth_bind t1 - WHERE t1.deleted_at = ? AND t1.status = ? AND t1.user_id = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - model.UserStatusNormal, - userID, - } - err = GetRows(db, &authList, sql, sqlParams...) - return authList, err -} diff --git a/business/partner/purchase/ebai/common.go b/business/partner/purchase/ebai/common.go index 588685ec8..08f849c25 100644 --- a/business/partner/purchase/ebai/common.go +++ b/business/partner/purchase/ebai/common.go @@ -3,6 +3,7 @@ package ebai import ( "git.rosy.net.cn/baseapi/platformapi/ebaiapi" "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" @@ -11,30 +12,31 @@ import ( func (p *PurchaseHandler) UpdatePlaces() (err error) { provinces, err := api.EbaiAPI.CommonShopCities(0) if err == nil { - task := tasksch.NewParallelTask("UpdatePlaces", nil, "test", func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - province := batchItemList[0].(*ebaiapi.CityInfo) - retSlice := make([]*ebaiapi.CityInfo, 0) - if province.IsOpen != 0 { - retSlice = append(retSlice, province) - cities, err := api.EbaiAPI.CommonShopCities(province.ID) - for _, city := range cities { - if city.IsOpen != 0 { - retSlice = append(retSlice, city) - districts, err2 := api.EbaiAPI.CommonShopCities(city.ID) - if err = err2; err == nil { - for _, district := range districts { - if district.IsOpen != 0 { - retSlice = append(retSlice, district) + task := tasksch.NewParallelTask("UpdatePlaces", nil, jxcontext.AdminCtx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + province := batchItemList[0].(*ebaiapi.CityInfo) + retSlice := make([]*ebaiapi.CityInfo, 0) + if province.IsOpen != 0 { + retSlice = append(retSlice, province) + cities, err := api.EbaiAPI.CommonShopCities(province.ID) + for _, city := range cities { + if city.IsOpen != 0 { + retSlice = append(retSlice, city) + districts, err2 := api.EbaiAPI.CommonShopCities(city.ID) + if err = err2; err == nil { + for _, district := range districts { + if district.IsOpen != 0 { + retSlice = append(retSlice, district) + } } + } else { + break } - } else { - break } } } - } - return retSlice, err - }, provinces) + return retSlice, err + }, provinces) task.Run() places, err2 := task.GetResult(0) if err = err2; err == nil { diff --git a/business/partner/purchase/ebai/order.go b/business/partner/purchase/ebai/order.go index da9b582a7..2e8ed48f2 100644 --- a/business/partner/purchase/ebai/order.go +++ b/business/partner/purchase/ebai/order.go @@ -338,17 +338,17 @@ func (c *PurchaseHandler) RefreshRealMobile(ctx *jxcontext.Context, fromTime, to var orderList []*model.GoodsOrder db := dao.GetDB() if err = dao.GetRows(db, &orderList, sql, sqlParams...); err == nil && len(orderList) > 0 { - task := tasksch.NewParallelTask("ebai RefreshRealMobile", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - order := batchItemList[0].(*model.GoodsOrder) - mobile, err2 := api.EbaiAPI.GetRealMobile4Order(order.VendorOrderID) - if err = err2; err == nil && !jxutils.IsMobileFake(mobile) && strings.Index(order.ConsigneeMobile, mobile) == -1 { - order.ConsigneeMobile2 = mobile - _, err = dao.UpdateEntity(db, order, "ConsigneeMobile2") - } - return nil, err - }, orderList) - ctx.SetTaskOrAddChild(task, nil) - tasksch.ManageTask(task).Run() + task := tasksch.NewParallelTask("ebai RefreshRealMobile", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + order := batchItemList[0].(*model.GoodsOrder) + mobile, err2 := api.EbaiAPI.GetRealMobile4Order(order.VendorOrderID) + if err = err2; err == nil && !jxutils.IsMobileFake(mobile) && strings.Index(order.ConsigneeMobile, mobile) == -1 { + order.ConsigneeMobile2 = mobile + _, err = dao.UpdateEntity(db, order, "ConsigneeMobile2") + } + return nil, err + }, orderList) + tasksch.HandleTask(task, nil, true).Run() hint = task.ID if !isAsync { _, err = task.GetResult(0) diff --git a/business/partner/purchase/ebai/store.go b/business/partner/purchase/ebai/store.go index 009249e15..179b2ebc2 100644 --- a/business/partner/purchase/ebai/store.go +++ b/business/partner/purchase/ebai/store.go @@ -216,44 +216,45 @@ func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask const stepCount = 3 var stores []*tEbaiStoreInfo db := dao.GetDB() - rootTask := tasksch.NewSeqTask("ebai RefreshAllStoresID", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - err = dao.GetRows(db, &stores, ` + rootTask := tasksch.NewSeqTask("ebai RefreshAllStoresID", ctx, + func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + err = dao.GetRows(db, &stores, ` SELECT t1.*, t2.vendor_store_id FROM store t1 JOIN store_map t2 ON t1.id = t2.store_id AND t2.deleted_at = ? AND t2.vendor_id = ? WHERE t1.deleted_at = ? `, utils.DefaultTimeValue, model.VendorIDEBAI, utils.DefaultTimeValue) - default: - taskName := "ebai RefreshAllStoresID update to custom id" - if step != stepCount-1 { - taskName = "ebai RefreshAllStoresID update to uuid" + default: + taskName := "ebai RefreshAllStoresID update to custom id" + if step != stepCount-1 { + taskName = "ebai RefreshAllStoresID update to uuid" + } + task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetBatchSize(batchSize), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + baiduShopIDs := make([]string, len(batchItemList)) + shopIDs := make([]string, len(batchItemList)) + for k, v := range batchItemList { + store := v.(*tEbaiStoreInfo) + baiduShopIDs[k] = store.VendorStoreID + shopIDs[k] = utils.Int2Str(store.ID) + if step != stepCount-1 { + shopIDs[k] = utils.GetUUID() + } + } + if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite { + err = api.EbaiAPI.ShopIDBatchUpdate(baiduShopIDs, shopIDs) + } + return nil, err + }, stores) + task.AddChild(task1).Run() + _, err = task1.GetResult(0) } - task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetBatchSize(batchSize), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - baiduShopIDs := make([]string, len(batchItemList)) - shopIDs := make([]string, len(batchItemList)) - for k, v := range batchItemList { - store := v.(*tEbaiStoreInfo) - baiduShopIDs[k] = store.VendorStoreID - shopIDs[k] = utils.Int2Str(store.ID) - if step != stepCount-1 { - shopIDs[k] = utils.GetUUID() - } - } - if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.ShopIDBatchUpdate(baiduShopIDs, shopIDs) - } - return nil, err - }, stores) - task.AddChild(task1).Run() - _, err = task1.GetResult(0) - } - return nil, err - }, stepCount) + return nil, err + }, stepCount) - ctx.SetTaskOrAddChild(rootTask, parentTask) - rootTask.Run() + tasksch.HandleTask(rootTask, parentTask, false).Run() if !isAsync { _, err = rootTask.GetResult(0) } diff --git a/business/partner/purchase/ebai/store_sku.go b/business/partner/purchase/ebai/store_sku.go index a68c52459..80ce72362 100644 --- a/business/partner/purchase/ebai/store_sku.go +++ b/business/partner/purchase/ebai/store_sku.go @@ -144,29 +144,30 @@ func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask t globals.SugarLogger.Debugf("FullSyncStoreSkus storeID:%d, isContinueWhenError:%t, userName:%s", storeID, isContinueWhenError, userName) db := dao.GetDB() - rootTask := tasksch.NewSeqTask("FullSyncStoreSkus", userName, func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - err = p.DeleteRemoteSkus(ctx, rootTask, storeID, nil) - // 强制忽略删除SKU错误 - if isContinueWhenError { - err = nil + rootTask := tasksch.NewSeqTask("FullSyncStoreSkus", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + err = p.DeleteRemoteSkus(ctx, rootTask, storeID, nil) + // 强制忽略删除SKU错误 + if isContinueWhenError { + err = nil + } + case 1: + _, err = p.setStoreSkuSyncStatus(ctx, db, storeID, nil, model.SyncFlagNewMask) + case 2: + if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil { + _, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDEBAI, storeID, nil, model.SyncFlagNewMask) + } + case 3: + err = p.SyncLocalStoreCategory(db, storeID, userName) + case 4: + _, err = p.SyncStoreCategory(ctx, rootTask, storeID, false) + case 5: + _, err = p.SyncStoreSkus(ctx, rootTask, storeID, nil, false, isContinueWhenError) } - case 1: - _, err = p.setStoreSkuSyncStatus(ctx, db, storeID, nil, model.SyncFlagNewMask) - case 2: - if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil { - _, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDEBAI, storeID, nil, model.SyncFlagNewMask) - } - case 3: - err = p.SyncLocalStoreCategory(db, storeID, userName) - case 4: - _, err = p.SyncStoreCategory(ctx, rootTask, storeID, false) - case 5: - _, err = p.SyncStoreSkus(ctx, rootTask, storeID, nil, false, isContinueWhenError) - } - return nil, err - }, 6) + return nil, err + }, 6) tasksch.AddChild(parentTask, rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) @@ -180,24 +181,25 @@ func (p *PurchaseHandler) DeleteRemoteStoreSkus(ctx *jxcontext.Context, parentTa db := dao.GetDB() var errDeleteSku error - rootTask := tasksch.NewSeqTask("DeleteRemoteStoreSkus", userName, func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - err = p.DeleteRemoteSkus(ctx, rootTask, storeID, nil) - errDeleteSku = err - // 强制忽略删除SKU错误 - if isContinueWhenError { - err = nil + rootTask := tasksch.NewSeqTask("DeleteRemoteStoreSkus", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + err = p.DeleteRemoteSkus(ctx, rootTask, storeID, nil) + errDeleteSku = err + // 强制忽略删除SKU错误 + if isContinueWhenError { + err = nil + } + case 1: + _, err = p.setStoreSkuSyncStatus(ctx, db, storeID, nil, model.SyncFlagNewMask) + case 2: + if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil { + _, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDEBAI, storeID, nil, model.SyncFlagNewMask) + } } - case 1: - _, err = p.setStoreSkuSyncStatus(ctx, db, storeID, nil, model.SyncFlagNewMask) - case 2: - if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil { - _, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDEBAI, storeID, nil, model.SyncFlagNewMask) - } - } - return nil, err - }, 3) + return nil, err + }, 3) tasksch.AddChild(parentTask, rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) @@ -215,58 +217,60 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks var storeSkuInfoList []*tStoreSkuFullInfo var num int64 strStoreID := utils.Int2Str(storeID) - rootTask := tasksch.NewSeqTask("SyncStoreSkus饿百1", userName, func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - if step == 0 { - db := dao.GetDB() - for i := 0; i < 3; i++ { - if storeSkuInfoList, err = p.getDirtyStoreSkus(db, storeID, skuIDs); err != nil { - return nil, err - } - if num, err = p.createCatByStoreSkus(ctx, rootTask, db, storeID, storeSkuInfoList); err != nil { - return nil, err - } - if num == 0 { - break - } - } - if num != 0 { - globals.SugarLogger.Infof("SyncStoreSkus 不能创建商品所需的类别, storeID:%d, skuIDs:%v, isContinueWhenError:%t, userName:%s", storeID, skuIDs, isContinueWhenError, userName) - return nil, errors.New("不能创建商品所需的类别") - } - } else if step == 1 { - task := tasksch.NewParallelTask("SyncStoreSkus饿百2", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), userName, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeSku := batchItemList[0].(*tStoreSkuFullInfo) - updateFields := []string{model.FieldEbaiSyncStatus} - if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite { - 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)) - // todo 适当处理重复(即已经创建)的情况 - if storeSku.EbaiID, err = api.EbaiAPI.SkuCreate(strStoreID, storeSku.SkuID, genSkuParamsFromStoreSkuInfo(storeSku)); err == nil { - updateFields = append(updateFields, model.FieldEbaiID) - } - } else if storeSku.EbaiSyncStatus&model.SyncFlagModifiedMask != 0 { - if jxutils.IsFakeID(storeSku.EbaiID) { - err = fmt.Errorf("京西数据异常,修改一个没有创建的饿百商品:%d, store:%s", storeSku.SkuID, strStoreID) - } else { - if _, err = api.EbaiAPI.SkuUpdate(strStoreID, storeSku.EbaiID, genSkuParamsFromStoreSkuInfo(storeSku)); err == nil { - // err = api.EbaiAPI.SkuShopCategoryMap(strStoreID, storeSku.EbaiID, utils.Int64ToStr(storeSku.CatEbaiID)) - } - } + rootTask := tasksch.NewSeqTask("SyncStoreSkus饿百1", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + if step == 0 { + db := dao.GetDB() + for i := 0; i < 3; i++ { + if storeSkuInfoList, err = p.getDirtyStoreSkus(db, storeID, skuIDs); err != nil { + return nil, err + } + if num, err = p.createCatByStoreSkus(ctx, rootTask, db, storeID, storeSkuInfoList); err != nil { + return nil, err + } + if num == 0 { + break } } - if err == nil { - storeSku.EbaiSyncStatus = 0 - _, err = dao.UpdateEntity(nil, &storeSku.StoreSkuBind, updateFields...) + if num != 0 { + globals.SugarLogger.Infof("SyncStoreSkus 不能创建商品所需的类别, storeID:%d, skuIDs:%v, isContinueWhenError:%t, userName:%s", storeID, skuIDs, isContinueWhenError, userName) + return nil, errors.New("不能创建商品所需的类别") } - return nil, err - }, storeSkuInfoList) - tasksch.AddChild(rootTask, task).Run() - _, err = task.GetResult(0) - } - return nil, err - }, 2) + } else if step == 1 { + task := tasksch.NewParallelTask("SyncStoreSkus饿百2", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + storeSku := batchItemList[0].(*tStoreSkuFullInfo) + updateFields := []string{model.FieldEbaiSyncStatus} + if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite { + 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)) + // todo 适当处理重复(即已经创建)的情况 + if storeSku.EbaiID, err = api.EbaiAPI.SkuCreate(strStoreID, storeSku.SkuID, genSkuParamsFromStoreSkuInfo(storeSku)); err == nil { + updateFields = append(updateFields, model.FieldEbaiID) + } + } else if storeSku.EbaiSyncStatus&model.SyncFlagModifiedMask != 0 { + if jxutils.IsFakeID(storeSku.EbaiID) { + err = fmt.Errorf("京西数据异常,修改一个没有创建的饿百商品:%d, store:%s", storeSku.SkuID, strStoreID) + } else { + if _, err = api.EbaiAPI.SkuUpdate(strStoreID, storeSku.EbaiID, genSkuParamsFromStoreSkuInfo(storeSku)); err == nil { + // err = api.EbaiAPI.SkuShopCategoryMap(strStoreID, storeSku.EbaiID, utils.Int64ToStr(storeSku.CatEbaiID)) + } + } + } + } + if err == nil { + storeSku.EbaiSyncStatus = 0 + _, err = dao.UpdateEntity(nil, &storeSku.StoreSkuBind, updateFields...) + } + return nil, err + }, storeSkuInfoList) + tasksch.AddChild(rootTask, task).Run() + _, err = task.GetResult(0) + } + return nil, err + }, 2) tasksch.AddChild(parentTask, rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) @@ -274,7 +278,7 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks return rootTask.ID, err } -func (p *PurchaseHandler) GetAllRemoteSkus(storeID int) (skus []map[string]interface{}, err error) { +func (p *PurchaseHandler) GetAllRemoteSkus(ctx *jxcontext.Context, storeID int, parentTask tasksch.ITask) (skus []map[string]interface{}, err error) { page1, err := api.EbaiAPI.SkuList(utils.Int2Str(storeID), utils.Params2Map("pagesize", MaxPageSize)) if err == nil { skus = append(skus, page1.List...) @@ -283,19 +287,20 @@ func (p *PurchaseHandler) GetAllRemoteSkus(storeID int) (skus []map[string]inter for i := 2; i <= page1.Pages; i++ { pages[i-2] = i } - task := tasksch.NewParallelTask("GetAllRemoteSkus", nil, "", func(t *tasksch.ParallelTask, 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) - task.Run() + task := tasksch.NewParallelTask("GetAllRemoteSkus", nil, ctx, + func(t *tasksch.ParallelTask, 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) + tasksch.HandleTask(task, parentTask, false).Run() result, err2 := task.GetResult(0) if err = err2; err == nil { for _, v := range result { @@ -311,7 +316,7 @@ func (p *PurchaseHandler) DeleteRemoteSkus(ctx *jxcontext.Context, parentTask ta globals.SugarLogger.Debugf("DeleteRemoteSkus饿百 storeID:%d", storeID) if vendorSkuIDs == nil { - result, err2 := p.GetAllRemoteSkus(storeID) + result, err2 := p.GetAllRemoteSkus(ctx, storeID, parentTask) if err = err2; err == nil { vendorSkuIDs = make([]string, len(result)) for k, v := range result { @@ -319,16 +324,17 @@ func (p *PurchaseHandler) DeleteRemoteSkus(ctx *jxcontext.Context, parentTask ta } } } - task := tasksch.NewParallelTask("DeleteRemoteSkus", tasksch.NewParallelConfig().SetBatchSize(100).SetIsContinueWhenError(true), "", func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - strList := make([]string, len(batchItemList)) - for k, v := range batchItemList { - strList[k] = v.(string) - } - if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.SkuDelete(utils.Int2Str(storeID), strings.Join(strList, ",")) - } - return nil, err - }, vendorSkuIDs) + task := tasksch.NewParallelTask("DeleteRemoteSkus", tasksch.NewParallelConfig().SetBatchSize(100).SetIsContinueWhenError(true), ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + strList := make([]string, len(batchItemList)) + for k, v := range batchItemList { + strList[k] = v.(string) + } + if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite { + err = api.EbaiAPI.SkuDelete(utils.Int2Str(storeID), strings.Join(strList, ",")) + } + return nil, err + }, vendorSkuIDs) tasksch.AddChild(parentTask, task).Run() _, err = task.GetResult(0) return err @@ -347,12 +353,13 @@ func (p *PurchaseHandler) DeleteRemoteCategories(ctx *jxcontext.Context, parentT } } } - task := tasksch.NewParallelTask("DeleteRemoteCategories", tasksch.NewParallelConfig().SetIsContinueWhenError(true), "", func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.ShopCategoryDelete(strStoreID, batchItemList[0].(int64)) - } - return nil, err - }, vendorCatIDs) + task := tasksch.NewParallelTask("DeleteRemoteCategories", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite { + err = api.EbaiAPI.ShopCategoryDelete(strStoreID, batchItemList[0].(int64)) + } + return nil, err + }, vendorCatIDs) tasksch.AddChild(parentTask, task).Run() _, err = task.GetResult(0) return err @@ -465,9 +472,10 @@ func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask t globals.SugarLogger.Debugf("SyncOneStoreCategories storeID:%d, userName:%s", storeID, userName) db := dao.GetDB() - rootTask := tasksch.NewSeqTask("ebai SyncStoreCategory", userName, func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - level := step + 1 - sql := ` + rootTask := tasksch.NewSeqTask("ebai SyncStoreCategory", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + level := step + 1 + 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 @@ -475,45 +483,46 @@ func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask t LEFT JOIN store_sku_category_map t2p ON t1p.id = t2p.category_id AND t2p.store_id = ? AND t2p.deleted_at = ? WHERE t1.level = ? AND t1.deleted_at = ? ` - var catList []*tStoreCatInfo - sqlParams := []interface{}{ - storeID, - storeID, - utils.DefaultTimeValue, - level, - utils.DefaultTimeValue, - } - if err = dao.GetRows(db, &catList, sql, sqlParams...); err == nil { - strStoreID := utils.Int2Str(storeID) - task := tasksch.NewParallelTask("SyncStoreCategory", nil, userName, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - updateFields := []string{model.FieldEbaiSyncStatus} - catInfo := batchItemList[0].(*tStoreCatInfo) - // globals.SugarLogger.Debug(utils.Format4Output(catInfo, false)) - if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite { - 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, formatName(catInfo.Name), jxCatSeq2Ebai(catInfo.Seq)) - if err = err2; err == nil { - catInfo.EbaiID = ebaiID - updateFields = append(updateFields, model.FieldEbaiID) + var catList []*tStoreCatInfo + sqlParams := []interface{}{ + storeID, + storeID, + utils.DefaultTimeValue, + level, + utils.DefaultTimeValue, + } + if err = dao.GetRows(db, &catList, sql, sqlParams...); err == nil { + strStoreID := utils.Int2Str(storeID) + task := tasksch.NewParallelTask("SyncStoreCategory", nil, ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + updateFields := []string{model.FieldEbaiSyncStatus} + catInfo := batchItemList[0].(*tStoreCatInfo) + // globals.SugarLogger.Debug(utils.Format4Output(catInfo, false)) + if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite { + 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, formatName(catInfo.Name), jxCatSeq2Ebai(catInfo.Seq)) + 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, formatName(catInfo.Name), jxCatSeq2Ebai(catInfo.Seq)) + } } - } else if catInfo.EbaiSyncStatus&model.SyncFlagModifiedMask != 0 { // 修改 - err = api.EbaiAPI.ShopCategoryUpdate(strStoreID, catInfo.EbaiID, formatName(catInfo.Name), jxCatSeq2Ebai(catInfo.Seq)) - } - } - if err == nil { - db2 := dao.GetDB() - catInfo.EbaiSyncStatus = 0 - _, err = dao.UpdateEntity(db2, &catInfo.StoreSkuCategoryMap, updateFields...) - } - return nil, err - }, catList) - rootTask.AddChild(task).Run() - _, err = task.GetResult(0) - } - return nil, err - }, 2) + if err == nil { + db2 := dao.GetDB() + catInfo.EbaiSyncStatus = 0 + _, err = dao.UpdateEntity(db2, &catInfo.StoreSkuCategoryMap, updateFields...) + } + return nil, err + }, catList) + rootTask.AddChild(task).Run() + _, err = task.GetResult(0) + } + return nil, err + }, 2) tasksch.AddChild(parentTask, rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) diff --git a/business/partner/purchase/ebai/store_sku_test.go b/business/partner/purchase/ebai/store_sku_test.go index f9df3c905..dcaa40413 100644 --- a/business/partner/purchase/ebai/store_sku_test.go +++ b/business/partner/purchase/ebai/store_sku_test.go @@ -36,7 +36,7 @@ func TestSyncOneStoreCategoriesFromLocal2Remote(t *testing.T) { } func TestGetAllRemoteSkus(t *testing.T) { - result, err := new(PurchaseHandler).GetAllRemoteSkus(testShopID) + result, err := new(PurchaseHandler).GetAllRemoteSkus(jxcontext.AdminCtx, testShopID, nil) if err != nil { t.Fatal(err.Error()) } else { diff --git a/business/partner/purchase/jd/sku.go b/business/partner/purchase/jd/sku.go index 14e0d91dd..ed82a7d52 100644 --- a/business/partner/purchase/jd/sku.go +++ b/business/partner/purchase/jd/sku.go @@ -302,44 +302,45 @@ func (p *PurchaseHandler) RefreshAllSkusID(ctx *jxcontext.Context, parentTask ta var skuPairs []*jdapi.SkuIDPair const stepCount = 2 - rootTask := tasksch.NewSeqTask("jd RefreshAllSkusID", ctx.GetUserName(), func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - err = dao.GetRows(db, &skuPairs, ` + rootTask := tasksch.NewSeqTask("jd RefreshAllSkusID", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + err = dao.GetRows(db, &skuPairs, ` SELECT t1.id out_sku_id, t1.jd_id sku_id FROM sku t1 WHERE t1.deleted_at = ? `, utils.DefaultTimeValue) - default: - taskName := "RefreshAllSkusID update id" - if step != stepCount-1 { - taskName = "RefreshAllSkusID update uuid" + default: + taskName := "RefreshAllSkusID update id" + if step != stepCount-1 { + taskName = "RefreshAllSkusID update uuid" + } + task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true).SetBatchSize(jdapi.MaxBatchSize4BatchUpdateOutSkuId), ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + skuPairs := make([]*jdapi.SkuIDPair, len(batchItemList)) + for k, v := range batchItemList { + pair := v.(*jdapi.SkuIDPair) + skuPairs[k] = &jdapi.SkuIDPair{ + SkuId: pair.SkuId, + OutSkuId: pair.OutSkuId, + } + if step != stepCount-1 { + skuPairs[k].OutSkuId = utils.GetUUID() + } + } + globals.SugarLogger.Debug(utils.Format4Output(skuPairs, false)) + if globals.EnableStoreWrite { + _, err = api.JdAPI.BatchUpdateOutSkuId(skuPairs) + } + return nil, err + }, skuPairs) + rootTask.AddChild(task1).Run() + _, err = task1.GetResult(0) } - task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true).SetBatchSize(jdapi.MaxBatchSize4BatchUpdateOutSkuId), ctx.GetUserName(), func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - skuPairs := make([]*jdapi.SkuIDPair, len(batchItemList)) - for k, v := range batchItemList { - pair := v.(*jdapi.SkuIDPair) - skuPairs[k] = &jdapi.SkuIDPair{ - SkuId: pair.SkuId, - OutSkuId: pair.OutSkuId, - } - if step != stepCount-1 { - skuPairs[k].OutSkuId = utils.GetUUID() - } - } - globals.SugarLogger.Debug(utils.Format4Output(skuPairs, false)) - if globals.EnableStoreWrite { - _, err = api.JdAPI.BatchUpdateOutSkuId(skuPairs) - } - return nil, err - }, skuPairs) - rootTask.AddChild(task1).Run() - _, err = task1.GetResult(0) - } - return nil, err - }, stepCount) - ctx.SetTaskOrAddChild(rootTask, parentTask) - rootTask.Run() + return nil, err + }, stepCount) + tasksch.HandleTask(rootTask, parentTask, false).Run() if !isAsync { _, err = rootTask.GetResult(0) } diff --git a/business/partner/purchase/jd/store.go b/business/partner/purchase/jd/store.go index 8d833717f..82a898fc6 100644 --- a/business/partner/purchase/jd/store.go +++ b/business/partner/purchase/jd/store.go @@ -209,41 +209,42 @@ func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask const stepCount = 3 var stores []*tJdStoreInfo db := dao.GetDB() - rootTask := tasksch.NewSeqTask("jd RefreshAllStoresID", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - err = dao.GetRows(db, &stores, ` + rootTask := tasksch.NewSeqTask("jd RefreshAllStoresID", ctx, + func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + err = dao.GetRows(db, &stores, ` SELECT t1.*, t2.vendor_store_id FROM store t1 JOIN store_map t2 ON t1.id = t2.store_id AND t2.deleted_at = ? AND t2.vendor_id = ? WHERE t1.deleted_at = ? `, utils.DefaultTimeValue, model.VendorIDJD, utils.DefaultTimeValue) - default: - taskName := "jd RefreshAllStoresID update outSystemId" - if step != stepCount-1 { - taskName = "jd RefreshAllStoresID update to uuid" - } - task1 := tasksch.NewParallelTask(taskName, nil, ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - store := batchItemList[0].(*tJdStoreInfo) - storeParams := map[string]interface{}{ - "outSystemId": utils.Int2Str(int(store.ID)), - } + default: + taskName := "jd RefreshAllStoresID update outSystemId" if step != stepCount-1 { - storeParams["outSystemId"] = utils.GetUUID() + taskName = "jd RefreshAllStoresID update to uuid" } - if true { //globals.EnableStoreWrite { - err = api.JdAPI.UpdateStoreInfo4Open(store.VendorStoreID, ctx.GetUserName(), storeParams) - } - return nil, err - }, stores) - task.AddChild(task1).Run() - _, err = task1.GetResult(0) - } - return nil, err - }, stepCount) + task1 := tasksch.NewParallelTask(taskName, nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + store := batchItemList[0].(*tJdStoreInfo) + storeParams := map[string]interface{}{ + "outSystemId": utils.Int2Str(int(store.ID)), + } + if step != stepCount-1 { + storeParams["outSystemId"] = utils.GetUUID() + } + if true { //globals.EnableStoreWrite { + err = api.JdAPI.UpdateStoreInfo4Open(store.VendorStoreID, ctx.GetUserName(), storeParams) + } + return nil, err + }, stores) + task.AddChild(task1).Run() + _, err = task1.GetResult(0) + } + return nil, err + }, stepCount) - ctx.SetTaskOrAddChild(rootTask, parentTask) - rootTask.Run() + tasksch.HandleTask(rootTask, parentTask, false).Run() if !isAsync { _, err = rootTask.GetResult(0) } diff --git a/business/partner/purchase/jd/store_sku.go b/business/partner/purchase/jd/store_sku.go index d155346bd..8332a072f 100644 --- a/business/partner/purchase/jd/store_sku.go +++ b/business/partner/purchase/jd/store_sku.go @@ -54,106 +54,106 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks if err = dao.GetRows(db, &storeSkus, sql, append(sqlParams, sqlWhereParams...)...); err != nil { return "", err } - task := tasksch.NewParallelTask("SyncStoresSkus京东", tasksch.NewParallelConfig().SetBatchSize(jdapi.MaxStoreSkuBatchSize).SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - var skuPriceInfoList []*jdapi.SkuPriceInfo - var skuVendibilityList []*jdapi.StockVendibility - var skuStockList []*jdapi.SkuStock - stationNo := batchItemList[0].(*tStoreSkuBindExt).VendorStoreID - var batchSkuIDs []int - for _, v := range batchItemList { - storeSku := v.(*tStoreSkuBindExt) - alreadyAddStock := false - if storeSku.JdSyncStatus&model.SyncFlagChangedMask != 0 { - batchSkuIDs = append(batchSkuIDs, storeSku.SkuID) - if storeSku.JdSyncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask) != 0 { // 关注或取消关注 - stock := &jdapi.SkuStock{ - OutSkuId: utils.Int2Str(storeSku.SkuID), - StockQty: model.MaxStoreSkuStockQty, - } - if storeSku.DeletedAt != utils.DefaultTimeValue { - stock.StockQty = 0 - } else { - alreadyAddStock = true - } - if stock.StockQty != 0 || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) { - skuStockList = append(skuStockList, stock) - } - } - if storeSku.JdSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 { - skuPriceInfoList = append(skuPriceInfoList, &jdapi.SkuPriceInfo{ - OutSkuId: utils.Int2Str(storeSku.SkuID), - Price: jxutils.CaculateSkuVendorPrice(storeSku.Price, storeSku.PricePercentage), - }) - } - if storeSku.JdSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 { - vendibility := &jdapi.StockVendibility{ - OutSkuId: utils.Int2Str(storeSku.SkuID), - DoSale: true, - } - if storeSku.Status != model.StoreSkuBindStatusNormal { - vendibility.DoSale = false - } else if !alreadyAddStock { // 如果是设置可售则自动将库存加满 + task := tasksch.NewParallelTask("SyncStoresSkus京东", tasksch.NewParallelConfig().SetBatchSize(jdapi.MaxStoreSkuBatchSize).SetIsContinueWhenError(isContinueWhenError), ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + var skuPriceInfoList []*jdapi.SkuPriceInfo + var skuVendibilityList []*jdapi.StockVendibility + var skuStockList []*jdapi.SkuStock + stationNo := batchItemList[0].(*tStoreSkuBindExt).VendorStoreID + var batchSkuIDs []int + for _, v := range batchItemList { + storeSku := v.(*tStoreSkuBindExt) + alreadyAddStock := false + if storeSku.JdSyncStatus&model.SyncFlagChangedMask != 0 { + batchSkuIDs = append(batchSkuIDs, storeSku.SkuID) + if storeSku.JdSyncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask) != 0 { // 关注或取消关注 stock := &jdapi.SkuStock{ OutSkuId: utils.Int2Str(storeSku.SkuID), StockQty: model.MaxStoreSkuStockQty, } - skuStockList = append(skuStockList, stock) + if storeSku.DeletedAt != utils.DefaultTimeValue { + stock.StockQty = 0 + } else { + alreadyAddStock = true + } + if stock.StockQty != 0 || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) { + skuStockList = append(skuStockList, stock) + } } - if vendibility.DoSale || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) { - skuVendibilityList = append(skuVendibilityList, vendibility) + if storeSku.JdSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 { + skuPriceInfoList = append(skuPriceInfoList, &jdapi.SkuPriceInfo{ + OutSkuId: utils.Int2Str(storeSku.SkuID), + Price: jxutils.CaculateSkuVendorPrice(storeSku.Price, storeSku.PricePercentage), + }) + } + if storeSku.JdSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 { + vendibility := &jdapi.StockVendibility{ + OutSkuId: utils.Int2Str(storeSku.SkuID), + DoSale: true, + } + if storeSku.Status != model.StoreSkuBindStatusNormal { + vendibility.DoSale = false + } else if !alreadyAddStock { // 如果是设置可售则自动将库存加满 + stock := &jdapi.SkuStock{ + OutSkuId: utils.Int2Str(storeSku.SkuID), + StockQty: model.MaxStoreSkuStockQty, + } + skuStockList = append(skuStockList, stock) + } + if vendibility.DoSale || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) { + skuVendibilityList = append(skuVendibilityList, vendibility) + } } } } - } - syncMask := 0 - errList := []error{} - if globals.EnableStoreWrite { - // todo 以下可以优化为并行操作 - globals.SugarLogger.Debug(utils.Format4Output(skuVendibilityList, false), utils.Format4Output(skuPriceInfoList, false), utils.Format4Output(skuStockList, false)) - if len(skuVendibilityList) > 0 { - if _, err = api.JdAPI.BatchUpdateVendibility("", stationNo, skuVendibilityList, ctx.GetUserName()); err == nil { - syncMask |= model.SyncFlagSaleMask - } else { - errList = append(errList, err) + syncMask := 0 + errList := []error{} + if globals.EnableStoreWrite { + // todo 以下可以优化为并行操作 + globals.SugarLogger.Debug(utils.Format4Output(skuVendibilityList, false), utils.Format4Output(skuPriceInfoList, false), utils.Format4Output(skuStockList, false)) + if len(skuVendibilityList) > 0 { + if _, err = api.JdAPI.BatchUpdateVendibility("", stationNo, skuVendibilityList, ctx.GetUserName()); err == nil { + syncMask |= model.SyncFlagSaleMask + } else { + errList = append(errList, err) + } + } + if (err == nil || isContinueWhenError) && len(skuStockList) > 0 { + if _, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, skuStockList, ctx.GetUserName()); err == nil { + syncMask |= model.SyncFlagNewMask | model.SyncFlagDeletedMask + } else { + errList = append(errList, err) + } + } + if (err == nil || isContinueWhenError) && len(skuPriceInfoList) > 0 { + if _, err = api.JdAPI.UpdateVendorStationPrice("", stationNo, skuPriceInfoList); err == nil { + syncMask |= model.SyncFlagPriceMask + } else { + errList = append(errList, err) + } } } - if (err == nil || isContinueWhenError) && len(skuStockList) > 0 { - if _, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, skuStockList, ctx.GetUserName()); err == nil { - syncMask |= model.SyncFlagNewMask | model.SyncFlagDeletedMask - } else { - errList = append(errList, err) - } + if len(errList) == 0 { + syncMask = -1 } - if (err == nil || isContinueWhenError) && len(skuPriceInfoList) > 0 { - if _, err = api.JdAPI.UpdateVendorStationPrice("", stationNo, skuPriceInfoList); err == nil { - syncMask |= model.SyncFlagPriceMask - } else { - errList = append(errList, err) - } - } - } - if len(errList) == 0 { - syncMask = -1 - } - if syncMask != 0 && len(batchSkuIDs) > 0 { - db := dao.GetDB() // 多线程问题 - sql := ` + if syncMask != 0 && len(batchSkuIDs) > 0 { + db := dao.GetDB() // 多线程问题 + sql := ` UPDATE store_sku_bind t1 SET t1.jd_sync_status = t1.jd_sync_status & ? ` + sqlWhere0 + " AND t1.sku_id IN (" + dao.GenQuestionMarks(len(batchSkuIDs)) + ")" - if _, err = dao.ExecuteSQL(db, sql, ^syncMask, storeID, batchSkuIDs); err != nil { - errList = append(errList, err) + if _, err = dao.ExecuteSQL(db, sql, ^syncMask, storeID, batchSkuIDs); err != nil { + errList = append(errList, err) + } } - } - if len(errList) == 1 { - err = errList[0] - } else if len(errList) > 1 { - err = fmt.Errorf("%v", errList) - } - return nil, err - }, storeSkus) - ctx.SetTaskOrAddChild(task, parentTask) - task.Run() + if len(errList) == 1 { + err = errList[0] + } else if len(errList) > 1 { + err = fmt.Errorf("%v", errList) + } + return nil, err + }, storeSkus) + tasksch.HandleTask(task, parentTask, false).Run() if !isAsync { _, err = task.GetResult(0) } @@ -185,83 +185,83 @@ func (p *PurchaseHandler) syncStoreSkus(ctx *jxcontext.Context, parentTask tasks 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, + task := tasksch.NewParallelTask("SyncStoresSkus京东", tasksch.NewParallelConfig().SetBatchSize(jdapi.MaxStoreSkuBatchSize).SetIsContinueWhenError(isContinueWhenError), ctx, + 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.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.StoreSkuStatus != model.StoreSkuBindStatusNormal { - vendibility.DoSale = false - } else if !alreadyAddStock { // 如果是设置可售则自动将库存加满 + if storeSku.SkuSyncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask) != 0 || storeSku.BindID == 0 { // 关注或取消关注 stock := &jdapi.SkuStock{ OutSkuId: utils.Int2Str(storeSku.ID), StockQty: model.MaxStoreSkuStockQty, } - skuStockList = append(skuStockList, stock) + 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 vendibility.DoSale || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) { - skuVendibilityList = append(skuVendibilityList, vendibility) + 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.StoreSkuStatus != 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.Debugf("jd syncStoreSkus sync detail, storeID:%d, skuVendibilityList:%s, skuPriceInfoList:%s, skuStockList:%s", storeID, utils.Format4Output(skuVendibilityList, true), utils.Format4Output(skuPriceInfoList, true), utils.Format4Output(skuStockList, true)) - if globals.EnableStoreWrite { - // todo 以下可以优化为并行操作 - if len(skuVendibilityList) > 0 { - _, err = api.JdAPI.BatchUpdateVendibility("", stationNo, skuVendibilityList, ctx.GetUserName()) + globals.SugarLogger.Debugf("jd syncStoreSkus sync detail, storeID:%d, skuVendibilityList:%s, skuPriceInfoList:%s, skuStockList:%s", storeID, utils.Format4Output(skuVendibilityList, true), utils.Format4Output(skuPriceInfoList, true), utils.Format4Output(skuStockList, true)) + if globals.EnableStoreWrite { + // todo 以下可以优化为并行操作 + if len(skuVendibilityList) > 0 { + _, err = api.JdAPI.BatchUpdateVendibility("", stationNo, skuVendibilityList, ctx.GetUserName()) + } + if err == nil && len(skuStockList) > 0 { + _, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, skuStockList, 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(skuPriceInfoList) > 0 { - _, err = api.JdAPI.UpdateVendorStationPrice("", stationNo, skuPriceInfoList) - } - } - if err == nil && len(batchSkuIDs) > 0 { - db := dao.GetDB() // 多线程问题 - sql := ` + 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() + _, err = dao.ExecuteSQL(db, sql, batchSkuIDs) + } + return nil, err + }, skus) + tasksch.HandleTask(task, parentTask, false).Run() if !isAsync { _, err = task.GetResult(0) } diff --git a/business/partner/purchase/mtwm/store_sku.go b/business/partner/purchase/mtwm/store_sku.go index d050bbfaa..26317a8c3 100644 --- a/business/partner/purchase/mtwm/store_sku.go +++ b/business/partner/purchase/mtwm/store_sku.go @@ -17,7 +17,6 @@ import ( // hint,如果是异步,返回的是任务ID,如果是同步,返回是本次需要同步的目录数 func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync bool) (hint string, err error) { - userName := ctx.GetUserName() num := 0 db := dao.GetDB() storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDMTWM) @@ -25,57 +24,59 @@ func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask t return hint, err } vendorStoreID := storeDetail.VendorStoreID - rootTask := tasksch.NewSeqTask("美团外卖SyncStoreCategory step1", userName, func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - level := step + 1 - catList, err := dao.GetStoreCategories(db, model.VendorIDMTWM, storeID, level) - if len(catList) > 0 { - num += len(catList) - task := tasksch.NewParallelTask(fmt.Sprintf("美团外卖SyncStoreCategory step2, level=%d", level), 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) - if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { - if catInfo.MtwmSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除 - globals.SugarLogger.Debugf("RetailCatDelete vendorStoreID:%s, MtwmID:%s", vendorStoreID, catInfo.MtwmID) - err = api.MtwmAPI.RetailCatDelete(vendorStoreID, catInfo.MtwmID) - } else if catInfo.MtwmSyncStatus&(model.SyncFlagNewMask|model.SyncFlagModifiedMask) != 0 { // 新增 - catName := catInfo.CatName - subCatName := "" - originName := "" - if catInfo.MtwmSyncStatus&model.SyncFlagNewMask == 0 { - originName = catInfo.MtwmID - } - if level == 2 { - originName = catInfo.ParentCatName - catName = catInfo.ParentCatName - subCatName = catInfo.CatName - if catInfo.MtwmSyncStatus&model.SyncFlagNewMask == 0 { - originName = catInfo.MtwmID - catName = catInfo.CatName - subCatName = "" + rootTask := tasksch.NewSeqTask("美团外卖SyncStoreCategory step1", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + level := step + 1 + catList, err := dao.GetStoreCategories(db, model.VendorIDMTWM, storeID, level) + if len(catList) > 0 { + num += len(catList) + task := tasksch.NewParallelTask(fmt.Sprintf("美团外卖SyncStoreCategory step2, level=%d", level), nil, ctx, + 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) + if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { + if catInfo.MtwmSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除 + globals.SugarLogger.Debugf("RetailCatDelete vendorStoreID:%s, MtwmID:%s", vendorStoreID, catInfo.MtwmID) + err = api.MtwmAPI.RetailCatDelete(vendorStoreID, catInfo.MtwmID) + } else if catInfo.MtwmSyncStatus&(model.SyncFlagNewMask|model.SyncFlagModifiedMask) != 0 { // 新增 + catName := catInfo.CatName + subCatName := "" + originName := "" + if catInfo.MtwmSyncStatus&model.SyncFlagNewMask == 0 { + originName = catInfo.MtwmID + } + if level == 2 { + originName = catInfo.ParentCatName + catName = catInfo.ParentCatName + subCatName = catInfo.CatName + if catInfo.MtwmSyncStatus&model.SyncFlagNewMask == 0 { + originName = catInfo.MtwmID + catName = catInfo.CatName + subCatName = "" + } + } + if catName == "" { + panic("catName is empty") + } + globals.SugarLogger.Debugf("RetailCatUpdate vendorStoreID:%s, originName:%s, catName:%s, subCatName:%s, seq:%d", vendorStoreID, originName, catName, subCatName, catInfo.Seq) + if err = api.MtwmAPI.RetailCatUpdate(vendorStoreID, originName, catName, subCatName, catInfo.Seq); err == nil { + catInfo.MtwmID = catInfo.CatName + updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[model.VendorIDMTWM])) + } } } - if catName == "" { - panic("catName is empty") + if err == nil { + db2 := dao.GetDB() + catInfo.MtwmSyncStatus = 0 + _, err = dao.UpdateEntity(db2, &catInfo.StoreSkuCategoryMap, updateFields...) } - globals.SugarLogger.Debugf("RetailCatUpdate vendorStoreID:%s, originName:%s, catName:%s, subCatName:%s, seq:%d", vendorStoreID, originName, catName, subCatName, catInfo.Seq) - if err = api.MtwmAPI.RetailCatUpdate(vendorStoreID, originName, catName, subCatName, catInfo.Seq); err == nil { - catInfo.MtwmID = catInfo.CatName - updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[model.VendorIDMTWM])) - } - } - } - if err == nil { - db2 := dao.GetDB() - catInfo.MtwmSyncStatus = 0 - _, err = dao.UpdateEntity(db2, &catInfo.StoreSkuCategoryMap, updateFields...) - } - return nil, err - }, catList) - rootTask.AddChild(task).Run() - _, err = task.GetResult(0) - } - return nil, err - }, 2) + return nil, err + }, catList) + rootTask.AddChild(task).Run() + _, err = task.GetResult(0) + } + return nil, err + }, 2) tasksch.AddChild(parentTask, rootTask).Run() if !isAsync { hint = utils.Int2Str(num) @@ -235,56 +236,57 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks } // globals.SugarLogger.Debug(utils.Format4Output(skus, false)) vendorStoreID := storeDetail.VendorStoreID - rootTask := tasksch.NewParallelTask("美团外卖SyncStoreSkus", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(rootTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - foodDataList := make([]map[string]interface{}, len(batchItemList)) - // for k, v := range batchItemList { - v := batchItemList[0] - skuItem := v.(*dao.StoreSkuSyncInfo) - if skuItem.SkuSyncStatus&model.SyncFlagDeletedMask != 0 { - err = api.MtwmAPI.RetailDelete(vendorStoreID, utils.Int2Str(skuItem.ID)) - } else if skuItem.SkuSyncStatus&(model.SyncFlagModifiedMask|model.SyncFlagNewMask) != 0 { - foodData := make(map[string]interface{}) - foodDataList[0] = foodData - 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(int64(jxutils.CaculateSkuVendorPrice(int(skuItem.Price), int(storeDetail.PricePercentage)))) - foodData["min_order_count"] = 1 - foodData["unit"] = skuItem.Unit - foodData["box_num"] = 0 - foodData["box_price"] = 0.0 - foodData["category_name"] = skuItem.VendorCatID - foodData["is_sold_out"] = skuStatusJX2Mtwm(jxutils.MergeSkuStatus(skuItem.Status, skuItem.StoreSkuStatus)) - foodData["picture"] = skuItem.Img - if skuItem.VendorVendorCatID != 0 { - foodData["tag_id"] = utils.Int64ToStr(skuItem.VendorVendorCatID) - } else { - // foodData["tag_id"] = utils.Int64ToStr(defVendorCatID) + rootTask := tasksch.NewParallelTask("美团外卖SyncStoreSkus", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(rootTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + foodDataList := make([]map[string]interface{}, len(batchItemList)) + // for k, v := range batchItemList { + v := batchItemList[0] + skuItem := v.(*dao.StoreSkuSyncInfo) + if skuItem.SkuSyncStatus&model.SyncFlagDeletedMask != 0 { + err = api.MtwmAPI.RetailDelete(vendorStoreID, utils.Int2Str(skuItem.ID)) + } else if skuItem.SkuSyncStatus&(model.SyncFlagModifiedMask|model.SyncFlagNewMask) != 0 { + foodData := make(map[string]interface{}) + foodDataList[0] = foodData + 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(int64(jxutils.CaculateSkuVendorPrice(int(skuItem.Price), int(storeDetail.PricePercentage)))) + foodData["min_order_count"] = 1 + foodData["unit"] = skuItem.Unit + foodData["box_num"] = 0 + foodData["box_price"] = 0.0 + foodData["category_name"] = skuItem.VendorCatID + foodData["is_sold_out"] = skuStatusJX2Mtwm(jxutils.MergeSkuStatus(skuItem.Status, skuItem.StoreSkuStatus)) + foodData["picture"] = skuItem.Img + if skuItem.VendorVendorCatID != 0 { + foodData["tag_id"] = utils.Int64ToStr(skuItem.VendorVendorCatID) + } else { + // foodData["tag_id"] = utils.Int64ToStr(defVendorCatID) + } + skus := []map[string]interface{}{ + map[string]interface{}{ + "sku_id": foodData[mtwmapi.KeyAppFoodCode], + "spec": jxutils.ComposeSkuSpec(skuItem.SpecQuality, skuItem.SpecUnit), + "price": foodData["price"], + "stock": "*", + "upc": skuItem.Upc, + }, + } + if foodData["tag_id"] != nil { + skus[0]["weight"] = skuItem.Weight // weight字段仅限服饰鞋帽、美妆、日用品、母婴、生鲜果蔬、生活超市下的便利店/超市门店品类的商家使用 + } + foodData["skus"] = skus + if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { + err = api.MtwmAPI.RetailBatchInitData(vendorStoreID, foodDataList) + } } - skus := []map[string]interface{}{ - map[string]interface{}{ - "sku_id": foodData[mtwmapi.KeyAppFoodCode], - "spec": jxutils.ComposeSkuSpec(skuItem.SpecQuality, skuItem.SpecUnit), - "price": foodData["price"], - "stock": "*", - "upc": skuItem.Upc, - }, + if err == nil { + storeSkuBind := &model.StoreSkuBind{} + storeSkuBind.ID = skuItem.BindID + _, err = dao.UpdateEntity(nil, storeSkuBind, model.FieldMtwmSyncStatus) } - if foodData["tag_id"] != nil { - skus[0]["weight"] = skuItem.Weight // weight字段仅限服饰鞋帽、美妆、日用品、母婴、生鲜果蔬、生活超市下的便利店/超市门店品类的商家使用 - } - foodData["skus"] = skus - if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.RetailBatchInitData(vendorStoreID, foodDataList) - } - } - if err == nil { - storeSkuBind := &model.StoreSkuBind{} - storeSkuBind.ID = skuItem.BindID - _, err = dao.UpdateEntity(nil, storeSkuBind, model.FieldMtwmSyncStatus) - } - return nil, err - }, skus) + return nil, err + }, skus) if parentTask != nil { parentTask.AddChild(rootTask) } @@ -307,28 +309,29 @@ func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask t globals.SugarLogger.Debugf("mtwm FullSyncStoreSkus storeID:%d, isContinueWhenError:%t, userName:%s", storeID, isContinueWhenError, userName) db := dao.GetDB() - rootTask := tasksch.NewSeqTask("美团外卖FullSyncStoreSkus", userName, func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - err = p.DeleteRemoteSkus(ctx, rootTask, storeID, nil) - if isContinueWhenError { - err = nil + rootTask := tasksch.NewSeqTask("美团外卖FullSyncStoreSkus", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + err = p.DeleteRemoteSkus(ctx, rootTask, storeID, nil) + if isContinueWhenError { + err = nil + } + case 1: + _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDMTWM, storeID, nil, model.SyncFlagNewMask) + case 2: + if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil { + _, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDMTWM, storeID, nil, model.SyncFlagNewMask) + } + case 3: + _, err = p.SyncLocalStoreCategory(ctx, db, storeID, true) + case 4: + _, err = p.SyncStoreCategory(ctx, rootTask, storeID, false) + case 5: + _, err = p.SyncStoreSkus(ctx, rootTask, storeID, nil, false, isContinueWhenError) } - case 1: - _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDMTWM, storeID, nil, model.SyncFlagNewMask) - case 2: - if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil { - _, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDMTWM, storeID, nil, model.SyncFlagNewMask) - } - case 3: - _, err = p.SyncLocalStoreCategory(ctx, db, storeID, true) - case 4: - _, err = p.SyncStoreCategory(ctx, rootTask, storeID, false) - case 5: - _, err = p.SyncStoreSkus(ctx, rootTask, storeID, nil, false, isContinueWhenError) - } - return nil, err - }, 6) + return nil, err + }, 6) tasksch.AddChild(parentTask, rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) @@ -351,13 +354,14 @@ func (p *PurchaseHandler) DeleteRemoteSkus(ctx *jxcontext.Context, parentTask ta return err } vendorStoreID := storeDetail.VendorStoreID - task := tasksch.NewParallelTask("mtwm DeleteRemoteSkus", tasksch.NewParallelConfig().SetIsContinueWhenError(true), "", func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { - // globals.SugarLogger.Debugf("mtwm RetailDelete vendorStoreID:%s, sku:%s", vendorStoreID, batchItemList[0].(string)) - err = api.MtwmAPI.RetailDelete(vendorStoreID, batchItemList[0].(string)) - } - return nil, err - }, vendorSkuIDs) + task := tasksch.NewParallelTask("mtwm DeleteRemoteSkus", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { + // globals.SugarLogger.Debugf("mtwm RetailDelete vendorStoreID:%s, sku:%s", vendorStoreID, batchItemList[0].(string)) + err = api.MtwmAPI.RetailDelete(vendorStoreID, batchItemList[0].(string)) + } + return nil, err + }, vendorSkuIDs) tasksch.AddChild(parentTask, task).Run() _, err = task.GetResult(0) return err @@ -402,25 +406,27 @@ func (p *PurchaseHandler) DeleteRemoteCategories(ctx *jxcontext.Context, parentT } } } - 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", tasksch.NewParallelConfig().SetIsContinueWhenError(true), "", func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.RetailCatDelete(vendorStoreID, batchItemList[0].(string)) - } - return nil, err - }, catIDs) - rootTask.AddChild(task).Run() - _, err = task.GetResult(0) - } - return nil, err - }, 2) + rootTask := tasksch.NewSeqTask("mtwm DeleteRemoteCategories", ctx, + 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", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + if globals.EnableStoreWrite && globals.EnableMtwmStoreWrite { + err = api.MtwmAPI.RetailCatDelete(vendorStoreID, batchItemList[0].(string)) + } + return nil, err + }, catIDs) + rootTask.AddChild(task).Run() + _, err = task.GetResult(0) + } + return nil, err + }, 2) tasksch.AddChild(parentTask, rootTask).Run() _, err = rootTask.GetResult(0) return err @@ -432,24 +438,25 @@ func (p *PurchaseHandler) DeleteRemoteStoreSkus(ctx *jxcontext.Context, parentTa db := dao.GetDB() var errDeleteSku error - rootTask := tasksch.NewSeqTask("mtwm DeleteRemoteStoreSkus", userName, func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - err = p.DeleteRemoteSkus(ctx, rootTask, storeID, nil) - errDeleteSku = err - // 强制忽略删除SKU错误 - if isContinueWhenError { - err = nil + rootTask := tasksch.NewSeqTask("mtwm DeleteRemoteStoreSkus", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + err = p.DeleteRemoteSkus(ctx, rootTask, storeID, nil) + errDeleteSku = err + // 强制忽略删除SKU错误 + if isContinueWhenError { + err = nil + } + case 1: + _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDMTWM, storeID, nil, model.SyncFlagNewMask) + case 2: + if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil { + _, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDMTWM, storeID, nil, model.SyncFlagNewMask) + } } - case 1: - _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDMTWM, storeID, nil, model.SyncFlagNewMask) - case 2: - if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil { - _, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDMTWM, storeID, nil, model.SyncFlagNewMask) - } - } - return nil, err - }, 3) + return nil, err + }, 3) tasksch.AddChild(parentTask, rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) diff --git a/business/partner/purchase/weimob/wsc/store_sku.go b/business/partner/purchase/weimob/wsc/store_sku.go index 2e3e0c95f..98aa969f4 100644 --- a/business/partner/purchase/weimob/wsc/store_sku.go +++ b/business/partner/purchase/weimob/wsc/store_sku.go @@ -24,47 +24,48 @@ const ( ) func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync bool) (hint string, err error) { - userName := ctx.GetUserName() strStoreID := utils.Int2Str(storeID) num := 0 db := dao.GetDB() - rootTask := tasksch.NewSeqTask("微盟微商城SyncStoreCategory step1", userName, func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - level := step + 1 - catList, err := dao.GetStoreCategories(db, model.VendorIDWSC, storeID, level) - // globals.SugarLogger.Debug(utils.Format4Output(catList, false)) - if len(catList) > 0 { - num += len(catList) - task := tasksch.NewParallelTask(fmt.Sprintf("微盟微商城SyncStoreCategory step2, level=%d", level), nil, userName, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - updateFields := []string{dao.GetSyncStatusStructField(model.VendorNames[model.VendorIDWSC])} - catInfo := batchItemList[0].(*dao.StoreCatSyncInfo) - if globals.EnableStoreWrite && globals.EnableWscStoreWrite { - if catInfo.WscSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除 - globals.SugarLogger.Debugf("UpdateClassify strStoreID:%s, WscID:%d", strStoreID, catInfo.WscID) - err = api.WeimobAPI.UpdateClassify(catInfo.WscID, composeFakeDelName(catInfo.CatName), "") - } else if catInfo.WscSyncStatus&(model.SyncFlagNewMask|model.SyncFlagModifiedMask) != 0 { // 新增 - catImg := "" - if level == 2 { - catImg = DefCatImg + rootTask := tasksch.NewSeqTask("微盟微商城SyncStoreCategory step1", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + level := step + 1 + catList, err := dao.GetStoreCategories(db, model.VendorIDWSC, storeID, level) + // globals.SugarLogger.Debug(utils.Format4Output(catList, false)) + if len(catList) > 0 { + num += len(catList) + task := tasksch.NewParallelTask(fmt.Sprintf("微盟微商城SyncStoreCategory step2, level=%d", level), nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + updateFields := []string{dao.GetSyncStatusStructField(model.VendorNames[model.VendorIDWSC])} + catInfo := batchItemList[0].(*dao.StoreCatSyncInfo) + if globals.EnableStoreWrite && globals.EnableWscStoreWrite { + if catInfo.WscSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除 + globals.SugarLogger.Debugf("UpdateClassify strStoreID:%s, WscID:%d", strStoreID, catInfo.WscID) + err = api.WeimobAPI.UpdateClassify(catInfo.WscID, composeFakeDelName(catInfo.CatName), "") + } else if catInfo.WscSyncStatus&(model.SyncFlagNewMask|model.SyncFlagModifiedMask) != 0 { // 新增 + catImg := "" + if level == 2 { + catImg = DefCatImg + } + if catInfo.WscID, err = api.WeimobAPI.AddClassify(catInfo.CatName, utils.Str2Int64WithDefault(catInfo.ParentVendorCatID, 0), catImg); err == nil { + updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[model.VendorIDWSC])) + } + } else if catInfo.WscSyncStatus&(model.SyncFlagModifiedMask|model.SyncFlagModifiedMask) != 0 { // 修改 + err = api.WeimobAPI.UpdateClassify(catInfo.WscID, catInfo.CatName, "") + } } - if catInfo.WscID, err = api.WeimobAPI.AddClassify(catInfo.CatName, utils.Str2Int64WithDefault(catInfo.ParentVendorCatID, 0), catImg); err == nil { - updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[model.VendorIDWSC])) + if err == nil { + db2 := dao.GetDB() + catInfo.WscSyncStatus = 0 + _, err = dao.UpdateEntity(db2, &catInfo.StoreSkuCategoryMap, updateFields...) } - } else if catInfo.WscSyncStatus&(model.SyncFlagModifiedMask|model.SyncFlagModifiedMask) != 0 { // 修改 - err = api.WeimobAPI.UpdateClassify(catInfo.WscID, catInfo.CatName, "") - } - } - if err == nil { - db2 := dao.GetDB() - catInfo.WscSyncStatus = 0 - _, err = dao.UpdateEntity(db2, &catInfo.StoreSkuCategoryMap, updateFields...) - } - return nil, err - }, catList) - rootTask.AddChild(task).Run() - _, err = task.GetResult(0) - } - return nil, err - }, 2) + return nil, err + }, catList) + rootTask.AddChild(task).Run() + _, err = task.GetResult(0) + } + return nil, err + }, 2) tasksch.AddChild(parentTask, rootTask).Run() if !isAsync { hint = utils.Int2Str(num) @@ -170,80 +171,81 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks return "", err } globals.SugarLogger.Debug(utils.Format4Output(skus, false)) - rootTask := tasksch.NewParallelTask("微盟微商城SyncStoreSkus", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(rootTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - v := batchItemList[0] - skuItem := v.(*dao.StoreSkuSyncInfo) - updateFields := []string{model.FieldWscSyncStatus} - storeSkuBind := &model.StoreSkuBind{} - storeSkuBind.ID = skuItem.BindID - if skuItem.SkuSyncStatus&model.SyncFlagDeletedMask != 0 { - goodsID := utils.Str2Int64WithDefault(skuItem.VendorNameID, 0) - if err = api.WeimobAPI.UpdateGoodsShelfStatus([]int64{goodsID}, false); err == nil { - err = api.WeimobAPI.UpdateGoodsTitle(goodsID, composeFakeDelName(skuItem.Name)) - } - } else if skuItem.SkuSyncStatus&(model.SyncFlagModifiedMask|model.SyncFlagNewMask) != 0 { - outerGoodsCode := utils.Int2Str(skuItem.NameID) - title := jxutils.ComposeSkuName(skuItem.Prefix, skuItem.Name, skuItem.Comment, skuItem.Unit, skuItem.SpecQuality, skuItem.SpecUnit, 30) - isPutAway := jxutils.MergeSkuStatus(skuItem.Status, skuItem.StoreSkuStatus) == model.SkuStatusNormal - categoryId := skuItem.VendorVendorCatID - if categoryId == 0 { - categoryId = DefVendorCategoryId - } - classifyIdList := []int64{utils.Str2Int64WithDefault(skuItem.VendorCatID, 0)} - if skuItem.SkuVendorCatID != "" { - if int64Value := utils.Str2Int64WithDefault(skuItem.SkuVendorCatID, 0); int64Value > 0 { - classifyIdList = append(classifyIdList, int64Value) + rootTask := tasksch.NewParallelTask("微盟微商城SyncStoreSkus", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(rootTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + v := batchItemList[0] + skuItem := v.(*dao.StoreSkuSyncInfo) + updateFields := []string{model.FieldWscSyncStatus} + storeSkuBind := &model.StoreSkuBind{} + storeSkuBind.ID = skuItem.BindID + if skuItem.SkuSyncStatus&model.SyncFlagDeletedMask != 0 { + goodsID := utils.Str2Int64WithDefault(skuItem.VendorNameID, 0) + if err = api.WeimobAPI.UpdateGoodsShelfStatus([]int64{goodsID}, false); err == nil { + err = api.WeimobAPI.UpdateGoodsTitle(goodsID, composeFakeDelName(skuItem.Name)) } - } - b2cGoods := &weimobapi.PendingSaveB2CGoodsVo{ - FreightTemplateId: DefFreightTemplateId, - DeliveryTypeIdList: []int64{DefDeliveryTypeId}, - B2cGoodsType: weimobapi.GoodsTypeNormal, - } - salePrice := int64(jxutils.CaculateSkuVendorPrice(int(skuItem.Price), int(storeDetail.PricePercentage))) - skuList := []map[string]interface{}{ - map[string]interface{}{ - weimobapi.KeyOuterSkuCode: utils.Int2Str(skuItem.ID), - weimobapi.KeyImageURL: skuItem.Img, - weimobapi.KeySalePrice: jxutils.IntPrice2Standard(salePrice), - weimobapi.KeyCostPrice: jxutils.IntPrice2Standard(salePrice * 8 / 10), - weimobapi.KeyOriginalPrice: jxutils.IntPrice2Standard(salePrice * 10 / (6 + rand.Int63n(4))), - weimobapi.KeyEditStockNum: model.MaxStoreSkuStockQty, - weimobapi.KeyB2cSku: &weimobapi.PendingSaveB2CSkuVo{ - Weight: jxutils.IntWeight2Float(skuItem.Weight), + } else if skuItem.SkuSyncStatus&(model.SyncFlagModifiedMask|model.SyncFlagNewMask) != 0 { + outerGoodsCode := utils.Int2Str(skuItem.NameID) + title := jxutils.ComposeSkuName(skuItem.Prefix, skuItem.Name, skuItem.Comment, skuItem.Unit, skuItem.SpecQuality, skuItem.SpecUnit, 30) + isPutAway := jxutils.MergeSkuStatus(skuItem.Status, skuItem.StoreSkuStatus) == model.SkuStatusNormal + categoryId := skuItem.VendorVendorCatID + if categoryId == 0 { + categoryId = DefVendorCategoryId + } + classifyIdList := []int64{utils.Str2Int64WithDefault(skuItem.VendorCatID, 0)} + if skuItem.SkuVendorCatID != "" { + if int64Value := utils.Str2Int64WithDefault(skuItem.SkuVendorCatID, 0); int64Value > 0 { + classifyIdList = append(classifyIdList, int64Value) + } + } + b2cGoods := &weimobapi.PendingSaveB2CGoodsVo{ + FreightTemplateId: DefFreightTemplateId, + DeliveryTypeIdList: []int64{DefDeliveryTypeId}, + B2cGoodsType: weimobapi.GoodsTypeNormal, + } + salePrice := int64(jxutils.CaculateSkuVendorPrice(int(skuItem.Price), int(storeDetail.PricePercentage))) + skuList := []map[string]interface{}{ + map[string]interface{}{ + weimobapi.KeyOuterSkuCode: utils.Int2Str(skuItem.ID), + weimobapi.KeyImageURL: skuItem.Img, + weimobapi.KeySalePrice: jxutils.IntPrice2Standard(salePrice), + weimobapi.KeyCostPrice: jxutils.IntPrice2Standard(salePrice * 8 / 10), + weimobapi.KeyOriginalPrice: jxutils.IntPrice2Standard(salePrice * 10 / (6 + rand.Int63n(4))), + weimobapi.KeyEditStockNum: model.MaxStoreSkuStockQty, + weimobapi.KeyB2cSku: &weimobapi.PendingSaveB2CSkuVo{ + Weight: jxutils.IntWeight2Float(skuItem.Weight), + }, }, - }, - } - if globals.EnableStoreWrite && globals.EnableWscStoreWrite { - if skuItem.SkuSyncStatus&model.SyncFlagNewMask != 0 { - goodsID, skuMap, err2 := api.WeimobAPI.AddGoods(outerGoodsCode, title, false, []string{skuItem.Img}, skuItem.Comment, isPutAway, 0, categoryId, classifyIdList, b2cGoods, skuList, nil) - if err = err2; err == nil { - storeSkuBind.WscID = skuMap[utils.Int2Str(skuItem.ID)] - storeSkuBind.WscID2 = goodsID - updateFields = append(updateFields, model.FieldWscID, model.FieldWscID2) - } - } else { - goodsID := utils.Str2Int64WithDefault(skuItem.VendorNameID, 0) - - goodsInfo, err2 := api.WeimobAPI.QueryGoodsDetail(goodsID) - if err = err2; err == nil { - // http://open.weimob.com/docapi/article?tag=Af - // sku id,如果为空,则新增sku; 如果更新之前的skuId与入参skuId对应,则更新sku; 如果更新之前的skuId没有和入参的skuId对应,删除更新之前的sku - skuList[0][weimobapi.KeySkuID] = utils.Str2Int64WithDefault(skuItem.VendorSkuID, 0) - remoteSkuList := goodsInfo[weimobapi.KeySkuList].([]interface{}) - if len(remoteSkuList) > 0 { - skuList[0][weimobapi.KeyEditStockNum] = model.MaxStoreSkuStockQty - int(utils.MustInterface2Int64(remoteSkuList[0].(map[string]interface{})[weimobapi.KeyAvailableStockNum])) + } + if globals.EnableStoreWrite && globals.EnableWscStoreWrite { + if skuItem.SkuSyncStatus&model.SyncFlagNewMask != 0 { + goodsID, skuMap, err2 := api.WeimobAPI.AddGoods(outerGoodsCode, title, false, []string{skuItem.Img}, skuItem.Comment, isPutAway, 0, categoryId, classifyIdList, b2cGoods, skuList, nil) + if err = err2; err == nil { + storeSkuBind.WscID = skuMap[utils.Int2Str(skuItem.ID)] + storeSkuBind.WscID2 = goodsID + updateFields = append(updateFields, model.FieldWscID, model.FieldWscID2) + } + } else { + goodsID := utils.Str2Int64WithDefault(skuItem.VendorNameID, 0) + + goodsInfo, err2 := api.WeimobAPI.QueryGoodsDetail(goodsID) + if err = err2; err == nil { + // http://open.weimob.com/docapi/article?tag=Af + // sku id,如果为空,则新增sku; 如果更新之前的skuId与入参skuId对应,则更新sku; 如果更新之前的skuId没有和入参的skuId对应,删除更新之前的sku + skuList[0][weimobapi.KeySkuID] = utils.Str2Int64WithDefault(skuItem.VendorSkuID, 0) + remoteSkuList := goodsInfo[weimobapi.KeySkuList].([]interface{}) + if len(remoteSkuList) > 0 { + skuList[0][weimobapi.KeyEditStockNum] = model.MaxStoreSkuStockQty - int(utils.MustInterface2Int64(remoteSkuList[0].(map[string]interface{})[weimobapi.KeyAvailableStockNum])) + } + _, _, err = api.WeimobAPI.UpdateGoods(goodsID, title, false, []string{skuItem.Img}, skuItem.Comment, isPutAway, 0, categoryId, classifyIdList, b2cGoods, skuList, nil) } - _, _, err = api.WeimobAPI.UpdateGoods(goodsID, title, false, []string{skuItem.Img}, skuItem.Comment, isPutAway, 0, categoryId, classifyIdList, b2cGoods, skuList, nil) } } } - } - if err == nil { - _, err = dao.UpdateEntity(nil, storeSkuBind, updateFields...) - } - return nil, err - }, skus) + if err == nil { + _, err = dao.UpdateEntity(nil, storeSkuBind, updateFields...) + } + return nil, err + }, skus) if parentTask != nil { parentTask.AddChild(rootTask) } @@ -266,21 +268,22 @@ func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask t globals.SugarLogger.Debugf("wsc FullSyncStoreSkus storeID:%d, isContinueWhenError:%t, userName:%s", storeID, isContinueWhenError, userName) db := dao.GetDB() - rootTask := tasksch.NewSeqTask("微盟微商城FullSyncStoreSkus", userName, func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - _, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDWSC, storeID, nil, model.SyncFlagNewMask) - case 1: - _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDWSC, storeID, nil, model.SyncFlagNewMask) - case 2: - _, err = p.SyncLocalStoreCategory(ctx, db, storeID, false) - case 3: - _, err = p.SyncStoreCategory(ctx, rootTask, storeID, false) - case 4: - _, err = p.SyncStoreSkus(ctx, rootTask, storeID, nil, true, isContinueWhenError) - } - return nil, err - }, 5) + rootTask := tasksch.NewSeqTask("微盟微商城FullSyncStoreSkus", ctx, + func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + _, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDWSC, storeID, nil, model.SyncFlagNewMask) + case 1: + _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDWSC, storeID, nil, model.SyncFlagNewMask) + case 2: + _, err = p.SyncLocalStoreCategory(ctx, db, storeID, false) + case 3: + _, err = p.SyncStoreCategory(ctx, rootTask, storeID, false) + case 4: + _, err = p.SyncStoreSkus(ctx, rootTask, storeID, nil, true, isContinueWhenError) + } + return nil, err + }, 5) tasksch.AddChild(parentTask, rootTask).Run() if !isAsync { _, err = rootTask.GetResult(0) diff --git a/conf/app.conf b/conf/app.conf index c7211424e..d7a8b2588 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -54,6 +54,7 @@ weimobCallbackURL = "http://callback.test.jxc4.com/weimob" weixinPageAppID = "wx018dbe7daa3d5627" weixinPageSecret = "c7a84ed3ef3ae04ac78e02fb593ffbe5" +dingdingAgentID = 241047291 dingdingAppKey = "dingpx4hcf55zb4ubewg" dingdingSecret = "1zooB4bmEXPesdwb1ElWASVQ1vinOSZM-1XCUFrrSjHsNAId1UuVCT5tmHSmg5_V" @@ -123,6 +124,7 @@ enableWscStoreWrite = true weimobCallbackURL = "http://callback.jxc4.com/weimob" +dingdingAgentID = 239461075 dingdingAppKey = "ding7iu9cptairtcls0c" dingdingSecret = "LWrZAFeqUfuVv7n_tc8vPpCAx6PT4CwManx2XCVhJOqGsx2L5XCDuX1sAN_JtvsI" diff --git a/globals/api/api.go b/globals/api/api.go index c622873a2..fd2669cb5 100644 --- a/globals/api/api.go +++ b/globals/api/api.go @@ -90,7 +90,7 @@ func Init() { weimobAPIConfig.ClientTimeout = 120 * time.Second WeimobAPI = weimobapi.New(nil, beego.AppConfig.DefaultString("weimobAppID", ""), beego.AppConfig.DefaultString("weimobAppSecret", ""), &weimobAPIConfig) - DingDingAPI = dingdingapi.New(beego.AppConfig.DefaultString("dingdingCorpID", ""), beego.AppConfig.DefaultString("dingdingAppKey", ""), beego.AppConfig.DefaultString("dingdingSecret", "")) + DingDingAPI = dingdingapi.NewWithAgentID(beego.AppConfig.DefaultInt64("dingdingAgentID", 0), beego.AppConfig.DefaultString("dingdingCorpID", ""), beego.AppConfig.DefaultString("dingdingAppKey", ""), beego.AppConfig.DefaultString("dingdingSecret", "")) DingDingQRCodeAPI = dingdingapi.New(beego.AppConfig.DefaultString("dingdingCorpID", ""), beego.AppConfig.DefaultString("dingdingQRCodeAppKey", ""), beego.AppConfig.DefaultString("dingdingQRCodeSecret", "")) }