Version:0.0.4.dev.260203
feat: 📚 完成课程导入与校验接口(赶在 token 过期前…) - 实现课程导入接口 ✅ - 实现课程信息校验接口 🔍 - 测试通过 🧪 fix: 🐛 修了一堆 bug,15 分钟 accessToken 默默见证了时间的流逝 ⏳😭
This commit is contained in:
@@ -3,4 +3,5 @@ package api
|
||||
type ApiHandlers struct {
|
||||
UserHandler *UserHandler
|
||||
TaskHandler *TaskHandler
|
||||
ScheduleHandler *ScheduleHandler
|
||||
}
|
||||
|
||||
66
backend/api/schedule.go
Normal file
66
backend/api/schedule.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/LoveLosita/smartflow/backend/model"
|
||||
"github.com/LoveLosita/smartflow/backend/respond"
|
||||
"github.com/LoveLosita/smartflow/backend/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ScheduleHandler struct {
|
||||
// 伸出手:准备接住 Service
|
||||
service *service.ScheduleService
|
||||
}
|
||||
|
||||
// NewScheduleHandler 创建 ScheduleHandler 实例
|
||||
func NewScheduleHandler(service *service.ScheduleService) *ScheduleHandler {
|
||||
return &ScheduleHandler{
|
||||
service: service,
|
||||
}
|
||||
}
|
||||
|
||||
func (sa *ScheduleHandler) CheckUserCourse(c *gin.Context) {
|
||||
//1.从请求中获取课程信息
|
||||
var req model.UserCheckCourseRequest
|
||||
err := c.ShouldBindJSON(&req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, respond.WrongParamType)
|
||||
return
|
||||
}
|
||||
//2.调用 service 层的 CheckSingleCourse 方法进行校验
|
||||
result := service.CheckSingleCourse(req)
|
||||
//3.根据校验结果返回响应
|
||||
if result {
|
||||
c.JSON(http.StatusOK, respond.Ok)
|
||||
} else {
|
||||
c.JSON(http.StatusBadRequest, respond.WrongCourseInfo)
|
||||
}
|
||||
}
|
||||
|
||||
func (sa *ScheduleHandler) AddUserCourses(c *gin.Context) {
|
||||
//1.从请求中获取课程信息
|
||||
var req model.UserImportCoursesRequest
|
||||
err := c.ShouldBindJSON(&req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, respond.WrongParamType)
|
||||
return
|
||||
}
|
||||
//2.从上下文获取用户ID
|
||||
userIDInterface := c.GetInt("user_id")
|
||||
//3.调用 service 层的 AddUserCourses 方法添加课程
|
||||
err = sa.service.AddUserCourses(req, userIDInterface)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, respond.WrongParamType), errors.Is(err, respond.WrongCourseInfo):
|
||||
c.JSON(http.StatusBadRequest, err)
|
||||
default:
|
||||
c.JSON(http.StatusInternalServerError, respond.InternalError(err))
|
||||
}
|
||||
return
|
||||
}
|
||||
//4.返回成功响应
|
||||
c.JSON(http.StatusOK, respond.Ok)
|
||||
}
|
||||
@@ -43,16 +43,20 @@ func Start() {
|
||||
userRepo := dao.NewUserDAO(db)
|
||||
cacheRepo := dao.NewCacheDAO(rdb)
|
||||
taskRepo := dao.NewTaskDAO(db)
|
||||
scheduleRepo := dao.NewScheduleDAO(db)
|
||||
//service 层
|
||||
userService := service.NewUserService(userRepo, cacheRepo)
|
||||
taskSv := service.NewTaskService(taskRepo)
|
||||
scheduleService := service.NewScheduleService(scheduleRepo)
|
||||
//api 层
|
||||
userApi := api.NewUserHandler(userService)
|
||||
taskApi := api.NewTaskHandler(taskSv)
|
||||
scheduleApi := api.NewScheduleHandler(scheduleService)
|
||||
|
||||
handlers := &api.ApiHandlers{
|
||||
UserHandler: userApi,
|
||||
TaskHandler: taskApi,
|
||||
ScheduleHandler: scheduleApi,
|
||||
}
|
||||
r := routers.RegisterRouters(handlers, cacheRepo)
|
||||
routers.StartEngine(r)
|
||||
|
||||
24
backend/dao/schedule.go
Normal file
24
backend/dao/schedule.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"github.com/LoveLosita/smartflow/backend/model"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ScheduleDAO struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewScheduleDAO 创建ScheduleDAO实例
|
||||
func NewScheduleDAO(db *gorm.DB) *ScheduleDAO {
|
||||
return &ScheduleDAO{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (dao *ScheduleDAO) AddUserCourses(courses []model.Schedule) error {
|
||||
if err := dao.db.Create(&courses).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
31
backend/model/schedule.go
Normal file
31
backend/model/schedule.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package model
|
||||
|
||||
type Schedule struct {
|
||||
ID int `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
UserID int `gorm:"column:user_id;index" json:"user_id"`
|
||||
Type string `gorm:"type:enum('course','task');comment:'course / task'" json:"type"`
|
||||
RelID int `gorm:"column:rel_id;comment:'关联 course_id 或 task_item_id'" json:"rel_id"`
|
||||
CanBeEmbedded bool `gorm:"column:can_be_embedded;comment:'是否允许嵌入水课'" json:"can_be_embedded"`
|
||||
EmbeddedTaskID *uint `gorm:"column:embedded_task_id;comment:'若为水课嵌入,记录任务ID'" json:"embedded_task_id"`
|
||||
Week int `gorm:"column:week" json:"week"`
|
||||
DayOfWeek int `gorm:"column:day_of_week" json:"day_of_week"`
|
||||
Sections string `gorm:"type:varchar(255)" json:"sections"`
|
||||
Status string `gorm:"type:enum('normal','interrupted');default:'normal'" json:"status"`
|
||||
}
|
||||
|
||||
type UserImportCoursesRequest struct {
|
||||
Courses []UserCheckCourseRequest `json:"courses"`
|
||||
}
|
||||
|
||||
type UserCheckCourseRequest struct {
|
||||
CourseName string `json:"course_name"`
|
||||
Location string `json:"location"`
|
||||
IsAllowTasks bool `json:"is_allow_tasks"`
|
||||
Arrangements []struct {
|
||||
StartWeek int `json:"start_week"`
|
||||
EndWeek int `json:"end_week"`
|
||||
DayOfWeek int `json:"day_of_week"`
|
||||
StartSection int `json:"start_section"`
|
||||
EndSection int `json:"end_section"`
|
||||
} `json:"arrangements"`
|
||||
}
|
||||
@@ -133,4 +133,9 @@ var ( //请求相关的响应
|
||||
Status: "40018",
|
||||
Info: "invalid priority",
|
||||
}
|
||||
|
||||
WrongCourseInfo = Response{ //课程信息错误
|
||||
Status: "40019",
|
||||
Info: "wrong course info",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -54,6 +54,12 @@ func RegisterRouters(handlers *api.ApiHandlers, cache *dao.CacheDAO) *gin.Engine
|
||||
taskGroup.POST("/create", handlers.TaskHandler.AddTask)
|
||||
taskGroup.GET("/get", handlers.TaskHandler.GetUserTasks)
|
||||
}
|
||||
scheduleGroup := apiGroup.Group("/schedule")
|
||||
{
|
||||
scheduleGroup.Use(middleware.JWTTokenAuth(cache))
|
||||
scheduleGroup.POST("/validate", handlers.ScheduleHandler.CheckUserCourse)
|
||||
scheduleGroup.POST("/import-courses", handlers.ScheduleHandler.AddUserCourses)
|
||||
}
|
||||
}
|
||||
// 初始化Gin引擎
|
||||
log.Println("Routes setup completed")
|
||||
|
||||
71
backend/service/schedule.go
Normal file
71
backend/service/schedule.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/LoveLosita/smartflow/backend/dao"
|
||||
"github.com/LoveLosita/smartflow/backend/model"
|
||||
"github.com/LoveLosita/smartflow/backend/respond"
|
||||
)
|
||||
|
||||
type ScheduleService struct {
|
||||
// 伸出手:准备接住 DAO
|
||||
dao *dao.ScheduleDAO
|
||||
}
|
||||
|
||||
// NewScheduleService 创建 ScheduleService 实例
|
||||
func NewScheduleService(dao *dao.ScheduleDAO) *ScheduleService {
|
||||
return &ScheduleService{
|
||||
dao: dao,
|
||||
}
|
||||
}
|
||||
|
||||
func CheckSingleCourse(req model.UserCheckCourseRequest) bool {
|
||||
for _, arrangement := range req.Arrangements {
|
||||
if arrangement.StartWeek > arrangement.EndWeek ||
|
||||
arrangement.DayOfWeek < 1 || arrangement.DayOfWeek > 7 ||
|
||||
arrangement.StartSection < 1 || arrangement.EndSection < arrangement.StartSection ||
|
||||
arrangement.EndSection > 12 || arrangement.StartWeek < 1 || arrangement.EndWeek > 24 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// AddUserCourses 添加用户课程表
|
||||
func (ss *ScheduleService) AddUserCourses(req model.UserImportCoursesRequest, userID int) error {
|
||||
//1.先校验参数是否正确
|
||||
for _, course := range req.Courses {
|
||||
result := CheckSingleCourse(course)
|
||||
if !result {
|
||||
return respond.WrongCourseInfo
|
||||
}
|
||||
}
|
||||
//2.转换为 Schedule 切片
|
||||
for _, course := range req.Courses {
|
||||
var schedules []model.Schedule
|
||||
for _, arrangement := range course.Arrangements {
|
||||
for week := arrangement.StartWeek; week <= arrangement.EndWeek; week++ {
|
||||
sections := fmt.Sprintf("%d-%d", arrangement.StartSection, arrangement.EndSection)
|
||||
schedule := model.Schedule{
|
||||
Type: "course",
|
||||
Week: week,
|
||||
DayOfWeek: arrangement.DayOfWeek,
|
||||
Sections: sections,
|
||||
Status: "normal",
|
||||
UserID: userID,
|
||||
CanBeEmbedded: course.IsAllowTasks,
|
||||
}
|
||||
schedules = append(schedules, schedule)
|
||||
}
|
||||
}
|
||||
//3.调用 DAO 方法添加课程
|
||||
err := ss.dao.AddUserCourses(schedules)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
//4.返回结果
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user