dao-exam-record.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. package dao
  2. import (
  3. "database/sql"
  4. "encoding/json"
  5. "exam_system/config"
  6. "exam_system/entity"
  7. "exam_system/result"
  8. "exam_system/utils"
  9. "exam_system/vo"
  10. "fmt"
  11. "strconv"
  12. "time"
  13. "github.com/gin-gonic/gin"
  14. "github.com/jmoiron/sqlx"
  15. uuid "github.com/satori/go.uuid"
  16. "github.com/xuri/excelize/v2"
  17. )
  18. func AddExamRecord(er *entity.ExamRecord) *result.Result {
  19. // 2、插入
  20. uuId := uuid.NewV4().String()
  21. sqlStr := "update exam_record er set create_at=?,update_at=?,token=?,ip=inet_aton(?),status=? where er.id = ? and er.user_id=?"
  22. _, err := config.DB.Exec(sqlStr, time.Now(), time.Now(), uuId, er.Ip, entity.TESTING, er.Id, er.UserId)
  23. if err != nil {
  24. return result.UNKNOW_ERROR.SetData(err)
  25. }
  26. fmt.Println("--------------------ADDTOKEN--------------------------------")
  27. fmt.Printf("ID:%d\n", er.Id)
  28. fmt.Printf("TOKEN:%s\n", uuId)
  29. return result.SuccessResult(gin.H{
  30. "id": er.Id,
  31. "token": uuId,
  32. })
  33. }
  34. func ExamRecordDetail(id, uid int) *result.Result {
  35. // 1、考试详情
  36. sqlStr := `select e.name,e.create_at,e.update_at,e.duration,e.start_at,e.end_at,e.publish_at,tp.score,tp.pass_score,er.score user_score,timestampdiff(minute,er.create_at,er.update_at) user_take_time
  37. from user u left join exam_record er on u.id = er.user_id
  38. LEFT JOIN exam e ON e.id = er.exam_id
  39. LEFT JOIN test_paper tp ON e.tp_id = tp.id
  40. LEFT JOIN exam_class ec ON e.id = ec.exam_id
  41. LEFT JOIN class c ON ec.class_id = c.id
  42. where er.id = ? and u.id = ? and e.delete_at is null `
  43. var t vo.ExamRecordVo1
  44. err := config.DB.Get(&t, sqlStr, id, uid)
  45. if err != nil {
  46. if err == sql.ErrNoRows {
  47. return result.DATA_NOT_FOUND
  48. }
  49. return result.UNKNOW_ERROR.SetMsg(err.Error())
  50. }
  51. if t.PublishAt.After(time.Now()) {
  52. t.UserScore = nil
  53. }
  54. // 题目答案, 用户答案
  55. sqlStr = "select er.answer from exam_record er where er.id = ? and er.delete_at is null"
  56. var answerStr string
  57. err = config.DB.Get(&answerStr, sqlStr, id)
  58. if err != nil {
  59. return result.UNKNOW_ERROR.SetMsg(err.Error())
  60. }
  61. var avs []*vo.AnswerVo
  62. err = json.Unmarshal([]byte(answerStr), &avs)
  63. if err != nil {
  64. return result.FORMATE_ERROR
  65. }
  66. for i := 0; i < len(avs); i++ {
  67. var av vo.AnswerVo
  68. sqlStr = "select * from subject where id = ?"
  69. err = config.DB.Get(&av, sqlStr, avs[i].Id)
  70. if err != nil {
  71. if err == sql.ErrNoRows {
  72. continue
  73. }
  74. return result.UNKNOW_ERROR.SetMsg(err.Error())
  75. }
  76. if t.PublishAt.After(time.Now()) {
  77. av.Answer = ""
  78. }
  79. av.OwnAnswer = avs[i].OwnAnswer
  80. avs[i] = &av
  81. }
  82. return result.SuccessResult(gin.H{
  83. "exam_detail": &t,
  84. "subject": &avs,
  85. })
  86. }
  87. func ExamRecordList(page, size int, query map[string]interface{}, uid int) *result.Result {
  88. // 1、获取list
  89. sqlStr := `select er.id,e.name,e.create_at,e.update_at,e.duration,e.start_at,e.end_at,e.publish_at,inet_ntoa(er.ip) ip,tp.score,tp.pass_score,er.score user_score,timestampdiff(minute,er.create_at,er.update_at) user_take_time
  90. from user u left join exam_record er on u.id = er.user_id
  91. LEFT JOIN exam e ON e.id = er.exam_id
  92. LEFT JOIN test_paper tp ON e.tp_id = tp.id
  93. LEFT JOIN exam_class ec ON e.id = ec.exam_id
  94. LEFT JOIN class c ON ec.class_id = c.id
  95. where u.id = ? and e.delete_at is null and er.status!=0 `
  96. params := []interface{}{uid}
  97. if query["name"] != nil {
  98. sqlStr += "and e.name like ? "
  99. params = append(params, "%"+query["name"].(string)+"%")
  100. }
  101. sqlStr += "group by er.id "
  102. if query["create_at"] != nil {
  103. if query["create_at"] == "desc" {
  104. sqlStr += "order by create_at desc "
  105. } else {
  106. sqlStr += "order by create_at asc "
  107. }
  108. } else if query["user_take_time"] != nil {
  109. if query["user_take_time"] == "desc" {
  110. sqlStr += "order by user_take_time desc "
  111. } else {
  112. sqlStr += "order by user_take_time asc "
  113. }
  114. } else if query["user_score"] != nil {
  115. if query["user_score"] == "desc" {
  116. sqlStr += "order by user_score desc "
  117. } else {
  118. sqlStr += "order by user_score asc "
  119. }
  120. } else {
  121. sqlStr += "order by create_at desc "
  122. }
  123. sqlStr += "limit ?,?"
  124. params = append(params, utils.PostionSize(page, size), size)
  125. var evos []*vo.ExamRecordVo1
  126. err := config.DB.Select(&evos, sqlStr, params...)
  127. if err != nil {
  128. return result.UNKNOW_ERROR.SetMsg(err.Error())
  129. }
  130. // 2、总数
  131. sqlStr = `select count(distinct(er.id))
  132. from user u left join exam_record er on u.id = er.user_id
  133. LEFT JOIN exam e ON e.id = er.exam_id
  134. LEFT JOIN test_paper tp ON e.tp_id = tp.id
  135. LEFT JOIN exam_class ec ON e.id = ec.exam_id
  136. LEFT JOIN class c ON ec.class_id = c.id
  137. where u.id = ? and e.delete_at is null and er.status!=0 `
  138. params = []interface{}{uid}
  139. if query["name"] != nil {
  140. sqlStr += "and e.name like ? "
  141. params = append(params, "%"+query["name"].(string)+"%")
  142. }
  143. sqlStr += "group by er.id"
  144. for _, e := range evos {
  145. if e.PublishAt.After(time.Now()) {
  146. e.UserScore = nil
  147. }
  148. }
  149. var total int
  150. err = config.DB.Get(&total, sqlStr, params...)
  151. if err != nil {
  152. return result.UNKNOW_ERROR.SetMsg(err.Error())
  153. }
  154. return result.SUCCESS.SetData(result.NewPage(page, len(evos), total, evos))
  155. }
  156. func UpdateExamRecord(erv *vo.ExamRecordVo) *result.Result {
  157. tx, err := config.DB.Beginx()
  158. return utils.Transation(tx, err, func(tx *sqlx.Tx) *result.Result {
  159. // 1、查询是否存在该记录
  160. sqlStr := `select er.id, er.exam_id
  161. from exam_record er
  162. left join exam e on e.id = er.exam_id
  163. where er.id = ?
  164. and er.token = ?
  165. and er.update_at - er.create_at <= e.duration
  166. and e.end_at > ?
  167. `
  168. err = tx.Get(erv, sqlStr, erv.Id, erv.Token, time.Now())
  169. if err != nil {
  170. if err == sql.ErrNoRows {
  171. return result.DATA_NOT_FOUND.SetMsg("该场考试已过期")
  172. }
  173. return result.UNKNOW_ERROR.SetMsg(err.Error())
  174. }
  175. sqlStr = "update exam_record set token = null,status = ? where id = ?"
  176. var res sql.Result
  177. _, err = tx.Exec(sqlStr, entity.TESTED, erv.Id)
  178. if err != nil {
  179. return result.UNKNOW_ERROR.SetMsg(err.Error())
  180. }
  181. // 2、查询出所需id
  182. sqlStr = "select c.sub_ids from chapter c left join exam e on c.tp_id = e.tp_id where e.id=?"
  183. var subIdStrs []string
  184. err = tx.Select(&subIdStrs, sqlStr, erv.ExamId)
  185. if err != nil {
  186. return result.UNKNOW_ERROR.SetMsg(err.Error())
  187. }
  188. subIds := make([]*vo.SubIdsVo, 0)
  189. for _, subIdStr := range subIdStrs {
  190. var subIdsVo []*vo.SubIdsVo
  191. err = json.Unmarshal([]byte(subIdStr), &subIdsVo)
  192. if err != nil {
  193. return result.UNKNOW_ERROR.SetMsg(err.Error())
  194. }
  195. subIds = append(subIds, subIdsVo...)
  196. }
  197. // 2.1 构造一个key为id的 map
  198. subIdMap := make(map[int]int, 0)
  199. for _, subId := range subIds {
  200. subIdMap[*subId.Id] = *subId.Score
  201. }
  202. // 2、 批量查询id
  203. toatalScore := 0
  204. for _, answerVo := range erv.AnswerVo {
  205. // 判断提交的试题是否在考试范围内
  206. if _, ok := subIdMap[*answerVo.Id]; !ok {
  207. return result.UNKNOW_ERROR.SetMsg("不存在该试题")
  208. }
  209. var score int
  210. sqlStr = "select count(id) from subject where id=? and answer=?"
  211. err = tx.Get(&score, sqlStr, answerVo.Id, utils.SubjectSort(answerVo.OwnAnswer))
  212. if err != nil {
  213. return result.UNKNOW_ERROR.SetMsg(err.Error())
  214. }
  215. toatalScore += score * subIdMap[*answerVo.Id]
  216. delete(subIdMap, *answerVo.Id)
  217. }
  218. if len(subIdMap) != 0 {
  219. return result.UNKNOW_ERROR.SetMsg("试题提交不完整")
  220. }
  221. var anwserData []byte
  222. anwserData, err = json.Marshal(erv.AnswerVo)
  223. // 插入记录表
  224. sqlStr = "update exam_record set score=?,answer=?,update_at=? where id=? and delete_at is null "
  225. res, err = tx.Exec(sqlStr, toatalScore, string(anwserData), time.Now(), erv.Id)
  226. if err != nil {
  227. return result.UNKNOW_ERROR.SetData(err)
  228. }
  229. affected, _ := res.RowsAffected()
  230. return result.SuccessResult(result.NewResultChange(affected))
  231. })
  232. }
  233. func DeleteExamRecords(ids []string) *result.Result {
  234. parm := []interface{}{time.Now()}
  235. parmStr := ""
  236. for k, id := range ids {
  237. parm = append(parm, id)
  238. if k == (len(ids) - 1) {
  239. parmStr += "?"
  240. } else {
  241. parmStr += "?,"
  242. }
  243. }
  244. sqlStr := fmt.Sprintf("update exam_record set delete_at=? where id in (%s)", parmStr)
  245. res, err := config.DB.Exec(sqlStr, parm...)
  246. if err != nil {
  247. return result.UNKNOW_ERROR.SetMsg(err.Error())
  248. }
  249. affected, _ := res.RowsAffected()
  250. return result.SUCCESS.SetData(result.NewResultChange(affected))
  251. }
  252. func AdminExamRecordDetail(id int) *result.Result {
  253. // 1、考试详情
  254. // sqlStr := `select e.name,e.create_at,e.update_at,e.duration,e.start_at,e.end_at,e.publish_at,tp.score,tp.pass_score,er.score user_score,timestampdiff(minute,er.create_at,er.update_at) user_take_time
  255. //from exam_record er left join exam e on er.exam_id = e.id
  256. // left join test_paper tp on e.tp_id = tp.id
  257. // left join exam_class ec on e.id = ec.exam_id
  258. // left join class c on ec.class_id = c.id
  259. // left join user u on u.class_id = c.id
  260. // where er.id=? and e.delete_at is null
  261. // GROUP BY er.id`
  262. //
  263. // var t vo.ExamRecordVo1
  264. // err := config.DB.Get(&t, sqlStr, id)
  265. // if err != nil {
  266. // if err == sql.ErrNoRows {
  267. // return result.DATA_NOT_FOUND
  268. // }
  269. // return result.UNKNOW_ERROR.SetMsg(err.Error())
  270. // }
  271. // 题目答案, 用户答案
  272. sqlStr := "select er.answer from exam_record er where er.id = ? and er.delete_at is null"
  273. var answerStr string
  274. err := config.DB.Get(&answerStr, sqlStr, id)
  275. if err != nil {
  276. return result.UNKNOW_ERROR.SetMsg(err.Error())
  277. }
  278. var avs []*vo.AnswerVo
  279. err = json.Unmarshal([]byte(answerStr), &avs)
  280. if err != nil {
  281. return result.FORMATE_ERROR
  282. }
  283. for i := 0; i < len(avs); i++ {
  284. var av vo.AnswerVo
  285. sqlStr = "select * from subject where id = ?"
  286. err = config.DB.Get(&av, sqlStr, avs[i].Id)
  287. if err != nil {
  288. if err.Error() == "sql: no rows in result set" {
  289. continue
  290. }
  291. return result.UNKNOW_ERROR.SetMsg(err.Error())
  292. }
  293. av.OwnAnswer = avs[i].OwnAnswer
  294. if avs[i].OwnAnswer == "-1" {
  295. av.OwnAnswer = ""
  296. }
  297. avs[i] = &av
  298. }
  299. return result.SuccessResult(gin.H{
  300. //"exam_detail": &t,
  301. "subject": &avs,
  302. })
  303. }
  304. func AdminExamRecordList(page, size int, query map[string]interface{}, examId int) *result.Result {
  305. // 1、获取list
  306. sqlStr := `select er.id,
  307. e.name,
  308. e.create_at,
  309. e.update_at,
  310. e.duration,
  311. e.start_at,
  312. e.end_at,
  313. e.publish_at,
  314. tp.score,
  315. tp.pass_score,
  316. er.score user_score,
  317. u.username,
  318. c.name classname,
  319. timestampdiff(minute, er.create_at, er.update_at) user_take_time
  320. from exam_record er
  321. LEFT JOIN exam e ON er.exam_id = e.id
  322. LEFT JOIN test_paper tp ON e.tp_id = tp.id
  323. LEFT JOIN user u on er.user_id = u.id
  324. LEFT JOIN class c on u.class_id = c.id
  325. where e.id = ?
  326. and e.delete_at is null `
  327. params := []interface{}{examId}
  328. if query["name"] != nil {
  329. sqlStr += "and e.name like ? "
  330. params = append(params, "%"+query["name"].(string)+"%")
  331. }
  332. if query["class_id"] != nil {
  333. sqlStr += "and c.id = ? "
  334. params = append(params, query["class_id"])
  335. }
  336. if query["create_at"] != nil {
  337. if query["create_at"] == "desc" {
  338. sqlStr += "order by create_at desc "
  339. } else {
  340. sqlStr += "order by create_at asc "
  341. }
  342. } else if query["user_take_time"] != nil {
  343. if query["user_take_time"] == "desc" {
  344. sqlStr += "order by user_take_time desc "
  345. } else {
  346. sqlStr += "order by user_take_time asc "
  347. }
  348. } else if query["user_score"] != nil {
  349. if query["user_score"] == "desc" {
  350. sqlStr += "order by user_score desc "
  351. } else {
  352. sqlStr += "order by user_score asc "
  353. }
  354. } else {
  355. sqlStr += "order by create_at desc "
  356. }
  357. sqlStr += "limit ?,?"
  358. params = append(params, utils.PostionSize(page, size), size)
  359. var evos []*vo.ExamRecordVo1
  360. err := config.DB.Select(&evos, sqlStr, params...)
  361. if err != nil {
  362. return result.UNKNOW_ERROR.SetMsg(err.Error())
  363. }
  364. // 2、总数
  365. sqlStr = `select count(er.id)
  366. from exam_record er
  367. LEFT JOIN exam e ON er.exam_id = e.id
  368. LEFT JOIN test_paper tp ON e.tp_id = tp.id
  369. LEFT JOIN user u on er.user_id = u.id
  370. LEFT JOIN class c on u.class_id = c.id
  371. where e.id = ? and e.delete_at is null `
  372. params = []interface{}{examId}
  373. if query["name"] != nil {
  374. sqlStr += "and e.name like ? "
  375. params = append(params, "%"+query["name"].(string)+"%")
  376. }
  377. if query["class_id"] != nil {
  378. sqlStr += "and c.id = ? "
  379. params = append(params, query["class_id"])
  380. }
  381. var total int
  382. err = config.DB.Get(&total, sqlStr, params...)
  383. if err != nil {
  384. return result.UNKNOW_ERROR.SetMsg(err.Error())
  385. }
  386. return result.SUCCESS.SetData(result.NewPage(page, len(evos), total, evos))
  387. }
  388. func AdminDownloadExamRecord(file *excelize.File, id string) *result.Result {
  389. // 1、获取list
  390. sqlStr := `SELECT
  391. e.name exam_name,
  392. u.username,
  393. CONCAT(t.name,c.name,'>') term_class,
  394. u.username name,
  395. u.sid,
  396. er.create_at,
  397. er.update_at,
  398. inet_ntoa( er.ip ) ip,
  399. er.score user_score,
  400. timestampdiff( MINUTE, er.create_at, er.update_at ) user_take_time
  401. FROM
  402. exam e left join exam_record er on e.id = er.exam_id
  403. LEFT JOIN user u ON u.id = er.user_id
  404. LEFT JOIN class c ON u.class_id = c.id
  405. LEFT JOIN term t on c.term_id = t.id
  406. WHERE
  407. u.delete_at IS NULL and e.id = ?
  408. `
  409. var evos []*vo.ExamRecordVo2
  410. err := config.DB.Select(&evos, sqlStr, id)
  411. if err != nil {
  412. if err == sql.ErrNoRows {
  413. return result.DATA_NOT_FOUND
  414. }
  415. return result.UNKNOW_ERROR.SetMsg(err.Error())
  416. }
  417. file.SetCellValue("Sheet1", "A1", evos[0].ExamName)
  418. i := 4
  419. for _, evo := range evos {
  420. if evo.TermClass != nil {
  421. file.SetCellValue("Sheet1", "A"+strconv.Itoa(i), *evo.TermClass)
  422. }
  423. file.SetCellValue("Sheet1", "B"+strconv.Itoa(i), evo.Name)
  424. file.SetCellValue("Sheet1", "C"+strconv.Itoa(i), evo.Sid)
  425. file.SetCellValue("Sheet1", "D"+strconv.Itoa(i), evo.CreateAt.Format("2006-01-02 15:04:05"))
  426. file.SetCellValue("Sheet1", "E"+strconv.Itoa(i), evo.UpdateAt.Format("2006-01-02 15:04:05"))
  427. if evo.UserScore != nil {
  428. file.SetCellValue("Sheet1", "F"+strconv.Itoa(i), *evo.UserScore)
  429. }
  430. i++
  431. }
  432. return result.SUCCESS
  433. }