diff --git a/business/jxcallback/auth/auth.go b/business/jxcallback/auth/auth.go index 6e18d40de..a3fec7a2e 100644 --- a/business/jxcallback/auth/auth.go +++ b/business/jxcallback/auth/auth.go @@ -6,7 +6,7 @@ import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" ) const ( @@ -52,7 +52,7 @@ func Login(id, loginType, secret string) (loginInfo *LoginInfo, err error) { ExpiresIn: time.Now().Add(DefTokenDuration).Unix(), Token: token, } - globals.Cacher.Set(token, loginInfo, DefTokenDuration) + api.Cacher.Set(token, loginInfo, DefTokenDuration) return loginInfo, nil } } else { @@ -63,18 +63,18 @@ func Login(id, loginType, secret string) (loginInfo *LoginInfo, err error) { func Logout(token string) (err error) { loginInfo := new(LoginInfo) - if err = globals.Cacher.GetAs(token, loginInfo); err == nil { + if err = api.Cacher.GetAs(token, loginInfo); err == nil { if handler := authers[loginInfo.LoginType]; handler != nil { err = handler.Logout(loginInfo.ID) } - globals.Cacher.Del(token) + api.Cacher.Del(token) } return err } func GetUserInfo(token string) (loginInfo *LoginInfo, err error) { loginInfo = new(LoginInfo) - if err = globals.Cacher.GetAs(token, loginInfo); err == nil { + if err = api.Cacher.GetAs(token, loginInfo); err == nil { return loginInfo, nil } return nil, model.ErrTokenIsInvalid diff --git a/business/jxcallback/auth/mobile/mobile.go b/business/jxcallback/auth/mobile/mobile.go index 9b17cc9e4..2d55dc309 100644 --- a/business/jxcallback/auth/mobile/mobile.go +++ b/business/jxcallback/auth/mobile/mobile.go @@ -7,6 +7,7 @@ import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" "github.com/KenmyZhang/aliyun-communicate" ) @@ -23,7 +24,7 @@ func SendVerifyCode(mobileNumber string) error { "code": code, }))) if err == nil { - globals.Cacher.Set(mobileNumber, code, DefVerifyCodeDuration) + api.Cacher.Set(mobileNumber, code, DefVerifyCodeDuration) } else { globals.SugarLogger.Infof("SendVerifyCode mobileNumber:%s failed with error:%v", mobileNumber, err) } @@ -33,9 +34,9 @@ func SendVerifyCode(mobileNumber string) error { func VerifyCode(mobileNumber, code string) bool { globals.SugarLogger.Debugf("VerifyCode mobileNumber:%s, code:%s", mobileNumber, code) - if value := globals.Cacher.Get(mobileNumber); value != nil { + if value := api.Cacher.Get(mobileNumber); value != nil { if code == value.(string) { - globals.Cacher.Del(mobileNumber) + api.Cacher.Del(mobileNumber) return true } } diff --git a/business/jxcallback/auth/weixin/weixin.go b/business/jxcallback/auth/weixin/weixin.go index c24df83b3..c0bcb04b1 100644 --- a/business/jxcallback/auth/weixin/weixin.go +++ b/business/jxcallback/auth/weixin/weixin.go @@ -54,7 +54,7 @@ func GetUserInfo(code string, state string) (token *UserInfoExt, err error) { if err = err2; err == nil { pwd := utils.GetUUID() globals.SugarLogger.Debugf("GetUserInfo code:%s, pwd:%s", code, pwd) - globals.Cacher.Set(wxUserinfo.OpenID, pwd, DefTempPasswordDuration) + api.Cacher.Set(wxUserinfo.OpenID, pwd, DefTempPasswordDuration) return &UserInfoExt{ UserInfo: *wxUserinfo, TempPassword: pwd, @@ -70,13 +70,13 @@ func GetUserInfo(code string, state string) (token *UserInfoExt, err error) { func (a *Auther) Login(openid, password string) (err error) { globals.SugarLogger.Debugf("Login openid:%s, password:%s", openid, password) - if value := globals.Cacher.Get(openid); value != nil { + if value := api.Cacher.Get(openid); value != nil { if password == value.(string) { // wxUser := &legacymodel.WeiXins{ // OpenID: openid, // } // if err = dao.GetEntity(nil, wxUser, "OpenID"); err == nil { - globals.Cacher.Del(openid) + api.Cacher.Del(openid) return nil // } } @@ -87,14 +87,14 @@ func (a *Auther) Login(openid, password string) (err error) { } func (a *Auther) Logout(openid string) error { - return globals.Cacher.Del(openid) + return api.Cacher.Del(openid) } func BindMobile(token, mobileNum, code, nickname string) (err error) { globals.SugarLogger.Debugf("BindMobile mobileNum:%s, code:%s, nickname:%s", mobileNum, code, nickname) loginInfo := new(auth.LoginInfo) - if err = globals.Cacher.GetAs(token, loginInfo); err == nil { + if err = api.Cacher.GetAs(token, loginInfo); err == nil { if mobile.VerifyCode(mobileNum, code) { user := &legacymodel.WeiXins{ OpenID: loginInfo.ID, diff --git a/business/jxstore/promotion/jd_promotion.go b/business/jxstore/promotion/jd_promotion.go index 2fe7d4927..6ed360d5c 100644 --- a/business/jxstore/promotion/jd_promotion.go +++ b/business/jxstore/promotion/jd_promotion.go @@ -197,90 +197,93 @@ func Init() { scheduleRoutine() } -func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueWhenError bool, params *PromotionParams, userName string) (hint string, err error) { +func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueWhenError bool, vendorPromotionID string, params *PromotionParams, userName string) (hint string, err error) { if len(params.SkuPrices) == 0 { return "", ErrEmptySkus } db := dao.GetDB() - skuIDs := make([]int, len(params.SkuPrices)) - skuPriceMap := make(map[int64]*SkuPrice) - for k, v := range params.SkuPrices { - skuIDs[k] = v.SkuID - skuPriceMap[int64(v.SkuID)] = v - } - sql := "" - var sqlParam []interface{} - if isIDJd { - sql = ` + modifyPricesList := make(map[int][]*jdapi.SkuPriceInfo) + promotionPrices := make([]map[string]interface{}, len(params.StoreIDs)*len(params.SkuPrices)) + var jxStoreIDs []int + + if vendorPromotionID == "" { + skuIDs := make([]int, len(params.SkuPrices)) + skuPriceMap := make(map[int64]*SkuPrice) + for k, v := range params.SkuPrices { + skuIDs[k] = v.SkuID + skuPriceMap[int64(v.SkuID)] = v + } + sql := "" + var sqlParam []interface{} + if isIDJd { + sql = ` SELECT t1.*, t2.jd_id FROM store_sku_bind t1 JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? JOIN store_map t3 ON t1.store_id = t3.store_id AND t3.vendor_id = ? AND t3.deleted_at = ? WHERE t1.jd_sync_status = 0 AND t1.deleted_at = ? AND t2.jd_id IN ( ` + dao.GenQuestionMarks(len(skuIDs)) + ") AND t3.vendor_store_id = ?" - sqlParam = append(sqlParam, utils.DefaultTimeValue, model.VendorIDJD, utils.DefaultTimeValue) - } else { - sql = ` + sqlParam = append(sqlParam, utils.DefaultTimeValue, model.VendorIDJD, utils.DefaultTimeValue) + } else { + sql = ` SELECT t1.*, 0 jd_id FROM store_sku_bind t1 WHERE t1.jd_sync_status = 0 AND t1.deleted_at = ? AND t1.sku_id IN ( ` + dao.GenQuestionMarks(len(skuIDs)) + ") AND t1.store_id = ?" - } - sqlParam = append(sqlParam, utils.DefaultTimeValue, skuIDs) + } + sqlParam = append(sqlParam, utils.DefaultTimeValue, skuIDs) - errMsg := "" - modifyPricesList := make(map[int][]*jdapi.SkuPriceInfo) - promotionPrices := make([]map[string]interface{}, len(params.StoreIDs)*len(params.SkuPrices)) - index := 0 - var jxStoreIDs []int - for _, storeID := range params.StoreIDs { - var skuBinds []*tStoreSkuBindExt - if err = dao.GetRows(db, &skuBinds, sql, append(sqlParam, storeID)...); err != nil { - return "", err - } - for k, skuBind := range skuBinds { - if k == 0 { - jxStoreIDs = append(jxStoreIDs, skuBind.StoreID) + errMsg := "" + index := 0 + for _, storeID := range params.StoreIDs { + var skuBinds []*tStoreSkuBindExt + if err = dao.GetRows(db, &skuBinds, sql, append(sqlParam, storeID)...); err != nil { + return "", err } - mapSkuID := int64(skuBind.SkuID) - if isIDJd { - mapSkuID = skuBind.JdID - } - promotionSkuPrice := skuPriceMap[mapSkuID] - if promotionSkuPrice.PriceType == PriceTypePercentage { - promotionSkuPrice.Price = skuBind.Price * promotionSkuPrice.Price / 100 - } - if promotionSkuPrice.Price >= skuBind.Price { - errMsg += fmt.Sprintf("促销价大于等于原价,storeID:%d, skuID:%d\n", skuBind.StoreID, skuBind.SkuID) - } - if promotionSkuPrice.LimitSkuCount <= 0 { - promotionSkuPrice.LimitSkuCount = DefaultLimitSkuCount - } - if errMsg == "" { - if params.Type == PromotionTypeLimitedTime { - if skuBind.Price*PromotionLimitedTimeMinPercentage/100 < promotionSkuPrice.Price { - modifyPricesList[skuBind.StoreID] = append(modifyPricesList[skuBind.StoreID], &jdapi.SkuPriceInfo{ - OutSkuId: utils.Int2Str(skuBind.SkuID), - Price: promotionSkuPrice.Price*100/PromotionLimitedTimeMinPercentage + 5, - }) + for k, skuBind := range skuBinds { + if k == 0 { + jxStoreIDs = append(jxStoreIDs, skuBind.StoreID) + } + mapSkuID := int64(skuBind.SkuID) + if isIDJd { + mapSkuID = skuBind.JdID + } + promotionSkuPrice := skuPriceMap[mapSkuID] + if promotionSkuPrice.PriceType == PriceTypePercentage { + promotionSkuPrice.Price = skuBind.Price * promotionSkuPrice.Price / 100 + } + if promotionSkuPrice.Price >= skuBind.Price { + errMsg += fmt.Sprintf("促销价大于等于原价,storeID:%d, skuID:%d\n", skuBind.StoreID, skuBind.SkuID) + } + if promotionSkuPrice.LimitSkuCount <= 0 { + promotionSkuPrice.LimitSkuCount = DefaultLimitSkuCount + } + if errMsg == "" { + if params.Type == PromotionTypeLimitedTime { + if skuBind.Price*PromotionLimitedTimeMinPercentage/100 < promotionSkuPrice.Price { + modifyPricesList[skuBind.StoreID] = append(modifyPricesList[skuBind.StoreID], &jdapi.SkuPriceInfo{ + OutSkuId: utils.Int2Str(skuBind.SkuID), + Price: promotionSkuPrice.Price*100/PromotionLimitedTimeMinPercentage + 5, + }) + } } + promotionPrices[index] = map[string]interface{}{ + jdapi.KeyOutStationNo: utils.Int2Str(skuBind.StoreID), + jdapi.KeyOutSkuId: utils.Int2Str(skuBind.SkuID), + jdapi.KeyPromotionPrice: promotionSkuPrice.Price, + jdapi.KeyLimitSkuCount: promotionSkuPrice.LimitSkuCount, + } + index++ } - promotionPrices[index] = map[string]interface{}{ - jdapi.KeyOutStationNo: utils.Int2Str(skuBind.StoreID), - jdapi.KeyOutSkuId: utils.Int2Str(skuBind.SkuID), - jdapi.KeyPromotionPrice: promotionSkuPrice.Price, - jdapi.KeyLimitSkuCount: promotionSkuPrice.LimitSkuCount, - } - index++ } } - } - if errMsg != "" { - return "", errors.New(errMsg) - } - promotionPrices = promotionPrices[:index] - if len(promotionPrices) == 0 { - return "", ErrEmptySkus + if errMsg != "" { + return "", errors.New(errMsg) + } + promotionPrices = promotionPrices[:index] + if len(promotionPrices) == 0 { + return "", ErrEmptySkus + } } promotion := &model.Promotion{ @@ -292,6 +295,9 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW BeginAt: params.BeginAt, EndAt: params.EndAt, } + if vendorPromotionID != "" { + promotion.VendorPromotionID = vendorPromotionID + } dao.WrapAddIDCULDEntity(promotion, userName) // if promotion.Params, err = jxutils.SerializeData(params); err != nil { // return "", err @@ -331,78 +337,83 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW } } - promotionHandler := getPromotionHander(params.Type) - if promotionHandler == nil { - return "", errors.New("非法的促销类型") - } - infoId, err2 := promotionHandler.CreatePromotionInfos(params.Name, params.BeginAt, params.EndAt, utils.Int2Str(promotion.ID), params.Advertising) - if err = err2; err != nil { - return "", err - } - promotion.VendorPromotionID = utils.Int64ToStr(infoId) - if _, err = dao.UpdateEntity(db, promotion); err != nil { - return "", err - } - dao.Commit(db) + if vendorPromotionID == "" { + promotionHandler := getPromotionHander(params.Type) + if promotionHandler == nil { + return "", errors.New("非法的促销类型") + } + infoId, err2 := promotionHandler.CreatePromotionInfos(params.Name, params.BeginAt, params.EndAt, utils.Int2Str(promotion.ID), params.Advertising) + if err = err2; err != nil { + return "", err + } + promotion.VendorPromotionID = utils.Int64ToStr(infoId) + if _, err = dao.UpdateEntity(db, promotion); err != nil { + return "", err + } + 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", 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 + } } } + return nil, nil + }, jxStoreIDs) + task.AddChild(task1).Run() + _, err = task1.GetResult(0) + } else if step == 1 { + err = promotionHandler.CreatePromotionRules(infoId, "", 1, 1, 1, 1) + } 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 } - return nil, nil - }, jxStoreIDs) - task.AddChild(task1).Run() - _, err = task1.GetResult(0) - } else if step == 1 { - err = promotionHandler.CreatePromotionRules(infoId, "", 1, 1, 1, 1) - } 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{}) + } else if step == 3 { + err = promotionHandler.ConfirmPromotion(infoId, "") + if err == nil { + promotion.Status = model.PromotionStatusRemoteCreated + } else { + promotion.Status = model.PromotionStatusRemoteFailed + } + db := dao.GetDB() + if _, err = dao.UpdateEntityLogically(db, promotion, map[string]interface{}{ + "Status": promotion.Status, + }, ctx.GetUserName(), nil); err == nil { + RefreshJdPromotionLockStatus(promotion.ID) } - _, 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 { - promotion.Status = model.PromotionStatusRemoteCreated - } else { - promotion.Status = model.PromotionStatusRemoteFailed - } - db := dao.GetDB() - if _, err = dao.UpdateEntityLogically(db, promotion, map[string]interface{}{ - "Status": promotion.Status, - }, ctx.GetUserName(), nil); err == nil { - RefreshJdPromotionLockStatus(promotion.ID) } + return nil, err + }, 4) + ctx.SetTaskOrAddChild(rootTask, nil) + tasksch.ManageTask(rootTask).Run() + if !isAsync { + _, err = rootTask.GetResult(0) } - return nil, err - }, 4) - ctx.SetTaskOrAddChild(rootTask, nil) - tasksch.ManageTask(rootTask).Run() - if !isAsync { - _, err = rootTask.GetResult(0) + hint = rootTask.ID + } else { + dao.Commit(db) } - return rootTask.ID, err + return hint, err } // func CreatePromotionByExcel(ctx *jxcontext.Context, isAsync bool, promotionType int, fileHeader *multipart.FileHeader, userName string) (hint string, err error) { @@ -506,7 +517,7 @@ func GetJdPromotions(ctx *jxcontext.Context, keyword string, params map[string]i } if params["vendorPromotionID"] != nil { sql += " AND t1.vendor_promotion_id = ?" - sqlParams = append(sqlParams, params["vendorPromotionID"].(int)) + sqlParams = append(sqlParams, params["vendorPromotionID"].(string)) } if params["name"] != nil { sql += " AND t1.name LIKE ?" @@ -651,6 +662,7 @@ func RefreshJdLockStoreSku() (err error) { } return err } + storeskulock.ClearJdStoreSkuLock() return RefreshJdPromotionItemListLockStatus(promotionItemList) } @@ -784,6 +796,33 @@ func RefreshJdPromotionLockStatus(promotionID int) (err error) { return RefreshJdPromotionItemListLockStatus(promotionItemList) } +func LockPromotionSkus(ctx *jxcontext.Context, promotionID int, isLock bool, skuIDs []int) (num int64, err error) { + sql := ` + UPDATE promotion_sku t1 + SET t1.is_lock = ? + WHERE t1.promotion_id = ? + ` + intIsLock := 0 + if isLock { + intIsLock = 1 + } + sqlParams := []interface{}{ + intIsLock, + promotionID, + } + if len(skuIDs) > 0 { + sql += " AND t1.sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")" + sqlParams = append(sqlParams, skuIDs) + } + db := dao.GetDB() + num, err = dao.ExecuteSQL(db, sql, sqlParams...) + if err == nil { + RefreshJdPromotionLockStatus(promotionID) + RefreshJdStoreSkuStock() + } + return num, err +} + func OnStoreStockMsg(msg *jdapi.CallbackStoreStockMsg) (retVal *jdapi.CallbackResponse) { var err error globals.SugarLogger.Debugf("OnStoreStockMsg msg:%s", utils.Format4Output(msg, false)) diff --git a/business/jxutils/cache/cache.go b/business/jxutils/cache/cache.go index 3766d542c..e4682120e 100644 --- a/business/jxutils/cache/cache.go +++ b/business/jxutils/cache/cache.go @@ -5,9 +5,10 @@ import ( ) type ICacher interface { - FlushAll() error + FlushKeys(prefix string) error Set(key string, value interface{}, expiration time.Duration) error Del(key string) error Get(key string) interface{} GetAs(key string, ptr interface{}) error + Keys(prefix string) ([]string, error) } diff --git a/business/jxutils/cache/redis/redis.go b/business/jxutils/cache/redis/redis.go index 76ccfffb8..37e6d0bb0 100644 --- a/business/jxutils/cache/redis/redis.go +++ b/business/jxutils/cache/redis/redis.go @@ -25,8 +25,19 @@ func New(host string, port int, password string) *Cacher { } } -func (c *Cacher) FlushAll() error { - return c.client.FlushAll().Err() +func (c *Cacher) FlushKeys(prefix string) (err error) { + if prefix == "" { + return c.client.FlushAll().Err() + } + keys, err := c.Keys(prefix) + if err == nil { + for _, key := range keys { + if err = c.Del(key); err != nil { + break + } + } + } + return err } func (c *Cacher) Set(key string, value interface{}, expiration time.Duration) error { @@ -58,3 +69,7 @@ func (c *Cacher) GetAs(key string, ptr interface{}) error { } return err } + +func (c *Cacher) Keys(prefix string) ([]string, error) { + return c.client.Keys(prefix + "*").Result() +} diff --git a/business/jxutils/cache/redis/redis_test.go b/business/jxutils/cache/redis/redis_test.go index 8759d01cc..598b4f7d3 100644 --- a/business/jxutils/cache/redis/redis_test.go +++ b/business/jxutils/cache/redis/redis_test.go @@ -3,12 +3,16 @@ package redis import ( "testing" + "git.rosy.net.cn/jx-callback/business/jxutils/cache" "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/globals/beegodb" "github.com/astaxie/beego" ) +var ( + cacher cache.ICacher +) + func init() { //E:/goprojects/src/git.rosy.net.cn/jx-callback/conf/app.conf ///Users/xujianhua/go/src/git.rosy.net.cn/jx-callback/conf/app.conf @@ -17,7 +21,9 @@ func init() { globals.Init() beegodb.Init() - api.Init() + // api.Init() + + cacher = New("localhost", 6379, "") } type FuckYou struct { @@ -25,8 +31,7 @@ type FuckYou struct { } func TestIt(t *testing.T) { - cacher := New("localhost", 6379, "") - cacher.FlushAll() + cacher.FlushKeys("") if cacher.Get("key") != nil { t.Fatal("should get nothing") } @@ -46,3 +51,35 @@ func TestIt(t *testing.T) { t.Fatal("should get value") } } + +func TestKeys(t *testing.T) { + cacher.FlushKeys("") + keys, err := cacher.Keys("") + if err != nil { + t.Fatal(err) + } + if len(keys) != 0 { + t.Fatal("keys should be empty here") + } + cacher.Set("key1", 1, 0) + cacher.Set("key2", 2, 0) + cacher.Set("key22", 3, 0) + cacher.Set("key23", 4, 0) + cacher.Set("key24", 5, 0) + keys, err = cacher.Keys("") + if len(keys) != 5 { + t.Fatal("keys should be 5 here") + } + keys, err = cacher.Keys("key") + if len(keys) != 5 { + t.Fatal("keys should be 5 here") + } + keys, err = cacher.Keys("key2") + if len(keys) != 4 { + t.Fatal("keys should be 4 here") + } + keys, err = cacher.Keys("key22") + if len(keys) != 1 { + t.Fatal("keys should be 1 here") + } +} diff --git a/business/jxutils/storeskulock/storeskulock.go b/business/jxutils/storeskulock/storeskulock.go index a29a2cf05..b202fe890 100644 --- a/business/jxutils/storeskulock/storeskulock.go +++ b/business/jxutils/storeskulock/storeskulock.go @@ -5,6 +5,7 @@ import ( "time" "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" ) const ( @@ -15,16 +16,20 @@ func LockJdStoreSku(jdStoreID string, jdSkuID int64, expire time.Time) { globals.SugarLogger.Debug(expire, " ", time.Now()) duration := expire.Sub(time.Now()) if duration > 0 { - globals.Cacher.Set(genCacheKey(jdStoreID, jdSkuID), 1, duration) + api.Cacher.Set(genCacheKey(jdStoreID, jdSkuID), 1, duration) } } func UnlockJdStoreSku(jdStoreID string, jdSkuID int64) { - globals.Cacher.Del(genCacheKey(jdStoreID, jdSkuID)) + api.Cacher.Del(genCacheKey(jdStoreID, jdSkuID)) } func IsJdStoreSkuLocked(jdStoreID string, jdSkuID int64) bool { - return globals.Cacher.Get(genCacheKey(jdStoreID, jdSkuID)) != nil + return api.Cacher.Get(genCacheKey(jdStoreID, jdSkuID)) != nil +} + +func ClearJdStoreSkuLock() { + api.Cacher.FlushKeys(cacheKeyPrefix) } func genCacheKey(jdStoreID string, jdSkuID int64) string { diff --git a/controllers/promotion.go b/controllers/promotion.go index 37d0ca000..6e915a010 100644 --- a/controllers/promotion.go +++ b/controllers/promotion.go @@ -27,6 +27,7 @@ type PromotionController struct { // @Param isAsync formData bool false "是否异步,缺省否(暂时只支持同步)" // @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" // @Param advertising formData string false "广告语" +// @Param vendorPromotionID formData string false "厂商活动id,设置此字段表示关联京东活动,并不会真正去创建" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult // @router /CreatePromotion [post] @@ -52,7 +53,7 @@ func (c *PromotionController) CreatePromotion() { } if err = utils.UnmarshalUseNumber([]byte(params.StoreIDs), &promotionParams.StoreIDs); err == nil { if err = utils.UnmarshalUseNumber([]byte(params.SkuPrices), &promotionParams.SkuPrices); err == nil { - retVal, err = promotion.CreateJdPromotion(params.Ctx, false, params.IsAsync, params.IsContinueWhenError, promotionParams, params.Ctx.GetUserName()) + retVal, err = promotion.CreateJdPromotion(params.Ctx, false, params.IsAsync, params.IsContinueWhenError, params.VendorPromotionID, promotionParams, params.Ctx.GetUserName()) } } return retVal, "", err @@ -115,7 +116,7 @@ func (c *PromotionController) SendAdvertingByGoodsOrder() { // @Param keyword query string false "关键字" // @Param vendorID query int false "厂商ID,当前只支持京东:0 " // @Param promotionID query int false "活动id" -// @Param vendorPromotionID query int false "厂商活动id" +// @Param vendorPromotionID query string false "厂商活动id" // @Param days query int false "多少天内创建的,缺省7天" // @Param name query string false "促销名,不完全匹配" // @Param beginAt query string false "开始日期,包括" @@ -135,10 +136,10 @@ func (c *PromotionController) GetPromotions() { }) } -// @Title 查询促销 -// @Description 查询促销 +// @Title 取消促销 +// @Description 取消促销 // @Param token header string true "认证token" -// @Param promotionID query int true "活动id" +// @Param promotionID formData int true "活动id" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult // @router /CancelPromotion [put] @@ -148,3 +149,25 @@ func (c *PromotionController) CancelPromotion() { return retVal, "", err }) } + +// @Title 锁定解锁活动SKU +// @Description 锁定解锁活动SKU +// @Param token header string true "认证token" +// @Param promotionID formData int true "活动id" +// @Param isLock formData bool true "活动id" +// @Param skuIDs formData string false "缺省全部" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /LockPromotionSkus [put] +func (c *PromotionController) LockPromotionSkus() { + c.callLockPromotionSkus(func(params *tPromotionLockPromotionSkusParams) (retVal interface{}, errCode string, err error) { + var skuIDs []int + if params.SkuIDs != "" { + if err = utils.UnmarshalUseNumber([]byte(params.SkuIDs), &skuIDs); err != nil { + return retVal, "", err + } + } + retVal, err = promotion.LockPromotionSkus(params.Ctx, params.PromotionID, params.IsLock, skuIDs) + return retVal, "", err + }) +} diff --git a/globals/api/api.go b/globals/api/api.go index a0d297570..001097d32 100644 --- a/globals/api/api.go +++ b/globals/api/api.go @@ -9,6 +9,8 @@ import ( "git.rosy.net.cn/baseapi/platformapi/mtpsapi" "git.rosy.net.cn/baseapi/platformapi/weixinapi" "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils/cache" + "git.rosy.net.cn/jx-callback/business/jxutils/cache/redis" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" @@ -24,6 +26,8 @@ var ( WeixinAPI *weixinapi.API AutonaviAPI *autonavi.API QiniuAPI *qbox.Mac + + Cacher cache.ICacher ) func Init() { @@ -47,6 +51,7 @@ func Init() { if !beego.AppConfig.DefaultBool("disableEbai", false) { EbaiAPI = ebaiapi.New(beego.AppConfig.String("ebaiSource"), beego.AppConfig.String("ebaiSecret")) } + Cacher = redis.New(beego.AppConfig.DefaultString("redisHost", "localhost"), beego.AppConfig.DefaultInt("redisPort", 0), beego.AppConfig.DefaultString("redisPassword", "")) } func initElm() { diff --git a/globals/globals.go b/globals/globals.go index 59feffd2b..f01781e77 100644 --- a/globals/globals.go +++ b/globals/globals.go @@ -2,8 +2,6 @@ package globals import ( "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/jx-callback/business/jxutils/cache" - "git.rosy.net.cn/jx-callback/business/jxutils/cache/redis" "github.com/astaxie/beego" "github.com/astaxie/beego/logs" _ "github.com/go-sql-driver/mysql" // import your used driver @@ -22,8 +20,6 @@ var ( SugarLogger *zap.SugaredLogger - Cacher cache.ICacher - AliKey string AliSecret string @@ -51,8 +47,6 @@ func Init() { ReallySendWeixinMsg = beego.BConfig.RunMode == "prod" ReallyCallPlatformAPI = true - Cacher = redis.New(beego.AppConfig.DefaultString("redisHost", "localhost"), beego.AppConfig.DefaultInt("redisPort", 0), beego.AppConfig.DefaultString("redisPassword", "")) - AliKey = beego.AppConfig.DefaultString("aliKey", "") AliSecret = beego.AppConfig.DefaultString("aliSecret", "") diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 5eddec1f7..83fe26460 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -239,6 +239,14 @@ func init() { MethodParams: param.Make(), Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:PromotionController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:PromotionController"], + beego.ControllerComments{ + Method: "LockPromotionSkus", + Router: `/LockPromotionSkus`, + AllowHTTPMethods: []string{"put"}, + MethodParams: param.Make(), + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:PromotionController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:PromotionController"], beego.ControllerComments{ Method: "SendAdvertingByGoodsOrder",