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 }