100 lines
2.7 KiB
Go
100 lines
2.7 KiB
Go
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,
|
|
})
|
|
}
|