new-api/model/promo_code.go
zizi 1de1cdb14f feat: add promo code bonus flow
Add promo code models and APIs, persist selected promo codes on top-up orders, and apply bonus quota idempotently when payments complete.
2026-05-20 12:57:54 +08:00

77 lines
2.2 KiB
Go

package model
import (
"time"
"gorm.io/gorm"
)
type PromoCode struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
Code string `json:"code" gorm:"type:varchar(32);uniqueIndex;not null"`
BonusAmount int `json:"bonus_amount" gorm:"not null;default:0"`
MaxUses int `json:"max_uses" gorm:"not null;default:0"`
UsedCount int `json:"used_count" gorm:"not null;default:0"`
Status int `json:"status" gorm:"not null;default:1"`
MinRechargeAmount int `json:"min_recharge_amount" gorm:"not null;default:0"`
ExpiresAt *time.Time `json:"expires_at"`
Notes string `json:"notes" gorm:"type:varchar(255);default:''"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func (PromoCode) TableName() string {
return "promo_codes"
}
func (p *PromoCode) Insert() error {
return DB.Create(p).Error
}
func (p *PromoCode) Update() error {
return DB.Save(p).Error
}
func (p *PromoCode) IncrementUsed() error {
return DB.Model(&PromoCode{}).Where("id = ?", p.Id).UpdateColumn("used_count", gorm.Expr("used_count + 1")).Error
}
func GetPromoCodeByID(id int) (*PromoCode, error) {
var promoCode PromoCode
err := DB.First(&promoCode, "id = ?", id).Error
return &promoCode, err
}
func GetPromoCodeByCode(code string) (*PromoCode, error) {
var promoCode PromoCode
err := DB.Where("code = ?", code).First(&promoCode).Error
return &promoCode, err
}
func GetPromoCodes(page int, pageSize int, status *int, keyword string) ([]PromoCode, int64, error) {
var promoCodes []PromoCode
var total int64
query := DB.Model(&PromoCode{})
if status != nil {
query = query.Where("status = ?", *status)
}
if keyword != "" {
query = query.Where("code LIKE ?", "%"+keyword+"%")
}
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
if page < 1 {
page = 1
}
if pageSize < 1 {
pageSize = 20
}
err := query.Order("id DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&promoCodes).Error
return promoCodes, total, err
}
func DeletePromoCodeByID(id int) error {
return DB.Delete(&PromoCode{}, id).Error
}