完成课程资源
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/model"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/util"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -31,46 +32,109 @@ func NewGetContentListLogic(ctx context.Context, cfg *config.Config, model model
|
||||
}
|
||||
|
||||
func (l *GetContentListLogic) GetContentList(req *types.GetContentListReq) (resp *types.GetContentListResp, err error) {
|
||||
// 1. 参数校验:确保课程ID有效
|
||||
// 1. 参数校验(增强校验,确保CourseId必填)
|
||||
if req.CourseId <= 0 {
|
||||
return nil, fmt.Errorf("参数错误:课程ID必须为正整数")
|
||||
}
|
||||
// ParentId 可选,允许为0(表示章节)或其他正数(表示小节),此处仅校验非负
|
||||
if req.ParentId < 0 {
|
||||
return nil, fmt.Errorf("参数错误:父级ID不能为负数")
|
||||
}
|
||||
|
||||
// 2. 调用 Model 层查询符合条件的内容列表
|
||||
// 假设 Model 层有查询方法:根据 course_id 和 parent_id 筛选,按 sort 排序
|
||||
// 若 Model 层无此方法,可构造 SQL:SELECT * FROM course_content WHERE course_id=? AND parent_id=? ORDER BY sort
|
||||
contentModels, err := l.model.FindByCourseAndParent(l.ctx,
|
||||
int64(req.CourseId), int64(req.ParentId))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询课程内容列表失败:%w", err)
|
||||
}
|
||||
|
||||
// 3. 转换模型数据为响应结构体(适配前端需要的格式)
|
||||
// 2. 区分查询场景:parentId=0 查树形结构(章节+子章节),否则查平级内容
|
||||
var contentList []types.CourseContent
|
||||
for _, modelItem := range contentModels {
|
||||
contentList = append(contentList, types.CourseContent{
|
||||
Id: int(modelItem.Id), // 数据库ID可能为int64,转换为int
|
||||
CourseId: int(modelItem.CourseId), // 课程ID转换
|
||||
ParentId: int(modelItem.ParentId), // 父级ID转换
|
||||
Title: modelItem.Title,
|
||||
// 若数据库中Content是sql.NullString,需转换为普通string(复用工具函数)
|
||||
Content: NullStringToString(modelItem.Content),
|
||||
Sort: int(modelItem.Sort),
|
||||
})
|
||||
if req.ParentId == 0 {
|
||||
// 场景1:查询所有章节(parentId=0)及其子章节
|
||||
contentList, err = l.queryTreeContent(req.CourseId)
|
||||
} else {
|
||||
// 场景2:查询指定父级的平级内容(兼容原有逻辑)
|
||||
contentList, err = l.queryFlatContent(req.CourseId, req.ParentId)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询课程内容失败:%w", err)
|
||||
}
|
||||
|
||||
// 4. 构造响应(包含空列表的情况,前端可正常处理)
|
||||
// 3. 构造响应
|
||||
resp = &types.GetContentListResp{
|
||||
BaseResp: types.BaseResp{
|
||||
Code: 0,
|
||||
Message: "查询课程内容列表成功",
|
||||
},
|
||||
Data: contentList, // 即使为空列表,也正常返回(避免前端处理null的麻烦)
|
||||
Data: contentList,
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// queryTreeContent 查询树形结构:章节(parentId=0)+ 子章节
|
||||
func (l *GetContentListLogic) queryTreeContent(courseId int) ([]types.CourseContent, error) {
|
||||
// 第一步:查询所有章节(parentId=0),按sort升序
|
||||
chapterModels, err := l.model.FindByCourseAndParent(l.ctx, int64(courseId), 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 第二步:遍历每个章节,查询对应的子章节(parentId=章节ID)
|
||||
var treeList []types.CourseContent
|
||||
for _, chapter := range chapterModels {
|
||||
// 转换章节为响应格式
|
||||
respChapter := types.CourseContent{
|
||||
Id: int(chapter.Id),
|
||||
CourseId: int(chapter.CourseId),
|
||||
ParentId: int(chapter.ParentId),
|
||||
Title: chapter.Title,
|
||||
Content: util.NullStringToString(chapter.Content),
|
||||
Sort: int(chapter.Sort),
|
||||
Children: []types.CourseContent{}, // 初始化子章节切片
|
||||
}
|
||||
|
||||
// 查询当前章节的子章节(parentId=章节ID)
|
||||
childModels, err := l.model.FindByCourseAndParent(l.ctx, int64(courseId), chapter.Id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询子章节失败(章节ID:%d):%w", chapter.Id, err)
|
||||
}
|
||||
|
||||
// 转换子章节为响应格式,添加到章节的Children字段
|
||||
for _, child := range childModels {
|
||||
respChild := types.CourseContent{
|
||||
Id: int(child.Id),
|
||||
CourseId: int(child.CourseId),
|
||||
ParentId: int(child.ParentId),
|
||||
Title: child.Title,
|
||||
Content: NullStringToString(child.Content),
|
||||
Sort: int(child.Sort),
|
||||
Children: []types.CourseContent{}, // 子章节暂无下级,默认空切片
|
||||
}
|
||||
respChapter.Children = append(respChapter.Children, respChild)
|
||||
}
|
||||
|
||||
// 添加章节到树形列表
|
||||
treeList = append(treeList, respChapter)
|
||||
}
|
||||
|
||||
return treeList, nil
|
||||
}
|
||||
|
||||
// queryFlatContent 查询平级内容(兼容原有逻辑:按courseId和parentId查指定层级)
|
||||
func (l *GetContentListLogic) queryFlatContent(courseId, parentId int) ([]types.CourseContent, error) {
|
||||
// 调用数据层查询平级内容
|
||||
contentModels, err := l.model.FindByCourseAndParent(l.ctx, int64(courseId), int64(parentId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 转换为响应格式
|
||||
var flatList []types.CourseContent
|
||||
for _, modelItem := range contentModels {
|
||||
flatList = append(flatList, types.CourseContent{
|
||||
Id: int(modelItem.Id),
|
||||
CourseId: int(modelItem.CourseId),
|
||||
ParentId: int(modelItem.ParentId),
|
||||
Title: modelItem.Title,
|
||||
Content: NullStringToString(modelItem.Content),
|
||||
Sort: int(modelItem.Sort),
|
||||
Children: []types.CourseContent{}, // 平级查询时子章节为空
|
||||
})
|
||||
}
|
||||
|
||||
return flatList, nil
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
package types
|
||||
|
||||
type AddContentReq struct {
|
||||
CourseId int `json:"course_id" form:"course_id"` // 课程ID,必填
|
||||
ParentId int `json:"parent_id" form:"parent_id"` // 父级ID,必填
|
||||
Title string `json:"title" form:"title"` // 标题,必填
|
||||
Content string `json:"content" form:"content"` // 内容详情,可选
|
||||
Sort int `json:"sort" form:"sort"` // 排序,可选
|
||||
CourseId int `json:"course_id"` // 课程ID,必填
|
||||
ParentId int `json:"parent_id"` // 父级ID,必填
|
||||
Title string `json:"title"` // 标题,必填
|
||||
Content string `json:"content"` // 内容详情,可选
|
||||
Sort int `json:"sort"` // 排序,可选
|
||||
}
|
||||
|
||||
type AddContentResp struct {
|
||||
@@ -23,12 +23,13 @@ type BaseResp struct {
|
||||
}
|
||||
|
||||
type CourseContent struct {
|
||||
Id int `json:"id"` // 内容ID(主键)
|
||||
CourseId int `json:"course_id"` // 关联课程ID
|
||||
ParentId int `json:"parent_id"` // 父级ID(0表示章节,>0表示小节)
|
||||
Title string `json:"title"` // 章节/小节标题
|
||||
Content string `json:"content"` // 内容详情
|
||||
Sort int `json:"sort"` // 排序
|
||||
Id int `json:"id"` // 内容ID(主键)
|
||||
CourseId int `json:"course_id"` // 关联课程ID
|
||||
ParentId int `json:"parent_id"` // 父级ID(0表示章节,>0表示小节)
|
||||
Title string `json:"title"` // 章节/小节标题
|
||||
Content string `json:"content"` // 内容详情
|
||||
Sort int `json:"sort"` // 排序
|
||||
Children []CourseContent `json:"children"` // 子章节列表(仅章节有值)
|
||||
}
|
||||
|
||||
type DeleteContentReq struct {
|
||||
@@ -40,8 +41,8 @@ type DeleteContentResp struct {
|
||||
}
|
||||
|
||||
type GetContentListReq struct {
|
||||
CourseId int `json:"course_id" form:"course_id"` // 课程ID,必填
|
||||
ParentId int `json:"parent_id" form:"parent_id"` // 父级ID,可选,0表示获取章节
|
||||
CourseId int `json:"course_id"` // 课程ID,必填
|
||||
ParentId int `json:"parent_id"` // 父级ID,可选,0表示获取章节
|
||||
}
|
||||
|
||||
type GetContentListResp struct {
|
||||
@@ -59,10 +60,10 @@ type GetContentResp struct {
|
||||
}
|
||||
|
||||
type UpdateContentReq struct {
|
||||
Id int `json:"id" form:"id"` // 内容ID,必填
|
||||
Title string `json:"title" form:"title"` // 标题,可选
|
||||
Content string `json:"content" form:"content"` // 内容详情,可选
|
||||
Sort int `json:"sort" form:"sort"` // 排序,可选
|
||||
Id int `json:"id" ` // 内容ID,必填
|
||||
Title string `json:"title" ` // 标题,可选
|
||||
Content string `json:"content" ` // 内容详情,可选
|
||||
Sort int `json:"sort" ` // 排序,可选
|
||||
}
|
||||
|
||||
type UpdateContentResp struct {
|
||||
|
||||
Reference in New Issue
Block a user