package handlers import ( "net/http" "strings" "github.com/gin-gonic/gin" "query-database/api/internal/auth" ) type exerciseSummary struct { ID string `json:"id"` Title string `json:"title"` Level string `json:"level"` Database string `json:"databaseKey"` IsSolved bool `json:"isSolved"` } func (h *Handlers) ListExercises(c *gin.Context) { userID := auth.UserID(c) level := strings.TrimSpace(c.Query("level")) if level == "" { level = "beginner" } if level != "beginner" && level != "normal" && level != "advanced" { c.JSON(http.StatusBadRequest, gin.H{"message": "level 不合法"}) return } moduleKey := strings.TrimSpace(c.Query("moduleKey")) if moduleKey == "" { _ = h.sqlite.QueryRow(`SELECT module_key FROM users WHERE id = ?`, userID).Scan(&moduleKey) } if moduleKey != "shop" && moduleKey != "hr" { c.JSON(http.StatusBadRequest, gin.H{"message": "moduleKey 不合法"}) return } rows, err := h.sqlite.Query( `SELECT e.id, e.title, e.level, e.database_key, COALESCE(p.is_solved, 0) AS is_solved FROM exercises e LEFT JOIN progress p ON p.exercise_id = e.id AND p.user_id = ? WHERE e.level = ? AND e.database_key = ? ORDER BY e.created_at ASC`, userID, level, moduleKey, ) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"message": "服务异常"}) return } defer rows.Close() out := make([]exerciseSummary, 0) for rows.Next() { var id, title, lvl, dbKey string var solved int if err := rows.Scan(&id, &title, &lvl, &dbKey, &solved); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"message": "服务异常"}) return } out = append(out, exerciseSummary{ID: id, Title: title, Level: lvl, Database: dbKey, IsSolved: solved == 1}) } c.JSON(http.StatusOK, out) } type exerciseDetail struct { ID string `json:"id"` Title string `json:"title"` Level string `json:"level"` Prompt string `json:"prompt"` Database string `json:"databaseKey"` IsSolved bool `json:"isSolved"` DraftSQL string `json:"draftSql"` } func (h *Handlers) GetExercise(c *gin.Context) { userID := auth.UserID(c) id := c.Param("id") var title, level, prompt, dbKey string if err := h.sqlite.QueryRow(`SELECT title, level, prompt, database_key FROM exercises WHERE id = ?`, id).Scan(&title, &level, &prompt, &dbKey); err != nil { c.JSON(http.StatusNotFound, gin.H{"message": "题目不存在"}) return } var draft string var solved int _ = h.sqlite.QueryRow( `SELECT draft_sql, is_solved FROM progress WHERE user_id = ? AND exercise_id = ?`, userID, id, ).Scan(&draft, &solved) c.JSON(http.StatusOK, exerciseDetail{ ID: id, Title: title, Level: level, Prompt: prompt, Database: dbKey, IsSolved: solved == 1, DraftSQL: draft, }) }