package router import ( "exam_system/dao" "exam_system/entity" "exam_system/result" "exam_system/utils" "fmt" "github.com/gin-gonic/gin" "github.com/xuri/excelize/v2" "net/http" "regexp" "strconv" "strings" ) func Subject(router *RouterPlus) { r := router.Group("/admin") { // 添加试题 r.POST("/subject", AdminAddSubject) // 获取试题 r.GET("/subject/:id", AdminGetSubject) // 获取试题列表 r.GET("/subject/list", AdminSubjectList) // 修改试题 r.PUT("/subject", AdminUpdateSubject) // 删除试题 r.DELETE("/subject/:ids", AdminDeleteSubject) // 上传试题 r.POST("/subject/upload/:id", AdminUploadSuject) // 下载试题 r.routerGroup.GET("/subject/:id/:type", AdminDownloadSubject) // 下载试题模板 r.routerGroup.GET("/subject/template", AdminSubjectTemplate) } } func AdminAddSubject(c *gin.Context) *result.Result { var subject entity.Subject err := c.ShouldBindJSON(&subject) if err != nil || !CheckSubject(&subject) { return result.PARAM_ERROR } return dao.AddSubject(&subject) } func AdminGetSubject(c *gin.Context) *result.Result { id := c.Param("id") if id == "" { return result.UNKNOW_ERROR } return dao.SubjectDetail(id) } func AdminSubjectList(c *gin.Context) *result.Result { page, size, sort, query, err := utils.Page(c) if err != nil { return result.PARAM_ERROR } return dao.SubjectList(page, size, sort, query) } func AdminUpdateSubject(c *gin.Context) *result.Result { var subject entity.Subject err := c.ShouldBindJSON(&subject) if err != nil || subject.Id == 0 || subject.Type == nil { return result.PARAM_ERROR } return dao.UpdateSubject(&subject) } func AdminDeleteSubject(c *gin.Context) *result.Result { idStr := c.Param("ids") if idStr == "" { return result.PARAM_ERROR } ids := strings.Split(idStr, ",") return dao.DeleteSubjects(ids) } func CheckSubject(s *entity.Subject) bool { if s.Type == nil || s.QbId == 0 || s.Question == "" { return false } s.Answer = strings.TrimSpace(s.Answer) if *s.Type == 0 || *s.Type == 1 { match, _ := regexp.MatchString("^[1-4]?$", s.Answer) if s.OptA == "" || s.OptB == "" || s.OptC == "" || s.OptD == "" || !match { return false } } if *s.Type == 2 { if s.OptA == "" || s.OptB == "" || s.OptC == "" || s.OptD == "" { return false } match1, _ := regexp.MatchString("^[1-4]{0,4}$", s.Answer) match2, _ := regexp.MatchString(`([\s\S])[\s\S]*?\1`, s.Answer) if !match1 || match2 { return false } } if *s.Type == 3 { match, _ := regexp.MatchString("^[1-2]?$", s.Answer) if !match { return false } } return true } func AdminUploadSuject(c *gin.Context) *result.Result { id := c.Param("id") fh, _ := c.FormFile("file") file, err := fh.Open() if err != nil { return result.UNKNOW_ERROR.SetMsg(err.Error()) } return dao.AddSubjectBatch(file, id) } func AdminSubjectTemplate(c *gin.Context) { c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", "试题模板.zip")) c.Writer.Header().Set("Content-Type", "application/zip") c.File(utils.SubTemplatePath) } func AdminDownloadSubject(c *gin.Context) { idStr := c.Param("id") tpStr := c.Param("type") id, err := strconv.Atoi(idStr) if err != nil { c.JSON(http.StatusOK, result.UNKNOW_ERROR.SetMsg(err.Error())) } tp, err := strconv.Atoi(tpStr) if err != nil { c.JSON(http.StatusOK, result.UNKNOW_ERROR.SetMsg(err.Error())) } var path string switch tp { case entity.SINGEL_CHOICE: path = utils.SingelChoicePath case entity.Judgement: path = utils.JudgementPath case entity.MULTIPLE_CHOICE: path = utils.MultipleChoicePath case entity.Completion: path = utils.CompletionPath } file, err := excelize.OpenFile(path) if err != nil { c.JSON(http.StatusOK, result.UNKNOW_ERROR.SetMsg(err.Error())) } res := dao.DownloadSubject(file, id, tp) if res.Code != result.SUCCESS.Code { file.Close() c.JSON(http.StatusOK, res) }else{ c.Header("Content-Type", "application/octet-stream") c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s.xlsx", res.Data.(string))) c.Header("Content-Transfer-Encoding", "binary") _ = file.Write(c.Writer) } }