LingxinMeng 6 月之前
父节点
当前提交
2ae847b0ad

+ 0 - 1
amd64/web_server/src/domain/monitor/e_monitor.go

@@ -1 +0,0 @@
-package monitor

+ 17 - 0
amd64/web_server/src/infrastructure/global/global_var.go

@@ -0,0 +1,17 @@
+package global
+
+import (
+	"sync"
+	"time"
+)
+
+var (
+	CacheTeamName          sync.Map          // = make(map[string]time.Time)
+	HeartBeatTimeThreshold = 5 * time.Second // 心跳时间
+	DefaultTime            = time.Date(2006, time.January, 2, 15, 4, 5, 0, time.Local)
+
+	InitialPositionX = 565266.0482367771 // todo 需要比赛确认起点
+	InitialPositionY = 4329773.48728322  // todo 需要比赛确认起点
+	TrialBegin       = time.Date(2024, time.June, 16, 13, 00, 00, 0, time.Local)
+	TrialEnd         = time.Date(2024, time.June, 19, 23, 59, 59, 0, time.Local)
+)

+ 95 - 0
amd64/web_server/src/infrastructure/scheduler/exam_ticker.go

@@ -0,0 +1,95 @@
+package scheduler
+
+import (
+	"cicv-data-closedloop/amd64/web_server/src/domain/competition"
+	"cicv-data-closedloop/amd64/web_server/src/infrastructure/global"
+	"cicv-data-closedloop/common/config/c_db"
+	"cicv-data-closedloop/common/config/c_log"
+	"cicv-data-closedloop/common/util"
+	"fmt"
+	"time"
+)
+
+func ExamEndTicker() {
+	// 创建一个定时器,每隔一秒触发一次
+	ticker := time.NewTicker(1 * time.Second)
+	for {
+		select {
+		// 定时器触发时执行的代码
+		case <-ticker.C:
+			var keysToDelete []string
+			global.CacheTeamName.Range(func(teamName, heartBeatTimeAny interface{}) bool {
+				heartBeatTime, _ := util.AnyToTime(heartBeatTimeAny)
+				if time.Since(heartBeatTime) > global.HeartBeatTimeThreshold { // 检查缓存中的队名,如果超过心跳时间,则代表考试结束,删除缓存中的队名
+					c_log.GlobalLogger.Infof("队伍 %v 心跳超时,比赛结束。", teamName)
+					keysToDelete = append(keysToDelete, fmt.Sprintf("%v", teamName))
+				}
+				return true // 如果要终止遍历,返回 false
+			})
+
+			//for teamName, heartBeatTime := range cacheTeamName {
+			//	if time.Since(heartBeatTime) > heartBeatTimeThreshold { // 检查缓存中的队名,如果超过心跳时间,则代表考试结束,删除缓存中的队名
+			//		c_log.GlobalLogger.Infof("队伍 %v 心跳超时,比赛结束。", teamName)
+			//
+			//		keysToDelete = append(keysToDelete, teamName)
+			//	}
+			//}
+			for _, teamName := range keysToDelete { // 检查缓存中的队名,如果超过心跳时间,则代表考试结束,删除缓存中的队名
+				global.CacheTeamName.Delete(teamName)
+				//delete(cacheTeamName, teamName)
+				// 1 查询指定队伍的开始时间最新的考试是否有结束时间,如果有则不在处理,如果没有则更新
+				var result []competition.ExamPo
+				selectSql, err := util.ReadFile(c_db.SqlFilesMap["exam-select-latest-by-team_name.sql"])
+				if err != nil {
+					c_log.GlobalLogger.Error("读取sql文件报错:", err)
+					return
+				}
+				// 可以传参数
+				if err = c_db.MysqlDb.Select(&result, selectSql, teamName); err != nil {
+					c_log.GlobalLogger.Error("数据库查询报错:", err)
+					return
+				}
+				if !result[0].EndTime.Equal(defaultTime) {
+					c_log.GlobalLogger.Error("赛队", teamName, "考试已结束!")
+					return
+				}
+				// 更新到数据库(只更新最新一条)
+				stage := ""
+				if time.Now().Before(trialBegin) {
+					stage = "表演赛"
+				} else if time.Now().After(trialBegin) && time.Now().Before(trialEnd) {
+					stage = "预赛"
+				} else {
+					stage = "决赛"
+				}
+				// 查询最新一条的id
+				selectSql, err = util.ReadFile(c_db.SqlFilesMap["exam-select-max-id-by-team_name-and-topic.sql"])
+				if err != nil {
+					c_log.GlobalLogger.Error("读取sql文件报错:", err)
+					return
+				}
+				// 可以传参数
+				var resultId []int
+				if err = c_db.MysqlDb.Select(&resultId, selectSql, teamName, stage); err != nil {
+					c_log.GlobalLogger.Error("数据库查询报错:", err)
+					return
+				}
+				if len(resultId) == 1 {
+					c_log.GlobalLogger.Info("更新数据结束时间,id为:", resultId)
+
+					sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-update-end_time-by-id.sql"])
+					if err := c_db.DoTx(sqlTemplate, []any{
+						time.Now(),
+						resultId[0],
+					}); err != nil {
+						c_log.GlobalLogger.Error("插入数据报错:", err)
+						return
+					}
+				} else {
+					c_log.GlobalLogger.Error("查询id失败:", resultId)
+				}
+				c_log.GlobalLogger.Infof("队伍 %v 的考试结束。", teamName)
+			}
+		}
+	}
+}

