123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495 |
- package dao
- import (
- "database/sql"
- "encoding/json"
- "exam_system/config"
- "exam_system/entity"
- "exam_system/result"
- "exam_system/utils"
- "exam_system/vo"
- "fmt"
- "strconv"
- "time"
- "github.com/gin-gonic/gin"
- "github.com/jmoiron/sqlx"
- uuid "github.com/satori/go.uuid"
- "github.com/xuri/excelize/v2"
- )
- func AddExamRecord(er *entity.ExamRecord) *result.Result {
- // 2、插入
- uuId := uuid.NewV4().String()
- sqlStr := "update exam_record er set create_at=?,update_at=?,token=?,ip=inet_aton(?),status=? where er.id = ? and er.user_id=?"
- _, err := config.DB.Exec(sqlStr, time.Now(), time.Now(), uuId, er.Ip, entity.TESTING, er.Id, er.UserId)
- if err != nil {
- return result.UNKNOW_ERROR.SetData(err)
- }
- return result.SuccessResult(gin.H{
- "id": er.Id,
- "token": uuId,
- })
- }
- func ExamRecordDetail(id, uid int) *result.Result {
- // 1、考试详情
- 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
- from user u left join exam_record er on u.id = er.user_id
- LEFT JOIN exam e ON e.id = er.exam_id
- LEFT JOIN test_paper tp ON e.tp_id = tp.id
- LEFT JOIN exam_class ec ON e.id = ec.exam_id
- LEFT JOIN class c ON ec.class_id = c.id
- where er.id = ? and u.id = ? and e.delete_at is null `
- var t vo.ExamRecordVo1
- err := config.DB.Get(&t, sqlStr, id, uid)
- if err != nil {
- if err == sql.ErrNoRows {
- return result.DATA_NOT_FOUND
- }
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- if t.PublishAt.After(time.Now()) {
- t.UserScore = nil
- }
- // 题目答案, 用户答案
- sqlStr = "select er.answer from exam_record er where er.id = ? and er.delete_at is null"
- var answerStr string
- err = config.DB.Get(&answerStr, sqlStr, id)
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- var avs []*vo.AnswerVo
- err = json.Unmarshal([]byte(answerStr), &avs)
- if err != nil {
- return result.FORMATE_ERROR
- }
- for i := 0; i < len(avs); i++ {
- var av vo.AnswerVo
- sqlStr = "select * from subject where id = ?"
- err = config.DB.Get(&av, sqlStr, avs[i].Id)
- if err != nil {
- if err == sql.ErrNoRows {
- continue
- }
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- if t.PublishAt.After(time.Now()) {
- av.Answer = ""
- }
- av.OwnAnswer = avs[i].OwnAnswer
- avs[i] = &av
- }
- return result.SuccessResult(gin.H{
- "exam_detail": &t,
- "subject": &avs,
- })
- }
- func ExamRecordList(page, size int, query map[string]interface{}, uid int) *result.Result {
- // 1、获取list
- 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
- from user u left join exam_record er on u.id = er.user_id
- LEFT JOIN exam e ON e.id = er.exam_id
- LEFT JOIN test_paper tp ON e.tp_id = tp.id
- LEFT JOIN exam_class ec ON e.id = ec.exam_id
- LEFT JOIN class c ON ec.class_id = c.id
- where u.id = ? and e.delete_at is null and er.status!=0 `
- params := []interface{}{uid}
- if query["name"] != nil {
- sqlStr += "and e.name like ? "
- params = append(params, "%"+query["name"].(string)+"%")
- }
- sqlStr += "group by er.id "
- if query["create_at"] != nil {
- if query["create_at"] == "desc" {
- sqlStr += "order by create_at desc "
- } else {
- sqlStr += "order by create_at asc "
- }
- } else if query["user_take_time"] != nil {
- if query["user_take_time"] == "desc" {
- sqlStr += "order by user_take_time desc "
- } else {
- sqlStr += "order by user_take_time asc "
- }
- } else if query["user_score"] != nil {
- if query["user_score"] == "desc" {
- sqlStr += "order by user_score desc "
- } else {
- sqlStr += "order by user_score asc "
- }
- } else {
- sqlStr += "order by create_at desc "
- }
- sqlStr += "limit ?,?"
- params = append(params, utils.PostionSize(page, size), size)
- var evos []*vo.ExamRecordVo1
- err := config.DB.Select(&evos, sqlStr, params...)
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- // 2、总数
- sqlStr = `select count(distinct(er.id))
- from user u left join exam_record er on u.id = er.user_id
- LEFT JOIN exam e ON e.id = er.exam_id
- LEFT JOIN test_paper tp ON e.tp_id = tp.id
- LEFT JOIN exam_class ec ON e.id = ec.exam_id
- LEFT JOIN class c ON ec.class_id = c.id
- where u.id = ? and e.delete_at is null and er.status!=0 `
- params = []interface{}{uid}
- if query["name"] != nil {
- sqlStr += "and e.name like ? "
- params = append(params, "%"+query["name"].(string)+"%")
- }
- sqlStr += "group by er.id"
- for _, e := range evos {
- if e.PublishAt.After(time.Now()) {
- e.UserScore = nil
- }
- }
- var total int
- err = config.DB.Get(&total, sqlStr, params...)
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- return result.SUCCESS.SetData(result.NewPage(page, len(evos), total, evos))
- }
- func UpdateExamRecord(erv *vo.ExamRecordVo) *result.Result {
- tx, err := config.DB.Beginx()
- return utils.Transation(tx, err, func(tx *sqlx.Tx) *result.Result {
- // 1、查询是否存在该记录
- sqlStr := `select er.id, er.exam_id
- from exam_record er
- left join exam e on e.id = er.exam_id
- where er.id = ?
- and er.token = ?
- and er.update_at - er.create_at <= e.duration
- and e.end_at > ?
- `
- err = tx.Get(erv, sqlStr, erv.Id, erv.Token, time.Now())
- if err != nil {
- if err == sql.ErrNoRows {
- return result.DATA_NOT_FOUND.SetMsg("该场考试已过期")
- }
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- sqlStr = "update exam_record set token = null,status = ? where id = ?"
- var res sql.Result
- _, err = tx.Exec(sqlStr, entity.TESTED, erv.Id)
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- // 2、查询出所需id
- sqlStr = "select c.sub_ids from chapter c left join exam e on c.tp_id = e.tp_id where e.id=?"
- var subIdStrs []string
- err = tx.Select(&subIdStrs, sqlStr, erv.ExamId)
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- subIds := make([]*vo.SubIdsVo, 0)
- for _, subIdStr := range subIdStrs {
- var subIdsVo []*vo.SubIdsVo
- err = json.Unmarshal([]byte(subIdStr), &subIdsVo)
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- subIds = append(subIds, subIdsVo...)
- }
- // 2.1 构造一个key为id的 map
- subIdMap := make(map[int]int, 0)
- for _, subId := range subIds {
- subIdMap[*subId.Id] = *subId.Score
- }
- // 2、 批量查询id
- toatalScore := 0
- for _, answerVo := range erv.AnswerVo {
- // 判断提交的试题是否在考试范围内
- if _, ok := subIdMap[*answerVo.Id]; !ok {
- return result.UNKNOW_ERROR.SetMsg("不存在该试题")
- }
- var score int
- sqlStr = "select count(id) from subject where id=? and answer=?"
- err = tx.Get(&score, sqlStr, answerVo.Id, utils.SubjectSort(answerVo.OwnAnswer))
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- toatalScore += score * subIdMap[*answerVo.Id]
- delete(subIdMap, *answerVo.Id)
- }
- if len(subIdMap) != 0 {
- return result.UNKNOW_ERROR.SetMsg("试题提交不完整")
- }
- var anwserData []byte
- anwserData, err = json.Marshal(erv.AnswerVo)
- // 插入记录表
- sqlStr = "update exam_record set score=?,answer=?,update_at=? where id=? and delete_at is null "
- res, err = tx.Exec(sqlStr, toatalScore, string(anwserData), time.Now(), erv.Id)
- if err != nil {
- return result.UNKNOW_ERROR.SetData(err)
- }
- affected, _ := res.RowsAffected()
- return result.SuccessResult(result.NewResultChange(affected))
- })
- }
- func DeleteExamRecords(ids []string) *result.Result {
- parm := []interface{}{time.Now()}
- parmStr := ""
- for k, id := range ids {
- parm = append(parm, id)
- if k == (len(ids) - 1) {
- parmStr += "?"
- } else {
- parmStr += "?,"
- }
- }
- sqlStr := fmt.Sprintf("update exam_record set delete_at=? where id in (%s)", parmStr)
- res, err := config.DB.Exec(sqlStr, parm...)
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- affected, _ := res.RowsAffected()
- return result.SUCCESS.SetData(result.NewResultChange(affected))
- }
- func AdminExamRecordDetail(id int) *result.Result {
- // 1、考试详情
- // 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
- //from exam_record er left join exam e on er.exam_id = e.id
- // left join test_paper tp on e.tp_id = tp.id
- // left join exam_class ec on e.id = ec.exam_id
- // left join class c on ec.class_id = c.id
- // left join user u on u.class_id = c.id
- // where er.id=? and e.delete_at is null
- // GROUP BY er.id`
- //
- // var t vo.ExamRecordVo1
- // err := config.DB.Get(&t, sqlStr, id)
- // if err != nil {
- // if err == sql.ErrNoRows {
- // return result.DATA_NOT_FOUND
- // }
- // return result.UNKNOW_ERROR.SetMsg(err.Error())
- // }
- // 题目答案, 用户答案
- sqlStr := "select er.answer from exam_record er where er.id = ? and er.delete_at is null"
- // ! 20240305 这里修改answer为*string类型 数据库为null值会报错
- var answerStr *string
- err := config.DB.Get(&answerStr, sqlStr, id)
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- if answerStr == nil {
- return result.UNKNOW_ERROR.SetMsg("试卷数据不存在!")
- }
- var avs []*vo.AnswerVo
- err = json.Unmarshal([]byte(*answerStr), &avs)
- if err != nil {
- return result.FORMATE_ERROR
- }
- for i := 0; i < len(avs); i++ {
- var av vo.AnswerVo
- sqlStr = "select * from subject where id = ?"
- err = config.DB.Get(&av, sqlStr, avs[i].Id)
- if err != nil {
- if err.Error() == "sql: no rows in result set" {
- continue
- }
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- av.OwnAnswer = avs[i].OwnAnswer
- if avs[i].OwnAnswer == "-1" {
- av.OwnAnswer = ""
- }
- avs[i] = &av
- }
- return result.SuccessResult(gin.H{
- //"exam_detail": &t,
- "subject": &avs,
- })
- }
- func AdminExamRecordList(page, size int, query map[string]interface{}, examId int) *result.Result {
- // 1、获取list
- sqlStr := `select er.id,
- 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,
- u.username,
- c.name classname,
- timestampdiff(minute, er.create_at, er.update_at) user_take_time
- from exam_record er
- LEFT JOIN exam e ON er.exam_id = e.id
- LEFT JOIN test_paper tp ON e.tp_id = tp.id
- LEFT JOIN user u on er.user_id = u.id
- LEFT JOIN class c on u.class_id = c.id
- where e.id = ?
- and e.delete_at is null `
- params := []interface{}{examId}
- if query["name"] != nil {
- sqlStr += "and e.name like ? "
- params = append(params, "%"+query["name"].(string)+"%")
- }
- if query["class_id"] != nil {
- sqlStr += "and c.id = ? "
- params = append(params, query["class_id"])
- }
- if query["create_at"] != nil {
- if query["create_at"] == "desc" {
- sqlStr += "order by create_at desc "
- } else {
- sqlStr += "order by create_at asc "
- }
- } else if query["user_take_time"] != nil {
- if query["user_take_time"] == "desc" {
- sqlStr += "order by user_take_time desc "
- } else {
- sqlStr += "order by user_take_time asc "
- }
- } else if query["user_score"] != nil {
- if query["user_score"] == "desc" {
- sqlStr += "order by user_score desc "
- } else {
- sqlStr += "order by user_score asc "
- }
- } else {
- sqlStr += "order by create_at desc "
- }
- sqlStr += "limit ?,?"
- params = append(params, utils.PostionSize(page, size), size)
- var evos []*vo.ExamRecordVo1
- err := config.DB.Select(&evos, sqlStr, params...)
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- // 2、总数
- sqlStr = `select count(er.id)
- from exam_record er
- LEFT JOIN exam e ON er.exam_id = e.id
- LEFT JOIN test_paper tp ON e.tp_id = tp.id
- LEFT JOIN user u on er.user_id = u.id
- LEFT JOIN class c on u.class_id = c.id
- where e.id = ? and e.delete_at is null `
- params = []interface{}{examId}
- if query["name"] != nil {
- sqlStr += "and e.name like ? "
- params = append(params, "%"+query["name"].(string)+"%")
- }
- if query["class_id"] != nil {
- sqlStr += "and c.id = ? "
- params = append(params, query["class_id"])
- }
- var total int
- err = config.DB.Get(&total, sqlStr, params...)
- if err != nil {
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- return result.SUCCESS.SetData(result.NewPage(page, len(evos), total, evos))
- }
- func AdminDownloadExamRecord(file *excelize.File, id string) *result.Result {
- // 1、获取list
- sqlStr := `SELECT
- e.name exam_name,
- u.username,
- CONCAT(t.name,c.name,'>') term_class,
- u.username name,
- u.sid,
- er.create_at,
- er.update_at,
- inet_ntoa( er.ip ) ip,
- er.score user_score,
- timestampdiff( MINUTE, er.create_at, er.update_at ) user_take_time
- FROM
- exam e left join exam_record er on e.id = er.exam_id
- LEFT JOIN user u ON u.id = er.user_id
- LEFT JOIN class c ON u.class_id = c.id
- LEFT JOIN term t on c.term_id = t.id
- WHERE
- u.delete_at IS NULL and e.id = ?
- `
- var evos []*vo.ExamRecordVo2
- err := config.DB.Select(&evos, sqlStr, id)
- if err != nil {
- if err == sql.ErrNoRows {
- return result.DATA_NOT_FOUND
- }
- return result.UNKNOW_ERROR.SetMsg(err.Error())
- }
- file.SetCellValue("Sheet1", "A1", evos[0].ExamName)
- i := 4
- for _, evo := range evos {
- if evo.TermClass != nil {
- file.SetCellValue("Sheet1", "A"+strconv.Itoa(i), *evo.TermClass)
- }
- file.SetCellValue("Sheet1", "B"+strconv.Itoa(i), evo.Name)
- file.SetCellValue("Sheet1", "C"+strconv.Itoa(i), evo.Sid)
- file.SetCellValue("Sheet1", "D"+strconv.Itoa(i), evo.CreateAt.Format("2006-01-02 15:04:05"))
- file.SetCellValue("Sheet1", "E"+strconv.Itoa(i), evo.UpdateAt.Format("2006-01-02 15:04:05"))
- if evo.UserScore != nil {
- file.SetCellValue("Sheet1", "F"+strconv.Itoa(i), *evo.UserScore)
- }
- i++
- }
- return result.SUCCESS
- }
|