diff --git a/business/jxstore/act/act.go b/business/jxstore/act/act.go index 7886a15fb..4102d66cf 100644 --- a/business/jxstore/act/act.go +++ b/business/jxstore/act/act.go @@ -2,6 +2,7 @@ package act import ( "fmt" + "strings" "time" "git.rosy.net.cn/baseapi/utils" @@ -209,6 +210,10 @@ func AddActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actSto } func checkActValidation(act *model.Act, vendorIDs []int) (err error) { + var errList []error + if utils.IsTimeZero(act.BeginAt) || utils.IsTimeZero(act.EndAt) { + errList = append(errList, fmt.Errorf("活动开始与结束时间必须指定")) + } vendorIDMap := make(map[int]int) for _, vendorID := range vendorIDs { vendorIDMap[vendorID] = 1 @@ -216,21 +221,28 @@ func checkActValidation(act *model.Act, vendorIDs []int) (err error) { if act.Type == model.ActSkuDirectDown || act.Type == model.ActSkuSecKill { if act.PricePercentage == 0 { - return fmt.Errorf("活动必须指定价格折扣") + errList = append(errList, fmt.Errorf("活动必须指定价格折扣")) } if act.Type == model.ActSkuDirectDown && act.PricePercentage <= minDiscount4SkuDirectDown || act.PricePercentage >= 100 { - return fmt.Errorf("%s活动折扣必须大于:%d, 且必须有折扣", model.ActTypeName[act.Type], minDiscount4SkuDirectDown) + errList = append(errList, fmt.Errorf("%s活动折扣必须大于:%d, 且必须有折扣", model.ActTypeName[act.Type], minDiscount4SkuDirectDown)) } if act.Type == model.ActSkuSecKill && act.PricePercentage >= maxDiscount4SkuSecKill { if vendorIDMap[model.VendorIDMTWM] == 1 { - return fmt.Errorf("平台%s暂不支持%s活动", model.VendorChineseNames[model.VendorIDMTWM], model.ActTypeName[act.Type]) + errList = append(errList, fmt.Errorf("平台%s暂不支持%s活动", model.VendorChineseNames[model.VendorIDMTWM], model.ActTypeName[act.Type])) } - return fmt.Errorf("%s活动折扣必须小于:%d", model.ActTypeName[act.Type], maxDiscount4SkuSecKill) + errList = append(errList, fmt.Errorf("%s活动折扣必须小于:%d", model.ActTypeName[act.Type], maxDiscount4SkuSecKill)) } } else { - return fmt.Errorf("当前只支持直降与秒杀活动") + errList = append(errList, fmt.Errorf("当前只支持直降与秒杀活动")) } - return nil + if errList == nil { + return nil + } + strList := make([]string, len(errList)) + for k, v := range errList { + strList[k] = v.Error() + } + return fmt.Errorf("%s", strings.Join(strList, ",\n")) } func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam, isAsync bool) (hint string, err error) { diff --git a/business/jxstore/act/act_test.go b/business/jxstore/act/act_test.go index 3a7af931b..4e9c6b514 100644 --- a/business/jxstore/act/act_test.go +++ b/business/jxstore/act/act_test.go @@ -2,10 +2,12 @@ package act import ( "testing" + "time" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/model/dao" + "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/testinit" "git.rosy.net.cn/jx-callback/business/model" @@ -25,7 +27,7 @@ func TestInitDb(t *testing.T) { `) } -func TestCreateAct(t *testing.T) { +func TestCreateActOnAlpha(t *testing.T) { actStoreSkuList := []*ActStoreSkuParam{ &ActStoreSkuParam{ ActStoreSku: model.ActStoreSku{ @@ -64,6 +66,46 @@ func TestCreateAct(t *testing.T) { // globals.SugarLogger.Debug(actID) } +func TestCreateActOnDev(t *testing.T) { + actStoreSkuList := []*ActStoreSkuParam{ + &ActStoreSkuParam{ + ActStoreSku: model.ActStoreSku{ + StoreID: 100884, + SkuID: 22716, + }, + }, + &ActStoreSkuParam{ + ActStoreSku: model.ActStoreSku{ + StoreID: 100884, + SkuID: 22717, + }, + }, + &ActStoreSkuParam{ + ActStoreSku: model.ActStoreSku{ + StoreID: 100920, + SkuID: 22714, + }, + }, + &ActStoreSkuParam{ + ActStoreSku: model.ActStoreSku{ + StoreID: 100920, + SkuID: 22715, + }, + }, + } + actID, err := CreateAct(jxcontext.AdminCtx, &model.Act{ + Name: "测试活动", + PricePercentage: 80, + Type: model.ActSkuDirectDown, + BeginAt: time.Now().Add(-24 * time.Hour), + EndAt: time.Now().Add(10 * 24 * time.Hour), + }, []int{model.VendorIDJD, model.VendorIDMTWM /*, model.VendorIDEBAI*/}, nil, actStoreSkuList, false) + if err != nil { + t.Fatal(err) + } + globals.SugarLogger.Debug(actID) +} + func TestCancelAct(t *testing.T) { err := CancelAct(jxcontext.AdminCtx, 1) if err != nil { diff --git a/business/model/act.go b/business/model/act.go index 87856ccf3..dbda67228 100644 --- a/business/model/act.go +++ b/business/model/act.go @@ -48,8 +48,8 @@ type Act struct { Source string `orm:"size(255)" json:"source"` CreateType int `json:"createType"` PricePercentage int `json:"pricePercentage"` // 单品级活动才有效 - BeginAt time.Time `orm:"type(datetime);index;null" json:"beginAt"` - EndAt time.Time `orm:"type(datetime);index;null" json:"endAt"` + BeginAt time.Time `orm:"type(datetime);index" json:"beginAt"` + EndAt time.Time `orm:"type(datetime);index" json:"endAt"` Remark string `orm:"size(255)" json:"remark"` } diff --git a/business/model/dao/act.go b/business/model/dao/act.go index fd59680a6..b8ff1a473 100644 --- a/business/model/dao/act.go +++ b/business/model/dao/act.go @@ -210,3 +210,55 @@ func QueryActs(db *DaoDB, actID int, offset, pageSize int, keyword string, statu } return pagedInfo, err } + +func GetEffectiveActStoreSkuInfo(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs []int, fromTime, toTime time.Time) (actStoreSkuList []*model.ActStoreSku2, err error) { + if utils.IsTimeZero(fromTime) { + return nil, fmt.Errorf("GeActStoreSkuInfo必须指定fromTime") + } + if utils.IsTimeZero(toTime) { + toTime = fromTime + } + sql := ` + SELECT t2.* + FROM` + sqlParams := []interface{}{} + if len(vendorIDs) > 0 { + sqlParams = append(sqlParams, utils.DefaultTimeValue, vendorIDs, fromTime, toTime) + actSQL := "" + if actID > 0 { + actSQL = " AND t11.id = ?" + sqlParams = append(sqlParams, actID) + } + sql += fmt.Sprintf(` + ( + SELECT t11.id, t11.begin_at, t11.end_at, t11.status + FROM act t11 + JOIN act_map t12 ON t12.act_id = t11.id AND t12.deleted_at = ? AND t12.vendor_id IN (`+GenQuestionMarks(len(vendorIDs))+`) + WHERE t11.begin_at <= ? AND t11.end_at >= ? %s + GROUP BY 1,2,3 + ) t1`, actSQL) + } else { + sql += ` + act t1` + } + sql += ` + JOIN act_store_sku t2 ON t2.act_id = t1.id AND t2.deleted_at = ? + WHERE t1.status = ? AND t1.begin_at <= ? AND t1.end_at >= ?` + sqlParams = append(sqlParams, utils.DefaultTimeValue, model.ActStatusCreated, fromTime, toTime) + if actID > 0 { + sql = " AND t1.id = ?" + sqlParams = append(sqlParams, actID) + } + if len(storeIDs) > 0 { + sql += " AND t2.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" + sqlParams = append(sqlParams, storeIDs) + } + if len(skuIDs) > 0 { + sql += " AND t2.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" + sqlParams = append(sqlParams, skuIDs) + } + // globals.SugarLogger.Debug(sql) + // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) + err = GetRows(db, &actStoreSkuList, sql, sqlParams...) + return actStoreSkuList, err +} diff --git a/business/model/dao/act_test.go b/business/model/dao/act_test.go new file mode 100644 index 000000000..58e3f2588 --- /dev/null +++ b/business/model/dao/act_test.go @@ -0,0 +1,60 @@ +package dao + +import ( + "testing" + "time" + + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/model" +) + +func TestGetEffectiveActStoreSkuInfo(t *testing.T) { + type testData struct { + ResultCount int + + ActID int + VendorIDs []int + StoreIDs []int + SkuIDs []int + FromTime time.Time + ToTime time.Time + } + for _, v := range []*testData{ + &testData{ + ResultCount: 4, + FromTime: time.Now(), + ToTime: time.Now(), + }, + &testData{ + ResultCount: 0, + FromTime: time.Now().Add(-48 * time.Hour), + ToTime: time.Now().Add(-48 * time.Hour), + }, + &testData{ + ResultCount: 2, + StoreIDs: []int{100884}, + FromTime: time.Now(), + ToTime: time.Now(), + }, + &testData{ + ResultCount: 1, + SkuIDs: []int{22714}, + FromTime: time.Now(), + ToTime: time.Now(), + }, + &testData{ + ResultCount: 0, + VendorIDs: []int{model.VendorIDEBAI}, + FromTime: time.Now(), + ToTime: time.Now(), + }, + } { + result, err := GetEffectiveActStoreSkuInfo(GetDB(), v.ActID, v.VendorIDs, v.StoreIDs, v.SkuIDs, v.FromTime, v.ToTime) + if err != nil { + t.Fatal(err) + } + if len(result) != v.ResultCount { + t.Errorf("cond:%s, len(result):%d, v.ResultCount:%d", utils.Format4Output(v, false), len(result), v.ResultCount) + } + } +}