添加course的业务层和实现层
This commit is contained in:
50
server/internal/course/handler/course/createcoursehandler.go
Normal file
50
server/internal/course/handler/course/createcoursehandler.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/logic/course"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/model"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateCourseHandler(cfg *config.Config) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.CreateCourseReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mysqlCfg := cfg.MySQL
|
||||||
|
dsn := fmt.Sprintf(
|
||||||
|
"%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=true&loc=Local",
|
||||||
|
mysqlCfg.Username,
|
||||||
|
mysqlCfg.Password,
|
||||||
|
mysqlCfg.Host,
|
||||||
|
mysqlCfg.Port,
|
||||||
|
mysqlCfg.Database,
|
||||||
|
mysqlCfg.Charset,
|
||||||
|
)
|
||||||
|
fmt.Println("接收到articlePost请求")
|
||||||
|
|
||||||
|
conn := sqlx.NewSqlConn("mysql", dsn)
|
||||||
|
|
||||||
|
baseModel := model.NewCourseModel(conn)
|
||||||
|
|
||||||
|
l := course.NewCreateCourseLogic(r.Context(), cfg, baseModel)
|
||||||
|
resp, err := l.CreateCourse(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
61
server/internal/course/handler/course/deletecoursehandler.go
Normal file
61
server/internal/course/handler/course/deletecoursehandler.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/logic/course"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/model"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DeleteCourseHandler(cfg *config.Config) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.DeleteCourseReq
|
||||||
|
pathParts := strings.Split(r.URL.Path, "/")
|
||||||
|
if len(pathParts) < 3 { // 确保路径格式正确
|
||||||
|
httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid path format"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
idStr := pathParts[3]
|
||||||
|
id, err := strconv.ParseInt(idStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid meeting ID"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("idStr:", idStr)
|
||||||
|
req.Id = id
|
||||||
|
|
||||||
|
mysqlCfg := cfg.MySQL
|
||||||
|
dsn := fmt.Sprintf(
|
||||||
|
"%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=true&loc=Local",
|
||||||
|
mysqlCfg.Username,
|
||||||
|
mysqlCfg.Password,
|
||||||
|
mysqlCfg.Host,
|
||||||
|
mysqlCfg.Port,
|
||||||
|
mysqlCfg.Database,
|
||||||
|
mysqlCfg.Charset,
|
||||||
|
)
|
||||||
|
fmt.Println("接收到articlePost请求")
|
||||||
|
|
||||||
|
conn := sqlx.NewSqlConn("mysql", dsn)
|
||||||
|
|
||||||
|
baseModel := model.NewCourseModel(conn)
|
||||||
|
|
||||||
|
l := course.NewDeleteCourseLogic(r.Context(), cfg, baseModel)
|
||||||
|
resp, err := l.DeleteCourse(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
61
server/internal/course/handler/course/getcoursehandler.go
Normal file
61
server/internal/course/handler/course/getcoursehandler.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/logic/course"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/model"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetCourseHandler(cfg *config.Config) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.GetCourseReq
|
||||||
|
pathParts := strings.Split(r.URL.Path, "/")
|
||||||
|
if len(pathParts) < 3 { // 确保路径格式正确
|
||||||
|
httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid path format"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
idStr := pathParts[3]
|
||||||
|
id, err := strconv.ParseInt(idStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid meeting ID"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("idStr:", idStr)
|
||||||
|
req.Id = id
|
||||||
|
|
||||||
|
mysqlCfg := cfg.MySQL
|
||||||
|
dsn := fmt.Sprintf(
|
||||||
|
"%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=true&loc=Local",
|
||||||
|
mysqlCfg.Username,
|
||||||
|
mysqlCfg.Password,
|
||||||
|
mysqlCfg.Host,
|
||||||
|
mysqlCfg.Port,
|
||||||
|
mysqlCfg.Database,
|
||||||
|
mysqlCfg.Charset,
|
||||||
|
)
|
||||||
|
fmt.Println("接收到articlePost请求")
|
||||||
|
|
||||||
|
conn := sqlx.NewSqlConn("mysql", dsn)
|
||||||
|
|
||||||
|
baseModel := model.NewCourseModel(conn)
|
||||||
|
|
||||||
|
l := course.NewGetCourseLogic(r.Context(), cfg, baseModel)
|
||||||
|
resp, err := l.GetCourse(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
50
server/internal/course/handler/course/listcoursehandler.go
Normal file
50
server/internal/course/handler/course/listcoursehandler.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/logic/course"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/model"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ListCourseHandler(cfg *config.Config) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.ListCourseReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mysqlCfg := cfg.MySQL
|
||||||
|
dsn := fmt.Sprintf(
|
||||||
|
"%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=true&loc=Local",
|
||||||
|
mysqlCfg.Username,
|
||||||
|
mysqlCfg.Password,
|
||||||
|
mysqlCfg.Host,
|
||||||
|
mysqlCfg.Port,
|
||||||
|
mysqlCfg.Database,
|
||||||
|
mysqlCfg.Charset,
|
||||||
|
)
|
||||||
|
fmt.Println("接收到articlePost请求")
|
||||||
|
|
||||||
|
conn := sqlx.NewSqlConn("mysql", dsn)
|
||||||
|
|
||||||
|
baseModel := model.NewCourseModel(conn)
|
||||||
|
|
||||||
|
l := course.NewListCourseLogic(r.Context(), cfg, baseModel)
|
||||||
|
resp, err := l.ListCourse(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
50
server/internal/course/handler/course/updatecoursehandler.go
Normal file
50
server/internal/course/handler/course/updatecoursehandler.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/logic/course"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/model"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UpdateCourseHandler(cfg *config.Config) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.UpdateCourseReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mysqlCfg := cfg.MySQL
|
||||||
|
dsn := fmt.Sprintf(
|
||||||
|
"%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=true&loc=Local",
|
||||||
|
mysqlCfg.Username,
|
||||||
|
mysqlCfg.Password,
|
||||||
|
mysqlCfg.Host,
|
||||||
|
mysqlCfg.Port,
|
||||||
|
mysqlCfg.Database,
|
||||||
|
mysqlCfg.Charset,
|
||||||
|
)
|
||||||
|
fmt.Println("接收到articlePost请求")
|
||||||
|
|
||||||
|
conn := sqlx.NewSqlConn("mysql", dsn)
|
||||||
|
|
||||||
|
baseModel := model.NewCourseModel(conn)
|
||||||
|
|
||||||
|
l := course.NewUpdateCourseLogic(r.Context(), cfg, baseModel)
|
||||||
|
resp, err := l.UpdateCourse(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/model"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/types"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateCourseLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
cfg *config.Config
|
||||||
|
model model.CourseModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCreateCourseLogic(ctx context.Context, cfg *config.Config, model model.CourseModel) *CreateCourseLogic {
|
||||||
|
return &CreateCourseLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
cfg: cfg,
|
||||||
|
model: model,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *CreateCourseLogic) CreateCourse(req *types.CreateCourseReq) (resp *types.BaseResp, err error) {
|
||||||
|
// 初始化验证器
|
||||||
|
validate := validator.New()
|
||||||
|
|
||||||
|
// 验证请求参数
|
||||||
|
if err := validate.Struct(req); err != nil {
|
||||||
|
// 收集所有验证错误
|
||||||
|
var errMsg string
|
||||||
|
for _, e := range err.(validator.ValidationErrors) {
|
||||||
|
errMsg += fmt.Sprintf("参数 %s 验证失败: %s; ", e.Field(), e.Tag())
|
||||||
|
}
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 400, // 非0表示失败
|
||||||
|
Msg: "参数验证失败: " + errMsg,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造课程数据对象
|
||||||
|
course := &model.Course{
|
||||||
|
Title: req.Title,
|
||||||
|
Subtitle: req.Subtitle,
|
||||||
|
CoverUrl: req.CoverUrl,
|
||||||
|
Intro: stringToNullString(req.Intro),
|
||||||
|
Status: int64(req.Status),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用模型层插入数据
|
||||||
|
result, err := l.model.Insert(l.ctx, course)
|
||||||
|
if err != nil {
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 500, // 非0表示失败
|
||||||
|
Msg: "创建课程失败: " + err.Error(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取插入的课程ID
|
||||||
|
courseId, err := result.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 500, // 非0表示失败
|
||||||
|
Msg: "获取课程ID失败: " + err.Error(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回成功响应(0表示成功)
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 0,
|
||||||
|
Msg: fmt.Sprintf("课程创建成功,ID: %d", courseId),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringToNullString(s string) sql.NullString {
|
||||||
|
if s == "" {
|
||||||
|
return sql.NullString{Valid: false}
|
||||||
|
}
|
||||||
|
return sql.NullString{
|
||||||
|
String: s,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/model"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/types"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeleteCourseLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
cfg *config.Config
|
||||||
|
model model.CourseModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDeleteCourseLogic(ctx context.Context, cfg *config.Config, model model.CourseModel) *DeleteCourseLogic {
|
||||||
|
return &DeleteCourseLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
cfg: cfg,
|
||||||
|
model: model,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DeleteCourseLogic) DeleteCourse(req *types.DeleteCourseReq) (resp *types.BaseResp, err error) {
|
||||||
|
// 1. 参数验证
|
||||||
|
validate := validator.New()
|
||||||
|
if err := validate.Struct(req); err != nil {
|
||||||
|
var errMsg string
|
||||||
|
for _, e := range err.(validator.ValidationErrors) {
|
||||||
|
errMsg += fmt.Sprintf("参数 %s 验证失败: %s; ", e.Field(), e.Tag())
|
||||||
|
}
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 400,
|
||||||
|
Msg: "参数验证失败: " + errMsg,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 复用FindOne方法检查课程是否存在
|
||||||
|
_, err = l.model.FindOne(l.ctx, req.Id)
|
||||||
|
if err != nil {
|
||||||
|
if err == model.ErrNotFound { // 注意:这里需要匹配你实际的ErrNotFound定义
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 404,
|
||||||
|
Msg: fmt.Sprintf("课程ID=%d不存在", req.Id),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
// 其他查询错误
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 500,
|
||||||
|
Msg: "查询课程信息失败: " + err.Error(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 执行逻辑删除(更新is_delete为1)
|
||||||
|
err = l.model.Delete(l.ctx, req.Id)
|
||||||
|
if err != nil {
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 500,
|
||||||
|
Msg: "删除课程失败: " + err.Error(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 返回成功响应
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 0,
|
||||||
|
Msg: fmt.Sprintf("课程ID=%d删除成功", req.Id),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/model"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/types"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetCourseLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
cfg *config.Config
|
||||||
|
model model.CourseModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetCourseLogic(ctx context.Context, cfg *config.Config, model model.CourseModel) *GetCourseLogic {
|
||||||
|
return &GetCourseLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
cfg: cfg,
|
||||||
|
model: model,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetCourseLogic) GetCourse(req *types.GetCourseReq) (resp *types.CourseResp, err error) {
|
||||||
|
// 1. 参数验证(匹配结构体中的validate标签)
|
||||||
|
validate := validator.New()
|
||||||
|
if err := validate.Struct(req); err != nil {
|
||||||
|
var errMsg string
|
||||||
|
for _, e := range err.(validator.ValidationErrors) {
|
||||||
|
errMsg += fmt.Sprintf("参数 %s 验证失败: %s; ", e.Field(), e.Tag())
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("参数验证失败: %s", errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 调用模型层查询课程
|
||||||
|
course, err := l.model.FindOne(l.ctx, req.Id)
|
||||||
|
if err != nil {
|
||||||
|
if err == model.ErrNotFound {
|
||||||
|
return nil, fmt.Errorf("课程不存在")
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("查询课程失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 转换模型数据到响应结构体
|
||||||
|
resp = &types.CourseResp{
|
||||||
|
Id: course.Id,
|
||||||
|
Title: course.Title,
|
||||||
|
Subtitle: course.Subtitle,
|
||||||
|
CoverUrl: course.CoverUrl,
|
||||||
|
Intro: nullStringToString(course.Intro),
|
||||||
|
Status: int8(course.Status),
|
||||||
|
CreateTime: formatTime(course.CreateTime),
|
||||||
|
UpdateTime: formatTime(course.UpdateTime),
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:将sql.NullString转换为string(处理数据库NULL值)
|
||||||
|
func nullStringToString(ns sql.NullString) string {
|
||||||
|
if ns.Valid {
|
||||||
|
return ns.String
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:格式化时间为字符串(处理可能的零值时间)
|
||||||
|
func formatTime(t time.Time) string {
|
||||||
|
if t.IsZero() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return t.Format("2006-01-02 15:04:05")
|
||||||
|
}
|
||||||
107
server/internal/course/internal/logic/course/listcourselogic.go
Normal file
107
server/internal/course/internal/logic/course/listcourselogic.go
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/model"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ListCourseLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
cfg *config.Config
|
||||||
|
model model.CourseModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewListCourseLogic(ctx context.Context, cfg *config.Config, model model.CourseModel) *ListCourseLogic {
|
||||||
|
return &ListCourseLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
cfg: cfg,
|
||||||
|
model: model,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *ListCourseLogic) ListCourse(req *types.ListCourseReq) (resp *types.ListCourseResp, err error) {
|
||||||
|
// 1. 参数验证与默认值处理
|
||||||
|
if err := validateListCourseReq(req); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理分页默认值(根据结构体tag的default定义)
|
||||||
|
page := req.Page
|
||||||
|
size := req.Size
|
||||||
|
if page <= 0 {
|
||||||
|
page = 1 // 默认第一页
|
||||||
|
}
|
||||||
|
if size <= 0 {
|
||||||
|
size = 10 // 默认每页10条
|
||||||
|
}
|
||||||
|
offset := (page - 1) * size
|
||||||
|
|
||||||
|
// 2. 构建查询条件
|
||||||
|
filter := model.CourseFilter{
|
||||||
|
Status: req.Status,
|
||||||
|
Keyword: req.Keyword,
|
||||||
|
Offset: offset,
|
||||||
|
Limit: size,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 查询课程列表数据
|
||||||
|
courses, err := l.model.List(l.ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("查询课程列表失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 查询符合条件的总条数
|
||||||
|
total, err := l.model.Count(l.ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("查询课程总数失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 转换数据格式(model -> types)
|
||||||
|
var courseList []types.CourseResp
|
||||||
|
for _, course := range courses {
|
||||||
|
courseList = append(courseList, types.CourseResp{
|
||||||
|
Id: course.Id,
|
||||||
|
Title: course.Title,
|
||||||
|
Subtitle: course.Subtitle,
|
||||||
|
CoverUrl: course.CoverUrl,
|
||||||
|
Intro: nullStringToString(course.Intro), // 包含简介信息
|
||||||
|
Status: int8(course.Status),
|
||||||
|
CreateTime: formatTime(course.CreateTime),
|
||||||
|
UpdateTime: formatTime(course.UpdateTime), // 包含更新时间
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 组装响应数据
|
||||||
|
resp = &types.ListCourseResp{
|
||||||
|
Total: total,
|
||||||
|
List: courseList,
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参数验证函数
|
||||||
|
func validateListCourseReq(req *types.ListCourseReq) error {
|
||||||
|
// 自定义验证规则:页码和每页数量不能为负数
|
||||||
|
if req.Page < 0 {
|
||||||
|
return fmt.Errorf("页码不能为负数")
|
||||||
|
}
|
||||||
|
if req.Size < 0 {
|
||||||
|
return fmt.Errorf("每页数量不能为负数")
|
||||||
|
}
|
||||||
|
// 状态值验证(根据业务实际允许的状态值调整)
|
||||||
|
if req.Status < 0 && req.Status != -1 { // 假设-1表示不筛选状态
|
||||||
|
return fmt.Errorf("无效的状态值")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/model"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course/internal/types"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateCourseLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
cfg *config.Config
|
||||||
|
model model.CourseModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUpdateCourseLogic(ctx context.Context, cfg *config.Config, model model.CourseModel) *UpdateCourseLogic {
|
||||||
|
return &UpdateCourseLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
cfg: cfg,
|
||||||
|
model: model,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *UpdateCourseLogic) UpdateCourse(req *types.UpdateCourseReq) (resp *types.BaseResp, err error) {
|
||||||
|
// 1. 参数验证
|
||||||
|
validate := validator.New()
|
||||||
|
if err := validate.Struct(req); err != nil {
|
||||||
|
var errMsg string
|
||||||
|
for _, e := range err.(validator.ValidationErrors) {
|
||||||
|
errMsg += fmt.Sprintf("参数 %s 验证失败: %s; ", e.Field(), e.Tag())
|
||||||
|
}
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 400,
|
||||||
|
Msg: "参数验证失败: " + errMsg,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查课程是否存在
|
||||||
|
existingCourse, err := l.model.FindOne(l.ctx, req.Id)
|
||||||
|
if err != nil {
|
||||||
|
if err == model.ErrNotFound {
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 404,
|
||||||
|
Msg: fmt.Sprintf("课程ID=%d不存在", req.Id),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 500,
|
||||||
|
Msg: "查询课程信息失败: " + err.Error(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 构造更新数据(保留原有字段,仅更新请求中提供的字段)
|
||||||
|
updatedCourse := &model.Course{
|
||||||
|
Id: req.Id, // 必须指定更新的课程ID
|
||||||
|
Title: req.Title, // 标题(如果为空会覆盖原有值,根据业务需求调整)
|
||||||
|
Subtitle: req.Subtitle, // 副标题
|
||||||
|
CoverUrl: req.CoverUrl, // 封面图URL
|
||||||
|
Intro: stringToNullString(req.Intro), // 课程简介
|
||||||
|
Status: int64(req.Status), // 课程状态
|
||||||
|
CreateTime: existingCourse.CreateTime, // 保留原始创建时间
|
||||||
|
UpdateTime: existingCourse.UpdateTime, // 可由数据库自动更新,这里暂用原有值
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 执行更新操作
|
||||||
|
err = l.model.Update(l.ctx, updatedCourse)
|
||||||
|
if err != nil {
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 500,
|
||||||
|
Msg: "更新课程失败: " + err.Error(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 返回成功响应
|
||||||
|
return &types.BaseResp{
|
||||||
|
Code: 0,
|
||||||
|
Msg: fmt.Sprintf("课程ID=%d更新成功", req.Id),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
29
server/internal/course/internal/model/coursemodel.go
Normal file
29
server/internal/course/internal/model/coursemodel.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
|
||||||
|
var _ CourseModel = (*customCourseModel)(nil)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// CourseModel is an interface to be customized, add more methods here,
|
||||||
|
// and implement the added methods in customCourseModel.
|
||||||
|
CourseModel interface {
|
||||||
|
courseModel
|
||||||
|
withSession(session sqlx.Session) CourseModel
|
||||||
|
}
|
||||||
|
|
||||||
|
customCourseModel struct {
|
||||||
|
*defaultCourseModel
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewCourseModel returns a model for the database table.
|
||||||
|
func NewCourseModel(conn sqlx.SqlConn) CourseModel {
|
||||||
|
return &customCourseModel{
|
||||||
|
defaultCourseModel: newCourseModel(conn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customCourseModel) withSession(session sqlx.Session) CourseModel {
|
||||||
|
return NewCourseModel(sqlx.NewSqlConnFromSession(session))
|
||||||
|
}
|
||||||
157
server/internal/course/internal/model/coursemodel_gen.go
Normal file
157
server/internal/course/internal/model/coursemodel_gen.go
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// goctl version: 1.9.2
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
courseFieldNames = builder.RawFieldNames(&Course{})
|
||||||
|
courseRows = strings.Join(courseFieldNames, ",")
|
||||||
|
courseRowsExpectAutoSet = strings.Join(stringx.Remove(courseFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||||
|
courseRowsWithPlaceHolder = strings.Join(stringx.Remove(courseFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
courseModel interface {
|
||||||
|
Insert(ctx context.Context, data *Course) (sql.Result, error)
|
||||||
|
FindOne(ctx context.Context, id int64) (*Course, error)
|
||||||
|
Update(ctx context.Context, data *Course) error
|
||||||
|
Delete(ctx context.Context, id int64) error
|
||||||
|
List(ctx context.Context, filter CourseFilter) ([]*Course, error)
|
||||||
|
Count(ctx context.Context, filter CourseFilter) (int64, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultCourseModel struct {
|
||||||
|
conn sqlx.SqlConn
|
||||||
|
table string
|
||||||
|
}
|
||||||
|
|
||||||
|
Course struct {
|
||||||
|
Id int64 `db:"id"` // 课程ID(主键)
|
||||||
|
Title string `db:"title"` // 课程标题
|
||||||
|
Subtitle string `db:"subtitle"` // 课程副标题
|
||||||
|
CoverUrl string `db:"cover_url"` // 课程封面图URL
|
||||||
|
Intro sql.NullString `db:"intro"` // 课程简介(对应“课程简介”模块)
|
||||||
|
Status int64 `db:"status"` // 课程状态(0删除,1-已发布)
|
||||||
|
CreateTime time.Time `db:"create_time"` // 创建时间
|
||||||
|
UpdateTime time.Time `db:"update_time"` // 更新时间
|
||||||
|
}
|
||||||
|
|
||||||
|
CourseFilter struct {
|
||||||
|
Status int8 // 状态筛选
|
||||||
|
Keyword string // 关键词搜索
|
||||||
|
Offset int // 分页偏移量
|
||||||
|
Limit int // 分页数量
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func newCourseModel(conn sqlx.SqlConn) *defaultCourseModel {
|
||||||
|
return &defaultCourseModel{
|
||||||
|
conn: conn,
|
||||||
|
table: "`course`",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseModel) Delete(ctx context.Context, id int64) error {
|
||||||
|
query := fmt.Sprintf("update %s set `status` = 0, `update_time` = CURRENT_TIMESTAMP where `id` = ?", m.table)
|
||||||
|
_, err := m.conn.ExecCtx(ctx, query, id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseModel) FindOne(ctx context.Context, id int64) (*Course, error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", courseRows, m.table)
|
||||||
|
var resp Course
|
||||||
|
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlx.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseModel) Insert(ctx context.Context, data *Course) (sql.Result, error) {
|
||||||
|
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?)", m.table, courseRowsExpectAutoSet)
|
||||||
|
ret, err := m.conn.ExecCtx(ctx, query, data.Title, data.Subtitle, data.CoverUrl, data.Intro, data.Status)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseModel) Update(ctx context.Context, data *Course) error {
|
||||||
|
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, courseRowsWithPlaceHolder)
|
||||||
|
_, err := m.conn.ExecCtx(ctx, query, data.Title, data.Subtitle, data.CoverUrl, data.Intro, data.Status, data.Id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseModel) List(ctx context.Context, filter CourseFilter) ([]*Course, error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where 1=1", courseRows, m.table)
|
||||||
|
args := []interface{}{}
|
||||||
|
|
||||||
|
// 状态筛选逻辑:
|
||||||
|
// - 如果未指定filter.Status(默认值),默认只查询"已发布"(status=1)
|
||||||
|
// - 如果指定了filter.Status(0或1),则按指定值筛选(支持查询已删除的课程)
|
||||||
|
if filter.Status == -1 {
|
||||||
|
// 默认筛选:只查已发布(status=1)
|
||||||
|
query += " and `status` = 1"
|
||||||
|
} else {
|
||||||
|
// 按指定status筛选(0=删除,1=发布)
|
||||||
|
query += " and `status` = ?"
|
||||||
|
args = append(args, filter.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关键词搜索(标题和副标题模糊匹配)
|
||||||
|
if filter.Keyword != "" {
|
||||||
|
query += " and (`title` like ? or `subtitle` like ?)"
|
||||||
|
args = append(args, "%"+filter.Keyword+"%", "%"+filter.Keyword+"%")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页处理
|
||||||
|
query += " limit ?, ?"
|
||||||
|
args = append(args, filter.Offset, filter.Limit)
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
var courses []*Course
|
||||||
|
err := m.conn.QueryRowsCtx(ctx, &courses, query, args...)
|
||||||
|
return courses, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配套的Count方法也需要同步修改(确保总数计算正确)
|
||||||
|
func (m *defaultCourseModel) Count(ctx context.Context, filter CourseFilter) (int64, error) {
|
||||||
|
query := fmt.Sprintf("select count(1) from %s where 1=1", m.table)
|
||||||
|
args := []interface{}{}
|
||||||
|
|
||||||
|
// 与List方法保持一致的status筛选逻辑
|
||||||
|
if filter.Status == -1 {
|
||||||
|
query += " and `status` = 1"
|
||||||
|
} else {
|
||||||
|
query += " and `status` = ?"
|
||||||
|
args = append(args, filter.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关键词搜索条件
|
||||||
|
if filter.Keyword != "" {
|
||||||
|
query += " and (`title` like ? or `subtitle` like ?)"
|
||||||
|
args = append(args, "%"+filter.Keyword+"%", "%"+filter.Keyword+"%")
|
||||||
|
}
|
||||||
|
|
||||||
|
var total int64
|
||||||
|
err := m.conn.QueryRowCtx(ctx, &total, query, args...)
|
||||||
|
return total, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseModel) tableName() string {
|
||||||
|
return m.table
|
||||||
|
}
|
||||||
5
server/internal/course/internal/model/vars.go
Normal file
5
server/internal/course/internal/model/vars.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
|
||||||
|
var ErrNotFound = sqlx.ErrNotFound
|
||||||
57
server/internal/course/internal/types/types.go
Normal file
57
server/internal/course/internal/types/types.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package types
|
||||||
|
|
||||||
|
type BaseResp struct {
|
||||||
|
Code int `json:"code"` // 状态码(0成功,非0失败)
|
||||||
|
Msg string `json:"msg"` // 提示信息
|
||||||
|
}
|
||||||
|
|
||||||
|
type CourseResp struct {
|
||||||
|
Id int64 `json:"id"` // 课程ID
|
||||||
|
Title string `json:"title"` // 课程标题
|
||||||
|
Subtitle string `json:"subtitle"` // 课程副标题
|
||||||
|
CoverUrl string `json:"cover_url"` // 课程封面图URL
|
||||||
|
Intro string `json:"intro"` // 课程简介
|
||||||
|
Status int8 `json:"status"` // 课程状态
|
||||||
|
CreateTime string `json:"create_time"` // 创建时间
|
||||||
|
UpdateTime string `json:"update_time"` // 更新时间
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateCourseReq struct {
|
||||||
|
Title string `json:"title" validate:"required"` // 课程标题
|
||||||
|
Subtitle string `json:"subtitle"` // 课程副标题
|
||||||
|
CoverUrl string `json:"cover_url"` // 课程封面图URL
|
||||||
|
Intro string `json:"intro"` // 课程简介
|
||||||
|
Status int8 `json:"status" default:"1"` // 课程状态(0删除,1-已发布)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteCourseReq struct {
|
||||||
|
Id int64 `json:"id" validate:"required"` // 课程ID
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetCourseReq struct {
|
||||||
|
Id int64 `json:"id" path:"id" validate:"required"` // 课程ID
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListCourseReq struct {
|
||||||
|
Page int `json:"page" default:"1"` // 页码
|
||||||
|
Size int `json:"size" default:"10"` // 每页数量
|
||||||
|
Status int8 `json:"status"` // 课程状态筛选
|
||||||
|
Keyword string `json:"keyword"` // 搜索关键词(标题/副标题)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListCourseResp struct {
|
||||||
|
Total int64 `json:"total"` // 总条数
|
||||||
|
List []CourseResp `json:"list"` // 课程列表
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateCourseReq struct {
|
||||||
|
Id int64 `json:"id" validate:"required"` // 课程ID
|
||||||
|
Title string `json:"title"` // 课程标题
|
||||||
|
Subtitle string `json:"subtitle"` // 课程副标题
|
||||||
|
CoverUrl string `json:"cover_url"` // 课程封面图URL
|
||||||
|
Intro string `json:"intro"` // 课程简介
|
||||||
|
Status int8 `json:"status"` // 课程状态(0删除,1-已发布)
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course_content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/logic/course_content"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/svc"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddContentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.AddContentReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := course_content.NewAddContentLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.AddContent(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course_content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/logic/course_content"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/svc"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DeleteContentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.DeleteContentReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := course_content.NewDeleteContentLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.DeleteContent(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course_content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/logic/course_content"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/svc"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetContentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.GetContentReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := course_content.NewGetContentLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.GetContent(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course_content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/logic/course_content"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/svc"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetContentListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.GetContentListReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := course_content.NewGetContentListLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.GetContentList(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course_content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/logic/course_content"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/svc"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UpdateContentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.UpdateContentReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := course_content.NewUpdateContentLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.UpdateContent(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course_content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/svc"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AddContentLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAddContentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddContentLogic {
|
||||||
|
return &AddContentLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *AddContentLogic) AddContent(req *types.AddContentReq) (resp *types.AddContentResp, err error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course_content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/svc"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeleteContentLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDeleteContentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteContentLogic {
|
||||||
|
return &DeleteContentLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DeleteContentLogic) DeleteContent(req *types.DeleteContentReq) (resp *types.DeleteContentResp, err error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course_content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/svc"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetContentListLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetContentListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetContentListLogic {
|
||||||
|
return &GetContentListLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetContentListLogic) GetContentList(req *types.GetContentListReq) (resp *types.GetContentListResp, err error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course_content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/svc"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetContentLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetContentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetContentLogic {
|
||||||
|
return &GetContentLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetContentLogic) GetContent(req *types.GetContentReq) (resp *types.GetContentResp, err error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
package course_content
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/svc"
|
||||||
|
"github.com/JACKYMYPERSON/hldrCenter/internal/course_content/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateContentLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUpdateContentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateContentLogic {
|
||||||
|
return &UpdateContentLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *UpdateContentLogic) UpdateContent(req *types.UpdateContentReq) (resp *types.UpdateContentResp, err error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
|
||||||
|
var _ CourseContentModel = (*customCourseContentModel)(nil)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// CourseContentModel is an interface to be customized, add more methods here,
|
||||||
|
// and implement the added methods in customCourseContentModel.
|
||||||
|
CourseContentModel interface {
|
||||||
|
courseContentModel
|
||||||
|
withSession(session sqlx.Session) CourseContentModel
|
||||||
|
}
|
||||||
|
|
||||||
|
customCourseContentModel struct {
|
||||||
|
*defaultCourseContentModel
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewCourseContentModel returns a model for the database table.
|
||||||
|
func NewCourseContentModel(conn sqlx.SqlConn) CourseContentModel {
|
||||||
|
return &customCourseContentModel{
|
||||||
|
defaultCourseContentModel: newCourseContentModel(conn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customCourseContentModel) withSession(session sqlx.Session) CourseContentModel {
|
||||||
|
return NewCourseContentModel(sqlx.NewSqlConnFromSession(session))
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// goctl version: 1.9.2
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
courseContentFieldNames = builder.RawFieldNames(&CourseContent{})
|
||||||
|
courseContentRows = strings.Join(courseContentFieldNames, ",")
|
||||||
|
courseContentRowsExpectAutoSet = strings.Join(stringx.Remove(courseContentFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||||
|
courseContentRowsWithPlaceHolder = strings.Join(stringx.Remove(courseContentFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
courseContentModel interface {
|
||||||
|
Insert(ctx context.Context, data *CourseContent) (sql.Result, error)
|
||||||
|
FindOne(ctx context.Context, id int64) (*CourseContent, error)
|
||||||
|
Update(ctx context.Context, data *CourseContent) error
|
||||||
|
Delete(ctx context.Context, id int64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultCourseContentModel struct {
|
||||||
|
conn sqlx.SqlConn
|
||||||
|
table string
|
||||||
|
}
|
||||||
|
|
||||||
|
CourseContent struct {
|
||||||
|
Id int64 `db:"id"` // 内容ID(主键)
|
||||||
|
CourseId int64 `db:"course_id"` // 关联课程ID
|
||||||
|
ParentId int64 `db:"parent_id"` // 父级ID(0表示章节,>0表示小节,关联自身id)
|
||||||
|
Title string `db:"title"` // 章节/小节标题
|
||||||
|
Content sql.NullString `db:"content"` // 内容详情(如视频地址、图文内容等)
|
||||||
|
Sort int64 `db:"sort"` // 排序(数字越小越靠前)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func newCourseContentModel(conn sqlx.SqlConn) *defaultCourseContentModel {
|
||||||
|
return &defaultCourseContentModel{
|
||||||
|
conn: conn,
|
||||||
|
table: "`course_content`",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseContentModel) Delete(ctx context.Context, id int64) error {
|
||||||
|
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||||
|
_, err := m.conn.ExecCtx(ctx, query, id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseContentModel) FindOne(ctx context.Context, id int64) (*CourseContent, error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", courseContentRows, m.table)
|
||||||
|
var resp CourseContent
|
||||||
|
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlx.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseContentModel) Insert(ctx context.Context, data *CourseContent) (sql.Result, error) {
|
||||||
|
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?)", m.table, courseContentRowsExpectAutoSet)
|
||||||
|
ret, err := m.conn.ExecCtx(ctx, query, data.CourseId, data.ParentId, data.Title, data.Content, data.Sort)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseContentModel) Update(ctx context.Context, data *CourseContent) error {
|
||||||
|
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, courseContentRowsWithPlaceHolder)
|
||||||
|
_, err := m.conn.ExecCtx(ctx, query, data.CourseId, data.ParentId, data.Title, data.Content, data.Sort, data.Id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultCourseContentModel) tableName() string {
|
||||||
|
return m.table
|
||||||
|
}
|
||||||
5
server/internal/course_content/internal/model/vars.go
Normal file
5
server/internal/course_content/internal/model/vars.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
|
||||||
|
var ErrNotFound = sqlx.ErrNotFound
|
||||||
70
server/internal/course_content/internal/types/types.go
Normal file
70
server/internal/course_content/internal/types/types.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// goctl 1.9.2
|
||||||
|
|
||||||
|
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"` // 排序,可选
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddContentResp struct {
|
||||||
|
BaseResp
|
||||||
|
Data int `json:"data"` // 新增内容的ID
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseResp struct {
|
||||||
|
Code int `json:"code"` // 状态码,0表示成功
|
||||||
|
Message string `json:"message"` // 提示信息
|
||||||
|
Data interface{} `json:"data"` // 响应数据
|
||||||
|
}
|
||||||
|
|
||||||
|
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"` // 排序
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteContentReq struct {
|
||||||
|
Id int `json:"id" form:"id" uri:"id"` // 内容ID,必填
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteContentResp struct {
|
||||||
|
BaseResp
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetContentListReq struct {
|
||||||
|
CourseId int `json:"course_id" form:"course_id"` // 课程ID,必填
|
||||||
|
ParentId int `json:"parent_id" form:"parent_id"` // 父级ID,可选,0表示获取章节
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetContentListResp struct {
|
||||||
|
BaseResp
|
||||||
|
Data []CourseContent `json:"data"` // 内容列表
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetContentReq struct {
|
||||||
|
Id int `json:"id" form:"id" uri:"id"` // 内容ID,必填
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetContentResp struct {
|
||||||
|
BaseResp
|
||||||
|
Data CourseContent `json:"data"` // 内容详情
|
||||||
|
}
|
||||||
|
|
||||||
|
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"` // 排序,可选
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateContentResp struct {
|
||||||
|
BaseResp
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user