完成课程文件实现层
This commit is contained in:
@@ -28,6 +28,7 @@ type (
|
|||||||
FindOne(ctx context.Context, id int64) (*CourseContent, error)
|
FindOne(ctx context.Context, id int64) (*CourseContent, error)
|
||||||
Update(ctx context.Context, data *CourseContent) error
|
Update(ctx context.Context, data *CourseContent) error
|
||||||
Delete(ctx context.Context, id int64) error
|
Delete(ctx context.Context, id int64) error
|
||||||
|
FindByCourseAndParent(ctx context.Context, courseId, parentId int64) ([]*CourseContent, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultCourseContentModel struct {
|
defaultCourseContentModel struct {
|
||||||
@@ -84,6 +85,18 @@ func (m *defaultCourseContentModel) Update(ctx context.Context, data *CourseCont
|
|||||||
return err
|
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 {
|
func (m *defaultCourseContentModel) tableName() string {
|
||||||
return m.table
|
return m.table
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package course_file
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/JACKYMYPERSON/hldrCenter/config"
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
"github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/model"
|
"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) {
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ package course_file
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/JACKYMYPERSON/hldrCenter/config"
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
"github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/model"
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/model"
|
||||||
"github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/types"
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"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) {
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package course_file
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/JACKYMYPERSON/hldrCenter/config"
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
"github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/model"
|
"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) {
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ package course_file
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/JACKYMYPERSON/hldrCenter/config"
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
"github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/model"
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/model"
|
||||||
"github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/types"
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_file/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"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) {
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user