samba/server/other/code/manager.go
2025-06-04 09:51:39 +08:00

145 lines
3.2 KiB
Go

package code
import (
"samba/pkg/xtime"
"samba/proto"
"samba/util/model"
"strconv"
"time"
)
type textError string
func (t textError) Error() string {
return string(t)
}
const (
// ErrCodeFormat 兑换码格式不正确
ErrCodeFormat = textError("code format error")
// ErrCodeIsExists 兑换码已存在
ErrCodeIsExists = textError("code is exists")
// ErrCodeIsExpired 兑换码已过期
ErrCodeIsExpired = textError("code is expired")
// ErrCodeIsUsed 兑换码已使用
ErrCodeIsUsed = textError("code is used")
// ErrCodeIsNotValid 不符合兑换规则
ErrCodeIsNotValid = textError("code is not valid")
)
// 判断用户是否满足兑换码使用规则
func ruleIsValid(uid int64, r *model.Rule) (bool, error) {
// 判断用户注册时间
if r.UserRegStartTime != 0 && r.UserRegEndTime != 0 {
uInfo, err := model.NewUserInfoOp().Load(uid)
if err != nil {
return false, err
}
if !xtime.IsInDuration(uInfo.MTime, r.UserRegStartTime, r.UserRegEndTime) {
return false, nil
}
}
if r.UserLastOnlineTime > 0 {
// 判断用户最后登录时间
recent, err := model.NewUserRecentOp().Get(uid)
if err != nil {
return false, err
}
lastLoginTime, err := strconv.ParseInt(recent.Value.LastLoginTime, 10, 64)
if err != nil {
return false, err
}
if lastLoginTime < r.UserLastOnlineTime {
return false, nil
}
}
if r.MinPay > 0 {
// 判断最低支付金额
price, err := model.NewPaymentInfoOp().GetUserPayPrice(uid)
if err != nil {
return false, err
}
if float64(price) < r.MinPay {
return false, nil
}
}
// TODO 判断最低VIP等级
// TODO 判断最低用户等级
return true, nil
}
type RedeemCodeManager struct {
}
var CodeManager = &RedeemCodeManager{}
// AddCode 添加兑换码
func (m *RedeemCodeManager) AddCode(code *model.RedeemCode) error {
err := RedeemCodeGenerator{}.IsValid(code.Code)
if err != nil {
return err
}
op := model.NewRedeemCodeOp()
if op.IsExist(code.Code) {
return ErrCodeIsExists
}
return op.Insert(code)
}
// GetCode 获取兑换码
func (m *RedeemCodeManager) GetCode(code string) (*model.RedeemCode, error) {
return model.NewRedeemCodeOp().Get(code)
}
// UseCode 使用兑换码
func (m *RedeemCodeManager) UseCode(uid int64, code *model.RedeemCode) error {
// 判断兑换码时间是否生效
if !xtime.IsInDuration(time.Now(), code.StartTime, code.EndTime) {
return ErrCodeIsExpired
}
op := model.NewRedeemCodeUseRecordOp()
// 判断兑换码是否达到使用次数
if code.Count > 0 {
count, err := op.CodeUsedCount(code.Code)
if err != nil {
return err
}
if count >= int64(code.Count) {
return ErrCodeIsUsed
}
}
// 判断用户是否使用过该兑换码
used, err := op.UserIsUsedCode(uid, code.Code)
if used {
return ErrCodeIsUsed
}
if err != nil {
return err
}
// 判断用户是否符合兑换码使用规则
ok, err := ruleIsValid(uid, code.Rule)
if err != nil {
return err
}
if !ok {
return ErrCodeIsNotValid
}
// 插入使用记录
return op.Insert(uid, code.Code)
}
// GetCodeList 获取兑换码列表
func (m *RedeemCodeManager) GetCodeList(code string, limit, offset int) (list []proto.CodeUse, hasMore bool, err error) {
return
}