🎨 新增兑换码功能,新增vip过期检测定时任务
This commit is contained in:
@@ -5,4 +5,5 @@ type ServiceGroup struct {
|
||||
BannerService
|
||||
OrderService
|
||||
TeacherVipService
|
||||
RedeemCodeService
|
||||
}
|
||||
|
348
service/app/redeem_code.go
Normal file
348
service/app/redeem_code.go
Normal file
@@ -0,0 +1,348 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/app"
|
||||
request2 "git.echol.cn/loser/lckt/model/app/request"
|
||||
"git.echol.cn/loser/lckt/model/article"
|
||||
"git.echol.cn/loser/lckt/model/common/request"
|
||||
"git.echol.cn/loser/lckt/model/user"
|
||||
"git.echol.cn/loser/lckt/model/vip"
|
||||
"git.echol.cn/loser/lckt/utils"
|
||||
"git.echol.cn/loser/lckt/utils/wechat"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RedeemCodeService struct{}
|
||||
|
||||
// Create 创建兑换码库
|
||||
func (s RedeemCodeService) Create(p app.RedeemCode) (err error) {
|
||||
return global.GVA_DB.Create(&p).Error
|
||||
}
|
||||
|
||||
// Delete 删除兑换码库
|
||||
func (s RedeemCodeService) Delete(p app.RedeemCode) (err error) {
|
||||
return global.GVA_DB.Delete(&p).Error
|
||||
}
|
||||
|
||||
// Update 更新兑换码库
|
||||
func (s RedeemCodeService) Update(p app.RedeemCode) (err error) {
|
||||
return global.GVA_DB.Save(&p).Error
|
||||
}
|
||||
|
||||
// GetList 分页获取兑换码库列表
|
||||
func (s RedeemCodeService) GetList(p request.PageInfo) (list []app.RedeemCode, total int64, err error) {
|
||||
limit := p.PageSize
|
||||
offset := p.PageSize * (p.Page - 1)
|
||||
db := global.GVA_DB.Model(&app.RedeemCode{})
|
||||
|
||||
if p.Keyword != "" {
|
||||
db = db.Where("code_name LIKE ?", "%"+p.Keyword+"%")
|
||||
}
|
||||
|
||||
err = db.Count(&total).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = db.Limit(limit).Offset(offset).Find(&list).Error
|
||||
return
|
||||
}
|
||||
|
||||
// GetById 根据ID获取兑换码库
|
||||
func (s RedeemCodeService) GetById(id int) (redeem app.RedeemCode, err error) {
|
||||
err = global.GVA_DB.Where("id = ?", id).First(&redeem).Error
|
||||
return
|
||||
}
|
||||
|
||||
// ========================CDK相关========================
|
||||
|
||||
// CreateCDK 生成兑换码
|
||||
func (s RedeemCodeService) CreateCDK(p request2.GenerateCDK) ([]app.CDK, error) {
|
||||
codes := utils.GenerateRedeemCodes(p.Number)
|
||||
var cdks []app.CDK
|
||||
for _, code := range codes {
|
||||
var cdk app.CDK
|
||||
cdk.Code = code
|
||||
cdk.RedeemId = p.Eid
|
||||
cdk.ValidDay = p.Expirer
|
||||
cdk.Status = 1
|
||||
if p.Expirer == 0 {
|
||||
cdk.ExpireAt = "永久有效"
|
||||
} else {
|
||||
cdk.ExpireAt = time.Now().AddDate(0, 0, p.Expirer).Format("2006-01-02")
|
||||
}
|
||||
|
||||
cdks = append(cdks, cdk)
|
||||
}
|
||||
|
||||
err := global.GVA_DB.Create(&cdks).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("生成兑换码失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 更新兑换码库的数量
|
||||
err = global.GVA_DB.Model(&app.RedeemCode{}).Where("id = ?", p.Eid).Update("num", gorm.Expr("num + ?", p.Number)).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新兑换码库数量失败", zap.Error(err))
|
||||
}
|
||||
|
||||
return cdks, nil
|
||||
}
|
||||
|
||||
// GetCDKList 获取兑换码列表
|
||||
func (s RedeemCodeService) GetCDKList(p request2.GetCDKList) (list []app.CDK, total int64, err error) {
|
||||
limit := p.PageSize
|
||||
offset := p.PageSize * (p.Page - 1)
|
||||
db := global.GVA_DB.Model(&app.CDK{}).Where("redeem_id = ?", p.Eid)
|
||||
|
||||
if p.Code != "" {
|
||||
db = db.Where("code LIKE ?", "%"+p.Code+"%")
|
||||
}
|
||||
|
||||
if p.UseName != "" {
|
||||
db = db.Where("use_name LIKE ?", "%"+p.UseName+"%")
|
||||
}
|
||||
if p.Status != 0 {
|
||||
db = db.Where("status = ?", p.Status)
|
||||
}
|
||||
|
||||
err = db.Count(&total).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = db.Limit(limit).Offset(offset).Find(&list).Error
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteCDK 删除兑换码
|
||||
func (s RedeemCodeService) DeleteCDK(p app.CDK) (err error) {
|
||||
return global.GVA_DB.Delete(&p).Error
|
||||
}
|
||||
|
||||
// Redeem 用户兑换码
|
||||
func (s RedeemCodeService) Redeem(p request2.RedeemCDK, ctx *gin.Context) (err error) {
|
||||
var cdk app.CDK
|
||||
err = global.GVA_DB.Where("code = ?", p.Code).First(&cdk).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 判断状态
|
||||
if cdk.Status != 1 {
|
||||
return errors.New("兑换码不可用")
|
||||
}
|
||||
|
||||
// 判断是否过期
|
||||
if cdk.ValidDay != 0 {
|
||||
expireAt, _ := time.Parse("2006-01-02", cdk.ExpireAt)
|
||||
if time.Now().After(expireAt) {
|
||||
// 更新状态为已过期
|
||||
cdk.Status = 3
|
||||
_ = global.GVA_DB.Save(&cdk).Error
|
||||
return errors.New("兑换码已过期")
|
||||
}
|
||||
}
|
||||
|
||||
// 获取兑换码库信息
|
||||
var redeem app.RedeemCode
|
||||
err = global.GVA_DB.Where("id = ?", cdk.RedeemId).First(&redeem).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
userId := utils.GetUserID(ctx)
|
||||
var userInfo user.User
|
||||
err = global.GVA_DB.Where("id = ?", userId).First(&userInfo).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取用户信息出错", zap.Error(err))
|
||||
}
|
||||
|
||||
// 更新兑换码状态
|
||||
cdk.Status = 2
|
||||
cdk.UseId = userInfo.ID
|
||||
cdk.UseName = userInfo.NickName
|
||||
cdk.UseAt = time.Now().Format("2006-01-02 15:04:05")
|
||||
err = global.GVA_DB.Save(&cdk).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新兑换码状态失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新兑换码库已使用数量
|
||||
err = global.GVA_DB.Model(&app.RedeemCode{}).Where("id = ?", cdk.RedeemId).Update("no", gorm.Expr("no + ?", 1)).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新兑换码库已使用数量失败", zap.Error(err))
|
||||
}
|
||||
|
||||
// 发放对应的权益
|
||||
switch redeem.Type {
|
||||
case 1:
|
||||
// VIP
|
||||
var vipInfo vip.Vip
|
||||
err = global.GVA_DB.Where("id = ?", redeem.Item).First(&vipInfo).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vipLevel := 1
|
||||
if vipInfo.Level == 1 {
|
||||
vipLevel = 2
|
||||
} else if vipInfo.Level == 2 {
|
||||
vipLevel = 3
|
||||
}
|
||||
|
||||
// 判断用户是否已经是VIP
|
||||
if userInfo.IsVip == 1 {
|
||||
// 是VIP,判断会员等级
|
||||
if userInfo.UserLabel == int64(vipLevel) {
|
||||
// 等级相同,延长会员时间
|
||||
if userInfo.VipExpireTime != "" {
|
||||
expireTime, _ := time.Parse("2006-01-02", userInfo.VipExpireTime)
|
||||
if expireTime.After(time.Now()) {
|
||||
// 如果会员未过期,则在原有的基础上增加时间
|
||||
userInfo.VipExpireTime = expireTime.AddDate(0, 0, int(vipInfo.Expiration)).Format("2006-01-02")
|
||||
} else {
|
||||
// 如果会员已过期,则从当前时间开始计算
|
||||
userInfo.VipExpireTime = time.Now().AddDate(0, 0, int(vipInfo.Expiration)).Format("2006-01-02")
|
||||
}
|
||||
} else {
|
||||
// 如果没有会员时间,则从当前时间开始计算
|
||||
userInfo.VipExpireTime = time.Now().AddDate(0, 0, int(vipInfo.Expiration)).Format("2006-01-02")
|
||||
}
|
||||
err = global.GVA_DB.Save(&userInfo).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新用户VIP信息失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
if userInfo.UserLabel < int64(vipLevel) {
|
||||
// 等级更高,直接覆盖
|
||||
userInfo.UserLabel = int64(vipLevel)
|
||||
userInfo.VipExpireTime = time.Now().AddDate(0, 0, int(vipInfo.Expiration)).Format("2006-01-02")
|
||||
err = global.GVA_DB.Save(&userInfo).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新用户VIP信息失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 不是VIP,直接设置为VIP
|
||||
userInfo.IsVip = 1
|
||||
userInfo.UserLabel = int64(vipLevel)
|
||||
userInfo.VipExpireTime = time.Now().AddDate(0, 0, int(vipInfo.Expiration)).Format("2006-01-02")
|
||||
err = global.GVA_DB.Save(&userInfo).Error
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case 2:
|
||||
// 讲师VIP
|
||||
var teacherVip app.TeacherVip
|
||||
err = global.GVA_DB.Where("id = ?", redeem.Item).First(&teacherVip).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 判断是否已经拥有该讲师VIP
|
||||
var existingTeacherVip app.UserTeacherVip
|
||||
err = global.GVA_DB.Where("user_id = ? AND teacher_vip_id = ?", userInfo.ID, teacherVip.ID).First(&existingTeacherVip).Error
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
global.GVA_LOG.Error("获取用户讲师VIP信息出错", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
// 判断是否为空
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
userTeacherVip := app.UserTeacherVip{
|
||||
UserId: userInfo.ID,
|
||||
TeacherVipId: teacherVip.ID,
|
||||
TeacherId: teacherVip.TeacherId,
|
||||
IsExpire: 1,
|
||||
ExpireAt: time.Now().AddDate(0, 0, 30).Format("2006-01-02"),
|
||||
}
|
||||
err = global.GVA_DB.Create(&userTeacherVip).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("兑换讲师包月服务失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 默认未过期,获取过期时间+30天
|
||||
// 将 existingTeacherVip.ExpireAt转为time.Time类型
|
||||
parse, err := time.Parse("2006-01-02", existingTeacherVip.ExpireAt)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("转换过期时间出错", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
// 已过期 当前时间开始计算+30天
|
||||
if existingTeacherVip.IsExpire == 2 && time.Now().After(parse) {
|
||||
existingTeacherVip.IsExpire = 1
|
||||
existingTeacherVip.ExpireAt = time.Now().AddDate(0, 0, 30).Format("2006-01-02")
|
||||
} else {
|
||||
// 未过期 在原有时间上+30天
|
||||
existingTeacherVip.ExpireAt = parse.AddDate(0, 0, 30).Format("2006-01-02")
|
||||
}
|
||||
|
||||
err = global.GVA_DB.Save(&existingTeacherVip).Error
|
||||
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("兑换讲师包月服务失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
case 3:
|
||||
// 课程
|
||||
var course article.Article
|
||||
err = global.GVA_DB.Where("id = ?", redeem.Item).First(&course).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 判断用户是否购买过该课程
|
||||
var count int64
|
||||
err = global.GVA_DB.Model(&app.Order{}).Where("article_id = ? AND user_id = ? AND status = 2", course.ID, userInfo.ID).Count(&count).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询用户购买记录失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
// 未购买,新增购买记录
|
||||
order := app.Order{
|
||||
UserId: uint64(userInfo.ID),
|
||||
Name: userInfo.NickName,
|
||||
OpenId: userInfo.OpenId,
|
||||
Phone: userInfo.Phone,
|
||||
TeacherId: uint64(course.TeacherId),
|
||||
ArticleId: course.ID,
|
||||
Price: 0,
|
||||
Status: 2,
|
||||
OrderNo: wechat.GenerateOrderNum(),
|
||||
OrderType: 1,
|
||||
Title: course.Title,
|
||||
Desc: "兑换码兑换" + course.Title,
|
||||
PayType: 4,
|
||||
}
|
||||
err = global.GVA_DB.Create(&order).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("兑换课程失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// 已购买,直接返回
|
||||
return errors.New("您已购买过该课程,无需重复兑换")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user