Files
lckt-server/service/app/redeem_code.go

349 lines
9.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}