@@ -37,8 +37,8 @@ type (
|
|||||||
Id int64 `uri:"id" validate:"required,gt=0"`
|
Id int64 `uri:"id" validate:"required,gt=0"`
|
||||||
}
|
}
|
||||||
GetPromoRuleListRequest {
|
GetPromoRuleListRequest {
|
||||||
Page int64 `form:"page" validate:"required"`
|
Page int64 `form:"page" validate:"required,gt=0"`
|
||||||
Size int64 `form:"size" validate:"required"`
|
Size int64 `form:"size" validate:"required,gt=0,lte=200"`
|
||||||
Type string `form:"type" validate:"omitempty,oneof=new_user inactive_user campaign"`
|
Type string `form:"type" validate:"omitempty,oneof=new_user inactive_user campaign"`
|
||||||
Enabled *bool `form:"enabled"`
|
Enabled *bool `form:"enabled"`
|
||||||
Search string `form:"search,omitempty"`
|
Search string `form:"search,omitempty"`
|
||||||
@@ -49,12 +49,12 @@ type (
|
|||||||
}
|
}
|
||||||
SetPromoPriceRequest {
|
SetPromoPriceRequest {
|
||||||
PromoRuleId int64 `json:"promo_rule_id" validate:"required,gt=0"`
|
PromoRuleId int64 `json:"promo_rule_id" validate:"required,gt=0"`
|
||||||
Items []PromoPriceItem `json:"items" validate:"required,dive"`
|
Items []PromoPriceItem `json:"items" validate:"required,min=1,dive"`
|
||||||
}
|
}
|
||||||
GetPromoPriceListRequest {
|
GetPromoPriceListRequest {
|
||||||
PromoRuleId int64 `form:"promo_rule_id" validate:"required,gt=0"`
|
PromoRuleId int64 `form:"promo_rule_id" validate:"required,gt=0"`
|
||||||
Page int64 `form:"page" validate:"required"`
|
Page int64 `form:"page" validate:"required,gt=0"`
|
||||||
Size int64 `form:"size" validate:"required"`
|
Size int64 `form:"size" validate:"required,gt=0,lte=200"`
|
||||||
}
|
}
|
||||||
GetPromoPriceListResponse {
|
GetPromoPriceListResponse {
|
||||||
Total int64 `json:"total"`
|
Total int64 `json:"total"`
|
||||||
@@ -64,8 +64,8 @@ type (
|
|||||||
Id int64 `uri:"id" validate:"required,gt=0"`
|
Id int64 `uri:"id" validate:"required,gt=0"`
|
||||||
}
|
}
|
||||||
GetPromoUsageListRequest {
|
GetPromoUsageListRequest {
|
||||||
Page int64 `form:"page" validate:"required"`
|
Page int64 `form:"page" validate:"required,gt=0"`
|
||||||
Size int64 `form:"size" validate:"required"`
|
Size int64 `form:"size" validate:"required,gt=0,lte=200"`
|
||||||
RuleId int64 `form:"rule_id,omitempty"`
|
RuleId int64 `form:"rule_id,omitempty"`
|
||||||
UserId int64 `form:"user_id,omitempty"`
|
UserId int64 `form:"user_id,omitempty"`
|
||||||
SubscribeId int64 `form:"subscribe_id,omitempty"`
|
SubscribeId int64 `form:"subscribe_id,omitempty"`
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ package promo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
stderrors "errors"
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
"github.com/perfect-panel/server/internal/types"
|
"github.com/perfect-panel/server/internal/types"
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DeletePriceLogic struct {
|
type DeletePriceLogic struct {
|
||||||
@@ -27,6 +29,10 @@ func NewDeletePriceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Delet
|
|||||||
func (l *DeletePriceLogic) DeletePrice(req *types.DeletePromoPriceRequest) error {
|
func (l *DeletePriceLogic) DeletePrice(req *types.DeletePromoPriceRequest) error {
|
||||||
price, err := l.svcCtx.PromoModel.FindPrice(l.ctx, req.Id)
|
price, err := l.svcCtx.PromoModel.FindPrice(l.ctx, req.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if stderrors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
l.Errorw("[DeletePromoPrice] Price Not Found", logger.Field("id", req.Id))
|
||||||
|
return errors.Wrapf(xerr.NewErrCodeMsg(404, "promo price not found"), "promo price not found: %d", req.Id)
|
||||||
|
}
|
||||||
l.Errorw("[DeletePromoPrice] Find Price Error", logger.Field("error", err.Error()))
|
l.Errorw("[DeletePromoPrice] Find Price Error", logger.Field("error", err.Error()))
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find promo price error: %v", err.Error())
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find promo price error: %v", err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ package promo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
stderrors "errors"
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
"github.com/perfect-panel/server/internal/types"
|
"github.com/perfect-panel/server/internal/types"
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DeleteRuleLogic struct {
|
type DeleteRuleLogic struct {
|
||||||
@@ -25,6 +27,14 @@ func NewDeleteRuleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Delete
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *DeleteRuleLogic) DeleteRule(req *types.DeletePromoRuleRequest) error {
|
func (l *DeleteRuleLogic) DeleteRule(req *types.DeletePromoRuleRequest) error {
|
||||||
|
if _, err := l.svcCtx.PromoModel.FindRule(l.ctx, req.Id); err != nil {
|
||||||
|
if stderrors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
l.Errorw("[DeletePromoRule] Rule Not Found", logger.Field("id", req.Id))
|
||||||
|
return errors.Wrapf(xerr.NewErrCodeMsg(404, "promo rule not found"), "promo rule not found: %d", req.Id)
|
||||||
|
}
|
||||||
|
l.Errorw("[DeletePromoRule] Find Rule Error", logger.Field("error", err.Error()))
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find promo rule error: %v", err.Error())
|
||||||
|
}
|
||||||
if err := l.svcCtx.PromoModel.DeleteRule(l.ctx, req.Id); err != nil {
|
if err := l.svcCtx.PromoModel.DeleteRule(l.ctx, req.Id); err != nil {
|
||||||
l.Errorw("[DeletePromoRule] Database Error", logger.Field("error", err.Error()))
|
l.Errorw("[DeletePromoRule] Database Error", logger.Field("error", err.Error()))
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete promo rule error: %v", err.Error())
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete promo rule error: %v", err.Error())
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package promo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
promomodel "github.com/perfect-panel/server/internal/model/promo"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/internal/types"
|
||||||
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
|
pkgerrors "github.com/pkg/errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fakePromoModel struct{}
|
||||||
|
|
||||||
|
func (fakePromoModel) QueryEligibleRules(context.Context, int64, int64) ([]*promomodel.RuleWithPrice, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) InsertUsage(context.Context, *promomodel.Usage, ...*gorm.DB) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) InsertRule(context.Context, *promomodel.Rule) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) FindRule(context.Context, int64) (*promomodel.Rule, error) {
|
||||||
|
return nil, gorm.ErrRecordNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) UpdateRule(context.Context, *promomodel.Rule) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) DeleteRule(context.Context, int64) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) QueryRuleList(context.Context, int, int, string, *bool, string) (int64, []*promomodel.Rule, error) {
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) UpsertPrices(context.Context, int64, []*promomodel.SubscribePromo) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) FindPrice(context.Context, int64) (*promomodel.SubscribePromo, error) {
|
||||||
|
return nil, gorm.ErrRecordNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) DeletePrice(context.Context, int64) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) QueryPriceList(context.Context, int64, int, int) (int64, []*promomodel.SubscribePromo, error) {
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) QueryUsageList(context.Context, promomodel.UsageFilter) (int64, []*promomodel.Usage, error) {
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fakePromoModel) Transaction(context.Context, func(*gorm.DB) error) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteRuleNotFoundReturns404(t *testing.T) {
|
||||||
|
svcCtx := &svc.ServiceContext{PromoModel: fakePromoModel{}}
|
||||||
|
err := NewDeleteRuleLogic(context.Background(), svcCtx).DeleteRule(&types.DeletePromoRuleRequest{Id: 1})
|
||||||
|
assertCodeError(t, err, 404)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeletePriceNotFoundReturns404(t *testing.T) {
|
||||||
|
svcCtx := &svc.ServiceContext{PromoModel: fakePromoModel{}}
|
||||||
|
err := NewDeletePriceLogic(context.Background(), svcCtx).DeletePrice(&types.DeletePromoPriceRequest{Id: 1})
|
||||||
|
assertCodeError(t, err, 404)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertCodeError(t *testing.T, err error, want uint32) {
|
||||||
|
t.Helper()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected error")
|
||||||
|
}
|
||||||
|
codeErr, ok := pkgerrors.Cause(err).(*xerr.CodeError)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expected CodeError, got %T", pkgerrors.Cause(err))
|
||||||
|
}
|
||||||
|
if got := codeErr.GetErrCode(); got != want {
|
||||||
|
t.Fatalf("unexpected error code: got %d want %d", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,12 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
promomodel "github.com/perfect-panel/server/internal/model/promo"
|
promomodel "github.com/perfect-panel/server/internal/model/promo"
|
||||||
|
subscribeModel "github.com/perfect-panel/server/internal/model/subscribe"
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
"github.com/perfect-panel/server/internal/types"
|
"github.com/perfect-panel/server/internal/types"
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SetPriceLogic struct {
|
type SetPriceLogic struct {
|
||||||
@@ -31,17 +31,31 @@ func (l *SetPriceLogic) SetPrice(req *types.SetPromoPriceRequest) error {
|
|||||||
l.Errorw("[SetPromoPrice] Find Rule Error", logger.Field("error", err.Error()))
|
l.Errorw("[SetPromoPrice] Find Rule Error", logger.Field("error", err.Error()))
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find promo rule error: %v", err.Error())
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find promo rule error: %v", err.Error())
|
||||||
}
|
}
|
||||||
|
subscribeIds := make([]int64, 0, len(req.Items))
|
||||||
|
seenSubscribeIds := make(map[int64]struct{}, len(req.Items))
|
||||||
|
for _, item := range req.Items {
|
||||||
|
if _, ok := seenSubscribeIds[item.SubscribeId]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seenSubscribeIds[item.SubscribeId] = struct{}{}
|
||||||
|
subscribeIds = append(subscribeIds, item.SubscribeId)
|
||||||
|
}
|
||||||
|
var subscribes []*subscribeModel.Subscribe
|
||||||
|
if err := l.svcCtx.DB.WithContext(l.ctx).Model(&subscribeModel.Subscribe{}).Where("id IN ?", subscribeIds).Find(&subscribes).Error; err != nil {
|
||||||
|
l.Errorw("[SetPromoPrice] Find Subscribe Error", logger.Field("error", err.Error()))
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find subscribe error: %v", err.Error())
|
||||||
|
}
|
||||||
|
subscribeById := make(map[int64]*subscribeModel.Subscribe, len(subscribes))
|
||||||
|
for _, sub := range subscribes {
|
||||||
|
subscribeById[sub.Id] = sub
|
||||||
|
}
|
||||||
items := make([]*promomodel.SubscribePromo, 0, len(req.Items))
|
items := make([]*promomodel.SubscribePromo, 0, len(req.Items))
|
||||||
cacheKeys := make([]string, 0, len(req.Items))
|
cacheKeys := make([]string, 0, len(req.Items))
|
||||||
for _, item := range req.Items {
|
for _, item := range req.Items {
|
||||||
sub, err := l.svcCtx.SubscribeModel.FindOne(l.ctx, item.SubscribeId)
|
sub, ok := subscribeById[item.SubscribeId]
|
||||||
if err != nil {
|
if !ok {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "subscribe plan not found")
|
return errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "subscribe plan not found")
|
||||||
}
|
}
|
||||||
l.Errorw("[SetPromoPrice] Find Subscribe Error", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find subscribe error: %v", err.Error())
|
|
||||||
}
|
|
||||||
originPrice := sub.UnitPrice * item.Quantity
|
originPrice := sub.UnitPrice * item.Quantity
|
||||||
if item.PromoPrice >= originPrice {
|
if item.PromoPrice >= originPrice {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "promo_price must be less than unit_price * quantity")
|
return errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "promo_price must be less than unit_price * quantity")
|
||||||
|
|||||||
@@ -81,7 +81,15 @@ func (m *defaultPromoModel) FindRule(ctx context.Context, id int64) (*Rule, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *defaultPromoModel) UpdateRule(ctx context.Context, data *Rule) error {
|
func (m *defaultPromoModel) UpdateRule(ctx context.Context, data *Rule) error {
|
||||||
return m.db.WithContext(ctx).Save(data).Error
|
return m.db.WithContext(ctx).Model(&Rule{}).Where("id = ?", data.Id).Updates(map[string]interface{}{
|
||||||
|
"name": data.Name,
|
||||||
|
"type": data.Type,
|
||||||
|
"params": data.Params,
|
||||||
|
"priority": data.Priority,
|
||||||
|
"enabled": data.Enabled,
|
||||||
|
"start_time": data.StartTime,
|
||||||
|
"end_time": data.EndTime,
|
||||||
|
}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *defaultPromoModel) DeleteRule(ctx context.Context, id int64) error {
|
func (m *defaultPromoModel) DeleteRule(ctx context.Context, id int64) error {
|
||||||
@@ -129,7 +137,10 @@ func (m *defaultPromoModel) UpsertPrices(ctx context.Context, ruleId int64, item
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return tx.Create(item).Error
|
if err := tx.Create(item).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
existing.Quantity = item.Quantity
|
existing.Quantity = item.Quantity
|
||||||
existing.PromoPrice = item.PromoPrice
|
existing.PromoPrice = item.PromoPrice
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (Rule) TableName() string {
|
|||||||
type SubscribePromo struct {
|
type SubscribePromo struct {
|
||||||
Id int64 `gorm:"primaryKey"`
|
Id int64 `gorm:"primaryKey"`
|
||||||
SubscribeId int64 `gorm:"type:bigint unsigned;not null;comment:Subscribe ID"`
|
SubscribeId int64 `gorm:"type:bigint unsigned;not null;comment:Subscribe ID"`
|
||||||
Quantity int64 `gorm:"type:bigint;not null;default:1;comment:Quantity"`
|
Quantity int64 `gorm:"type:int;not null;default:0;comment:购买数量"`
|
||||||
PromoRuleId int64 `gorm:"type:bigint unsigned;not null;comment:Promo Rule ID"`
|
PromoRuleId int64 `gorm:"type:bigint unsigned;not null;comment:Promo Rule ID"`
|
||||||
PromoPrice int64 `gorm:"type:bigint;not null;default:0;comment:Promo Price"`
|
PromoPrice int64 `gorm:"type:bigint;not null;default:0;comment:Promo Price"`
|
||||||
CreatedAt time.Time `gorm:"<-:create;comment:Create Time"`
|
CreatedAt time.Time `gorm:"<-:create;comment:Create Time"`
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPromoPriceItemsMustNotBeEmpty(t *testing.T) {
|
||||||
|
validate := validator.New()
|
||||||
|
req := SetPromoPriceRequest{
|
||||||
|
PromoRuleId: 1,
|
||||||
|
Items: []PromoPriceItem{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.Struct(req); err == nil {
|
||||||
|
t.Fatal("expected empty promo price items to fail validation")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPromoListPageSizeLimit(t *testing.T) {
|
||||||
|
validate := validator.New()
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
req any
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "rule list",
|
||||||
|
req: GetPromoRuleListRequest{
|
||||||
|
Page: 1,
|
||||||
|
Size: 201,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "price list",
|
||||||
|
req: GetPromoPriceListRequest{
|
||||||
|
PromoRuleId: 1,
|
||||||
|
Page: 1,
|
||||||
|
Size: 201,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "usage list",
|
||||||
|
req: GetPromoUsageListRequest{
|
||||||
|
Page: 1,
|
||||||
|
Size: 201,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if err := validate.Struct(tt.req); err == nil {
|
||||||
|
t.Fatal("expected page size greater than 200 to fail validation")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1147,8 +1147,8 @@ type GetCouponListResponse struct {
|
|||||||
|
|
||||||
type GetPromoPriceListRequest struct {
|
type GetPromoPriceListRequest struct {
|
||||||
PromoRuleId int64 `form:"promo_rule_id" validate:"required,gt=0"`
|
PromoRuleId int64 `form:"promo_rule_id" validate:"required,gt=0"`
|
||||||
Page int64 `form:"page" validate:"required"`
|
Page int64 `form:"page" validate:"required,gt=0"`
|
||||||
Size int64 `form:"size" validate:"required"`
|
Size int64 `form:"size" validate:"required,gt=0,lte=200"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetPromoPriceListResponse struct {
|
type GetPromoPriceListResponse struct {
|
||||||
@@ -1161,8 +1161,8 @@ type GetPromoRuleDetailRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GetPromoRuleListRequest struct {
|
type GetPromoRuleListRequest struct {
|
||||||
Page int64 `form:"page" validate:"required"`
|
Page int64 `form:"page" validate:"required,gt=0"`
|
||||||
Size int64 `form:"size" validate:"required"`
|
Size int64 `form:"size" validate:"required,gt=0,lte=200"`
|
||||||
Type string `form:"type" validate:"omitempty,oneof=new_user inactive_user campaign"`
|
Type string `form:"type" validate:"omitempty,oneof=new_user inactive_user campaign"`
|
||||||
Enabled *bool `form:"enabled"`
|
Enabled *bool `form:"enabled"`
|
||||||
Search string `form:"search,omitempty"`
|
Search string `form:"search,omitempty"`
|
||||||
@@ -1174,8 +1174,8 @@ type GetPromoRuleListResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GetPromoUsageListRequest struct {
|
type GetPromoUsageListRequest struct {
|
||||||
Page int64 `form:"page" validate:"required"`
|
Page int64 `form:"page" validate:"required,gt=0"`
|
||||||
Size int64 `form:"size" validate:"required"`
|
Size int64 `form:"size" validate:"required,gt=0,lte=200"`
|
||||||
RuleId int64 `form:"rule_id,omitempty"`
|
RuleId int64 `form:"rule_id,omitempty"`
|
||||||
UserId int64 `form:"user_id,omitempty"`
|
UserId int64 `form:"user_id,omitempty"`
|
||||||
SubscribeId int64 `form:"subscribe_id,omitempty"`
|
SubscribeId int64 `form:"subscribe_id,omitempty"`
|
||||||
@@ -3223,7 +3223,7 @@ type UpdateCouponRequest struct {
|
|||||||
|
|
||||||
type SetPromoPriceRequest struct {
|
type SetPromoPriceRequest struct {
|
||||||
PromoRuleId int64 `json:"promo_rule_id" validate:"required,gt=0"`
|
PromoRuleId int64 `json:"promo_rule_id" validate:"required,gt=0"`
|
||||||
Items []PromoPriceItem `json:"items" validate:"required,dive"`
|
Items []PromoPriceItem `json:"items" validate:"required,min=1,dive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeletePromoPriceRequest struct {
|
type DeletePromoPriceRequest struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user