|
@@ -1,610 +0,0 @@
|
|
|
-package api
|
|
|
-
|
|
|
-import (
|
|
|
- "cicv-data-closedloop/amd64/web_server/src/domain/competition"
|
|
|
- "cicv-data-closedloop/amd64/web_server/src/infrastructure/config"
|
|
|
- "cicv-data-closedloop/amd64/web_server/src/infrastructure/global"
|
|
|
- "cicv-data-closedloop/amd64/web_server/src/infrastructure/persistence"
|
|
|
- "cicv-data-closedloop/common/config/c_db"
|
|
|
- "cicv-data-closedloop/common/config/c_log"
|
|
|
- commonEntity "cicv-data-closedloop/common/entity"
|
|
|
- "cicv-data-closedloop/common/util"
|
|
|
- "database/sql"
|
|
|
- "encoding/json"
|
|
|
- "fmt"
|
|
|
- "github.com/gin-gonic/gin"
|
|
|
- "github.com/signintech/gopdf"
|
|
|
- "io"
|
|
|
- "log"
|
|
|
- "math"
|
|
|
- "net/http"
|
|
|
- "os"
|
|
|
- "strconv"
|
|
|
- "time"
|
|
|
-)
|
|
|
-
|
|
|
-// 考试心跳
|
|
|
-func Tick(c *gin.Context) {
|
|
|
- param := new(competition.ExamPao)
|
|
|
- // 映射到结构体
|
|
|
- if err := c.ShouldBindJSON(¶m); err != nil {
|
|
|
- c_log.GlobalLogger.Error("请求体解析失败,错误信息为:", err)
|
|
|
- c.JSON(http.StatusBadRequest, commonEntity.Response{
|
|
|
- Code: 500,
|
|
|
- Msg: "请求体解析失败。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- teamName := param.TeamName
|
|
|
- positionX, _ := strconv.ParseFloat(param.PositionX, 64)
|
|
|
- var positionY float64
|
|
|
- numStr := param.PositionY
|
|
|
- _, _ = fmt.Sscanf(numStr, "%e", &positionY)
|
|
|
- if !util.ContainsKey(&global.CacheTeamName, teamName) && math.Abs(positionX-global.InitialPositionX) < 5.00 && math.Abs(positionY-global.InitialPositionY) < 5.00 { // (在起点开始)
|
|
|
-
|
|
|
- result := persistence.SelectLatestByTeamName(teamName)
|
|
|
- if len(result) == 1 {
|
|
|
- // 判断上一条记录的开始时间和当前时间是否小于2分钟
|
|
|
- temp := time.Since(result[0].BeginTime).Minutes()
|
|
|
- c_log.GlobalLogger.Infof("上一条数据记录为【%v】,距离当前时间为【%v】分钟", result[0].Id, temp)
|
|
|
- if temp < 2 {
|
|
|
- // 添加队伍名到缓存中
|
|
|
- global.CacheTeamName.Store(teamName, time.Now())
|
|
|
- // 更新记录结束时间为默认时间
|
|
|
- sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-reset-by-id.sql"])
|
|
|
- if err := c_db.DoTx(sqlTemplate, []any{
|
|
|
- global.DefaultTime,
|
|
|
- result[0].Id,
|
|
|
- }); err != nil {
|
|
|
- c_log.GlobalLogger.Error("插入数据报错:", err)
|
|
|
- return
|
|
|
- }
|
|
|
- c_log.GlobalLogger.Infof("队伍 %v 的考试在起点重复启动后重新开始。", teamName)
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 200,
|
|
|
- Msg: "队伍 " + teamName + " 的考试在起点重复启动后重新开始。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
- {
|
|
|
- sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-insert-begin_time-and-topic-and-equipment_no-by-team_name.sql"])
|
|
|
- stage := ""
|
|
|
- if time.Now().Before(global.TrialBegin) {
|
|
|
- stage = "表演赛"
|
|
|
- } else if time.Now().After(global.TrialBegin) && time.Now().Before(global.TrialEnd) {
|
|
|
- stage = "预赛"
|
|
|
- } else {
|
|
|
- stage = "决赛"
|
|
|
- }
|
|
|
- competitionBegin := time.Now()
|
|
|
- // 添加队伍名到缓存中
|
|
|
- global.CacheTeamName.Store(teamName, competitionBegin)
|
|
|
- c_log.GlobalLogger.Infof("当前比赛阶段为 %v ,队伍 %v 在起始点范围内第一次启动,保存新一条比赛记录的开始时间 %v", stage, teamName, competitionBegin)
|
|
|
- if err := c_db.DoTx(sqlTemplate, []any{param.TeamName, stage, competitionBegin, param.EquipmentNo}); err != nil {
|
|
|
- c_log.GlobalLogger.Error("保存比赛开始时间报错:", err)
|
|
|
- c.JSON(http.StatusBadRequest, commonEntity.Response{Code: 500, Msg: "保存比赛开始时间报错。"})
|
|
|
- return
|
|
|
- }
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 200,
|
|
|
- Msg: "队伍 " + teamName + " 的考试开始。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- } else if !util.ContainsKey(&global.CacheTeamName, teamName) && (math.Abs(positionX-global.InitialPositionX) > 5.00 || math.Abs(positionY-global.InitialPositionY) > 5.00) { // 不在起点(开始)
|
|
|
- // 车辆不是在起点启动的自动驾驶模式
|
|
|
- result := persistence.SelectLatestByTeamName(teamName)
|
|
|
- if len(result) == 1 {
|
|
|
- if time.Since(result[0].EndTime).Minutes() <= 5 { // 5分钟之内重启就还算上一条数据
|
|
|
- c_log.GlobalLogger.Info("上一条数据记录为:", result[0])
|
|
|
- // 添加队伍名到缓存中
|
|
|
- global.CacheTeamName.Store(teamName, time.Now())
|
|
|
- //cacheTeamName[teamName] = time.Now()
|
|
|
- // 更新记录结束时间为默认时间
|
|
|
- sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-reset-by-id.sql"])
|
|
|
- if err := c_db.DoTx(sqlTemplate, []any{
|
|
|
- global.DefaultTime,
|
|
|
- result[0].Id,
|
|
|
- }); err != nil {
|
|
|
- c_log.GlobalLogger.Error("插入数据报错:", err)
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 500,
|
|
|
- Msg: "插入数据报错。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- c_log.GlobalLogger.Infof("队伍 %v 的考试在中途中断后重新开始。", teamName)
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 200,
|
|
|
- Msg: "队伍 " + teamName + " 的考试在中途中断后重新开始。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
- {
|
|
|
- c_log.GlobalLogger.Errorf("队伍 %v 的考试车辆 %v 未在起点开启自动驾驶模式,且今日无考试记录,错误启动自动驾驶模式。", param.TeamName, param.EquipmentNo)
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 400,
|
|
|
- Msg: "车辆未在起点开启自动驾驶模式,且今日无考试记录,错误启动自动驾驶模式。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- } else if util.ContainsKey(&global.CacheTeamName, teamName) { // 进行中
|
|
|
- global.CacheTeamName.Store(teamName, time.Now())
|
|
|
- //cacheTeamName[teamName] = time.Now()
|
|
|
- c_log.GlobalLogger.Errorf("接收到心跳信息,队伍名字为 %s,x坐标为 %.f,y坐标为 %.f ", teamName, positionX, positionY)
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 200,
|
|
|
- Msg: "队伍 " + teamName + " 的考试进行中,心跳接收成功。",
|
|
|
- })
|
|
|
- return
|
|
|
- } else {
|
|
|
- c_log.GlobalLogger.Errorf("接收到心跳信息但考试并未开始,队伍名字为 %s,x坐标为 %.f,y坐标为 %.f ", teamName, positionX, positionY)
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 200,
|
|
|
- Msg: "队伍 " + teamName + " 的考试未开始。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 分页查询,如果日期为默认值,则返回空""
|
|
|
-func Page(c *gin.Context) {
|
|
|
- param := new(competition.ExamPagePao)
|
|
|
- _ = c.ShouldBindJSON(¶m)
|
|
|
- resultPos, resultPosTotal := persistence.SelectPage(param.TeamName, param.Topic, (param.CurrentPage-1)*param.PageSize, param.PageSize)
|
|
|
- var resultVos []competition.ExamVo
|
|
|
- for _, po := range resultPos {
|
|
|
-
|
|
|
- resultVos = append(resultVos, competition.ExamVo{
|
|
|
- Id: po.Id,
|
|
|
- TeamName: po.TeamName,
|
|
|
- Topic: po.Topic,
|
|
|
- BeginTime: util.GetTimeString(po.BeginTime),
|
|
|
- EndTime: util.GetTimeString(po.EndTime),
|
|
|
- ScoreOnline: po.ScoreOnline,
|
|
|
- ScoreOffline: po.ScoreOffline,
|
|
|
- ScoreFinal: po.ScoreFinal,
|
|
|
- Details: po.Details.String,
|
|
|
- ScoreReportPath: po.ScoreReportPath,
|
|
|
- DeductScoreOffline_1_1: po.DeductScoreOffline_1_1,
|
|
|
- DeductScoreOffline_1_2: po.DeductScoreOffline_1_2,
|
|
|
- DeductScoreOffline_1_3: po.DeductScoreOffline_1_3,
|
|
|
- DeductScoreOffline_1_4: po.DeductScoreOffline_1_4,
|
|
|
- DeductScoreOffline_2_1: po.DeductScoreOffline_2_1,
|
|
|
- DeductScoreOffline_2_2: po.DeductScoreOffline_2_2,
|
|
|
- DeductScoreOffline_3_1: po.DeductScoreOffline_3_1,
|
|
|
- DeductScoreOffline_3_2: po.DeductScoreOffline_3_2,
|
|
|
- DeductScoreOffline_3_3: po.DeductScoreOffline_3_3,
|
|
|
- DeductScoreOffline_3_4: po.DeductScoreOffline_3_4,
|
|
|
- DeductScoreOffline_4_1: po.DeductScoreOffline_4_1,
|
|
|
- DeductScoreOffline_4_2: po.DeductScoreOffline_4_2,
|
|
|
- DeductScoreOffline_4_3: po.DeductScoreOffline_4_3,
|
|
|
- DeductScoreOffline_5_1: po.DeductScoreOffline_5_1,
|
|
|
- DeductScoreOffline_5_2: po.DeductScoreOffline_5_2,
|
|
|
- DeductScoreOffline_5_3: po.DeductScoreOffline_5_3,
|
|
|
- DeductScoreOffline_6_1: po.DeductScoreOffline_6_1,
|
|
|
- DeductScoreOffline_6_2: po.DeductScoreOffline_6_2,
|
|
|
- DeductScoreOffline_7_1: po.DeductScoreOffline_7_1,
|
|
|
- DeductScoreOffline_7_2: po.DeductScoreOffline_7_2,
|
|
|
- DeductScoreOffline_7_3: po.DeductScoreOffline_7_3,
|
|
|
- DeductScoreOffline_8_1: po.DeductScoreOffline_8_1,
|
|
|
- DeductScoreOffline_8_2: po.DeductScoreOffline_8_2,
|
|
|
- DeductScoreOffline_8_3: po.DeductScoreOffline_8_3,
|
|
|
- DeductScoreOffline_9_1: po.DeductScoreOffline_9_1,
|
|
|
- DeductScoreOffline_9_2: po.DeductScoreOffline_9_2,
|
|
|
- DeductScoreOffline_9_3: po.DeductScoreOffline_9_3,
|
|
|
- DeductScoreOffline_10_1: po.DeductScoreOffline_10_1,
|
|
|
- DeductScoreOffline_10_2: po.DeductScoreOffline_10_2,
|
|
|
- DeductScoreOffline_11_1: po.DeductScoreOffline_11_1,
|
|
|
- DeductScoreOffline_11_2: po.DeductScoreOffline_11_2,
|
|
|
- DeductScoreOffline_12_1: po.DeductScoreOffline_12_1,
|
|
|
- DeductScoreOffline_12_2: po.DeductScoreOffline_12_2,
|
|
|
- DeductScoreOffline_12_3: po.DeductScoreOffline_12_3,
|
|
|
- DeductScoreOffline_13_1: po.DeductScoreOffline_13_1,
|
|
|
- DeductScoreOffline_13_2: po.DeductScoreOffline_13_2,
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 200,
|
|
|
- Msg: "分页查询成功!",
|
|
|
- Data: resultVos,
|
|
|
- Total: resultPosTotal[0],
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-// 评分报告pdf下载
|
|
|
-func Report(c *gin.Context) {
|
|
|
- pdfName := util.NewShortUUID() + ".pdf"
|
|
|
- pdfPath := config.ApplicationYaml.Pdf.LocalDir + pdfName
|
|
|
- param := new(competition.ExamReportPao)
|
|
|
- // 映射到结构体
|
|
|
- if err := c.ShouldBindJSON(¶m); err != nil {
|
|
|
- c_log.GlobalLogger.Error("接收请求参数报错:", err)
|
|
|
- c.JSON(http.StatusBadRequest, commonEntity.Response{
|
|
|
- Code: 500,
|
|
|
- Msg: "请求体解析失败。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- // 查询打分详情
|
|
|
- var detailsResult []sql.NullString
|
|
|
- selectSql, err := util.ReadFile(c_db.SqlFilesMap["exam-select-details-by-id.sql"])
|
|
|
- if err != nil {
|
|
|
- c_log.GlobalLogger.Error("读取sql文件报错:", err)
|
|
|
- c.JSON(http.StatusBadRequest, commonEntity.Response{
|
|
|
- Code: 500,
|
|
|
- Msg: "读取sql文件报错。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- // 可以传参数
|
|
|
- if err = c_db.MysqlDb.Select(&detailsResult, selectSql, param.Id); err != nil {
|
|
|
- c_log.GlobalLogger.Error("数据库查询报错:", err)
|
|
|
- c.JSON(http.StatusBadRequest, commonEntity.Response{
|
|
|
- Code: 500,
|
|
|
- Msg: "数据库查询报错。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- details := detailsResult[0]
|
|
|
- if !details.Valid {
|
|
|
- c_log.GlobalLogger.Error("未评分完成,无法下载pdf报告:", err)
|
|
|
- c.JSON(http.StatusBadRequest, commonEntity.Response{
|
|
|
- Code: 500,
|
|
|
- Msg: "未评分完成,无法下载pdf报告。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- // 解析详情为数组
|
|
|
- var detailsDtos []competition.DetailsDto
|
|
|
- _ = json.Unmarshal([]byte(details.String), &detailsDtos)
|
|
|
-
|
|
|
- layout := "2006-01-02 15:04:05"
|
|
|
- beginTime, _ := time.Parse(layout, param.BeginTime)
|
|
|
- endTime, _ := time.Parse(layout, param.EndTime)
|
|
|
- // 1 根据ID查询数据
|
|
|
- // 2 根据数据生成pdf
|
|
|
- // 3 创建pdf文件
|
|
|
- {
|
|
|
- // 初始化 pdf 对象
|
|
|
- pdf := gopdf.GoPdf{}
|
|
|
- pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4})
|
|
|
- // 添加字体文件到pdf
|
|
|
- err := pdf.AddTTFFont("simfang", config.ApplicationYaml.Pdf.Ttf)
|
|
|
- if err != nil {
|
|
|
- log.Print(err.Error())
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- leftMargin := 70.0
|
|
|
- topMargin := 100.0
|
|
|
- lineHeight := 25.0
|
|
|
- tableWidth := 450.0
|
|
|
- pdf.SetLeftMargin(leftMargin) // 设置左边距
|
|
|
- alignOptionText := gopdf.CellOption{Align: gopdf.Left | gopdf.Middle}
|
|
|
- //alignOptionText2 := gopdf.CellOption{Align: gopdf.Center | gopdf.Middle}
|
|
|
- alignOptionTable := gopdf.CellOption{Align: gopdf.Center | gopdf.Middle, Border: gopdf.Left | gopdf.Right | gopdf.Bottom | gopdf.Top}
|
|
|
- alignOptionTable2 := gopdf.CellOption{Align: gopdf.Left | gopdf.Middle}
|
|
|
-
|
|
|
- // ------- 封面页 -------
|
|
|
- pdf.AddPage()
|
|
|
- {
|
|
|
- err = pdf.SetFont("simfang", "", 36)
|
|
|
- err = pdf.Image(config.ApplicationYaml.Pdf.BackgroundPng, 0, 0, nil) // 背景图片
|
|
|
- err = pdf.Image(config.ApplicationYaml.Pdf.LogoPng, 20, 20, &gopdf.Rect{W: 320, H: 100})
|
|
|
- {
|
|
|
- pdf.SetXY(100, 250)
|
|
|
- _ = pdf.Text("车路云一体化算法挑战赛")
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(220, 315) // 200
|
|
|
- _ = pdf.Text("评分报告")
|
|
|
- }
|
|
|
- _ = pdf.SetFont("simfang", "", 14)
|
|
|
- currentLine := 0.0
|
|
|
- tableCellWidth := 100.0
|
|
|
- tableLeftMartin := 190.0
|
|
|
- tableTopMartin := 500.0
|
|
|
- {
|
|
|
- {
|
|
|
- pdf.SetXY(tableLeftMartin, tableTopMartin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: 100, H: lineHeight}, "赛队编号:", alignOptionTable2)
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(tableLeftMartin+1.0*tableCellWidth, tableTopMartin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: 100, H: lineHeight}, param.TeamName, alignOptionTable2)
|
|
|
- }
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- {
|
|
|
- {
|
|
|
- pdf.SetXY(tableLeftMartin, tableTopMartin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: 100, H: lineHeight}, "评测车型:", alignOptionTable2)
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(tableLeftMartin+1.0*tableCellWidth, tableTopMartin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: 100, H: lineHeight}, "多功能车平台", alignOptionTable2)
|
|
|
- }
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- {
|
|
|
- {
|
|
|
- pdf.SetXY(tableLeftMartin, tableTopMartin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: 100, H: lineHeight}, "评测地点:", alignOptionTable2)
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(tableLeftMartin+1.0*tableCellWidth, tableTopMartin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: 100, H: lineHeight}, "天津生态城", alignOptionTable2)
|
|
|
- }
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- {
|
|
|
- {
|
|
|
- pdf.SetXY(tableLeftMartin, tableTopMartin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: 100, H: lineHeight}, "报告时间:", alignOptionTable2)
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(tableLeftMartin+1.0*tableCellWidth, tableTopMartin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: 100, H: lineHeight}, time.Now().Format("2006年01月02日"), alignOptionTable2)
|
|
|
- }
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(165, 775)
|
|
|
- _ = pdf.Cell(nil, "国汽(北京)智能网联汽车研究院有限公司")
|
|
|
- }
|
|
|
- }
|
|
|
- // todo 先不要目录页
|
|
|
- //// ------- 目录页 -------
|
|
|
- //{
|
|
|
- // pdf.AddPage()
|
|
|
- // currentLine := 0.0
|
|
|
- // {
|
|
|
- // err = pdf.SetFont("simfang", "", 18)
|
|
|
- // pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- // _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "目录", alignOptionText2)
|
|
|
- // currentLine++
|
|
|
- // currentLine++
|
|
|
- // }
|
|
|
- // {
|
|
|
- // err = pdf.SetFont("simfang", "", 14)
|
|
|
- // pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- // currentLine++
|
|
|
- // _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "1. 总体情况 ............................... 1", alignOptionText)
|
|
|
- // }
|
|
|
- //}
|
|
|
- // ------- 详情页 第一页 -------
|
|
|
- {
|
|
|
- pdf.AddPage()
|
|
|
- currentLine := 0.0
|
|
|
- // 1. 总体分数情况
|
|
|
- {
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "1. 总体分数情况", alignOptionText)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- //{
|
|
|
- // pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- // _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "整体得分:"+util.ToString(param.ScoreFinal), alignOptionText)
|
|
|
- // currentLine++
|
|
|
- //}
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "线上得分:"+util.ToString(param.ScoreOnline), alignOptionText)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- //{
|
|
|
- // pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- // _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "线下得分:", alignOptionText)
|
|
|
- // currentLine++
|
|
|
- //}
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "整体耗时:"+endTime.Sub(beginTime).String(), alignOptionText)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- }
|
|
|
- // 2. 分数详情
|
|
|
- {
|
|
|
- //columnNumber := 4.0 // 列数
|
|
|
- //tableCellWidth := tableWidth / columnNumber // 单元格宽度
|
|
|
- tableCellWidth1 := 50.0
|
|
|
- tableCellWidth2 := 300.0
|
|
|
- tableCellWidth3 := 70.0
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "2. 分数详情", alignOptionText)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- // 分数详情表格
|
|
|
- {
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableCellWidth1, H: lineHeight}, "序号", alignOptionTable)
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin+tableCellWidth1, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableCellWidth2, H: lineHeight}, "场景名称", alignOptionTable)
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin+tableCellWidth1+tableCellWidth2, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableCellWidth3, H: lineHeight}, "线上得分", alignOptionTable)
|
|
|
- }
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- for i := 0; i < len(detailsDtos); i++ {
|
|
|
- {
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableCellWidth1, H: lineHeight}, util.ToString(i+1), alignOptionTable)
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin+tableCellWidth1, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableCellWidth2, H: lineHeight}, detailsDtos[i].SceneName, alignOptionTable)
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin+tableCellWidth1+tableCellWidth2, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableCellWidth3, H: lineHeight}, util.ToString(detailsDtos[i].TotalScore+detailsDtos[i].DeductedScore), alignOptionTable)
|
|
|
- }
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- // ------- 详情页 第二页 -------
|
|
|
- var detailsDtos2 []competition.DetailsDto // 扣分的场景
|
|
|
- for _, detailsDto := range detailsDtos {
|
|
|
- if detailsDto.Reason != "" {
|
|
|
- detailsDtos2 = append(detailsDtos2, detailsDto)
|
|
|
- }
|
|
|
- }
|
|
|
- size := len(detailsDtos2)
|
|
|
- {
|
|
|
- pdf.AddPage()
|
|
|
- currentLine := 0.0
|
|
|
- // 3. 线上扣分详情
|
|
|
- {
|
|
|
- tableCellWidth := 450.0 // 单元格宽度
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "3. 线上扣分详情", alignOptionText)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- for i := 0; i < 8; i++ {
|
|
|
- // 场景1
|
|
|
- {
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "("+util.ToString(i+1)+")"+detailsDtos2[i].SceneName, alignOptionText)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableCellWidth, H: lineHeight}, "扣分说明", alignOptionTable)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableCellWidth, H: lineHeight}, detailsDtos2[i].Reason, alignOptionTable)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // ------- 详情页 第三页 -------
|
|
|
-
|
|
|
- if size > 8 {
|
|
|
- pdf.AddPage()
|
|
|
- currentLine := 0.0
|
|
|
- // 3. 线上扣分详情
|
|
|
- {
|
|
|
- tableCellWidth := 450.0 // 单元格宽度
|
|
|
- for i := 8; i < len(detailsDtos2); i++ {
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "("+util.ToString(i+1)+")"+detailsDtos2[i].SceneName, alignOptionText)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableCellWidth, H: lineHeight}, "扣分说明", alignOptionTable)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- {
|
|
|
- pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- _ = pdf.CellWithOption(&gopdf.Rect{W: tableCellWidth, H: lineHeight}, detailsDtos2[i].Reason, alignOptionTable)
|
|
|
- currentLine++
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //// 4 作品优化建议
|
|
|
- //{
|
|
|
- // pdf.SetXY(leftMargin, topMargin+currentLine*lineHeight)
|
|
|
- // _ = pdf.CellWithOption(&gopdf.Rect{W: tableWidth, H: lineHeight}, "4. 作品优化建议", alignOptionText)
|
|
|
- // currentLine++
|
|
|
- //}
|
|
|
- }
|
|
|
- //// ------- 附录页 -------
|
|
|
- //pdf.AddPage()
|
|
|
- //{
|
|
|
- // pdf.SetXY(leftMargin, topMargin)
|
|
|
- // _ = pdf.Text("附件:评分规则")
|
|
|
- // pdf.AddExternalLink("https://www.baidu.com/", leftMargin, topMargin-lineHeight, 6*14, lineHeight)
|
|
|
- //}
|
|
|
- // 写入本地
|
|
|
- _ = pdf.WritePdf(pdfPath)
|
|
|
- }
|
|
|
-
|
|
|
- // 打开要发送的文件
|
|
|
- file, err := os.Open(pdfPath)
|
|
|
- if err != nil {
|
|
|
- c.String(http.StatusNotFound, "文件未找到")
|
|
|
- return
|
|
|
- }
|
|
|
- defer func(file *os.File) {
|
|
|
- err := file.Close()
|
|
|
- if err != nil {
|
|
|
- log.Fatal(err)
|
|
|
- }
|
|
|
- }(file)
|
|
|
-
|
|
|
- // 将文件复制到响应主体
|
|
|
- _, err = io.Copy(c.Writer, file)
|
|
|
- if err != nil {
|
|
|
- c.String(http.StatusInternalServerError, "无法复制文件到响应体")
|
|
|
- return
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 云控展示线上评分
|
|
|
-func Display(c *gin.Context) {
|
|
|
- exam := persistence.SelectAllFromExam()
|
|
|
- if exam == nil || len(exam) == 0 {
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 500,
|
|
|
- Msg: "未查询到成绩,比赛尚未开始。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 200,
|
|
|
- Msg: "查询成功。",
|
|
|
- Data: exam,
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-// 云控录入线下成绩
|
|
|
-func Offline(c *gin.Context) {
|
|
|
- param := new(competition.ExamOfflinePao)
|
|
|
- // 映射到结构体
|
|
|
- if err := c.ShouldBindJSON(¶m); err != nil {
|
|
|
- c_log.GlobalLogger.Error("接收请求参数报错:", err)
|
|
|
- c.JSON(http.StatusBadRequest, commonEntity.Response{
|
|
|
- Code: 500,
|
|
|
- Msg: "请求体解析失败。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- if param.Topic != "表演赛" && param.Topic != "预赛" && param.Topic != "决赛" {
|
|
|
- c_log.GlobalLogger.Error("比赛阶段错误:", param.Topic)
|
|
|
- c.JSON(http.StatusBadRequest, commonEntity.Response{
|
|
|
- Code: 400,
|
|
|
- Msg: "比赛阶段错误(表演赛、预赛、决赛)。",
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- // todo 这里可能会修改多条数据
|
|
|
- persistence.UpdateDeductScoreOffline(param)
|
|
|
- c.JSON(http.StatusOK, commonEntity.Response{
|
|
|
- Code: 200,
|
|
|
- Msg: "线下成绩录入成功。",
|
|
|
- })
|
|
|
-}
|