5d2460c310
Co-authored-by: multica-agent <github@multica.ai>
205 lines
6.1 KiB
Go
205 lines
6.1 KiB
Go
package promo
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type RuleWithPrice struct {
|
|
Rule
|
|
PromoPrice int64 `gorm:"column:promo_price"`
|
|
}
|
|
|
|
type Model interface {
|
|
QueryEligibleRules(ctx context.Context, subscribeId int64, quantity int64) ([]*RuleWithPrice, error)
|
|
InsertUsage(ctx context.Context, data *Usage, tx ...*gorm.DB) error
|
|
InsertRule(ctx context.Context, data *Rule) error
|
|
FindRule(ctx context.Context, id int64) (*Rule, error)
|
|
UpdateRule(ctx context.Context, data *Rule) error
|
|
DeleteRule(ctx context.Context, id int64) error
|
|
QueryRuleList(ctx context.Context, page, size int, ruleType string, enabled *bool, search string) (int64, []*Rule, error)
|
|
UpsertPrices(ctx context.Context, ruleId int64, items []*SubscribePromo) error
|
|
FindPrice(ctx context.Context, id int64) (*SubscribePromo, error)
|
|
DeletePrice(ctx context.Context, id int64) error
|
|
QueryPriceList(ctx context.Context, ruleId int64, page, size int) (int64, []*SubscribePromo, error)
|
|
QueryUsageList(ctx context.Context, params UsageFilter) (int64, []*Usage, error)
|
|
Transaction(ctx context.Context, fn func(db *gorm.DB) error) error
|
|
}
|
|
|
|
type UsageFilter struct {
|
|
Page int
|
|
Size int
|
|
RuleId int64
|
|
UserId int64
|
|
SubscribeId int64
|
|
OrderNo string
|
|
}
|
|
|
|
type defaultPromoModel struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewModel(db *gorm.DB, _ *redis.Client) Model {
|
|
return &defaultPromoModel{db: db}
|
|
}
|
|
|
|
func (m *defaultPromoModel) QueryEligibleRules(ctx context.Context, subscribeId int64, quantity int64) ([]*RuleWithPrice, error) {
|
|
var list []*RuleWithPrice
|
|
err := m.db.WithContext(ctx).
|
|
Table("promo_rule AS pr").
|
|
Select("pr.*, sp.promo_price").
|
|
Joins("JOIN subscribe_promo AS sp ON sp.promo_rule_id = pr.id").
|
|
Where("sp.subscribe_id = ? AND sp.quantity = ? AND sp.promo_price > 0 AND pr.enabled = ?", subscribeId, quantity, true).
|
|
Where("pr.deleted_at IS NULL").
|
|
Order("pr.priority DESC").
|
|
Order("pr.id ASC").
|
|
Find(&list).Error
|
|
return list, err
|
|
}
|
|
|
|
func (m *defaultPromoModel) InsertUsage(ctx context.Context, data *Usage, tx ...*gorm.DB) error {
|
|
db := m.db.WithContext(ctx)
|
|
if len(tx) > 0 {
|
|
db = tx[0].WithContext(ctx)
|
|
}
|
|
return db.Model(&Usage{}).Create(data).Error
|
|
}
|
|
|
|
func (m *defaultPromoModel) InsertRule(ctx context.Context, data *Rule) error {
|
|
return m.db.WithContext(ctx).Create(data).Error
|
|
}
|
|
|
|
func (m *defaultPromoModel) FindRule(ctx context.Context, id int64) (*Rule, error) {
|
|
var resp Rule
|
|
if err := m.db.WithContext(ctx).Model(&Rule{}).Where("id = ?", id).First(&resp).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
func (m *defaultPromoModel) UpdateRule(ctx context.Context, data *Rule) error {
|
|
return m.db.WithContext(ctx).Save(data).Error
|
|
}
|
|
|
|
func (m *defaultPromoModel) DeleteRule(ctx context.Context, id int64) error {
|
|
return m.db.WithContext(ctx).Delete(&Rule{}, id).Error
|
|
}
|
|
|
|
func (m *defaultPromoModel) QueryRuleList(ctx context.Context, page, size int, ruleType string, enabled *bool, search string) (int64, []*Rule, error) {
|
|
if page <= 0 {
|
|
page = 1
|
|
}
|
|
if size <= 0 {
|
|
size = 10
|
|
}
|
|
var total int64
|
|
var list []*Rule
|
|
db := m.db.WithContext(ctx).Model(&Rule{})
|
|
if ruleType != "" {
|
|
db = db.Where("type = ?", ruleType)
|
|
}
|
|
if enabled != nil {
|
|
db = db.Where("enabled = ?", *enabled)
|
|
}
|
|
if search != "" {
|
|
db = db.Where("name LIKE ?", "%"+search+"%")
|
|
}
|
|
if err := db.Count(&total).Error; err != nil {
|
|
return 0, nil, err
|
|
}
|
|
err := db.Order("priority DESC").Order("id DESC").Limit(size).Offset((page - 1) * size).Find(&list).Error
|
|
return total, list, err
|
|
}
|
|
|
|
func (m *defaultPromoModel) UpsertPrices(ctx context.Context, ruleId int64, items []*SubscribePromo) error {
|
|
return m.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
|
for _, item := range items {
|
|
if item == nil {
|
|
continue
|
|
}
|
|
item.PromoRuleId = ruleId
|
|
var existing SubscribePromo
|
|
err := tx.Model(&SubscribePromo{}).
|
|
Where("subscribe_id = ? AND quantity = ? AND promo_rule_id = ?", item.SubscribeId, item.Quantity, ruleId).
|
|
First(&existing).Error
|
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return err
|
|
}
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return tx.Create(item).Error
|
|
}
|
|
existing.Quantity = item.Quantity
|
|
existing.PromoPrice = item.PromoPrice
|
|
if err := tx.Save(&existing).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (m *defaultPromoModel) FindPrice(ctx context.Context, id int64) (*SubscribePromo, error) {
|
|
var resp SubscribePromo
|
|
if err := m.db.WithContext(ctx).Model(&SubscribePromo{}).Where("id = ?", id).First(&resp).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
func (m *defaultPromoModel) DeletePrice(ctx context.Context, id int64) error {
|
|
return m.db.WithContext(ctx).Delete(&SubscribePromo{}, id).Error
|
|
}
|
|
|
|
func (m *defaultPromoModel) QueryPriceList(ctx context.Context, ruleId int64, page, size int) (int64, []*SubscribePromo, error) {
|
|
if page <= 0 {
|
|
page = 1
|
|
}
|
|
if size <= 0 {
|
|
size = 10
|
|
}
|
|
var total int64
|
|
var list []*SubscribePromo
|
|
db := m.db.WithContext(ctx).Model(&SubscribePromo{}).Where("promo_rule_id = ?", ruleId)
|
|
if err := db.Count(&total).Error; err != nil {
|
|
return 0, nil, err
|
|
}
|
|
err := db.Order("id DESC").Limit(size).Offset((page - 1) * size).Find(&list).Error
|
|
return total, list, err
|
|
}
|
|
|
|
func (m *defaultPromoModel) QueryUsageList(ctx context.Context, params UsageFilter) (int64, []*Usage, error) {
|
|
if params.Page <= 0 {
|
|
params.Page = 1
|
|
}
|
|
if params.Size <= 0 {
|
|
params.Size = 10
|
|
}
|
|
var total int64
|
|
var list []*Usage
|
|
db := m.db.WithContext(ctx).Model(&Usage{})
|
|
if params.RuleId > 0 {
|
|
db = db.Where("promo_rule_id = ?", params.RuleId)
|
|
}
|
|
if params.UserId > 0 {
|
|
db = db.Where("user_id = ?", params.UserId)
|
|
}
|
|
if params.SubscribeId > 0 {
|
|
db = db.Where("subscribe_id = ?", params.SubscribeId)
|
|
}
|
|
if params.OrderNo != "" {
|
|
db = db.Where("order_no = ?", params.OrderNo)
|
|
}
|
|
if err := db.Count(&total).Error; err != nil {
|
|
return 0, nil, err
|
|
}
|
|
err := db.Order("id DESC").Limit(params.Size).Offset((params.Page - 1) * params.Size).Find(&list).Error
|
|
return total, list, err
|
|
}
|
|
|
|
func (m *defaultPromoModel) Transaction(ctx context.Context, fn func(db *gorm.DB) error) error {
|
|
return m.db.WithContext(ctx).Transaction(fn)
|
|
}
|