🎨 新增讲师包月功能,优化支付回调
This commit is contained in:
@@ -6,9 +6,11 @@ type ApiGroup struct {
|
||||
AppUserApi
|
||||
BannerApi
|
||||
OrderApi
|
||||
TeacherVip
|
||||
}
|
||||
|
||||
var userService = service.ServiceGroupApp.UserServiceGroup.UserService
|
||||
var appUserService = service.ServiceGroupApp.AppServiceGroup.AppUserService
|
||||
var bannerService = service.ServiceGroupApp.AppServiceGroup.BannerService
|
||||
var orderService = service.ServiceGroupApp.AppServiceGroup.OrderService
|
||||
var teacherVipService = service.ServiceGroupApp.AppServiceGroup.TeacherVipService
|
||||
|
112
api/v1/app/teacher_vip.go
Normal file
112
api/v1/app/teacher_vip.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/app"
|
||||
"git.echol.cn/loser/lckt/model/app/request"
|
||||
common "git.echol.cn/loser/lckt/model/common/request"
|
||||
r "git.echol.cn/loser/lckt/model/common/response"
|
||||
"git.echol.cn/loser/lckt/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type TeacherVip struct{}
|
||||
|
||||
// CreateTeacherVip 创建讲师VIP
|
||||
func (a *TeacherVip) CreateTeacherVip(context *gin.Context) {
|
||||
var p app.TeacherVip
|
||||
if err := context.ShouldBind(&p); err != nil {
|
||||
global.GVA_LOG.Error("参数错误,创建讲师VIP失败", zap.Error(err))
|
||||
r.FailWithMessage("参数错误,创建讲师VIP失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
id := utils.GetUserID(context)
|
||||
|
||||
err := teacherVipService.CreateTeacherVip(p, id)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("创建讲师VIP失败", zap.Error(err))
|
||||
r.FailWithMessage("创建讲师VIP失败", context)
|
||||
return
|
||||
}
|
||||
r.OkWithMessage("创建讲师VIP成功", context)
|
||||
}
|
||||
|
||||
// DeleteTeacherVip 删除讲师VIP
|
||||
func (a *TeacherVip) DeleteTeacherVip(context *gin.Context) {
|
||||
var p app.TeacherVip
|
||||
if err := context.ShouldBindJSON(&p); err != nil {
|
||||
global.GVA_LOG.Error("参数错误,删除讲师VIP失败", zap.Error(err))
|
||||
r.FailWithMessage("参数错误,删除讲师VIP失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
err := teacherVipService.DeleteTeacherVip(p)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("删除讲师VIP失败", zap.Error(err))
|
||||
r.FailWithMessage("删除讲师VIP失败", context)
|
||||
return
|
||||
}
|
||||
r.OkWithMessage("删除讲师VIP成功", context)
|
||||
}
|
||||
|
||||
// Update 更新讲师VIP
|
||||
func (a *TeacherVip) Update(context *gin.Context) {
|
||||
var p app.TeacherVip
|
||||
if err := context.ShouldBindJSON(&p); err != nil {
|
||||
global.GVA_LOG.Error("参数错误,更新讲师VIP失败", zap.Error(err))
|
||||
r.FailWithMessage("参数错误,更新讲师VIP失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
err := teacherVipService.Update(p)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新讲师VIP失败", zap.Error(err))
|
||||
r.FailWithMessage("更新讲师VIP失败", context)
|
||||
return
|
||||
}
|
||||
r.OkWithMessage("更新讲师VIP成功", context)
|
||||
}
|
||||
|
||||
// GetTeacherVipList 获取讲师VIP列表
|
||||
func (a *TeacherVip) GetTeacherVipList(context *gin.Context) {
|
||||
var p request.GetTeacherVipList
|
||||
if err := context.ShouldBind(&p); err != nil {
|
||||
global.GVA_LOG.Error("参数错误,获取讲师VIP列表失败", zap.Error(err))
|
||||
r.FailWithMessage("参数错误,获取讲师VIP列表失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
vips, total, err := teacherVipService.GetTeacherVipList(p)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取讲师VIP列表失败", zap.Error(err))
|
||||
r.FailWithMessage("获取讲师VIP列表失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
r.OkWithDetailed(
|
||||
r.PageResult{
|
||||
List: vips,
|
||||
Total: total,
|
||||
Page: p.Page,
|
||||
PageSize: p.PageSize,
|
||||
}, "获取讲师VIP列表成功", context)
|
||||
}
|
||||
|
||||
func (a *TeacherVip) GetTeacherVip(context *gin.Context) {
|
||||
var p common.GetById
|
||||
if err := context.ShouldBind(&p); err != nil {
|
||||
global.GVA_LOG.Error("参数错误,获取讲师VIP失败", zap.Error(err))
|
||||
r.FailWithMessage("参数错误,获取讲师VIP失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
vip, err := teacherVipService.GetTeacherVip(p.ID)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取讲师VIP失败", zap.Error(err))
|
||||
r.FailWithMessage("获取讲师VIP失败", context)
|
||||
return
|
||||
}
|
||||
r.OkWithDetailed(vip, "获取讲师VIP成功", context)
|
||||
}
|
@@ -476,3 +476,34 @@ func (a *AppUserApi) GetFollowStatus(ctx *gin.Context) {
|
||||
}
|
||||
r.OkWithDetailed(followed, "获取关注状态成功", ctx)
|
||||
}
|
||||
|
||||
// GetVipTeacherList 获取包月讲师列表
|
||||
func (a *AppUserApi) GetVipTeacherList(context *gin.Context) {
|
||||
var p common.PageInfo
|
||||
if err := context.ShouldBind(&p); err != nil {
|
||||
global.GVA_LOG.Error("参数错误,获取包月讲师列表失败", zap.Error(err))
|
||||
r.FailWithMessage("参数错误,获取包月讲师列表失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
userId := user_jwt.GetUserID(context)
|
||||
if userId == 0 {
|
||||
global.GVA_LOG.Error("获取用户ID失败")
|
||||
r.FailWithMessage("获取用户ID失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
teachers, total, err := appUserService.GetVipTeacherList(p, userId)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取包月讲师列表失败", zap.Error(err))
|
||||
r.FailWithMessage("获取包月讲师列表失败", context)
|
||||
return
|
||||
}
|
||||
r.OkWithDetailed(
|
||||
r.PageResult{
|
||||
List: teachers,
|
||||
Total: total,
|
||||
Page: p.Page,
|
||||
PageSize: p.PageSize,
|
||||
}, "获取包月讲师列表成功", context)
|
||||
}
|
||||
|
37
config.yaml
37
config.yaml
@@ -20,28 +20,25 @@ zap:
|
||||
|
||||
# redis configuration
|
||||
redis:
|
||||
#是否使用redis集群模式
|
||||
useCluster: false
|
||||
#使用集群模式addr和db默认无效
|
||||
addr: 127.0.0.1:6379
|
||||
password: ""
|
||||
name: "hw"
|
||||
addr: 120.46.165.63:6379
|
||||
password: "loser765911"
|
||||
db: 0
|
||||
useCluster: false
|
||||
clusterAddrs:
|
||||
- "172.21.0.3:7000"
|
||||
- "172.21.0.4:7001"
|
||||
- "172.21.0.2:7002"
|
||||
|
||||
# redis-list configuration
|
||||
- 172.21.0.3:7000
|
||||
- 172.21.0.4:7001
|
||||
- 172.21.0.2:7002
|
||||
redis-list:
|
||||
- name: cache # 数据库的名称,注意: name 需要在 redis-list 中唯一
|
||||
useCluster: false # 是否使用redis集群模式
|
||||
addr: 127.0.0.1:6379 # 使用集群模式addr和db默认无效
|
||||
password: ""
|
||||
db: 0
|
||||
- name: cache
|
||||
addr: 120.46.165.63:6379
|
||||
password: "loser765911"
|
||||
db: 1
|
||||
useCluster: false
|
||||
clusterAddrs:
|
||||
- "172.21.0.3:7000"
|
||||
- "172.21.0.4:7001"
|
||||
- "172.21.0.2:7002"
|
||||
- 172.21.0.3:7000
|
||||
- 172.21.0.4:7001
|
||||
- 172.21.0.2:7002
|
||||
|
||||
# mongo configuration
|
||||
mongo:
|
||||
@@ -76,7 +73,7 @@ system:
|
||||
addr: 8888
|
||||
db-type: mysql
|
||||
oss-type: aliyun-oss # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
|
||||
use-redis: false # 使用redis
|
||||
use-redis: true # 使用redis
|
||||
use-mongo: false # 使用mongo
|
||||
use-multipoint: false
|
||||
# IP限制次数 一个小时15000次
|
||||
@@ -265,7 +262,7 @@ disk-list:
|
||||
# 跨域配置
|
||||
# 需要配合 server/initialize/router.go -> `Router.Use(middleware.CorsByRules())` 使用
|
||||
cors:
|
||||
mode: allow-all # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝
|
||||
mode: allow-all # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝
|
||||
whitelist:
|
||||
- allow-origin: example1.com
|
||||
allow-headers: Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id
|
||||
|
@@ -81,6 +81,8 @@ func RegisterTables() {
|
||||
notice.Notice{},
|
||||
vip.Vip{},
|
||||
app.Follow{},
|
||||
app.TeacherVip{},
|
||||
app.UserTeacherVip{},
|
||||
)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("register table failed", zap.Error(err))
|
||||
|
@@ -4,20 +4,21 @@ import "git.echol.cn/loser/lckt/global"
|
||||
|
||||
type Order struct {
|
||||
global.GVA_MODEL
|
||||
OrderNo string `gorm:"column:order_no;type:varchar(24);comment:订单编号;NOT NULL" json:"order_no"`
|
||||
UserId uint64 `gorm:"column:user_id;type:bigint(20) unsigned;comment:用户ID;NOT NULL" json:"user_id"`
|
||||
OrderType int `gorm:"column:order_type;type:int(11);comment:订单类型 |1 课程|2 vip|;NOT NULL" json:"order_type"`
|
||||
ArticleId uint `gorm:"column:article_id;type:bigint(20) unsigned;default:0;comment:文章ID;NOT NULL" json:"article_id"`
|
||||
VipId uint `gorm:"column:vip_id;type:bigint(20) unsigned;default:0;comment:会员ID;NOT NULL" json:"vip_id"`
|
||||
Title string `gorm:"column:title;type:varchar(255);comment:订单标题;NOT NULL" json:"title"`
|
||||
Name string `gorm:"column:name;type:varchar(255);comment:名称;NOT NULL" json:"name"`
|
||||
Price int64 `gorm:"column:price;type:int(11) unsigned;default:0;comment:订单价格;NOT NULL" json:"price"`
|
||||
Phone string `gorm:"column:phone;type:varchar(11);comment:手机号;NOT NULL" json:"phone"`
|
||||
TeacherId uint64 `gorm:"column:teacher_Id;type:bigint(20);comment:教师Id;NOT NULL" json:"teacher_Id"`
|
||||
Status int `gorm:"column:status;type:int(11);default:1;comment:订单状态 |1 未付款|2 已付款|3 已过期|;NOT NULL" json:"status"`
|
||||
Desc string `gorm:"column:desc;type:varchar(24);comment:订单描述;NOT NULL" json:"desc"`
|
||||
OpenId string `gorm:"column:open_id;type:varchar(64);comment:用户OpenId;NOT NULL" json:"open_id"`
|
||||
PayType int `gorm:"column:pay_type;type:int(11);default:1;comment:支付方式 |1 微信|2 支付宝|3 余额|;NOT NULL" json:"pay_type"`
|
||||
OrderNo string `gorm:"column:order_no;type:varchar(24);comment:订单编号;NOT NULL" json:"order_no"`
|
||||
UserId uint64 `gorm:"column:user_id;type:bigint(20) unsigned;comment:用户ID;NOT NULL" json:"user_id"`
|
||||
OrderType int `gorm:"column:order_type;type:int(11);comment:订单类型 |1 课程|2 vip|3 讲师包月;NOT NULL" json:"order_type"`
|
||||
ArticleId uint `gorm:"column:article_id;type:bigint(20) unsigned;default:0;comment:文章ID;NOT NULL" json:"article_id"`
|
||||
VipId uint `gorm:"column:vip_id;type:bigint(20) unsigned;default:0;comment:会员ID;NOT NULL" json:"vip_id"`
|
||||
Title string `gorm:"column:title;type:varchar(255);comment:订单标题;NOT NULL" json:"title"`
|
||||
Name string `gorm:"column:name;type:varchar(255);comment:名称;NOT NULL" json:"name"`
|
||||
Price int64 `gorm:"column:price;type:int(11) unsigned;default:0;comment:订单价格;NOT NULL" json:"price"`
|
||||
Phone string `gorm:"column:phone;type:varchar(11);comment:手机号;NOT NULL" json:"phone"`
|
||||
TeacherId uint64 `gorm:"column:teacher_Id;type:bigint(20);comment:教师Id;NOT NULL" json:"teacher_Id"`
|
||||
TeacherVipId string `gorm:"column:teacher_vip_id;unsigned;comment:讲师VIP ID;NOT NULL" json:"teacher_vip_id"`
|
||||
Status int `gorm:"column:status;type:int(11);default:1;comment:订单状态 |1 未付款|2 已付款|3 已过期|;NOT NULL" json:"status"`
|
||||
Desc string `gorm:"column:desc;type:varchar(24);comment:订单描述;NOT NULL" json:"desc"`
|
||||
OpenId string `gorm:"column:open_id;type:varchar(64);comment:用户OpenId;NOT NULL" json:"open_id"`
|
||||
PayType int `gorm:"column:pay_type;type:int(11);default:1;comment:支付方式 |1 微信|2 支付宝|3 余额|;NOT NULL" json:"pay_type"`
|
||||
}
|
||||
|
||||
// TableName Order表
|
||||
|
8
model/app/request/user.go
Normal file
8
model/app/request/user.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package request
|
||||
|
||||
import common "git.echol.cn/loser/lckt/model/common/request"
|
||||
|
||||
type GetTeacherVipList struct {
|
||||
common.PageInfo
|
||||
TeacherId uint `json:"teacher_id" form:"teacher_id"` // 讲师ID
|
||||
}
|
16
model/app/teacher_vip.go
Normal file
16
model/app/teacher_vip.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package app
|
||||
|
||||
import "git.echol.cn/loser/lckt/global"
|
||||
|
||||
type TeacherVip struct {
|
||||
global.GVA_MODEL
|
||||
Title string `json:"title" form:"title" gorm:"comment:VIP标题;size:128"`
|
||||
TeacherId uint `json:"teacher_id" gorm:"comment:讲师ID;"`
|
||||
TeacherName string `json:"teacher_name" gorm:"comment:讲师名称"` // 讲师名称
|
||||
Price int `json:"price" gorm:"comment:VIP价格(单位为分)"`
|
||||
Desc string `json:"desc" gorm:"comment:VIP描述;type:longtext"`
|
||||
}
|
||||
|
||||
func (TeacherVip) TableName() string {
|
||||
return "app_teacher_vip"
|
||||
}
|
17
model/app/user_teacher_vip.go
Normal file
17
model/app/user_teacher_vip.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package app
|
||||
|
||||
import "git.echol.cn/loser/lckt/global"
|
||||
|
||||
type UserTeacherVip struct {
|
||||
global.GVA_MODEL
|
||||
UserId uint `gorm:"column:user_id;comment:用户ID;NOT NULL" json:"user_id"`
|
||||
TeacherId uint `gorm:"column:teacher_id;comment:讲师ID;NOT NULL" json:"teacher_id"`
|
||||
TeacherVipId uint `gorm:"column:teacher_vip_id;comment:讲师VIP ID;NOT NULL" json:"teacher_vip_id"`
|
||||
ExpireAt string `gorm:"column:expire_at;comment:到期时间;NOT NULL" json:"expire_at"`
|
||||
//是否过期
|
||||
IsExpire int `gorm:"column:is_expire;type:int(11);default:1;comment:是否过期 |1 未过期|2 已过期;NOT NULL" json:"is_expire"`
|
||||
}
|
||||
|
||||
func (UserTeacherVip) TableName() string {
|
||||
return "user_teacher_vip"
|
||||
}
|
@@ -11,3 +11,4 @@ type RouterGroup struct {
|
||||
var userApi = api.ApiGroupApp.AppApiGroup.AppUserApi
|
||||
var bannerApi = api.ApiGroupApp.AppApiGroup.BannerApi
|
||||
var orderApi = api.ApiGroupApp.AppApiGroup.OrderApi
|
||||
var teacherVipApi = api.ApiGroupApp.AppApiGroup.TeacherVip
|
||||
|
@@ -12,12 +12,13 @@ func (s *UserRouter) InitAppUserRouter(AppAuthGroup, PublicRouter *gin.RouterGro
|
||||
{
|
||||
appUserRouter.GET("/info", userApi.GetUserInfo) // 获取用户信息
|
||||
//申请成为讲师
|
||||
appUserRouter.POST("/applyTeacher", userApi.ApplyTeacher) // 申请成为讲师
|
||||
appUserRouter.GET("/applyTeacher", userApi.GetTeacherApply) // 获取教师申请状态
|
||||
appUserRouter.GET("/teachers", userApi.GetTeacherList) // 获取讲师列表
|
||||
appUserRouter.GET("/follows", userApi.GetFollowTeacherList) // 获取关注的讲师列表
|
||||
appUserRouter.POST("/follow", userApi.FollowTeacher) // 关注/取关讲师
|
||||
appUserRouter.GET("/followStatus", userApi.GetFollowStatus) // 获取关注状态
|
||||
appUserRouter.POST("/applyTeacher", userApi.ApplyTeacher) // 申请成为讲师
|
||||
appUserRouter.GET("/applyTeacher", userApi.GetTeacherApply) // 获取教师申请状态
|
||||
appUserRouter.GET("/teachers", userApi.GetTeacherList) // 获取讲师列表
|
||||
appUserRouter.GET("/follows", userApi.GetFollowTeacherList) // 获取关注的讲师列表
|
||||
appUserRouter.POST("/follow", userApi.FollowTeacher) // 关注/取关讲师
|
||||
appUserRouter.GET("/followStatus", userApi.GetFollowStatus) // 获取关注状态
|
||||
appUserRouter.GET("/vipTeachers", userApi.GetVipTeacherList) // 获取VIP讲师列表
|
||||
}
|
||||
{
|
||||
publicRouter.POST("wxLogin", userApi.WechatLogin) // 微信登录
|
||||
@@ -28,4 +29,12 @@ func (s *UserRouter) InitAppUserRouter(AppAuthGroup, PublicRouter *gin.RouterGro
|
||||
publicRouter.POST("login", userApi.Login) // 短信验证码登录
|
||||
publicRouter.POST("register", userApi.Register) // 注册
|
||||
}
|
||||
// 讲师包月相关接口
|
||||
{
|
||||
appUserRouter.GET("teacher_vips", teacherVipApi.GetTeacherVipList) // 获取讲师VIP列表
|
||||
appUserRouter.GET("teacher_vip/:id", teacherVipApi.GetTeacherVip) // 获取讲师VIP详情
|
||||
appUserRouter.POST("teacher_vip", teacherVipApi.CreateTeacherVip) // 创建讲师VIP
|
||||
appUserRouter.PUT("teacher_vip", teacherVipApi.Update) // 更新讲师VIP
|
||||
appUserRouter.DELETE("teacher_vip", teacherVipApi.DeleteTeacherVip) // 删除讲师VIP
|
||||
}
|
||||
}
|
||||
|
@@ -4,4 +4,5 @@ type ServiceGroup struct {
|
||||
AppUserService
|
||||
BannerService
|
||||
OrderService
|
||||
TeacherVipService
|
||||
}
|
||||
|
@@ -2,6 +2,10 @@ package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.echol.cn/loser/lckt/model/vip"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/app"
|
||||
@@ -53,19 +57,39 @@ func (s *OrderService) Create(o *app.Order) (*app.Order, error) {
|
||||
|
||||
// 查询订单商品价格
|
||||
price := 0
|
||||
if o.OrderType == 1 {
|
||||
switch o.OrderType {
|
||||
case 1:
|
||||
err := global.GVA_DB.Table("article").Select("price").Where("id = ?", o.ArticleId).Scan(&price).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询商品价格失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
case 2:
|
||||
err := global.GVA_DB.Table("lckt_vip").Select("price").Where("id = ?", o.VipId).Scan(&price).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询VIP价格失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
case 3:
|
||||
// 讲师包月
|
||||
|
||||
//切割TeacherVipId字符串
|
||||
ids := strings.Split(o.TeacherVipId, ",")
|
||||
// 查询每个服务的价格并累加
|
||||
totalPrice := 0
|
||||
for _, id := range ids {
|
||||
var p int
|
||||
err := global.GVA_DB.Table("app_teacher_vip").Select("price").Where("id = ?", id).Scan(&p).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询讲师包月价格失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
totalPrice += p
|
||||
}
|
||||
|
||||
price = totalPrice
|
||||
}
|
||||
|
||||
o.Price = int64(price)
|
||||
o.Status = 1 // 设置订单状态为未付款
|
||||
// 设置openid
|
||||
@@ -108,7 +132,7 @@ func (s *OrderService) BalancePay(p request.BalancePay) error {
|
||||
}
|
||||
// 检查用户余额是否足够
|
||||
var user user.User
|
||||
err = global.GVA_DB.Where("id = ?", p.UserId).Select("id,balance").First(&user).Error
|
||||
err = global.GVA_DB.Where("id = ?", p.UserId).First(&user).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询用户信息失败", zap.Error(err))
|
||||
return err
|
||||
@@ -141,6 +165,58 @@ func (s *OrderService) BalancePay(p request.BalancePay) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// 全站Vip
|
||||
if order.OrderType == 2 {
|
||||
// 更新用户的会员状态
|
||||
user.IsVip = 1
|
||||
// 查询用户购买的会员信息
|
||||
vipInfo := vip.Vip{}
|
||||
err = global.GVA_DB.Model(&vip.Vip{}).Where("id = ?", order.VipId).First(&vipInfo).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询会员信息失败", zap.Error(err))
|
||||
return nil
|
||||
}
|
||||
// 计算会员的过期时间
|
||||
if user.VipExpireTime != "" {
|
||||
expireTime, _ := time.Parse("2006-01-02", user.VipExpireTime)
|
||||
if expireTime.After(time.Now()) {
|
||||
// 如果会员未过期,则在原有的基础上增加时间
|
||||
user.VipExpireTime = expireTime.AddDate(0, 0, int(vipInfo.Expiration)).Format("2006-01-02")
|
||||
} else {
|
||||
// 如果会员已过期,则从当前时间开始计算
|
||||
user.VipExpireTime = time.Now().AddDate(0, 0, int(vipInfo.Expiration)).Format("2006-01-02")
|
||||
}
|
||||
} else {
|
||||
// 如果没有会员时间,则从当前时间开始计算
|
||||
user.VipExpireTime = time.Now().AddDate(0, 0, int(vipInfo.Expiration)).Format("2006-01-02")
|
||||
}
|
||||
err = global.GVA_DB.Save(&user).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新用户会员状态失败", zap.Error(err))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// 讲师包月
|
||||
if order.OrderType == 3 {
|
||||
// 逗号分割字符串
|
||||
ids := strings.Split(order.TeacherVipId, ",")
|
||||
for _, id := range ids {
|
||||
teacherVip := app.UserTeacherVip{}
|
||||
teacherVip.TeacherId = uint(order.TeacherId)
|
||||
// 将id转为uint
|
||||
teacherVipId, _ := strconv.ParseUint(id, 10, 64)
|
||||
teacherVip.TeacherVipId = uint(teacherVipId)
|
||||
teacherVip.UserId = uint(order.UserId)
|
||||
teacherVip.ExpireAt = time.Now().AddDate(0, 1, 0).Format("2006-01-02") // 会员有效期一个月
|
||||
teacherVip.IsExpire = 1 // 设置为未过期
|
||||
err = global.GVA_DB.Create(&teacherVip).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("购买讲师会员回调处理失败:", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
global.GVA_LOG.Info("余额支付成功", zap.Int64("user_id", int64(p.UserId)), zap.String("order_no", order.OrderNo))
|
||||
return nil
|
||||
}
|
||||
|
86
service/app/teacher_vip.go
Normal file
86
service/app/teacher_vip.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/app"
|
||||
"git.echol.cn/loser/lckt/model/app/request"
|
||||
user2 "git.echol.cn/loser/lckt/model/user"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type TeacherVipService struct{}
|
||||
|
||||
// GetTeacherVipList 获取讲师包月列表
|
||||
func (u *TeacherVipService) GetTeacherVipList(p request.GetTeacherVipList) (list []app.TeacherVip, total int64, err error) {
|
||||
limit := p.PageSize
|
||||
offset := (p.Page - 1) * p.PageSize
|
||||
|
||||
db := global.GVA_DB.Model(&app.TeacherVip{}).Where("teacher_id = ?", p.TeacherId)
|
||||
|
||||
if p.Keyword != "" {
|
||||
db = db.Where("title LIKE ?", "%"+p.Keyword+"%")
|
||||
}
|
||||
|
||||
err = db.Count(&total).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询讲师包月总数失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
err = db.Limit(limit).Offset(offset).Find(&list).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询讲师包月列表失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (u *TeacherVipService) CreateTeacherVip(p app.TeacherVip, userId uint) (err error) {
|
||||
// 判断是否是讲师
|
||||
var user user2.User
|
||||
err = global.GVA_DB.Where("id = ?", userId).First(&user).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询用户信息失败:", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
if user.UserType != 2 {
|
||||
// 不是讲师
|
||||
global.GVA_LOG.Error("当前用户不是讲师,无法创建讲师VIP")
|
||||
return errors.New("当前用户不是讲师,无法创建讲师VIP")
|
||||
}
|
||||
|
||||
err = global.GVA_DB.Create(&p).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("创建讲师VIP失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *TeacherVipService) DeleteTeacherVip(p app.TeacherVip) (err error) {
|
||||
err = global.GVA_DB.Delete(&p).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("删除讲师VIP失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *TeacherVipService) Update(p app.TeacherVip) (err error) {
|
||||
err = global.GVA_DB.Save(&p).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新讲师VIP失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *TeacherVipService) GetTeacherVip(id int) (vip app.TeacherVip, err error) {
|
||||
err = global.GVA_DB.Where("id = ?", id).First(&vip).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取讲师VIP失败", zap.Error(err))
|
||||
return vip, err
|
||||
}
|
||||
return vip, nil
|
||||
}
|
@@ -374,3 +374,45 @@ func (u *AppUserService) IsFollowTeacher(userId, teacherId uint) (bool, error) {
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
func (u *AppUserService) GetVipTeacherList(p common.PageInfo, userId uint) (list []vo.TeacherInfo, total int64, err error) {
|
||||
limit := p.PageSize
|
||||
offset := (p.Page - 1) * p.PageSize
|
||||
|
||||
// 1. 获取所有购买了讲师VIP的讲师ID
|
||||
var vipTeacherIds []uint
|
||||
err = global.GVA_DB.Model(&app.UserTeacherVip{}).Where("user_id = ? and is_expire = 1", userId).Select("id").Scan(&vipTeacherIds).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取用户讲师包月信息失败:", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
db := global.GVA_DB.Model(&user.User{}).Where("user_type = ? and id in ?", 2, vipTeacherIds)
|
||||
|
||||
if p.Keyword != "" {
|
||||
db = db.Where("nick_name LIKE ?", "%"+p.Keyword+"%")
|
||||
}
|
||||
|
||||
err = db.Count(&total).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询教师总数失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
err = db.Limit(limit).Offset(offset).Select("id, nick_name, avatar,des").Find(&list).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询教师列表失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 获取每个教师的粉丝数
|
||||
for i := range list {
|
||||
followCount, err := u.GetTeacherFansCount(list[i].ID)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询教师粉丝数失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
list[i].Follow = followCount
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
@@ -4,6 +4,8 @@ import (
|
||||
gfmt "fmt"
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/app"
|
||||
"git.echol.cn/loser/lckt/model/user"
|
||||
"git.echol.cn/loser/lckt/model/vip"
|
||||
"github.com/ArtisanCloud/PowerLibs/v3/fmt"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/models"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment"
|
||||
@@ -13,6 +15,8 @@ import (
|
||||
"go.uber.org/zap"
|
||||
"log"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -198,6 +202,66 @@ func NotifyHandle(ctx *gin.Context) error {
|
||||
return nil
|
||||
}
|
||||
order.Status = 2 // 设置订单状态为已支付
|
||||
|
||||
// 全站vip订单
|
||||
if order.OrderType == 2 {
|
||||
userInfo := user.User{}
|
||||
err = global.GVA_DB.Model(&user.User{}).Where("id = ?", order.UserId).First(&userInfo).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询用户信息失败", zap.Error(err))
|
||||
return nil
|
||||
}
|
||||
// 更新用户的会员状态
|
||||
userInfo.IsVip = 1
|
||||
// 查询用户购买的会员信息
|
||||
vipInfo := vip.Vip{}
|
||||
err = global.GVA_DB.Model(&vip.Vip{}).Where("id = ?", order.VipId).First(&vipInfo).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询会员信息失败", zap.Error(err))
|
||||
return nil
|
||||
}
|
||||
// 计算会员的过期时间
|
||||
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("更新用户会员状态失败", zap.Error(err))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是讲师包月订单,更新讲师的会员状态
|
||||
if order.OrderType == 3 {
|
||||
// 逗号分割字符串
|
||||
ids := strings.Split(order.TeacherVipId, ",")
|
||||
for _, id := range ids {
|
||||
teacherVip := app.UserTeacherVip{}
|
||||
teacherVip.TeacherId = uint(order.TeacherId)
|
||||
// 将id转为uint
|
||||
teacherVipId, _ := strconv.ParseUint(id, 10, 64)
|
||||
teacherVip.TeacherVipId = uint(teacherVipId)
|
||||
teacherVip.UserId = uint(order.UserId)
|
||||
teacherVip.ExpireAt = time.Now().AddDate(0, 1, 0).Format("2006-01-02") // 会员有效期一个月
|
||||
teacherVip.IsExpire = 1 // 设置为未过期
|
||||
err = global.GVA_DB.Create(&teacherVip).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("购买讲师会员回调处理失败:", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = global.GVA_DB.Save(&order).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新订单状态失败", zap.Error(err))
|
||||
|
Reference in New Issue
Block a user