feat: 实现我的课程API接口
- 新增mycourse API接口定义 (api/api/mycourse/) - 实现Controller层,遵循团队四层架构规范 - 实现Logic层业务逻辑,包含用户认证和模拟数据 - 自动生成Service层接口 (gf gen service) - 支持课程状态筛选和分页功能 - 返回课程基本信息、学习进度、讲师等数据
This commit is contained in:
parent
44112c2470
commit
fe46cc7499
@ -21,6 +21,7 @@ require (
|
|||||||
github.com/gogf/gf/v2 v2.9.1-0.20250624075347-5fa656d1cc92
|
github.com/gogf/gf/v2 v2.9.1-0.20250624075347-5fa656d1cc92
|
||||||
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f
|
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2
|
github.com/golang-jwt/jwt/v5 v5.2.2
|
||||||
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/websocket v1.5.3
|
github.com/gorilla/websocket v1.5.3
|
||||||
github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794
|
github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794
|
||||||
github.com/minio/minio-go/v7 v7.0.94
|
github.com/minio/minio-go/v7 v7.0.94
|
||||||
@ -86,7 +87,6 @@ require (
|
|||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/btree v1.1.3 // indirect
|
github.com/google/btree v1.1.3 // indirect
|
||||||
github.com/google/go-querystring v1.0.0 // indirect
|
github.com/google/go-querystring v1.0.0 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
|
||||||
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
|
@ -2,117 +2,17 @@ package mycourse
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"hotgo/api/api/mycourse/v1"
|
v1 "hotgo/api/api/mycourse/v1"
|
||||||
"hotgo/internal/library/contexts"
|
"hotgo/internal/service"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/errors/gerror"
|
|
||||||
"github.com/gogf/gf/v2/os/gtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MyCourseList 获取我的课程列表
|
// MyCourseList 获取我的课程列表
|
||||||
func (c *ControllerV1) MyCourseList(ctx context.Context, req *v1.MyCourseListReq) (res *v1.MyCourseListRes, err error) {
|
func (c *ControllerV1) MyCourseList(ctx context.Context, req *v1.MyCourseListReq) (res *v1.MyCourseListRes, err error) {
|
||||||
// 从JWT中间件解析出的用户ID
|
// 调用服务层处理业务逻辑
|
||||||
userId := contexts.GetUserId(ctx)
|
data, err := service.MyCourse().GetList(ctx, req)
|
||||||
if userId <= 0 {
|
if err != nil {
|
||||||
err = gerror.New("用户未登录")
|
return nil, err
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模拟数据 - 实际项目中应该从数据库查询
|
return data, nil
|
||||||
mockData := []*v1.MyCourseItem{
|
|
||||||
{
|
|
||||||
Id: 1,
|
|
||||||
Title: "Go语言基础教程",
|
|
||||||
Description: "从零开始学习Go语言,掌握基础语法和核心概念",
|
|
||||||
Cover: "https://example.com/covers/go-basic.jpg",
|
|
||||||
Instructor: "张老师",
|
|
||||||
Duration: 7200, // 2小时
|
|
||||||
Progress: 75,
|
|
||||||
Status: "learning",
|
|
||||||
EnrollTime: gtime.New("2024-01-15 10:30:00"),
|
|
||||||
LastStudyTime: gtime.New("2024-01-20 14:20:00"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id: 2,
|
|
||||||
Title: "Vue.js实战开发",
|
|
||||||
Description: "深入学习Vue.js框架,构建现代化前端应用",
|
|
||||||
Cover: "https://example.com/covers/vue-practice.jpg",
|
|
||||||
Instructor: "李老师",
|
|
||||||
Duration: 10800, // 3小时
|
|
||||||
Progress: 100,
|
|
||||||
Status: "completed",
|
|
||||||
EnrollTime: gtime.New("2024-01-10 09:15:00"),
|
|
||||||
LastStudyTime: gtime.New("2024-01-18 16:45:00"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id: 3,
|
|
||||||
Title: "MySQL数据库优化",
|
|
||||||
Description: "学习MySQL性能优化技巧和最佳实践",
|
|
||||||
Cover: "https://example.com/covers/mysql-optimization.jpg",
|
|
||||||
Instructor: "王老师",
|
|
||||||
Duration: 5400, // 1.5小时
|
|
||||||
Progress: 45,
|
|
||||||
Status: "learning",
|
|
||||||
EnrollTime: gtime.New("2024-01-20 14:00:00"),
|
|
||||||
LastStudyTime: gtime.New("2024-01-22 10:30:00"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id: 4,
|
|
||||||
Title: "Python数据分析",
|
|
||||||
Description: "使用Python进行数据分析和可视化",
|
|
||||||
Cover: "https://example.com/covers/python-analysis.jpg",
|
|
||||||
Instructor: "赵老师",
|
|
||||||
Duration: 9000, // 2.5小时
|
|
||||||
Progress: 100,
|
|
||||||
Status: "completed",
|
|
||||||
EnrollTime: gtime.New("2024-01-05 11:00:00"),
|
|
||||||
LastStudyTime: gtime.New("2024-01-12 15:30:00"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据状态筛选
|
|
||||||
var filteredData []*v1.MyCourseItem
|
|
||||||
if req.Status != "" {
|
|
||||||
for _, item := range mockData {
|
|
||||||
if item.Status == req.Status {
|
|
||||||
filteredData = append(filteredData, item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
filteredData = mockData
|
|
||||||
}
|
|
||||||
|
|
||||||
totalCount := len(filteredData)
|
|
||||||
|
|
||||||
// 分页处理
|
|
||||||
pageNum := req.Page
|
|
||||||
pageSize := req.PageSize
|
|
||||||
if pageNum <= 0 {
|
|
||||||
pageNum = 1
|
|
||||||
}
|
|
||||||
if pageSize <= 0 {
|
|
||||||
pageSize = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
start := (pageNum - 1) * pageSize
|
|
||||||
end := start + pageSize
|
|
||||||
|
|
||||||
var list []*v1.MyCourseItem
|
|
||||||
if start >= totalCount {
|
|
||||||
list = []*v1.MyCourseItem{}
|
|
||||||
} else {
|
|
||||||
if end > totalCount {
|
|
||||||
end = totalCount
|
|
||||||
}
|
|
||||||
list = filteredData[start:end]
|
|
||||||
}
|
|
||||||
|
|
||||||
res = &v1.MyCourseListRes{
|
|
||||||
List: list,
|
|
||||||
Total: totalCount,
|
|
||||||
Page: pageNum,
|
|
||||||
PageSize: pageSize,
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
_ "hotgo/internal/logic/common"
|
_ "hotgo/internal/logic/common"
|
||||||
_ "hotgo/internal/logic/hook"
|
_ "hotgo/internal/logic/hook"
|
||||||
_ "hotgo/internal/logic/middleware"
|
_ "hotgo/internal/logic/middleware"
|
||||||
|
_ "hotgo/internal/logic/mycourse"
|
||||||
_ "hotgo/internal/logic/pay"
|
_ "hotgo/internal/logic/pay"
|
||||||
_ "hotgo/internal/logic/sys"
|
_ "hotgo/internal/logic/sys"
|
||||||
_ "hotgo/internal/logic/tcpclient"
|
_ "hotgo/internal/logic/tcpclient"
|
||||||
|
129
server/internal/logic/mycourse/mycourse.go
Normal file
129
server/internal/logic/mycourse/mycourse.go
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package mycourse
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
v1 "hotgo/api/api/mycourse/v1"
|
||||||
|
"hotgo/internal/library/contexts"
|
||||||
|
"hotgo/internal/service"
|
||||||
|
|
||||||
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
|
"github.com/gogf/gf/v2/os/gtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type sMyCourse struct{}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
service.RegisterMyCourse(New())
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *sMyCourse {
|
||||||
|
return &sMyCourse{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetList 获取我的课程列表
|
||||||
|
func (s *sMyCourse) GetList(ctx context.Context, req *v1.MyCourseListReq) (res *v1.MyCourseListRes, err error) {
|
||||||
|
// 从JWT中间件解析出的用户ID
|
||||||
|
userId := contexts.GetUserId(ctx)
|
||||||
|
if userId <= 0 {
|
||||||
|
return nil, gerror.New("用户未登录")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟数据 - 实际项目中应该从数据库查询
|
||||||
|
// TODO: 后续可以替换为真实的数据库查询
|
||||||
|
mockData := []*v1.MyCourseItem{
|
||||||
|
{
|
||||||
|
Id: 1,
|
||||||
|
Title: "Go语言基础教程",
|
||||||
|
Description: "从零开始学习Go语言,掌握基础语法和核心概念",
|
||||||
|
Cover: "https://example.com/covers/go-basic.jpg",
|
||||||
|
Instructor: "张老师",
|
||||||
|
Duration: 7200, // 2小时
|
||||||
|
Progress: 75,
|
||||||
|
Status: "learning",
|
||||||
|
EnrollTime: gtime.New("2024-01-15 10:30:00"),
|
||||||
|
LastStudyTime: gtime.New("2024-01-20 14:20:00"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: 2,
|
||||||
|
Title: "Vue.js实战开发",
|
||||||
|
Description: "深入学习Vue.js框架,构建现代化前端应用",
|
||||||
|
Cover: "https://example.com/covers/vue-practice.jpg",
|
||||||
|
Instructor: "李老师",
|
||||||
|
Duration: 10800, // 3小时
|
||||||
|
Progress: 100,
|
||||||
|
Status: "completed",
|
||||||
|
EnrollTime: gtime.New("2024-01-10 09:15:00"),
|
||||||
|
LastStudyTime: gtime.New("2024-01-18 16:45:00"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: 3,
|
||||||
|
Title: "MySQL数据库优化",
|
||||||
|
Description: "学习MySQL性能优化技巧和最佳实践",
|
||||||
|
Cover: "https://example.com/covers/mysql-optimization.jpg",
|
||||||
|
Instructor: "王老师",
|
||||||
|
Duration: 5400, // 1.5小时
|
||||||
|
Progress: 45,
|
||||||
|
Status: "learning",
|
||||||
|
EnrollTime: gtime.New("2024-01-20 14:00:00"),
|
||||||
|
LastStudyTime: gtime.New("2024-01-22 10:30:00"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: 4,
|
||||||
|
Title: "Python数据分析",
|
||||||
|
Description: "使用Python进行数据分析和可视化",
|
||||||
|
Cover: "https://example.com/covers/python-analysis.jpg",
|
||||||
|
Instructor: "赵老师",
|
||||||
|
Duration: 9000, // 2.5小时
|
||||||
|
Progress: 100,
|
||||||
|
Status: "completed",
|
||||||
|
EnrollTime: gtime.New("2024-01-05 11:00:00"),
|
||||||
|
LastStudyTime: gtime.New("2024-01-12 15:30:00"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据状态筛选
|
||||||
|
var filteredData []*v1.MyCourseItem
|
||||||
|
if req.Status != "" {
|
||||||
|
for _, item := range mockData {
|
||||||
|
if item.Status == req.Status {
|
||||||
|
filteredData = append(filteredData, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filteredData = mockData
|
||||||
|
}
|
||||||
|
|
||||||
|
totalCount := len(filteredData)
|
||||||
|
|
||||||
|
// 分页处理
|
||||||
|
pageNum := req.Page
|
||||||
|
pageSize := req.PageSize
|
||||||
|
if pageNum <= 0 {
|
||||||
|
pageNum = 1
|
||||||
|
}
|
||||||
|
if pageSize <= 0 {
|
||||||
|
pageSize = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
start := (pageNum - 1) * pageSize
|
||||||
|
end := start + pageSize
|
||||||
|
|
||||||
|
var list []*v1.MyCourseItem
|
||||||
|
if start >= totalCount {
|
||||||
|
list = []*v1.MyCourseItem{}
|
||||||
|
} else {
|
||||||
|
if end > totalCount {
|
||||||
|
end = totalCount
|
||||||
|
}
|
||||||
|
list = filteredData[start:end]
|
||||||
|
}
|
||||||
|
|
||||||
|
res = &v1.MyCourseListRes{
|
||||||
|
List: list,
|
||||||
|
Total: totalCount,
|
||||||
|
Page: pageNum,
|
||||||
|
PageSize: pageSize,
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
@ -28,16 +28,19 @@ func Api(ctx context.Context, group *ghttp.RouterGroup) {
|
|||||||
)
|
)
|
||||||
group.Middleware(service.Middleware().ApiAuth)
|
group.Middleware(service.Middleware().ApiAuth)
|
||||||
group.Bind(
|
group.Bind(
|
||||||
member.NewV1(), // 管理员
|
member.NewV1(), // 管理员
|
||||||
mycourse.NewV1(), // 我的课程
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
group.Group(simple.RouterPrefix(ctx, consts.AppApi), func(group *ghttp.RouterGroup) {
|
group.Group(simple.RouterPrefix(ctx, consts.AppApi), func(group *ghttp.RouterGroup) {
|
||||||
group.Bind(
|
group.Bind(
|
||||||
users.NewV1(), // 前台用户
|
users.NewV1(), // 前台用户(登录注册等不需要认证的接口)
|
||||||
lesson.NewV1(), // 课程
|
lesson.NewV1(), // 课程(公开接口)
|
||||||
activity.NewV1(), // 活动
|
activity.NewV1(), // 活动(公开接口)
|
||||||
|
)
|
||||||
|
group.Middleware(service.Middleware().ApiAuth)
|
||||||
|
group.Bind(
|
||||||
|
mycourse.NewV1(), // 我的课程(需要用户认证)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
33
server/internal/service/mycourse.go
Normal file
33
server/internal/service/mycourse.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// ================================================================================
|
||||||
|
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||||
|
// You can delete these comments if you wish manually maintain this interface file.
|
||||||
|
// ================================================================================
|
||||||
|
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
v1 "hotgo/api/api/mycourse/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
IMyCourse interface {
|
||||||
|
// GetList 获取我的课程列表
|
||||||
|
GetList(ctx context.Context, req *v1.MyCourseListReq) (res *v1.MyCourseListRes, err error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
localMyCourse IMyCourse
|
||||||
|
)
|
||||||
|
|
||||||
|
func MyCourse() IMyCourse {
|
||||||
|
if localMyCourse == nil {
|
||||||
|
panic("implement not found for interface IMyCourse, forgot register?")
|
||||||
|
}
|
||||||
|
return localMyCourse
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterMyCourse(i IMyCourse) {
|
||||||
|
localMyCourse = i
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user