|
|
|
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
|
|
|
|
})
|
|
|
|
}
|