Compare commits
10 Commits
9f220dc025
...
3beb54c12c
Author | SHA1 | Date | |
---|---|---|---|
3beb54c12c | |||
90d4b959a1 | |||
670791d342 | |||
b6e238d739 | |||
2674f4f061 | |||
e4bfdc31da | |||
82c6003b4a | |||
9c51f0cbe4 | |||
da1ebd72f4 | |||
4ce59a3090 |
@@ -3,6 +3,7 @@ package app
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
common "git.echol.cn/loser/lckt/model/common/request"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -361,3 +362,30 @@ func (a *AppUserApi) BindPhone(context *gin.Context) {
|
||||
|
||||
r.OkWithDetailed(user, "绑定手机号成功", context)
|
||||
}
|
||||
|
||||
// -----------------讲师相关---------------------
|
||||
|
||||
// GetTeacherList 获取讲师列表
|
||||
func (a *AppUserApi) GetTeacherList(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
|
||||
}
|
||||
|
||||
teachers, total, err := appUserService.GetTeacherList(p)
|
||||
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)
|
||||
}
|
||||
|
@@ -115,7 +115,7 @@ func (ArticleApi) AppById(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
userId := user_jwt.GetUserID(ctx)
|
||||
article, err := articleService.APPGetArticle(id, userId)
|
||||
article, err := articleService.APPGetArticle(id, int(userId))
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||
r.FailWithMessage("查询失败:"+err.Error(), ctx)
|
||||
@@ -123,3 +123,86 @@ func (ArticleApi) AppById(ctx *gin.Context) {
|
||||
}
|
||||
r.OkWithData(article, ctx)
|
||||
}
|
||||
|
||||
// AppPush app端推送文章
|
||||
func (ArticleApi) AppPush(ctx *gin.Context) {
|
||||
var p article.Article
|
||||
if err := ctx.ShouldBind(&p); err != nil {
|
||||
r.FailWithMessage(err.Error(), ctx)
|
||||
global.GVA_LOG.Error("参数有误!", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
err := articleService.AppPush(p)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("推送失败!", zap.Error(err))
|
||||
r.FailWithMessage("推送失败:"+err.Error(), ctx)
|
||||
return
|
||||
}
|
||||
r.OkWithMessage("推送成功", ctx)
|
||||
}
|
||||
|
||||
// GetMyArticleList 获取我的文章列表
|
||||
func (ArticleApi) GetMyArticleList(ctx *gin.Context) {
|
||||
var p request.GetList
|
||||
if err := ctx.ShouldBind(&p); err != nil {
|
||||
r.FailWithMessage(err.Error(), ctx)
|
||||
global.GVA_LOG.Error("参数有误!", zap.Error(err))
|
||||
return
|
||||
}
|
||||
userId := user_jwt.GetUserID(ctx)
|
||||
if userId == 0 {
|
||||
r.FailWithMessage("用户未登录", ctx)
|
||||
return
|
||||
}
|
||||
p.TeacherId = int(userId) // 设置当前用户ID为教师ID
|
||||
|
||||
list, total, err := articleService.GetMyArticleList(p)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||
r.FailWithMessage("查询失败:"+err.Error(), ctx)
|
||||
return
|
||||
}
|
||||
r.OkWithDetailed(gin.H{"list": list, "total": total}, "查询成功", ctx)
|
||||
}
|
||||
|
||||
// GetBuyList 获取用户购买的文章列表
|
||||
func (ArticleApi) GetBuyList(ctx *gin.Context) {
|
||||
var p request.GetList
|
||||
if err := ctx.ShouldBind(&p); err != nil {
|
||||
r.FailWithMessage(err.Error(), ctx)
|
||||
global.GVA_LOG.Error("参数有误!", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
userId := user_jwt.GetUserID(ctx)
|
||||
if userId == 0 {
|
||||
r.FailWithMessage("用户未登录", ctx)
|
||||
return
|
||||
}
|
||||
p.UserId = userId // 设置当前用户ID
|
||||
|
||||
list, total, err := articleService.GetBuyList(p)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||
r.FailWithMessage("查询失败:"+err.Error(), ctx)
|
||||
return
|
||||
}
|
||||
r.OkWithDetailed(gin.H{"list": list, "total": total}, "查询成功", ctx)
|
||||
}
|
||||
|
||||
// AppDelete 删除文章
|
||||
func (ArticleApi) AppDelete(ctx *gin.Context) {
|
||||
id := ctx.Param("id")
|
||||
if id == "" {
|
||||
r.FailWithMessage("参数错误", ctx)
|
||||
return
|
||||
}
|
||||
err := articleService.AppDelete(id)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
r.FailWithMessage("删除失败:"+err.Error(), ctx)
|
||||
return
|
||||
}
|
||||
r.OkWithMessage("删除成功", ctx)
|
||||
}
|
||||
|
@@ -189,5 +189,5 @@ func (btApi *BotApi) FindKey(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
response.OkWithDetailed(bt.Content, "获取成功", c)
|
||||
response.OkWithDetailed(bt, "获取成功", c)
|
||||
}
|
||||
|
@@ -32,6 +32,7 @@ func (b *FileUploadAndDownloadApi) UploadFile(c *gin.Context) {
|
||||
response.FailWithMessage("接收文件失败", c)
|
||||
return
|
||||
}
|
||||
|
||||
file, err = fileUploadAndDownloadService.UploadFile(header, noSave, classId) // 文件上传后拿到文件路径
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("上传文件失败!", zap.Error(err))
|
||||
|
2
go.mod
2
go.mod
@@ -5,6 +5,7 @@ go 1.23.0
|
||||
toolchain go1.23.2
|
||||
|
||||
require (
|
||||
github.com/ArtisanCloud/PowerLibs/v3 v3.3.2
|
||||
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.8
|
||||
github.com/ArtisanCloud/PowerWeChat/v3 v3.4.21
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7
|
||||
@@ -64,7 +65,6 @@ require (
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/ArtisanCloud/PowerLibs/v3 v3.3.2 // indirect
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/STARRY-S/zip v0.1.0 // indirect
|
||||
|
@@ -81,8 +81,8 @@ func Routers() *gin.Engine {
|
||||
|
||||
PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()).Use(middleware.AllCors())
|
||||
AppAuthGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
|
||||
AppAuthGroup.Use(middleware.AllCors())
|
||||
//AppAuthGroup.Use(middleware.UserJWTAuth()).Use(middleware.AllCors())
|
||||
//AppAuthGroup.Use(middleware.AllCors())
|
||||
AppAuthGroup.Use(middleware.UserJWTAuth()).Use(middleware.AllCors())
|
||||
{
|
||||
// 健康监测
|
||||
PublicGroup.GET("/health", func(c *gin.Context) {
|
||||
@@ -95,24 +95,24 @@ func Routers() *gin.Engine {
|
||||
}
|
||||
|
||||
{
|
||||
systemRouter.InitApiRouter(PrivateGroup, PublicGroup) // 注册功能api路由
|
||||
systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由
|
||||
systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由
|
||||
systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由
|
||||
systemRouter.InitSystemRouter(PrivateGroup) // system相关路由
|
||||
systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由
|
||||
systemRouter.InitAutoCodeRouter(PrivateGroup, PublicGroup) // 创建自动化代码
|
||||
systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由
|
||||
systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理
|
||||
systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史
|
||||
systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录
|
||||
systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
|
||||
systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 按钮权限管理
|
||||
systemRouter.InitSysExportTemplateRouter(PrivateGroup, PublicGroup) // 导出模板
|
||||
systemRouter.InitSysParamsRouter(PrivateGroup, PublicGroup) // 参数管理
|
||||
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
|
||||
exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
|
||||
exampleRouter.InitAttachmentCategoryRouterRouter(PrivateGroup) // 文件上传下载分类
|
||||
systemRouter.InitApiRouter(PrivateGroup, PublicGroup) // 注册功能api路由
|
||||
systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由
|
||||
systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由
|
||||
systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由
|
||||
systemRouter.InitSystemRouter(PrivateGroup) // system相关路由
|
||||
systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由
|
||||
systemRouter.InitAutoCodeRouter(PrivateGroup, PublicGroup) // 创建自动化代码
|
||||
systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由
|
||||
systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理
|
||||
systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史
|
||||
systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录
|
||||
systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
|
||||
systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 按钮权限管理
|
||||
systemRouter.InitSysExportTemplateRouter(PrivateGroup, PublicGroup) // 导出模板
|
||||
systemRouter.InitSysParamsRouter(PrivateGroup, PublicGroup) // 参数管理
|
||||
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
|
||||
exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup, AppAuthGroup) // 文件上传下载功能路由
|
||||
exampleRouter.InitAttachmentCategoryRouterRouter(PrivateGroup) // 文件上传下载分类
|
||||
|
||||
}
|
||||
//APP相关路由
|
||||
@@ -126,7 +126,7 @@ func Routers() *gin.Engine {
|
||||
InstallPlugin(PrivateGroup, PublicGroup, Router)
|
||||
|
||||
// 注册业务路由
|
||||
initBizRouter(PrivateGroup, PublicGroup)
|
||||
initBizRouter(PrivateGroup, PublicGroup, AppAuthGroup)
|
||||
|
||||
PluginInit(PublicGroup, customerservice.CreateCustomerServicePlug())
|
||||
PluginInit(PrivateGroup, picturelibrary.CreatePictureLibraryPlug())
|
||||
|
@@ -12,6 +12,7 @@ func holder(routers ...*gin.RouterGroup) {
|
||||
func initBizRouter(routers ...*gin.RouterGroup) {
|
||||
privateGroup := routers[0]
|
||||
publicGroup := routers[1]
|
||||
appGroup := routers[2]
|
||||
holder(publicGroup, privateGroup)
|
||||
{
|
||||
categoryRouter := router.RouterGroupApp.Category
|
||||
@@ -23,7 +24,7 @@ func initBizRouter(routers ...*gin.RouterGroup) {
|
||||
}
|
||||
{
|
||||
articleRouter := router.RouterGroupApp.Article
|
||||
articleRouter.InitBotRouter(privateGroup, publicGroup)
|
||||
articleRouter.InitBotRouter(privateGroup, publicGroup, appGroup)
|
||||
}
|
||||
{
|
||||
userRouter := router.RouterGroupApp.User
|
||||
|
@@ -8,6 +8,7 @@ type Order struct {
|
||||
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"`
|
||||
|
@@ -15,3 +15,10 @@ type UserInfo struct {
|
||||
IsVip int8 `json:"is_vip" form:"is_vip"` //是否是VIP 0 否 1 是
|
||||
VipExpireTime string `json:"vip_expire_time" form:"vip_expire_time"` // VIP过期时间
|
||||
}
|
||||
|
||||
type TeacherInfo struct {
|
||||
ID uint `json:"id" form:"id"`
|
||||
NickName string `json:"nick_name" form:"nick_name"`
|
||||
Avatar string `json:"avatar" form:"avatar"`
|
||||
Des string `json:"des" form:"des"`
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ type Article struct {
|
||||
IsFree int `json:"isFree" gorm:"comment:是否免费;default:0"` // 是否免费 0-否 1-是
|
||||
// 分类ID
|
||||
CategoryId int `json:"categoryId" gorm:"comment:分类ID"`
|
||||
Status int `json:"status" gorm:"comment:状态 1-已发布 2-待审核 3-审核不通过;default:2"` // 状态 0-草稿 1-已发布 2-待审核 3-审核不通过
|
||||
}
|
||||
|
||||
// TableName 文章表
|
||||
|
@@ -6,8 +6,10 @@ type GetList struct {
|
||||
request.PageInfo
|
||||
Title string `json:"title" form:"title"` // 文章标题
|
||||
// 分类ID
|
||||
CategoryId int `json:"categoryId" form:"categoryId"` // 分类ID
|
||||
TeacherId int `json:"teacherId" form:"teacherId"` // 讲师ID
|
||||
CategoryId int `json:"categoryId" form:"categoryId"` // 分类ID
|
||||
TeacherId int `json:"teacherId" form:"teacherId"` // 讲师ID
|
||||
Status int `json:"status" form:"status"` // 状态 0-草稿 1-已发布 2-待审核 3-审核不通过
|
||||
UserId uint `json:"userId" form:"userId"` // 用户ID
|
||||
}
|
||||
|
||||
type DeleteIds struct {
|
||||
|
@@ -1,5 +1,7 @@
|
||||
package vo
|
||||
|
||||
import "git.echol.cn/loser/lckt/model/app/vo"
|
||||
|
||||
type ArticleListVo struct {
|
||||
ID int `json:"id" gorm:"comment:文章ID"`
|
||||
Title string `json:"title" gorm:"comment:文章标题"`
|
||||
@@ -26,3 +28,8 @@ type ArticleVo struct {
|
||||
IsFree int `json:"isFree" gorm:"comment:是否免费;default:0"` // 是否免费 0-否 1-是
|
||||
IsBuy int `json:"isBuy" gorm:"comment:是否购买;default:0"` // 是否购买 0-否 1-是
|
||||
}
|
||||
|
||||
type ArticleTeacherVo struct {
|
||||
TeacherInfo vo.TeacherInfo
|
||||
ArticleList []ArticleListVo `json:"articleList" gorm:"comment:文章列表"`
|
||||
}
|
||||
|
@@ -10,6 +10,8 @@ type Bot struct {
|
||||
global.GVA_MODEL
|
||||
Keyword string `json:"keyword" form:"keyword" gorm:"column:keyword;comment:关键词;" binding:"required"` //关键词
|
||||
Content *string `json:"content" form:"content" gorm:"column:content;comment:内容;type:text;" binding:"required"` //内容
|
||||
// 关联词
|
||||
RelatedWords *string `json:"related_words" form:"related_words" gorm:"column:related_words;comment:关联词;type:text;"` //关联词
|
||||
}
|
||||
|
||||
// TableName 机器人 Bot自定义表名 bots
|
||||
|
@@ -14,6 +14,7 @@ type Category struct {
|
||||
ParentId *int `json:"parentId" form:"parentId" gorm:"column:parent_id;comment:父类别ID;"` //父ID
|
||||
Icon *string `json:"icon" form:"icon" gorm:"column:icon;comment:类别图标;"` //图标
|
||||
IndexTrue *bool `json:"index" form:"index" gorm:"column:index;comment:是否首页显示;"` //是否首页显示
|
||||
Url *string `json:"url" form:"url" gorm:"column:url;comment:类别链接;"` //链接
|
||||
}
|
||||
|
||||
// TableName 类别 Category自定义表名 categories
|
||||
|
@@ -6,6 +6,7 @@ type User struct {
|
||||
global.GVA_MODEL
|
||||
NickName string `json:"nick_name" form:"nick_name" gorm:"comment:用户昵称"`
|
||||
Phone string `json:"phone" form:"phone" gorm:"comment:用户手机号"`
|
||||
Des string `json:"des" form:"des" gorm:"comment:用户描述"`
|
||||
UnionId string `json:"union_id" form:"union_id" gorm:"type:varchar(255) comment '微信UnionId'"`
|
||||
OpenId string `gorm:"column:open_id;default:'';comment:'openId'" json:"-"`
|
||||
Password string `json:"password" form:"password" gorm:"comment:用户密码"`
|
||||
|
@@ -8,6 +8,7 @@ type Vip struct {
|
||||
Level int `json:"level" form:"level" gorm:"comment:会员等级 1 Vip 2 Svip"` // 会员等级
|
||||
Price float64 `json:"price" form:"price" gorm:"comment:会员价格"` // 会员价格
|
||||
Expiration int64 `json:"expiration" form:"expiration" gorm:"comment:会员有效期"` // 会员过期时间
|
||||
Des string `json:"des" form:"des" gorm:"comment:会员描述"` // 会员描述
|
||||
}
|
||||
|
||||
// TableName 设置表名
|
||||
|
@@ -13,7 +13,8 @@ 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("/applyTeacher", userApi.GetTeacherApply) // 获取教师申请状态
|
||||
appUserRouter.GET("/teachers", userApi.GetTeacherList) // 获取讲师列表
|
||||
}
|
||||
{
|
||||
publicRouter.POST("wxLogin", userApi.WechatLogin) // 微信登录
|
||||
|
@@ -8,10 +8,11 @@ import (
|
||||
type ArticleRouter struct{}
|
||||
|
||||
// InitBotRouter 初始化 文章 路由信息
|
||||
func (s *ArticleRouter) InitBotRouter(Router *gin.RouterGroup, PublicRouter *gin.RouterGroup) {
|
||||
func (s *ArticleRouter) InitBotRouter(Router *gin.RouterGroup, PublicRouter *gin.RouterGroup, AppRouter *gin.RouterGroup) {
|
||||
articleRouter := Router.Group("article").Use(middleware.OperationRecord())
|
||||
articleRouterWithoutRecord := Router.Group("article")
|
||||
articleRouterWithoutAuth := PublicRouter.Group("article")
|
||||
appRouter := AppRouter.Group("article")
|
||||
{
|
||||
articleRouter.POST("", artApi.Create) // 新建文章
|
||||
articleRouter.DELETE("", artApi.Delete) // 批量删除文章
|
||||
@@ -27,4 +28,12 @@ func (s *ArticleRouter) InitBotRouter(Router *gin.RouterGroup, PublicRouter *gin
|
||||
articleRouterWithoutAuth.GET("app/list", artApi.APPGetList) // 文章公开接口
|
||||
articleRouterWithoutAuth.GET("app/:id", artApi.AppById) // 文章开放接口
|
||||
}
|
||||
{
|
||||
// App端文章相关接口
|
||||
appRouter.POST("publish", artApi.AppPush) // 获取文章列表
|
||||
appRouter.PUT("publish", artApi.AppPush)
|
||||
appRouter.DELETE("delete/:id", artApi.AppDelete) // 批量删除文章
|
||||
appRouter.GET("my", artApi.GetMyArticleList) // 获取我的文章列表
|
||||
appRouter.GET("buyList", artApi.GetBuyList) // 获取购买的文章列表
|
||||
}
|
||||
}
|
||||
|
@@ -6,8 +6,9 @@ import (
|
||||
|
||||
type FileUploadAndDownloadRouter struct{}
|
||||
|
||||
func (e *FileUploadAndDownloadRouter) InitFileUploadAndDownloadRouter(Router *gin.RouterGroup) {
|
||||
func (e *FileUploadAndDownloadRouter) InitFileUploadAndDownloadRouter(Router *gin.RouterGroup, APPRouter *gin.RouterGroup) {
|
||||
fileUploadAndDownloadRouter := Router.Group("fileUploadAndDownload")
|
||||
appFileRouter := APPRouter.Group("appFile")
|
||||
{
|
||||
fileUploadAndDownloadRouter.POST("upload", exaFileUploadAndDownloadApi.UploadFile) // 上传文件
|
||||
fileUploadAndDownloadRouter.POST("getFileList", exaFileUploadAndDownloadApi.GetFileList) // 获取上传文件列表
|
||||
@@ -19,4 +20,7 @@ func (e *FileUploadAndDownloadRouter) InitFileUploadAndDownloadRouter(Router *gi
|
||||
fileUploadAndDownloadRouter.POST("removeChunk", exaFileUploadAndDownloadApi.RemoveChunk) // 删除切片
|
||||
fileUploadAndDownloadRouter.POST("importURL", exaFileUploadAndDownloadApi.ImportURL) // 导入URL
|
||||
}
|
||||
{
|
||||
appFileRouter.POST("upload", exaFileUploadAndDownloadApi.UploadFile) // APP上传文件
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,6 @@ type NoticeRouter struct{}
|
||||
// InitNoticeRouter 初始化 通知 路由信息
|
||||
func (s *NoticeRouter) InitNoticeRouter(Router *gin.RouterGroup, PublicRouter *gin.RouterGroup) {
|
||||
notRouter := Router.Group("not").Use(middleware.OperationRecord())
|
||||
notRouterWithoutRecord := Router.Group("not")
|
||||
notRouterWithoutAuth := PublicRouter.Group("not")
|
||||
{
|
||||
notRouter.POST("createNotice", notApi.CreateNotice) // 新建通知
|
||||
@@ -19,10 +18,8 @@ func (s *NoticeRouter) InitNoticeRouter(Router *gin.RouterGroup, PublicRouter *g
|
||||
notRouter.PUT("updateNotice", notApi.UpdateNotice) // 更新通知
|
||||
}
|
||||
{
|
||||
notRouterWithoutRecord.GET("findNotice", notApi.FindNotice) // 根据ID获取通知
|
||||
notRouterWithoutRecord.GET("getNoticeList", notApi.GetNoticeList) // 获取通知列表
|
||||
}
|
||||
{
|
||||
notRouterWithoutAuth.GET("findNotice", notApi.FindNotice) // 根据ID获取通知
|
||||
notRouterWithoutAuth.GET("getNoticeList", notApi.GetNoticeList) // 获取通知列表
|
||||
notRouterWithoutAuth.GET("getNoticePublic", notApi.GetNoticePublic) // 通知开放接口
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/app"
|
||||
"git.echol.cn/loser/lckt/model/app/request"
|
||||
@@ -59,7 +60,7 @@ func (s *OrderService) Create(o *app.Order) (*app.Order, error) {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
err := global.GVA_DB.Table("lckt_vip").Select("price").Where("id = ?", o.ArticleId).Scan(&price).Error
|
||||
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
|
||||
@@ -112,16 +113,22 @@ func (s *OrderService) BalancePay(p request.BalancePay) error {
|
||||
global.GVA_LOG.Error("查询用户信息失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
// 将user.Balance转为int64类型进行比较
|
||||
balance := int64(user.Balance)
|
||||
if balance < order.Price/100 { // 订单价格是以分为单位存储的
|
||||
global.GVA_LOG.Error("用户余额不足", zap.Int64("balance", balance), zap.Int64("order_price", order.Price))
|
||||
|
||||
// 将订单价格从分转换为元(保持精度)
|
||||
orderPriceInYuan := float64(order.Price) / 100.0
|
||||
|
||||
// 检查用户余额是否足够(使用float64进行比较,避免精度丢失)
|
||||
if user.Balance < float32(orderPriceInYuan) {
|
||||
global.GVA_LOG.Error("用户余额不足",
|
||||
zap.Float32("balance", user.Balance),
|
||||
zap.Float64("order_price_yuan", orderPriceInYuan),
|
||||
zap.Int64("order_price_cent", order.Price))
|
||||
return fmt.Errorf("用户余额不足")
|
||||
}
|
||||
|
||||
// 扣除用户余额
|
||||
balance -= order.Price / 100
|
||||
err = global.GVA_DB.Model(&user).Where("id = ?", p.UserId).Update("balance", balance).Error
|
||||
// 扣除用户余额(保持精度)
|
||||
newBalance := user.Balance - float32(orderPriceInYuan)
|
||||
err = global.GVA_DB.Model(&user).Where("id = ?", p.UserId).Update("balance", newBalance).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("扣除用户余额失败", zap.Error(err))
|
||||
return err
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/app"
|
||||
"git.echol.cn/loser/lckt/model/app/vo"
|
||||
common "git.echol.cn/loser/lckt/model/common/request"
|
||||
"git.echol.cn/loser/lckt/model/user"
|
||||
"git.echol.cn/loser/lckt/model/user/request"
|
||||
utils2 "git.echol.cn/loser/lckt/utils"
|
||||
@@ -221,3 +222,25 @@ func (u *AppUserService) BindPhone(p request.BindPhoneReq) (*user.User, error) {
|
||||
|
||||
return &userInfo, nil
|
||||
}
|
||||
|
||||
func (u *AppUserService) GetTeacherList(p common.PageInfo) (list []vo.TeacherInfo, total int64, err error) {
|
||||
limit := p.PageSize
|
||||
offset := (p.Page - 1) * p.PageSize
|
||||
db := global.GVA_DB.Model(&user.User{}).Where("user_type = ?", 2)
|
||||
|
||||
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
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@@ -47,7 +47,7 @@ func (s ArticleService) APPGetArticleList(pageInfo request.GetList) (list []vo.A
|
||||
limit := pageInfo.PageSize
|
||||
offset := pageInfo.PageSize * (pageInfo.Page - 1)
|
||||
|
||||
db := global.GVA_DB.Model(&article.Article{})
|
||||
db := global.GVA_DB.Model(&article.Article{}).Where("status = 1") // 只查询已发布的文章
|
||||
err = db.Count(&total).Error
|
||||
if err != nil {
|
||||
return
|
||||
@@ -75,7 +75,7 @@ func (s ArticleService) APPGetArticleList(pageInfo request.GetList) (list []vo.A
|
||||
return
|
||||
}
|
||||
|
||||
func (s ArticleService) APPGetArticle(id string, userId uint) (article *vo.ArticleVo, err error) {
|
||||
func (s ArticleService) APPGetArticle(id string, userId int) (article *vo.ArticleVo, err error) {
|
||||
err = global.GVA_DB.Table("article").Where("id = ?", id).First(&article).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取文章失败", zap.Error(err))
|
||||
@@ -94,7 +94,9 @@ func (s ArticleService) APPGetArticle(id string, userId uint) (article *vo.Artic
|
||||
global.GVA_LOG.Error("查询用户购买记录失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
if count == 0 {
|
||||
|
||||
// 如果count = 0 或者 TeacherId 不等于 userId,表示用户没有购买过该文章
|
||||
if count == 0 && article.TeacherId != userId {
|
||||
// 用户没有购买过,隐藏Content
|
||||
article.Content = ""
|
||||
article.IsBuy = 0 // 设置为未购买
|
||||
@@ -103,3 +105,86 @@ func (s ArticleService) APPGetArticle(id string, userId uint) (article *vo.Artic
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// AppPush app端推送文章
|
||||
func (s ArticleService) AppPush(req article.Article) (err error) {
|
||||
req.Status = 2 // 默认状态为待审核
|
||||
if req.ID != 0 {
|
||||
err = global.GVA_DB.Model(&article.Article{}).Where("id = ?", req.ID).Updates(&req).Error
|
||||
} else {
|
||||
err = global.GVA_DB.Create(&req).Error
|
||||
}
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("推送文章失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s ArticleService) GetMyArticleList(req request.GetList) (list []article.Article, total int64, err error) {
|
||||
|
||||
limit := req.PageSize
|
||||
offset := req.PageSize * (req.Page - 1)
|
||||
|
||||
db := global.GVA_DB.Model(&article.Article{}).Where("teacher_id = ?", req.TeacherId)
|
||||
if req.Title != "" {
|
||||
db = db.Where("title LIKE ?", "%"+req.Title+"%")
|
||||
}
|
||||
|
||||
if req.CategoryId != 0 {
|
||||
db = db.Where("category_id = ?", req.CategoryId)
|
||||
}
|
||||
|
||||
if req.Status != 0 {
|
||||
db = db.Where("status = ?", req.Status)
|
||||
}
|
||||
|
||||
err = db.Count(&total).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
err = db.Limit(limit).Offset(offset).Find(&list).Error
|
||||
return list, total, err
|
||||
}
|
||||
|
||||
func (s ArticleService) GetBuyList(p request.GetList) (articles []article.Article, total int64, err error) {
|
||||
buyIds := make([]int, 0)
|
||||
// 获取用户购买的文章ID列表
|
||||
err = global.GVA_DB.Model(&app.Order{}).Where("user_id = ? AND status = 2", p.UserId).Select("article_id").Find(&buyIds).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询用户购买记录失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if len(buyIds) == 0 {
|
||||
// 如果没有购买记录,直接返回空列表
|
||||
return []article.Article{}, 0, nil
|
||||
}
|
||||
|
||||
db := global.GVA_DB.Model(&article.Article{}).Where("id IN ?", buyIds)
|
||||
if p.Title != "" {
|
||||
db = db.Where("title LIKE ?", "%"+p.Title+"%")
|
||||
}
|
||||
|
||||
err = db.Count(&total).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询购买文章总数失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
err = db.Limit(p.PageSize).Offset(p.PageSize * (p.Page - 1)).Find(&articles).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询购买文章列表失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
return articles, total, nil
|
||||
}
|
||||
|
||||
func (s ArticleService) AppDelete(id string) error {
|
||||
err := global.GVA_DB.Delete(&article.Article{}, "id = ?", id).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("删除文章失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -2,8 +2,11 @@ package example
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"git.echol.cn/loser/lckt/utils"
|
||||
"mime/multipart"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/example"
|
||||
@@ -94,11 +97,15 @@ func (e *FileUploadAndDownloadService) GetFileRecordInfoList(info request.ExaAtt
|
||||
|
||||
func (e *FileUploadAndDownloadService) UploadFile(header *multipart.FileHeader, noSave string, classId int) (file example.ExaFileUploadAndDownload, err error) {
|
||||
oss := upload.NewOss()
|
||||
s := strings.Split(header.Filename, ".")
|
||||
if classId == 2 {
|
||||
header.Filename = utils.GenerateRandomString(12) + "_" + strconv.FormatInt(time.Now().Unix(), 10) + "." + s[len(s)-1]
|
||||
}
|
||||
filePath, key, uploadErr := oss.UploadFile(header)
|
||||
if uploadErr != nil {
|
||||
return file, uploadErr
|
||||
}
|
||||
s := strings.Split(header.Filename, ".")
|
||||
|
||||
f := example.ExaFileUploadAndDownload{
|
||||
Url: filePath,
|
||||
Name: header.Filename,
|
||||
|
@@ -21,3 +21,16 @@ func GenerateInviteCode(userID uint) string {
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
func GenerateRandomString(length int) string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
// 拼接用户ID和随机数
|
||||
data := fmt.Sprintf("%d%d", 6, rand.Intn(1000000))
|
||||
hash := md5.Sum([]byte(data))
|
||||
code := ""
|
||||
for i := 0; i < 12; i++ {
|
||||
// 取哈希的前6位,每位映射到字符集
|
||||
code += string(charset[int(hash[i])%len(charset)])
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
@@ -7,7 +7,6 @@ import (
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
systemReq "git.echol.cn/loser/lckt/model/user/request"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -54,28 +53,25 @@ func GetToken(c *gin.Context) string {
|
||||
return token
|
||||
}
|
||||
|
||||
func GetClaims(c *gin.Context) (*systemReq.CustomClaims, error) {
|
||||
func GetClaims(c *gin.Context) (*request.CustomClaims, error) {
|
||||
token := GetToken(c)
|
||||
j := NewUserJWT()
|
||||
claims, err := j.ParseToken(token)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("从Gin的Context中获取从jwt解析信息失败, 请检查请求头是否存在Authorization且claims是否为规定结构")
|
||||
global.GVA_LOG.Error(err.Error())
|
||||
}
|
||||
return claims, err
|
||||
}
|
||||
|
||||
// GetUserID 从Gin的Context中获取从jwt解析出来的用户ID
|
||||
func GetUserID(c *gin.Context) uint {
|
||||
if claims, exists := c.Get("claims"); !exists {
|
||||
if cl, err := GetClaims(c); err != nil {
|
||||
return 0
|
||||
} else {
|
||||
return cl.BaseClaims.ID
|
||||
}
|
||||
|
||||
if cl, err := GetClaims(c); err != nil {
|
||||
return 0
|
||||
} else {
|
||||
waitUse := claims.(*systemReq.CustomClaims)
|
||||
return waitUse.BaseClaims.ID
|
||||
return cl.BaseClaims.ID
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// GetNickName 从Gin的Context中获取从jwt解析出来的用户名
|
||||
@@ -87,7 +83,7 @@ func GetNickName(c *gin.Context) string {
|
||||
return cl.NickName
|
||||
}
|
||||
} else {
|
||||
waitUse := claims.(*systemReq.CustomClaims)
|
||||
waitUse := claims.(*request.CustomClaims)
|
||||
return waitUse.NickName
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user