From 412fe44d32ec0fcddd0fa4cfd6de5c097ecde751 Mon Sep 17 00:00:00 2001 From: gazebo Date: Thu, 28 Nov 2019 08:59:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89=E6=B4=BB=E5=8A=A8=E8=A6=81=E6=B1=82?= =?UTF-8?q?=E5=BC=BA=E5=88=B6=E5=88=B7=E6=96=B0=E5=95=86=E5=93=81=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0=E4=BB=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/act/act.go | 99 ++++++++++++++++++++++++++ business/jxstore/act/act_test.go | 17 ++++- business/jxstore/cms/sync_store_sku.go | 13 +++- business/model/dao/store_sku.go | 57 ++++++++++++++- controllers/act.go | 20 ++++++ routers/commentsRouter_controllers.go | 9 +++ 6 files changed, 208 insertions(+), 7 deletions(-) diff --git a/business/jxstore/act/act.go b/business/jxstore/act/act.go index 119d3a727..a370b7c00 100644 --- a/business/jxstore/act/act.go +++ b/business/jxstore/act/act.go @@ -7,6 +7,7 @@ import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils/errlist" + "git.rosy.net.cn/jx-callback/business/jxstore/cms" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" @@ -937,3 +938,101 @@ func DeleteSkusFromAct(ctx *jxcontext.Context, vendorID int, skuIDs []int, isAsy } return hint, err } + +func ForceUpdateVendorPrice(ctx *jxcontext.Context, vendorID int, actType int, storeSkuList []*ActStoreSkuParam, isAsync bool) (hint string, err error) { + var wrongSkuList []*ActStoreSkuParam + var storeSkuBindList []*model.StoreSkuBind + + db := dao.GetDB() + errList := errlist.New() + for _, v := range storeSkuList { + storeSkuBind := &model.StoreSkuBind{ + StoreID: v.StoreID, + SkuID: v.SkuID, + } + storeSkuBind.DeletedAt = utils.DefaultTimeValue + if err = dao.GetEntity(db, storeSkuBind, model.FieldStoreID, model.FieldSkuID, model.FieldDeletedAt); err == nil { + if v.VendorPrice != 0 { + if err2 := checkDiscountValidation(actType, float64(v.ActualActPrice)*100/float64(v.VendorPrice)); err2 != nil { + v.ErrMsg = err2.Error() + wrongSkuList = append(wrongSkuList, v) + storeSkuBind = nil + } + } else { + vendorPrice := dao.GetStoreSkuBindVendorPrice(storeSkuBind, vendorID) + if checkDiscountValidation(actType, float64(v.ActualActPrice)*100/float64(vendorPrice)) != nil { + if actType == model.ActSkuSecKill { + vendorPrice = int(v.ActualActPrice)*100/maxDiscount4SkuSecKill + 10 + } else if actType == model.ActSkuDirectDown { + vendorPrice = int(v.ActualActPrice) + 10 + } + dao.SetStoreSkuBindVendorPrice(storeSkuBind, vendorID, vendorPrice) + if vendorID != model.VendorIDJX { + dao.SetStoreSkuBindSyncStatus(storeSkuBind, vendorID, dao.GetStoreSkuBindSyncStatus(storeSkuBind, vendorID)|model.SyncFlagPriceMask) + } + storeSkuBind.LastOperator = ctx.GetUserName() + } + } + if storeSkuBind != nil { + storeSkuBindList = append(storeSkuBindList, storeSkuBind) + } + } else { + errList.AddErr(err) + } + } + if err = errList.GetErrListAsOne(); err != nil { + return "", err + } + if len(wrongSkuList) > 0 { + return "", jsonerr.New(wrongSkuList, model.ErrCodeJsonActPriceTooLarger) + } + + storeVendorIDMap := make(map[int]string) + storeSkuIDMap := make(map[int][]int) + + task := tasksch.NewSeqTask2(fmt.Sprintf("强制刷新门店商品%s平台价", model.VendorChineseNames[vendorID]), ctx, false, + func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + errList := errlist.New() + for _, storeSkuBind := range storeSkuBindList { + if _, err2 := dao.UpdateEntity(db, storeSkuBind); err2 == nil { + if storeVendorIDMap[storeSkuBind.StoreID] == "" { + if storeDetail, err2 := dao.GetStoreDetail(db, storeSkuBind.StoreID, vendorID); err2 == nil { + storeVendorIDMap[storeSkuBind.StoreID] = storeDetail.VendorStoreID + } + } + storeSkuIDMap[storeSkuBind.StoreID] = append(storeSkuIDMap[storeSkuBind.StoreID], storeSkuBind.SkuID) + errList.AddErr(err2) + } + } + err = errList.GetErrListAsOne() + case 1: + if vendorID != model.VendorIDJX && len(storeVendorIDMap) > 0 { + var storeIDs []int + for storeID := range storeVendorIDMap { + storeIDs = append(storeIDs, storeID) + } + subTask := tasksch.NewParallelTask("同步平台价格", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + storeID := batchItemList[0].(int) + _, err = cms.SyncStoreSkuNew2(ctx, task, vendorID, storeID, storeVendorIDMap[storeID], nil, storeSkuIDMap[storeID], nil, true, false, true) + return retVal, err + }, storeIDs) + tasksch.HandleTask(subTask, task, true).Run() + _, err = subTask.GetResult(0) + } + } + return result, err + }, 2) + tasksch.HandleTask(task, nil, true).Run() + if isAsync { + hint = task.GetID() + } else { + _, err2 := task.GetResult(0) + if err = err2; err == nil { + hint = utils.Int2Str(1) + } + } + return hint, err +} diff --git a/business/jxstore/act/act_test.go b/business/jxstore/act/act_test.go index 670c21a76..47c393cf9 100644 --- a/business/jxstore/act/act_test.go +++ b/business/jxstore/act/act_test.go @@ -185,7 +185,22 @@ func TestAddActStoreBind(t *testing.T) { } func TestSyncAct(t *testing.T) { - _, err := SyncAct(jxcontext.AdminCtx, nil, 1, nil, nil, nil, false) + _, err := SyncAct(jxcontext.AdminCtx, nil, 1, nil, false) + if err != nil { + t.Fatal(err) + } +} + +func TestForceUpdateVendorPrice(t *testing.T) { + _, err := ForceUpdateVendorPrice(jxcontext.AdminCtx, model.VendorIDJD, model.ActSkuDirectDown, []*ActStoreSkuParam{ + &ActStoreSkuParam{ + ActStoreSku: model.ActStoreSku{ + StoreID: 100118, + SkuID: 22509, + }, + ActualActPrice: 9900, + }, + }, false) if err != nil { t.Fatal(err) } diff --git a/business/jxstore/cms/sync_store_sku.go b/business/jxstore/cms/sync_store_sku.go index ee9d426a8..cc8d4d3ea 100644 --- a/business/jxstore/cms/sync_store_sku.go +++ b/business/jxstore/cms/sync_store_sku.go @@ -132,6 +132,10 @@ func SyncStoreCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo } func SyncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, nameIDs, skuIDs, excludeSkuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { + return SyncStoreSkuNew2(ctx, parentTask, vendorID, storeID, vendorStoreID, nameIDs, skuIDs, excludeSkuIDs, false, isAsync, isContinueWhenError) +} + +func SyncStoreSkuNew2(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, nameIDs, skuIDs, excludeSkuIDs []int, useVendorPriceDirectly, isAsync, isContinueWhenError bool) (hint string, err error) { singleStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) if singleStoreHandler != nil { if err = CreateStoreCategoryByStoreSku(ctx, vendorID, storeID, vendorStoreID, nameIDs, skuIDs); err != nil { @@ -146,7 +150,7 @@ func SyncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, _, err = SyncStoreCategories(ctx, task, vendorID, storeID, vendorStoreID, nameIDs, skuIDs, false, isContinueWhenError) } case 1: - err = syncStoreSkuNew(ctx, task, false, vendorID, storeID, nameIDs, skuIDs, excludeSkuIDs, isContinueWhenError) + err = syncStoreSkuNew(ctx, task, false, vendorID, storeID, nameIDs, skuIDs, excludeSkuIDs, useVendorPriceDirectly, isContinueWhenError) } return result, err }, 2) @@ -176,7 +180,7 @@ func FullSyncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo if singleStoreHandler != nil { _, err = SyncStoreSkuNew(ctx, task, vendorID, storeID, vendorStoreID, nil, nil, nil, false, isContinueWhenError) } else { - err = syncStoreSkuNew(ctx, task, true, vendorID, storeID, nil, nil, nil, isContinueWhenError) + err = syncStoreSkuNew(ctx, task, true, vendorID, storeID, nil, nil, nil, false, isContinueWhenError) } } return retVal, err @@ -285,7 +289,7 @@ func updateStoreSku(db *dao.DaoDB, vendorID int, storeSkuList []*dao.StoreSkuSyn return num, err } -func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bool, vendorID, storeID int, nameIDs, skuIDs, excludeSkuIDs []int, isContinueWhenError bool) (err error) { +func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bool, vendorID, storeID int, nameIDs, skuIDs, excludeSkuIDs []int, useVendorPriceDirectly, isContinueWhenError bool) (err error) { db := dao.GetDB() storeDetail, err := dao.GetStoreDetail(db, storeID, vendorID) if err != nil { @@ -331,6 +335,9 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo } now := jxutils.OperationTime2HourMinuteFormat(time.Now()) for _, sku := range skus { + if !useVendorPriceDirectly { + sku.VendorPrice = 0 + } sku.MergedStatus = MergeSkuSaleStatusWithStoreOpTime(sku, storeDetail, now) var bareSku *partner.StoreSkuInfo isNeedReorder := false diff --git a/business/model/dao/store_sku.go b/business/model/dao/store_sku.go index f7d454e2a..c15fb5504 100644 --- a/business/model/dao/store_sku.go +++ b/business/model/dao/store_sku.go @@ -219,8 +219,9 @@ func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty boo } fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) sql := ` - SELECT t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status, %s.%s_id vendor_sku_id, - t1.%s_sync_status store_sku_sync_status, t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end, + SELECT t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status, + %s.%s_id vendor_sku_id, t1.%s_sync_status store_sku_sync_status, t1.%s_price vendor_price, + t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end, t2.*, t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, IF(t11.%s <> '', t11.%s, t3.img) img, @@ -228,7 +229,7 @@ func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty boo t13.%s desc_img, t4.%s_category_id vendor_vendor_cat_id` fmtParams := []interface{}{ - tableName, fieldPrefix, fieldPrefix, + tableName, fieldPrefix, fieldPrefix, fieldPrefix, GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), @@ -661,3 +662,53 @@ func GetStoreSkusByNameIDs(db *DaoDB, storeIDs []int, nameID int) (skuList []*St err = GetRows(db, &skuList, sql, sqlParams...) return skuList, err } + +func SetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int, vendorPrice int) { + switch vendorID { + case model.VendorIDJD: + storeSkuBind.JdPrice = vendorPrice + case model.VendorIDMTWM: + storeSkuBind.MtwmPrice = vendorPrice + case model.VendorIDEBAI: + storeSkuBind.EbaiPrice = vendorPrice + case model.VendorIDJX: + storeSkuBind.JxPrice = vendorPrice + } +} + +func GetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int) (vendorPrice int) { + switch vendorID { + case model.VendorIDJD: + vendorPrice = storeSkuBind.JdPrice + case model.VendorIDMTWM: + vendorPrice = storeSkuBind.MtwmPrice + case model.VendorIDEBAI: + vendorPrice = storeSkuBind.EbaiPrice + case model.VendorIDJX: + vendorPrice = storeSkuBind.JxPrice + } + return vendorPrice +} + +func SetStoreSkuBindSyncStatus(storeSkuBind *model.StoreSkuBind, vendorID int, syncStatus int8) { + switch vendorID { + case model.VendorIDJD: + storeSkuBind.JdSyncStatus = syncStatus + case model.VendorIDMTWM: + storeSkuBind.MtwmSyncStatus = syncStatus + case model.VendorIDEBAI: + storeSkuBind.EbaiSyncStatus = syncStatus + } +} + +func GetStoreSkuBindSyncStatus(storeSkuBind *model.StoreSkuBind, vendorID int) (syncStatus int8) { + switch vendorID { + case model.VendorIDJD: + syncStatus = storeSkuBind.JdSyncStatus + case model.VendorIDMTWM: + syncStatus = storeSkuBind.MtwmSyncStatus + case model.VendorIDEBAI: + syncStatus = storeSkuBind.EbaiSyncStatus + } + return syncStatus +} diff --git a/controllers/act.go b/controllers/act.go index 77c892d54..8f94495af 100644 --- a/controllers/act.go +++ b/controllers/act.go @@ -300,3 +300,23 @@ func (c *ActController) DeleteSkusFromAct() { return retVal, "", err }) } + +// @Title 强制更新商品平台价 +// @Description 强制更新商品平台价 +// @Param token header string true "认证token" +// @Param type formData int true "活动类型,3:直降,4:秒杀(美团当前不支持秒杀)" +// @Param vendorID formData int true "厂商ID,当前只支持,京东:0,京西(用于记录活动信息):9" +// @Param actStoreSkuList formData string true "活动门店商品信息" +// @Param isAsync formData bool false "是否异步,缺省否(暂时只支持同步)" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /ForceUpdateVendorPrice [post] +func (c *ActController) ForceUpdateVendorPrice() { + c.callForceUpdateVendorPrice(func(params *tActForceUpdateVendorPriceParams) (retVal interface{}, errCode string, err error) { + var actStoreSkuList []*act.ActStoreSkuParam + if err = jxutils.Strings2Objs(params.ActStoreSkuList, &actStoreSkuList); err == nil { + act.ForceUpdateVendorPrice(params.Ctx, params.VendorID, params.Type, actStoreSkuList, params.IsAsync) + } + return retVal, "", err + }) +} diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 74b861540..e1ae4ee88 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -34,6 +34,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:ActController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:ActController"], + beego.ControllerComments{ + Method: "ForceUpdateVendorPrice", + Router: `/ForceUpdateVendorPrice`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:ActController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:ActController"], beego.ControllerComments{ Method: "GetActStoreSkuInfo",