You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
4.0 KiB
Go

package model
import (
"context"
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormx"
"git.noahlan.cn/northlan/ntools-go/uuid"
"github.com/jinzhu/now"
"github.com/pkg/errors"
"gorm.io/gorm"
"live-service/common/nerr"
"live-service/common/timex"
"time"
)
var _ UserTitleModel = (*customUserTitleModel)(nil)
const (
TitleTypeDefault = "default" // 默认类型 可购买
TitleTypeRank = "rank" // 排行榜类型 不可购买
TitleTypeCustom = "custom" // 自定义类型 不可购买
)
type (
// UserTitleModel is an interface to be customized, add more methods here,
// and implement the added methods in customUserTitleModel.
UserTitleModel interface {
userTitleModel
// FindMaxSort 寻找当前用户的最大Sort 最小值2
FindMaxSort(ctx context.Context, tx *gorm.DB, userId int64) int64
// FindOneByUserIdSort 通过用户和排序号找寻称号
FindOneByUserIdSort(ctx context.Context, tx *gorm.DB, userId int64, sort int64) (*UserTitle, error)
// FindByUserId 查找用户所有列表,按sort升序排列
FindByUserId(ctx context.Context, tx *gorm.DB, userId int64) ([]UserTitle, error)
// Addon 添加新的或延长时间
Addon(ctx context.Context, tx *gorm.DB, userId, titleId int64, titleType string, duration time.Duration, forever bool) error
}
customUserTitleModel struct {
*defaultUserTitleModel
}
)
// NewUserTitleModel returns a model for the database table.
func NewUserTitleModel(conn *gorm.DB) UserTitleModel {
return &customUserTitleModel{
defaultUserTitleModel: newUserTitleModel(conn),
}
}
func (m *customUserTitleModel) FindMaxSort(ctx context.Context, tx *gorm.DB, userId int64) int64 {
db := gormx.WithTx(ctx, m.DB, tx)
var resp int64 = 0
db.Table(m.table).
Select("MAX(sort)").
Where("user_id = ?", userId).Take(&resp)
return resp
}
func (m *customUserTitleModel) FindOneByUserIdSort(ctx context.Context, tx *gorm.DB, userId int64, sort int64) (*UserTitle, error) {
db := gormx.WithTx(ctx, m.DB, tx)
var resp UserTitle
err := db.Model(&UserTitle{}).
Where("user_id = ? and sort = ?", userId, sort).Take(&resp).Error
err = gormx.WrapSelectErr(err)
if err != nil {
return nil, err
}
return &resp, nil
}
func (m *customUserTitleModel) FindByUserId(ctx context.Context, tx *gorm.DB, userId int64) ([]UserTitle, error) {
var resp []UserTitle
err := gormx.WithTx(ctx, m.DB, tx).Table(m.table).
Where("user_id = ?", userId).
Order("sort asc").Find(&resp).Error
err = gormx.WrapSelectErr(err)
if err != nil {
return nil, err
}
return resp, nil
}
func (m *customUserTitleModel) Addon(ctx context.Context, tx *gorm.DB, userId, titleId int64, titleType string, duration time.Duration, forever bool) error {
return m.TransactCtx(ctx, tx, func(tx *gorm.DB) error {
userTitle, err := m.FindOneByUserIdTitleId(ctx, tx, userId, titleId)
if err != nil {
if !errors.Is(err, gormx.ErrNotFound) {
return nerr.NewWithCode(nerr.DBError)
}
}
today := now.BeginningOfDay()
if userTitle == nil {
// sort
maxSort := m.FindMaxSort(ctx, tx, userId)
err = m.Insert(ctx, tx, &UserTitle{
Id: uuid.NextId(),
UserId: userId,
TitleId: titleId,
Sort: maxSort + 1,
Type: titleType,
Forever: BitBool(forever),
StartTime: today,
EndTime: today.Add(duration),
})
if err != nil {
return nerr.NewWithCode(nerr.DBError)
}
} else {
// update
if !timex.DayExpire(today, userTitle.EndTime, bool(userTitle.Forever)) {
// 未过期,endTime直接添加1day
userTitle.EndTime = userTitle.EndTime.Add(duration)
err = m.Update(ctx, tx, userTitle)
if err != nil {
return nerr.NewWithCode(nerr.DBError)
}
} else {
// 过期,更新日期
err = m.Update(ctx, tx, &UserTitle{
Id: userTitle.Id,
UserId: userId,
TitleId: titleId,
Sort: userTitle.Sort,
Type: titleType,
Forever: BitBool(forever),
StartTime: today,
EndTime: today.Add(duration),
})
if err != nil {
return nerr.NewWithCode(nerr.DBError)
}
}
}
return nil
})
}