package handler import ( "dd_fiber_api/internal/question" "dd_fiber_api/internal/question/service" "strconv" "strings" "github.com/gofiber/fiber/v2" ) // QuestionHandler 题目处理器 type QuestionHandler struct { questionService *service.QuestionService knowledgeTreeService *service.KnowledgeTreeService } // NewQuestionHandler 创建题目处理器 func NewQuestionHandler(questionService *service.QuestionService, knowledgeTreeService *service.KnowledgeTreeService) *QuestionHandler { return &QuestionHandler{ questionService: questionService, knowledgeTreeService: knowledgeTreeService, } } // CreateQuestion 创建题目 func (h *QuestionHandler) CreateQuestion(c *fiber.Ctx) error { var req service.CreateQuestionRequest if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "请求参数解析失败: " + err.Error(), }) } question, err := h.questionService.CreateQuestion(&req) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": err.Error(), }) } return c.JSON(fiber.Map{ "success": true, "message": "创建成功", "question": question, }) } // GetQuestion 获取题目 func (h *QuestionHandler) GetQuestion(c *fiber.Ctx) error { id := c.Query("id") if id == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "题目ID不能为空", }) } question, err := h.questionService.GetQuestion(id) if err != nil { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ "success": false, "message": err.Error(), }) } return c.JSON(fiber.Map{ "success": true, "message": "获取成功", "question": question, }) } // SearchQuestions 搜索题目 func (h *QuestionHandler) SearchQuestions(c *fiber.Ctx) error { query := c.Query("query", "") qTypeStr := c.Query("type", "0") knowledgeTreeIdsStr := c.Query("knowledge_tree_ids", "") pageStr := c.Query("page", "1") pageSizeStr := c.Query("page_size", "10") qType, _ := strconv.ParseInt(qTypeStr, 10, 32) page, _ := strconv.ParseInt(pageStr, 10, 32) pageSize, _ := strconv.ParseInt(pageSizeStr, 10, 32) var knowledgeTreeIds []string if knowledgeTreeIdsStr != "" { // 逗号分割的知识树ID列表 knowledgeTreeIds = strings.Split(knowledgeTreeIdsStr, ",") } questions, total, err := h.questionService.SearchQuestions( query, question.QuestionType(qType), knowledgeTreeIds, int32(page), int32(pageSize), ) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": err.Error(), }) } // 如果有 KnowledgeTreeService,则为每道题附加知识树名称,便于前端展示 if h.knowledgeTreeService != nil { // 收集所有题目中出现过的知识树ID(去重) idSet := make(map[string]struct{}) var allIDs []string for _, q := range questions { for _, id := range q.KnowledgeTreeIDs { if id == "" { continue } if _, exists := idSet[id]; !exists { idSet[id] = struct{}{} allIDs = append(allIDs, id) } } } if len(allIDs) > 0 { // 批量获取名称(不存在的知识树节点会跳过,不报错) idToName, err := h.knowledgeTreeService.GetKnowledgeTreeNames(allIDs) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": err.Error(), }) } // 为每道题填充 KnowledgeTreeNames for _, q := range questions { q.KnowledgeTreeNames = nil for _, id := range q.KnowledgeTreeIDs { if name, ok := idToName[id]; ok { q.KnowledgeTreeNames = append(q.KnowledgeTreeNames, name) } } } } } return c.JSON(fiber.Map{ "success": true, "message": "搜索成功", "questions": questions, "total": total, "page": page, "page_size": pageSize, }) } // UpdateQuestion 更新题目 func (h *QuestionHandler) UpdateQuestion(c *fiber.Ctx) error { var req service.UpdateQuestionRequest if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "请求参数解析失败: " + err.Error(), }) } if req.Id == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "题目ID不能为空", }) } err := h.questionService.UpdateQuestion(&req) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": err.Error(), }) } return c.JSON(fiber.Map{ "success": true, "message": "更新成功", }) } // DeleteQuestion 删除题目 func (h *QuestionHandler) DeleteQuestion(c *fiber.Ctx) error { id := c.Query("id") if id == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "题目ID不能为空", }) } err := h.questionService.DeleteQuestion(id) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": err.Error(), }) } return c.JSON(fiber.Map{ "success": true, "message": "删除成功", }) } // BatchDeleteQuestions 批量删除题目 func (h *QuestionHandler) BatchDeleteQuestions(c *fiber.Ctx) error { var req struct { QuestionIds []string `json:"question_ids"` } if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "请求参数解析失败: " + err.Error(), }) } if len(req.QuestionIds) == 0 { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "题目ID列表不能为空", }) } deletedCount, failedIDs, err := h.questionService.BatchDeleteQuestions(req.QuestionIds) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": err.Error(), }) } return c.JSON(fiber.Map{ "success": true, "message": "批量删除完成", "deleted_count": deletedCount, "failed_question_ids": failedIDs, }) }