From d23299ccac31e9b288f65071983497a5d86394e6 Mon Sep 17 00:00:00 2001 From: mayiming <1627832236@qq.com> Date: Sun, 2 Nov 2025 09:37:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=AF=BE=E7=A8=8B=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=AE=9E=E7=8E=B0=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/model/coursecontentmodel_gen.go | 13 ++++ .../course_file/createcoursefilelogic.go | 52 ++++++++++++- .../course_file/deletecoursefilelogic.go | 31 +++++++- .../logic/course_file/getcoursefilelogic.go | 31 +++++++- .../course_file/updatecoursefilelogic.go | 76 ++++++++++++++++++- 5 files changed, 195 insertions(+), 8 deletions(-) diff --git a/server/internal/course_content/internal/model/coursecontentmodel_gen.go b/server/internal/course_content/internal/model/coursecontentmodel_gen.go index d451e28b..5bba134b 100644 --- a/server/internal/course_content/internal/model/coursecontentmodel_gen.go +++ b/server/internal/course_content/internal/model/coursecontentmodel_gen.go @@ -28,6 +28,7 @@ type ( FindOne(ctx context.Context, id int64) (*CourseContent, error) Update(ctx context.Context, data *CourseContent) error Delete(ctx context.Context, id int64) error + FindByCourseAndParent(ctx context.Context, courseId, parentId int64) ([]*CourseContent, error) } defaultCourseContentModel struct { @@ -84,6 +85,18 @@ func (m *defaultCourseContentModel) Update(ctx context.Context, data *CourseCont return err } +func (m *defaultCourseContentModel) FindByCourseAndParent(ctx context.Context, courseId, parentId int64) ([]*CourseContent, error) { + // 构造查询语句:按course_id和parent_id筛选,按sort升序排序 + query := fmt.Sprintf("select %s from %s where `course_id` = ? and `parent_id` = ? order by `sort` asc", courseContentRows, m.table) + var contents []*CourseContent + // 执行查询(sqlx.QueryRowsCtx会自动将结果映射到结构体切片) + err := m.conn.QueryRowsCtx(ctx, &contents, query, courseId, parentId) + if err != nil { + return nil, err + } + return contents, nil +} + func (m *defaultCourseContentModel) tableName() string { return m.table } diff --git a/server/internal/course_file/internal/logic/course_file/createcoursefilelogic.go b/server/internal/course_file/internal/logic/course_file/createcoursefilelogic.go index f8be99d0..66c61b9f 100644 --- a/server/internal/course_file/internal/logic/course_file/createcoursefilelogic.go +++ b/server/internal/course_file/internal/logic/course_file/createcoursefilelogic.go @@ -5,6 +5,7 @@ package course_file import ( "context" + "fmt" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/model" @@ -30,7 +31,54 @@ func NewCreateCourseFileLogic(ctx context.Context, cfg *config.Config, model mod } func (l *CreateCourseFileLogic) CreateCourseFile(req *types.CreateCourseFileReq) (resp *types.CreateCourseFileResp, err error) { - // todo: add your logic here and delete this line + // 1. 参数校验(补充validate标签之外的业务校验) + if req.ContentId <= 0 { + return nil, fmt.Errorf("参数错误:关联的内容ID必须为正整数") + } + if len(req.Title) == 0 { + return nil, fmt.Errorf("参数错误:文件标题不能为空") + } + if len(req.Title) > 255 { + return nil, fmt.Errorf("参数错误:文件标题长度不能超过255字符") + } + if len(req.FileType) == 0 { + return nil, fmt.Errorf("参数错误:文件类型不能为空") + } + if len(req.FileType) > 30 { + return nil, fmt.Errorf("参数错误:文件类型长度不能超过30字符") + } + if len(req.FileUrl) == 0 { + return nil, fmt.Errorf("参数错误:文件URL不能为空") + } + if len(req.FileUrl) > 255 { + return nil, fmt.Errorf("参数错误:文件URL长度不能超过255字符") + } - return + // 2. 转换请求参数为Model层结构体(适配数据库字段类型) + courseFile := &model.CourseFile{ + ContentId: int64(req.ContentId), // 假设Model层ContentId为int64类型 + Title: req.Title, + FileType: req.FileType, + FileUrl: req.FileUrl, + } + + // 3. 调用Model层插入数据 + result, err := l.model.Insert(l.ctx, courseFile) + if err != nil { + return nil, fmt.Errorf("创建课程文件失败:%w", err) + } + + // 4. 获取新增记录的ID(从插入结果中提取) + newId, err := result.LastInsertId() + if err != nil { + return nil, fmt.Errorf("获取新增文件ID失败:%w", err) + } + + // 5. 构造响应 + resp = &types.CreateCourseFileResp{ + Id: int(newId), // 转换int64为int(适配响应结构体) + Message: "课程文件创建成功", + } + + return resp, nil } diff --git a/server/internal/course_file/internal/logic/course_file/deletecoursefilelogic.go b/server/internal/course_file/internal/logic/course_file/deletecoursefilelogic.go index 00c13ba7..993d0741 100644 --- a/server/internal/course_file/internal/logic/course_file/deletecoursefilelogic.go +++ b/server/internal/course_file/internal/logic/course_file/deletecoursefilelogic.go @@ -5,10 +5,12 @@ package course_file import ( "context" + "fmt" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/model" "github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/types" + "github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/core/logx" ) @@ -30,7 +32,32 @@ func NewDeleteCourseFileLogic(ctx context.Context, cfg *config.Config, model mod } func (l *DeleteCourseFileLogic) DeleteCourseFile(req *types.DeleteCourseFileReq) (resp *types.DeleteCourseFileResp, err error) { - // todo: add your logic here and delete this line + // 1. 参数校验:确保文件ID为正整数 + if req.Id <= 0 { + return nil, fmt.Errorf("参数错误:文件ID必须为正整数") + } - return + // 2. 检查文件是否存在(避免删除不存在的记录) + fileId := int64(req.Id) + _, err = l.model.FindOne(l.ctx, fileId) + if err != nil { + if err == sqlx.ErrNotFound { + return nil, fmt.Errorf("删除失败:该文件不存在或已被删除") + } + // 其他查询错误(如数据库连接问题) + return nil, fmt.Errorf("查询文件信息失败:%w", err) + } + + // 3. 调用Model层执行删除操作 + err = l.model.Delete(l.ctx, fileId) + if err != nil { + return nil, fmt.Errorf("删除课程文件失败:%w", err) + } + + // 4. 构造成功响应 + resp = &types.DeleteCourseFileResp{ + Message: "课程文件删除成功", + } + + return resp, nil } diff --git a/server/internal/course_file/internal/logic/course_file/getcoursefilelogic.go b/server/internal/course_file/internal/logic/course_file/getcoursefilelogic.go index 5c48bc9d..ffed3d28 100644 --- a/server/internal/course_file/internal/logic/course_file/getcoursefilelogic.go +++ b/server/internal/course_file/internal/logic/course_file/getcoursefilelogic.go @@ -5,6 +5,7 @@ package course_file import ( "context" + "fmt" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/model" @@ -30,7 +31,33 @@ func NewGetCourseFileLogic(ctx context.Context, cfg *config.Config, model model. } func (l *GetCourseFileLogic) GetCourseFile(req *types.GetCourseFileReq) (resp *types.GetCourseFileResp, err error) { - // todo: add your logic here and delete this line + // 1. 参数校验:确保文件ID为正整数 + if req.Id <= 0 { + return nil, fmt.Errorf("参数错误:文件ID必须为正整数") + } - return + // 2. 调用Model层查询文件详情 + fileId := int64(req.Id) + fileModel, err := l.model.FindOne(l.ctx, fileId) + if err != nil { + if err == model.ErrNotFound { // 匹配Model层自定义的"记录不存在"错误 + return nil, fmt.Errorf("查询失败:该课程文件不存在或已被删除") + } + // 其他查询错误(如数据库异常) + return nil, fmt.Errorf("查询课程文件失败:%w", err) + } + + // 3. 转换Model数据为响应结构体(含时间格式化) + resp = &types.GetCourseFileResp{ + Id: int(fileModel.Id), // 适配int64→int + ContentId: int(fileModel.ContentId), // 适配int64→int + Title: fileModel.Title, + FileType: fileModel.FileType, + FileUrl: fileModel.FileUrl, + // 时间格式化:默认转为 "2006-01-02 15:04:05" 格式(可根据需求调整) + CreateTime: fileModel.CreateTime.Format("2006-01-02 15:04:05"), + UpdateTime: fileModel.UpdateTime.Format("2006-01-02 15:04:05"), + } + + return resp, nil } diff --git a/server/internal/course_file/internal/logic/course_file/updatecoursefilelogic.go b/server/internal/course_file/internal/logic/course_file/updatecoursefilelogic.go index ff6e5626..b56797f4 100644 --- a/server/internal/course_file/internal/logic/course_file/updatecoursefilelogic.go +++ b/server/internal/course_file/internal/logic/course_file/updatecoursefilelogic.go @@ -5,10 +5,12 @@ package course_file import ( "context" + "fmt" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/model" "github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/types" + "github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/core/logx" ) @@ -30,7 +32,77 @@ func NewUpdateCourseFileLogic(ctx context.Context, cfg *config.Config, model mod } func (l *UpdateCourseFileLogic) UpdateCourseFile(req *types.UpdateCourseFileReq) (resp *types.UpdateCourseFileResp, err error) { - // todo: add your logic here and delete this line + // 1. 校验必填参数(文件ID) + if req.Id <= 0 { + return nil, fmt.Errorf("参数错误:文件ID必须为正整数") + } + fileId := int64(req.Id) - return + // 2. 校验可选参数(仅当参数存在时校验) + if req.ContentId > 0 { // 允许不传递ContentId,传递时必须为正整数 + if req.ContentId <= 0 { + return nil, fmt.Errorf("参数错误:关联的内容ID必须为正整数") + } + } + if req.Title != "" { // 标题非空时校验长度 + if len(req.Title) > 255 { + return nil, fmt.Errorf("参数错误:文件标题长度不能超过255字符") + } + } + if req.FileType != "" { // 文件类型非空时校验长度 + if len(req.FileType) > 30 { + return nil, fmt.Errorf("参数错误:文件类型长度不能超过30字符") + } + } + if req.FileUrl != "" { // 文件URL非空时校验长度 + if len(req.FileUrl) > 255 { + return nil, fmt.Errorf("参数错误:文件URL长度不能超过255字符") + } + } + + // 3. 检查文件是否存在(避免更新不存在的记录) + existingFile, err := l.model.FindOne(l.ctx, fileId) + if err != nil { + if err == model.ErrNotFound || err == sqlx.ErrNotFound { + return nil, fmt.Errorf("更新失败:该文件不存在或已被删除") + } + return nil, fmt.Errorf("查询文件信息失败:%w", err) + } + + // 4. 构造更新数据(仅更新请求中提供的字段,未提供的保留原数据) + updateData := &model.CourseFile{ + Id: existingFile.Id, // 必须保留原ID(更新条件) + ContentId: existingFile.ContentId, // 默认保留原关联ID + Title: existingFile.Title, // 默认保留原标题 + FileType: existingFile.FileType, // 默认保留原文件类型 + FileUrl: existingFile.FileUrl, // 默认保留原文件URL + // 若有时间字段,可在此更新UpdateTime(如:UpdateTime: time.Now()) + } + + // 覆盖请求中提供的字段 + if req.ContentId > 0 { + updateData.ContentId = int64(req.ContentId) + } + if req.Title != "" { + updateData.Title = req.Title + } + if req.FileType != "" { + updateData.FileType = req.FileType + } + if req.FileUrl != "" { + updateData.FileUrl = req.FileUrl + } + + // 5. 调用Model层执行更新 + err = l.model.Update(l.ctx, updateData) + if err != nil { + return nil, fmt.Errorf("更新课程文件失败:%w", err) + } + + // 6. 构造成功响应 + resp = &types.UpdateCourseFileResp{ + Message: "课程文件更新成功", + } + + return resp, nil }