+ 18 - 107
amd64/web_server/src/interfaces/api/h_exam.go

@@ -3,6 +3,7 @@ package api
 import (
 import (
 	"cicv-data-closedloop/amd64/web_server/src/domain/competition"
 	"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/config"
+	"cicv-data-closedloop/amd64/web_server/src/infrastructure/global"
 	"cicv-data-closedloop/amd64/web_server/src/infrastructure/persistence"
 	"cicv-data-closedloop/amd64/web_server/src/infrastructure/persistence"
 	"cicv-data-closedloop/common/config/c_db"
 	"cicv-data-closedloop/common/config/c_db"
 	"cicv-data-closedloop/common/config/c_log"
 	"cicv-data-closedloop/common/config/c_log"
@@ -19,20 +20,9 @@ import (
 	"net/http"
 	"net/http"
 	"os"
 	"os"
 	"strconv"
 	"strconv"
-	"sync"
 	"time"
 	"time"
 )
 )
 
 
-var (
-	defaultTime            = time.Date(2006, time.January, 2, 15, 4, 5, 0, time.Local)
-	cacheTeamName          sync.Map            // = make(map[string]time.Time)
-	heartBeatTimeThreshold = 5 * time.Second   // 心跳时间
-	InitialPositionX       = 565266.0482367771 // todo 需要比赛确认起点
-	InitialPositionY       = 4329773.48728322  // todo 需要比赛确认起点
-	trialBegin             = time.Date(2024, time.June, 16, 13, 00, 00, 0, time.Local)
-	trialEnd               = time.Date(2024, time.June, 19, 23, 59, 59, 0, time.Local)
-)
-
 // 考试心跳
 // 考试心跳
 func Tick(c *gin.Context) {
 func Tick(c *gin.Context) {
 	param := new(competition.ExamPao)
 	param := new(competition.ExamPao)
@@ -50,7 +40,7 @@ func Tick(c *gin.Context) {
 	var positionY float64
 	var positionY float64
 	numStr := param.PositionY
 	numStr := param.PositionY
 	_, _ = fmt.Sscanf(numStr, "%e", &positionY)
 	_, _ = fmt.Sscanf(numStr, "%e", &positionY)
-	if !util.ContainsKey(&cacheTeamName, teamName) && math.Abs(positionX-InitialPositionX) < 5.00 && math.Abs(positionY-InitialPositionY) < 5.00 { // (在起点开始)
+	if !util.ContainsKey(&global.CacheTeamName, teamName) && math.Abs(positionX-global.InitialPositionX) < 5.00 && math.Abs(positionY-global.InitialPositionY) < 5.00 { // (在起点开始)
 
 
 		result := persistence.SelectLatestByTeamName(teamName)
 		result := persistence.SelectLatestByTeamName(teamName)
 		if len(result) == 1 {
 		if len(result) == 1 {
@@ -59,11 +49,11 @@ func Tick(c *gin.Context) {
 			c_log.GlobalLogger.Infof("上一条数据记录为【%v】,距离当前时间为【%v】分钟", result[0].Id, temp)
 			c_log.GlobalLogger.Infof("上一条数据记录为【%v】,距离当前时间为【%v】分钟", result[0].Id, temp)
 			if temp < 2 {
 			if temp < 2 {
 				// 添加队伍名到缓存中
 				// 添加队伍名到缓存中
-				cacheTeamName.Store(teamName, time.Now())
+				global.CacheTeamName.Store(teamName, time.Now())
 				// 更新记录结束时间为默认时间
 				// 更新记录结束时间为默认时间
 				sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-reset-by-id.sql"])
 				sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-reset-by-id.sql"])
 				if err := c_db.DoTx(sqlTemplate, []any{
 				if err := c_db.DoTx(sqlTemplate, []any{
-					defaultTime,
+					global.DefaultTime,
 					result[0].Id,
 					result[0].Id,
 				}); err != nil {
 				}); err != nil {
 					c_log.GlobalLogger.Error("插入数据报错:", err)
 					c_log.GlobalLogger.Error("插入数据报错:", err)
@@ -80,16 +70,16 @@ func Tick(c *gin.Context) {
 		{
 		{
 			sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-insert-begin_time-and-topic-and-equipment_no-by-team_name.sql"])
 			sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-insert-begin_time-and-topic-and-equipment_no-by-team_name.sql"])
 			stage := ""
 			stage := ""
-			if time.Now().Before(trialBegin) {
+			if time.Now().Before(global.TrialBegin) {
 				stage = "表演赛"
 				stage = "表演赛"
-			} else if time.Now().After(trialBegin) && time.Now().Before(trialEnd) {
+			} else if time.Now().After(global.TrialBegin) && time.Now().Before(global.TrialEnd) {
 				stage = "预赛"
 				stage = "预赛"
 			} else {
 			} else {
 				stage = "决赛"
 				stage = "决赛"
 			}
 			}
 			competitionBegin := time.Now()
 			competitionBegin := time.Now()
 			// 添加队伍名到缓存中
 			// 添加队伍名到缓存中
-			cacheTeamName.Store(teamName, competitionBegin)
+			global.CacheTeamName.Store(teamName, competitionBegin)
 			c_log.GlobalLogger.Infof("当前比赛阶段为 %v ,队伍 %v 在起始点范围内第一次启动,保存新一条比赛记录的开始时间 %v", stage, 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 {
 			if err := c_db.DoTx(sqlTemplate, []any{param.TeamName, stage, competitionBegin, param.EquipmentNo}); err != nil {
 				c_log.GlobalLogger.Error("保存比赛开始时间报错:", err)
 				c_log.GlobalLogger.Error("保存比赛开始时间报错:", err)
@@ -103,19 +93,19 @@ func Tick(c *gin.Context) {
 			return
 			return
 		}
 		}
 
 
-	} else if !util.ContainsKey(&cacheTeamName, teamName) && (math.Abs(positionX-InitialPositionX) > 5.00 || math.Abs(positionY-InitialPositionY) > 5.00) { // 不在起点(开始)
+	} 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)
 		result := persistence.SelectLatestByTeamName(teamName)
 		if len(result) == 1 {
 		if len(result) == 1 {
 			if time.Since(result[0].EndTime).Minutes() <= 5 { // 5分钟之内重启就还算上一条数据
 			if time.Since(result[0].EndTime).Minutes() <= 5 { // 5分钟之内重启就还算上一条数据
 				c_log.GlobalLogger.Info("上一条数据记录为:", result[0])
 				c_log.GlobalLogger.Info("上一条数据记录为:", result[0])
 				// 添加队伍名到缓存中
 				// 添加队伍名到缓存中
-				cacheTeamName.Store(teamName, time.Now())
+				global.CacheTeamName.Store(teamName, time.Now())
 				//cacheTeamName[teamName] = time.Now()
 				//cacheTeamName[teamName] = time.Now()
 				// 更新记录结束时间为默认时间
 				// 更新记录结束时间为默认时间
 				sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-reset-by-id.sql"])
 				sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-reset-by-id.sql"])
 				if err := c_db.DoTx(sqlTemplate, []any{
 				if err := c_db.DoTx(sqlTemplate, []any{
-					defaultTime,
+					global.DefaultTime,
 					result[0].Id,
 					result[0].Id,
 				}); err != nil {
 				}); err != nil {
 					c_log.GlobalLogger.Error("插入数据报错:", err)
 					c_log.GlobalLogger.Error("插入数据报错:", err)
@@ -142,8 +132,8 @@ func Tick(c *gin.Context) {
 			return
 			return
 		}
 		}
 
 
-	} else if util.ContainsKey(&cacheTeamName, teamName) { // 进行中
-		cacheTeamName.Store(teamName, time.Now())
+	} else if util.ContainsKey(&global.CacheTeamName, teamName) { // 进行中
+		global.CacheTeamName.Store(teamName, time.Now())
 		//cacheTeamName[teamName] = time.Now()
 		//cacheTeamName[teamName] = time.Now()
 		c_log.GlobalLogger.Errorf("接收到心跳信息,队伍名字为 %s,x坐标为  %.f,y坐标为 %.f ", teamName, positionX, positionY)
 		c_log.GlobalLogger.Errorf("接收到心跳信息,队伍名字为 %s,x坐标为  %.f,y坐标为 %.f ", teamName, positionX, positionY)
 		c.JSON(http.StatusOK, commonEntity.Response{
 		c.JSON(http.StatusOK, commonEntity.Response{
@@ -161,90 +151,6 @@ func Tick(c *gin.Context) {
 	}
 	}
 }
 }
 
 
-func ExamEndTicker() {
-	// 创建一个定时器,每隔一秒触发一次
-	ticker := time.NewTicker(1 * time.Second)
-	for {
-		select {
-		// 定时器触发时执行的代码
-		case <-ticker.C:
-			var keysToDelete []string
-			cacheTeamName.Range(func(teamName, heartBeatTimeAny interface{}) bool {
-				heartBeatTime, _ := util.AnyToTime(heartBeatTimeAny)
-				if time.Since(heartBeatTime) > heartBeatTimeThreshold { // 检查缓存中的队名,如果超过心跳时间,则代表考试结束,删除缓存中的队名
-					c_log.GlobalLogger.Infof("队伍 %v 心跳超时,比赛结束。", teamName)
-					keysToDelete = append(keysToDelete, fmt.Sprintf("%v", teamName))
-				}
-				return true // 如果要终止遍历,返回 false
-			})
-
-			//for teamName, heartBeatTime := range cacheTeamName {
-			//	if time.Since(heartBeatTime) > heartBeatTimeThreshold { // 检查缓存中的队名,如果超过心跳时间,则代表考试结束,删除缓存中的队名
-			//		c_log.GlobalLogger.Infof("队伍 %v 心跳超时,比赛结束。", teamName)
-			//
-			//		keysToDelete = append(keysToDelete, teamName)
-			//	}
-			//}
-			for _, teamName := range keysToDelete { // 检查缓存中的队名,如果超过心跳时间,则代表考试结束,删除缓存中的队名
-				cacheTeamName.Delete(teamName)
-				//delete(cacheTeamName, teamName)
-				// 1 查询指定队伍的开始时间最新的考试是否有结束时间,如果有则不在处理,如果没有则更新
-				var result []competition.ExamPo
-				selectSql, err := util.ReadFile(c_db.SqlFilesMap["exam-select-latest-by-team_name.sql"])
-				if err != nil {
-					c_log.GlobalLogger.Error("读取sql文件报错:", err)
-					return
-				}
-				// 可以传参数
-				if err = c_db.MysqlDb.Select(&result, selectSql, teamName); err != nil {
-					c_log.GlobalLogger.Error("数据库查询报错:", err)
-					return
-				}
-				if !result[0].EndTime.Equal(defaultTime) {
-					c_log.GlobalLogger.Error("赛队", teamName, "考试已结束!")
-					return
-				}
-				// 更新到数据库(只更新最新一条)
-				stage := ""
-				if time.Now().Before(trialBegin) {
-					stage = "表演赛"
-				} else if time.Now().After(trialBegin) && time.Now().Before(trialEnd) {
-					stage = "预赛"
-				} else {
-					stage = "决赛"
-				}
-				// 查询最新一条的id
-				selectSql, err = util.ReadFile(c_db.SqlFilesMap["exam-select-max-id-by-team_name-and-topic.sql"])
-				if err != nil {
-					c_log.GlobalLogger.Error("读取sql文件报错:", err)
-					return
-				}
-				// 可以传参数
-				var resultId []int
-				if err = c_db.MysqlDb.Select(&resultId, selectSql, teamName, stage); err != nil {
-					c_log.GlobalLogger.Error("数据库查询报错:", err)
-					return
-				}
-				if len(resultId) == 1 {
-					c_log.GlobalLogger.Info("更新数据结束时间,id为:", resultId)
-
-					sqlTemplate, _ := util.ReadFile(c_db.SqlFilesMap["exam-update-end_time-by-id.sql"])
-					if err := c_db.DoTx(sqlTemplate, []any{
-						time.Now(),
-						resultId[0],
-					}); err != nil {
-						c_log.GlobalLogger.Error("插入数据报错:", err)
-						return
-					}
-				} else {
-					c_log.GlobalLogger.Error("查询id失败:", resultId)
-				}
-				c_log.GlobalLogger.Infof("队伍 %v 的考试结束。", teamName)
-			}
-		}
-	}
-}
-
 // 分页查询,如果日期为默认值,则返回空""
 // 分页查询,如果日期为默认值,则返回空""
 func Page(c *gin.Context) {
 func Page(c *gin.Context) {
 	param := new(competition.ExamPagePao)
 	param := new(competition.ExamPagePao)
@@ -643,7 +549,12 @@ func Report(c *gin.Context) {
 		c.String(http.StatusNotFound, "文件未找到")
 		c.String(http.StatusNotFound, "文件未找到")
 		return
 		return
 	}
 	}
-	defer file.Close()
+	defer func(file *os.File) {
+		err := file.Close()
+		if err != nil {
+			log.Fatal(err)
+		}
+	}(file)
 
 
 	// 将文件复制到响应主体
 	// 将文件复制到响应主体
 	_, err = io.Copy(c.Writer, file)
 	_, err = io.Copy(c.Writer, file)