271 lines
7.0 KiB
Go
271 lines
7.0 KiB
Go
package handler
|
|
|
|
import (
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/common"
|
|
"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/services"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// StudyPlanHandler 学习计划处理器
|
|
type StudyPlanHandler struct {
|
|
studyPlanService *services.StudyPlanService
|
|
}
|
|
|
|
func NewStudyPlanHandler(studyPlanService *services.StudyPlanService) *StudyPlanHandler {
|
|
return &StudyPlanHandler{studyPlanService: studyPlanService}
|
|
}
|
|
|
|
// CreateStudyPlan 创建学习计划
|
|
// POST /api/v1/study-plans
|
|
func (h *StudyPlanHandler) CreateStudyPlan(c *gin.Context) {
|
|
userID := c.GetInt64("user_id")
|
|
|
|
var req struct {
|
|
PlanName string `json:"plan_name" binding:"required,min=1,max=200"`
|
|
Description *string `json:"description"`
|
|
DailyGoal int `json:"daily_goal" binding:"required,min=1,max=200"`
|
|
BookID *string `json:"book_id"`
|
|
StartDate string `json:"start_date" binding:"required"` // YYYY-MM-DD
|
|
EndDate *string `json:"end_date"` // YYYY-MM-DD
|
|
RemindTime *string `json:"remind_time"` // HH:mm
|
|
RemindDays *string `json:"remind_days"` // "1,2,3,4,5" 表示周一到周五
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
common.ErrorResponse(c, 400, "参数错误: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// 解析日期
|
|
startDate, err := time.Parse("2006-01-02", req.StartDate)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 400, "开始日期格式错误")
|
|
return
|
|
}
|
|
|
|
var endDate *time.Time
|
|
if req.EndDate != nil {
|
|
parsedEndDate, err := time.Parse("2006-01-02", *req.EndDate)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 400, "结束日期格式错误")
|
|
return
|
|
}
|
|
endDate = &parsedEndDate
|
|
}
|
|
|
|
plan, err := h.studyPlanService.CreateStudyPlan(
|
|
userID,
|
|
req.PlanName,
|
|
req.Description,
|
|
req.DailyGoal,
|
|
req.BookID,
|
|
startDate,
|
|
endDate,
|
|
req.RemindTime,
|
|
req.RemindDays,
|
|
)
|
|
|
|
if err != nil {
|
|
common.ErrorResponse(c, 500, "创建学习计划失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
common.SuccessResponse(c, plan)
|
|
}
|
|
|
|
// GetUserStudyPlans 获取用户的学习计划列表
|
|
// GET /api/v1/study-plans
|
|
func (h *StudyPlanHandler) GetUserStudyPlans(c *gin.Context) {
|
|
userID := c.GetInt64("user_id")
|
|
status := c.DefaultQuery("status", "all") // all, active, paused, completed, cancelled
|
|
|
|
plans, err := h.studyPlanService.GetUserStudyPlans(userID, status)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 500, "获取学习计划失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
common.SuccessResponse(c, gin.H{
|
|
"plans": plans,
|
|
"total": len(plans),
|
|
})
|
|
}
|
|
|
|
// GetStudyPlanByID 获取学习计划详情
|
|
// GET /api/v1/study-plans/:id
|
|
func (h *StudyPlanHandler) GetStudyPlanByID(c *gin.Context) {
|
|
userID := c.GetInt64("user_id")
|
|
planIDStr := c.Param("id")
|
|
|
|
planID, err := strconv.ParseInt(planIDStr, 10, 64)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 400, "无效的计划ID")
|
|
return
|
|
}
|
|
|
|
plan, err := h.studyPlanService.GetStudyPlanByID(planID, userID)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 404, "学习计划不存在")
|
|
return
|
|
}
|
|
|
|
common.SuccessResponse(c, plan)
|
|
}
|
|
|
|
// UpdateStudyPlan 更新学习计划
|
|
// PUT /api/v1/study-plans/:id
|
|
func (h *StudyPlanHandler) UpdateStudyPlan(c *gin.Context) {
|
|
userID := c.GetInt64("user_id")
|
|
planIDStr := c.Param("id")
|
|
|
|
planID, err := strconv.ParseInt(planIDStr, 10, 64)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 400, "无效的计划ID")
|
|
return
|
|
}
|
|
|
|
var updates map[string]interface{}
|
|
if err := c.ShouldBindJSON(&updates); err != nil {
|
|
common.ErrorResponse(c, 400, "参数错误: "+err.Error())
|
|
return
|
|
}
|
|
|
|
plan, err := h.studyPlanService.UpdateStudyPlan(planID, userID, updates)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 500, "更新学习计划失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
common.SuccessResponse(c, plan)
|
|
}
|
|
|
|
// DeleteStudyPlan 删除学习计划
|
|
// DELETE /api/v1/study-plans/:id
|
|
func (h *StudyPlanHandler) DeleteStudyPlan(c *gin.Context) {
|
|
userID := c.GetInt64("user_id")
|
|
planIDStr := c.Param("id")
|
|
|
|
planID, err := strconv.ParseInt(planIDStr, 10, 64)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 400, "无效的计划ID")
|
|
return
|
|
}
|
|
|
|
err = h.studyPlanService.DeleteStudyPlan(planID, userID)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 500, "删除学习计划失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
common.SuccessResponse(c, gin.H{
|
|
"message": "学习计划已删除",
|
|
})
|
|
}
|
|
|
|
// UpdatePlanStatus 更新计划状态
|
|
// PATCH /api/v1/study-plans/:id/status
|
|
func (h *StudyPlanHandler) UpdatePlanStatus(c *gin.Context) {
|
|
userID := c.GetInt64("user_id")
|
|
planIDStr := c.Param("id")
|
|
|
|
planID, err := strconv.ParseInt(planIDStr, 10, 64)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 400, "无效的计划ID")
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
Status string `json:"status" binding:"required,oneof=active paused completed cancelled"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
common.ErrorResponse(c, 400, "参数错误: "+err.Error())
|
|
return
|
|
}
|
|
|
|
err = h.studyPlanService.UpdatePlanStatus(planID, userID, req.Status)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 500, "更新状态失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
common.SuccessResponse(c, gin.H{
|
|
"message": "状态更新成功",
|
|
"status": req.Status,
|
|
})
|
|
}
|
|
|
|
// RecordStudyProgress 记录学习进度
|
|
// POST /api/v1/study-plans/:id/progress
|
|
func (h *StudyPlanHandler) RecordStudyProgress(c *gin.Context) {
|
|
userID := c.GetInt64("user_id")
|
|
planIDStr := c.Param("id")
|
|
|
|
planID, err := strconv.ParseInt(planIDStr, 10, 64)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 400, "无效的计划ID")
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
WordsStudied int `json:"words_studied" binding:"required,min=1"`
|
|
StudyDuration int `json:"study_duration"` // 学习时长(分钟)
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
common.ErrorResponse(c, 400, "参数错误: "+err.Error())
|
|
return
|
|
}
|
|
|
|
err = h.studyPlanService.RecordStudyProgress(planID, userID, req.WordsStudied, req.StudyDuration)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 500, "记录进度失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
common.SuccessResponse(c, gin.H{
|
|
"message": "进度记录成功",
|
|
})
|
|
}
|
|
|
|
// GetStudyPlanStatistics 获取学习计划统计
|
|
// GET /api/v1/study-plans/:id/statistics
|
|
func (h *StudyPlanHandler) GetStudyPlanStatistics(c *gin.Context) {
|
|
userID := c.GetInt64("user_id")
|
|
planIDStr := c.Param("id")
|
|
|
|
planID, err := strconv.ParseInt(planIDStr, 10, 64)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 400, "无效的计划ID")
|
|
return
|
|
}
|
|
|
|
stats, err := h.studyPlanService.GetStudyPlanStatistics(planID, userID)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 500, "获取统计信息失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
common.SuccessResponse(c, stats)
|
|
}
|
|
|
|
// GetTodayStudyPlans 获取今日需要执行的学习计划
|
|
// GET /api/v1/study-plans/today
|
|
func (h *StudyPlanHandler) GetTodayStudyPlans(c *gin.Context) {
|
|
userID := c.GetInt64("user_id")
|
|
|
|
plans, err := h.studyPlanService.GetTodayStudyPlans(userID)
|
|
if err != nil {
|
|
common.ErrorResponse(c, 500, "获取今日计划失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
common.SuccessResponse(c, gin.H{
|
|
"plans": plans,
|
|
"total": len(plans),
|
|
})
|
|
}
|