router-subject.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. package router
  2. import (
  3. "exam_system/dao"
  4. "exam_system/entity"
  5. "exam_system/result"
  6. "exam_system/utils"
  7. "fmt"
  8. "github.com/gin-gonic/gin"
  9. "github.com/xuri/excelize/v2"
  10. "net/http"
  11. "regexp"
  12. "strconv"
  13. "strings"
  14. )
  15. func Subject(router *RouterPlus) {
  16. r := router.Group("/admin")
  17. {
  18. // 添加试题
  19. r.POST("/subject", AdminAddSubject)
  20. // 获取试题
  21. r.GET("/subject/:id", AdminGetSubject)
  22. // 获取试题列表
  23. r.GET("/subject/list", AdminSubjectList)
  24. // 修改试题
  25. r.PUT("/subject", AdminUpdateSubject)
  26. // 删除试题
  27. r.DELETE("/subject/:ids", AdminDeleteSubject)
  28. // 上传试题
  29. r.POST("/subject/upload/:id", AdminUploadSuject)
  30. // 下载试题
  31. r.routerGroup.GET("/subject/:id/:type", AdminDownloadSubject)
  32. // 下载试题模板
  33. r.routerGroup.GET("/subject/template", AdminSubjectTemplate)
  34. }
  35. }
  36. func AdminAddSubject(c *gin.Context) *result.Result {
  37. var subject entity.Subject
  38. err := c.ShouldBindJSON(&subject)
  39. if err != nil || !CheckSubject(&subject) {
  40. return result.PARAM_ERROR
  41. }
  42. return dao.AddSubject(&subject)
  43. }
  44. func AdminGetSubject(c *gin.Context) *result.Result {
  45. id := c.Param("id")
  46. if id == "" {
  47. return result.UNKNOW_ERROR
  48. }
  49. return dao.SubjectDetail(id)
  50. }
  51. func AdminSubjectList(c *gin.Context) *result.Result {
  52. page, size, sort, query, err := utils.Page(c)
  53. if err != nil {
  54. return result.PARAM_ERROR
  55. }
  56. return dao.SubjectList(page, size, sort, query)
  57. }
  58. func AdminUpdateSubject(c *gin.Context) *result.Result {
  59. var subject entity.Subject
  60. err := c.ShouldBindJSON(&subject)
  61. if err != nil || subject.Id == 0 || subject.Type == nil {
  62. return result.PARAM_ERROR
  63. }
  64. return dao.UpdateSubject(&subject)
  65. }
  66. func AdminDeleteSubject(c *gin.Context) *result.Result {
  67. idStr := c.Param("ids")
  68. if idStr == "" {
  69. return result.PARAM_ERROR
  70. }
  71. ids := strings.Split(idStr, ",")
  72. return dao.DeleteSubjects(ids)
  73. }
  74. func CheckSubject(s *entity.Subject) bool {
  75. if s.Type == nil || s.QbId == 0 || s.Question == "" {
  76. return false
  77. }
  78. s.Answer = strings.TrimSpace(s.Answer)
  79. if *s.Type == 0 || *s.Type == 1 {
  80. match, _ := regexp.MatchString("^[1-4]?$", s.Answer)
  81. if s.OptA == "" || s.OptB == "" || s.OptC == "" || s.OptD == "" || !match {
  82. return false
  83. }
  84. }
  85. if *s.Type == 2 {
  86. if s.OptA == "" || s.OptB == "" || s.OptC == "" || s.OptD == "" {
  87. return false
  88. }
  89. match1, _ := regexp.MatchString("^[1-4]{0,4}$", s.Answer)
  90. match2, _ := regexp.MatchString(`([\s\S])[\s\S]*?\1`, s.Answer)
  91. if !match1 || match2 {
  92. return false
  93. }
  94. }
  95. if *s.Type == 3 {
  96. match, _ := regexp.MatchString("^[1-2]?$", s.Answer)
  97. if !match {
  98. return false
  99. }
  100. }
  101. return true
  102. }
  103. func AdminUploadSuject(c *gin.Context) *result.Result {
  104. id := c.Param("id")
  105. fh, _ := c.FormFile("file")
  106. file, err := fh.Open()
  107. if err != nil {
  108. return result.UNKNOW_ERROR.SetMsg(err.Error())
  109. }
  110. return dao.AddSubjectBatch(file, id)
  111. }
  112. func AdminSubjectTemplate(c *gin.Context) {
  113. c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", "试题模板.zip"))
  114. c.Writer.Header().Set("Content-Type", "application/zip")
  115. c.File(utils.SubTemplatePath)
  116. }
  117. func AdminDownloadSubject(c *gin.Context) {
  118. idStr := c.Param("id")
  119. tpStr := c.Param("type")
  120. id, err := strconv.Atoi(idStr)
  121. if err != nil {
  122. c.JSON(http.StatusOK, result.UNKNOW_ERROR.SetMsg(err.Error()))
  123. }
  124. tp, err := strconv.Atoi(tpStr)
  125. if err != nil {
  126. c.JSON(http.StatusOK, result.UNKNOW_ERROR.SetMsg(err.Error()))
  127. }
  128. var path string
  129. switch tp {
  130. case entity.SINGEL_CHOICE:
  131. path = utils.SingelChoicePath
  132. case entity.Judgement:
  133. path = utils.JudgementPath
  134. case entity.MULTIPLE_CHOICE:
  135. path = utils.MultipleChoicePath
  136. case entity.Completion:
  137. path = utils.CompletionPath
  138. }
  139. file, err := excelize.OpenFile(path)
  140. if err != nil {
  141. c.JSON(http.StatusOK, result.UNKNOW_ERROR.SetMsg(err.Error()))
  142. }
  143. res := dao.DownloadSubject(file, id, tp)
  144. if res.Code != result.SUCCESS.Code {
  145. file.Close()
  146. c.JSON(http.StatusOK, res)
  147. }else{
  148. c.Header("Content-Type", "application/octet-stream")
  149. c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s.xlsx", res.Data.(string)))
  150. c.Header("Content-Transfer-Encoding", "binary")
  151. _ = file.Write(c.Writer)
  152. }
  153. }