2023-07-28 14:36:16 +08:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2023-07-31 17:27:05 +08:00
|
|
|
"fmt"
|
2023-07-28 14:36:16 +08:00
|
|
|
"net/http"
|
2023-07-31 17:27:05 +08:00
|
|
|
"strconv"
|
2023-07-28 14:36:16 +08:00
|
|
|
|
|
|
|
jwt "github.com/appleboy/gin-jwt/v2"
|
|
|
|
"github.com/gin-gonic/gin"
|
2023-07-31 17:27:05 +08:00
|
|
|
"github.com/golang/protobuf/proto"
|
2023-07-28 14:36:16 +08:00
|
|
|
"go.uber.org/zap"
|
2023-07-31 17:27:05 +08:00
|
|
|
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
|
|
|
|
"joylink.club/bj-rtsts-server/ats/verify/protos/state"
|
2023-07-31 08:41:42 +08:00
|
|
|
"joylink.club/bj-rtsts-server/ats/verify/simulation"
|
2023-08-01 14:54:11 +08:00
|
|
|
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/memory"
|
2023-07-28 14:36:16 +08:00
|
|
|
"joylink.club/bj-rtsts-server/dto"
|
2023-07-31 08:41:42 +08:00
|
|
|
apiproto "joylink.club/bj-rtsts-server/grpcproto"
|
2023-08-30 09:28:21 +08:00
|
|
|
"joylink.club/bj-rtsts-server/middleware"
|
2023-08-01 17:08:45 +08:00
|
|
|
"joylink.club/bj-rtsts-server/service"
|
2023-07-28 14:36:16 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
func InitSimulationRouter(api *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
|
2023-08-30 09:28:21 +08:00
|
|
|
authed := api.Group("/v1/simulation").Use(authMiddleware.MiddlewareFunc(), middleware.PermissMiddleware)
|
2023-07-28 14:36:16 +08:00
|
|
|
authed.POST("/create", create)
|
2023-08-30 13:25:57 +08:00
|
|
|
authed.POST("/createByProject", createByProjectId)
|
2023-08-01 17:08:45 +08:00
|
|
|
authed.GET("/state/:id", findSimulationState)
|
2023-07-28 17:24:58 +08:00
|
|
|
authed.POST("/destroy/:id", destroy)
|
2023-07-28 15:49:44 +08:00
|
|
|
authed.GET("/list", findAllSimulations)
|
|
|
|
authed.POST("/check/data", checkSimMapData)
|
2023-07-31 17:27:05 +08:00
|
|
|
authed.POST("/train/add", addTrain)
|
2023-07-28 15:49:44 +08:00
|
|
|
authed.POST("/train/remove", removeTrain)
|
|
|
|
authed.POST("/switch/operation", switchOperation)
|
2023-07-31 08:41:42 +08:00
|
|
|
|
2023-08-01 17:08:45 +08:00
|
|
|
// 初始化地图信息
|
|
|
|
initPublishMapInfo()
|
2023-07-31 08:41:42 +08:00
|
|
|
apiproto.RegisterMsgServer(&apiproto.SimulationServer{})
|
2023-08-30 13:25:57 +08:00
|
|
|
apiproto.RegisterMsgServer(&apiproto.MemoryChangeServer{})
|
2023-07-28 14:36:16 +08:00
|
|
|
}
|
|
|
|
|
2023-08-01 17:08:45 +08:00
|
|
|
func initPublishMapInfo() {
|
2023-08-01 17:16:16 +08:00
|
|
|
mapArr, err := service.ListAllPublishedGi()
|
2023-08-01 17:08:45 +08:00
|
|
|
if err != nil {
|
|
|
|
panic("地图加载出错")
|
|
|
|
}
|
|
|
|
for _, v := range mapArr {
|
|
|
|
memory.PublishMapVerifyStructure(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-28 14:36:16 +08:00
|
|
|
// 创建ATS测试仿真
|
|
|
|
//
|
|
|
|
// @Summary 创建ATS测试仿真
|
|
|
|
//
|
|
|
|
// @Security JwtAuth
|
|
|
|
//
|
|
|
|
// @Description 创建ATS测试仿真
|
|
|
|
// @Tags ATS测试仿真Api
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
// @Param Authorization header string true "JWT Token"
|
|
|
|
// @Param SimulationCreateReqDto body dto.SimulationCreateReqDto true "创建仿真请求"
|
|
|
|
// @Success 200 {object} dto.SimulationCreateRspDto
|
|
|
|
// @Failure 500 {object} dto.ErrorDto
|
|
|
|
// @Router /api/v1/simulation/create [post]
|
|
|
|
func create(c *gin.Context) {
|
2023-08-30 18:05:11 +08:00
|
|
|
if simulation.IsExistSimulation() {
|
|
|
|
panic(dto.ErrorDto{Code: dto.DataAlreadyExist, Message: "已有仿真在运行"})
|
|
|
|
}
|
2023-07-28 14:36:16 +08:00
|
|
|
req := dto.SimulationCreateReqDto{}
|
|
|
|
if err := c.ShouldBind(&req); nil != err {
|
2023-08-30 18:05:11 +08:00
|
|
|
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
|
2023-07-28 14:36:16 +08:00
|
|
|
}
|
|
|
|
zap.S().Debug("创建仿真请求:", req)
|
2023-07-31 17:27:05 +08:00
|
|
|
rsp := dto.SimulationCreateRspDto{
|
|
|
|
MapId: req.MapId,
|
2023-07-28 14:36:16 +08:00
|
|
|
}
|
2023-08-30 13:25:57 +08:00
|
|
|
rsp.SimulationId = simulation.CreateSimulation(req.MapId, req.ProjectId)
|
|
|
|
c.JSON(http.StatusOK, &rsp)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 创建ATS测试仿真通过项目ID
|
|
|
|
//
|
|
|
|
// @Summary 创建ATS测试仿真
|
|
|
|
//
|
|
|
|
// @Security JwtAuth
|
|
|
|
//
|
|
|
|
// @Description 创建ATS测试仿真通过项目ID
|
|
|
|
// @Tags ATS测试仿真Api
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
// @Param Authorization header string true "JWT Token"
|
|
|
|
// @Param SimulationCreateReqDto body dto.SimulationCreateReqDto true "创建仿真请求"
|
|
|
|
// @Success 200 {object} dto.SimulationCreateRspDto
|
|
|
|
// @Failure 500 {object} dto.ErrorDto
|
|
|
|
// @Router /api/v1/simulation/createByProject [post]
|
|
|
|
func createByProjectId(c *gin.Context) {
|
2023-08-30 18:05:11 +08:00
|
|
|
if simulation.IsExistSimulation() {
|
|
|
|
panic(dto.ErrorDto{Code: dto.DataAlreadyExist, Message: "已有仿真在运行"})
|
|
|
|
}
|
2023-08-30 13:25:57 +08:00
|
|
|
req := dto.SimulationCreateReqDto{}
|
|
|
|
if err := c.ShouldBind(&req); nil != err {
|
2023-08-30 18:05:11 +08:00
|
|
|
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
|
2023-08-30 13:25:57 +08:00
|
|
|
}
|
|
|
|
zap.S().Debug("创建仿真请求:", req)
|
|
|
|
rsp := dto.SimulationCreateRspDto{
|
|
|
|
ProjectId: req.ProjectId,
|
|
|
|
}
|
|
|
|
mapInfos := service.QueryPublishedGi(req.ProjectId)
|
|
|
|
if len(mapInfos) == 0 {
|
|
|
|
panic(dto.ErrorDto{Code: dto.DataNotExist, Message: "项目未关联地图"})
|
|
|
|
}
|
|
|
|
mapInfo := mapInfos[0]
|
2023-08-30 18:05:11 +08:00
|
|
|
rsp.MapId = mapInfo.ID
|
2023-08-30 13:25:57 +08:00
|
|
|
rsp.SimulationId = simulation.CreateSimulation(mapInfo.ID, req.ProjectId)
|
2023-07-28 14:36:16 +08:00
|
|
|
c.JSON(http.StatusOK, &rsp)
|
|
|
|
}
|
2023-07-28 15:49:44 +08:00
|
|
|
|
2023-08-01 17:08:45 +08:00
|
|
|
// 创建并进入仿真后获取仿真的设备信息
|
|
|
|
//
|
|
|
|
// @Summary 创建并进入仿真后获取仿真的设备信息
|
|
|
|
//
|
|
|
|
// @Security JwtAuth
|
|
|
|
//
|
|
|
|
// @Description 创建并进入仿真后获取仿真的设备信息
|
|
|
|
// @Tags ATS测试仿真Api
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
// @Param Authorization header string true "JWT Token"
|
2023-08-30 13:25:57 +08:00
|
|
|
// @Param id path int true "仿真id"
|
2023-08-01 17:08:45 +08:00
|
|
|
// @Success 200 {object} dto.SimulationCreateRspDto
|
|
|
|
// @Failure 500 {object} dto.ErrorDto
|
2023-08-30 13:25:57 +08:00
|
|
|
// @Router /api/v1/simulation/state/:id [get]
|
2023-08-01 17:08:45 +08:00
|
|
|
func findSimulationState(c *gin.Context) {
|
|
|
|
simId := c.Param("id")
|
|
|
|
simulation := checkDeviceDataAndReturn(simId)
|
|
|
|
allState := simulation.GetAllState()
|
|
|
|
c.JSON(http.StatusOK, allState)
|
|
|
|
}
|
|
|
|
|
2023-07-28 15:49:44 +08:00
|
|
|
// ATS仿真销毁
|
|
|
|
//
|
|
|
|
// @Summary ATS仿真销毁
|
|
|
|
//
|
|
|
|
// @Security JwtAuth
|
|
|
|
//
|
|
|
|
// @Description ATS测试仿真-添加列车
|
|
|
|
// @Tags ATS测试仿真Api
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
// @Param Authorization header string true "JWT Token"
|
|
|
|
// @Param id path int true "仿真id"
|
|
|
|
// @Success 200 {object} string
|
|
|
|
// @Failure 500 {object} dto.ErrorDto
|
2023-07-31 15:44:08 +08:00
|
|
|
// @Router /api/v1/simulation/destroy/{id} [post]
|
2023-07-28 15:49:44 +08:00
|
|
|
func destroy(c *gin.Context) {
|
|
|
|
simId := c.Param("id")
|
|
|
|
zap.S().Debug("ATS测试仿真-ATS仿真销毁 请求:", simId)
|
2023-07-31 15:44:08 +08:00
|
|
|
simulation.DestroySimulation(simId)
|
2023-07-28 15:49:44 +08:00
|
|
|
c.JSON(http.StatusOK, "ok")
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取ATS测试系统所有仿真实例的基本信息
|
|
|
|
//
|
2023-08-30 13:25:57 +08:00
|
|
|
// @Summary 获取ATS测试系统所有仿真实例的基本信息
|
2023-07-28 15:49:44 +08:00
|
|
|
//
|
2023-08-30 13:25:57 +08:00
|
|
|
// @Security JwtAuth
|
2023-07-28 15:49:44 +08:00
|
|
|
//
|
2023-08-30 13:25:57 +08:00
|
|
|
// @Description 获取ATS测试系统所有仿真实例的基本信息
|
|
|
|
// @Tags ATS测试仿真Api
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
// @Param Authorization header string true "JWT Token"
|
|
|
|
// @Success 200 {object} dto.SimulationInfoRspDtoArr
|
2023-07-28 15:49:44 +08:00
|
|
|
// @Failure 500 {object} dto.ErrorDto
|
2023-08-30 13:25:57 +08:00
|
|
|
// @Router /api/v1/simulation/list [get]
|
2023-07-28 15:49:44 +08:00
|
|
|
func findAllSimulations(c *gin.Context) {
|
2023-08-01 14:54:11 +08:00
|
|
|
c.JSON(http.StatusOK, simulation.ListAllSimulations())
|
2023-07-28 15:49:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// ATS测试仿真地图数据校验
|
|
|
|
//
|
|
|
|
// @Summary ATS测试仿真地图数据校验
|
|
|
|
//
|
|
|
|
// @Security JwtAuth
|
|
|
|
//
|
2023-08-30 13:25:57 +08:00
|
|
|
// @Description 地图数据校验
|
2023-07-28 15:49:44 +08:00
|
|
|
// @Tags ATS测试仿真Api
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
// @Param Authorization header string true "JWT Token"
|
|
|
|
// @Param RemoveTrainDto body dto.CheckMapDataReqDto true "ATS测试仿真-地图数据"
|
|
|
|
//
|
|
|
|
// @Success 200 {object} dto.CheckMapDataRspDto
|
|
|
|
// @Failure 500 {object} dto.ErrorDto
|
|
|
|
// @Router /api/v1/simulation/check/data [post]
|
|
|
|
func checkSimMapData(c *gin.Context) {
|
2023-07-31 17:27:05 +08:00
|
|
|
rt := &dto.CheckMapDataReqDto{}
|
|
|
|
if err := c.ShouldBind(&rt); nil != err {
|
2023-08-30 18:05:11 +08:00
|
|
|
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
|
2023-07-31 17:27:05 +08:00
|
|
|
}
|
|
|
|
err := proto.Unmarshal(rt.Data, &graphicData.RtssGraphicStorage{})
|
2023-07-28 15:49:44 +08:00
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusInternalServerError, "参数错误")
|
|
|
|
} else {
|
2023-07-31 17:27:05 +08:00
|
|
|
c.JSON(http.StatusOK, &dto.CheckMapDataRspDto{Success: true})
|
2023-07-28 15:49:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-31 17:27:05 +08:00
|
|
|
// ATS测试仿真-添加列车
|
|
|
|
//
|
|
|
|
// @Summary ATS测试仿真-添加列车
|
|
|
|
//
|
|
|
|
// @Security JwtAuth
|
|
|
|
//
|
|
|
|
// @Description ATS测试仿真-添加列车
|
|
|
|
// @Tags ATS测试仿真Api
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
// @Param Authorization header string true "JWT Token"
|
|
|
|
// @Param AddTrainReqDto body dto.AddTrainReqDto true "ATS测试仿真-添加列车"
|
|
|
|
// @Success 200 {object} dto.AddTrainRspDto
|
|
|
|
// @Failure 500 {object} dto.ErrorDto
|
|
|
|
// @Router /api/v1/simulation/train/add [post]
|
|
|
|
func addTrain(c *gin.Context) {
|
|
|
|
req := dto.AddTrainReqDto{}
|
|
|
|
if err := c.ShouldBind(&req); err != nil {
|
2023-08-30 18:05:11 +08:00
|
|
|
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
|
2023-07-31 17:27:05 +08:00
|
|
|
}
|
2023-08-01 17:08:45 +08:00
|
|
|
simulation := checkDeviceDataAndReturn(req.SimulationId)
|
2023-08-22 16:44:34 +08:00
|
|
|
id := getAddTrainPrimaryKey(simulation)
|
|
|
|
if id == -1 {
|
|
|
|
c.JSON(http.StatusBadRequest, "已存在在线列车")
|
|
|
|
} else {
|
|
|
|
rsp := &state.TrainState{
|
|
|
|
Id: strconv.Itoa(id),
|
|
|
|
HeadDeviceId: req.Id,
|
|
|
|
HeadOffset: req.HeadOffset,
|
|
|
|
DevicePort: req.DevicePort,
|
|
|
|
RunDirection: req.RunDirection,
|
2023-08-25 10:41:13 +08:00
|
|
|
TrainLength: req.TrainLength,
|
2023-07-31 17:27:05 +08:00
|
|
|
}
|
2023-08-22 16:44:34 +08:00
|
|
|
memory.AddTrainState(simulation, rsp)
|
|
|
|
c.JSON(http.StatusOK, &rsp)
|
2023-07-31 17:27:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-28 16:14:31 +08:00
|
|
|
// ATS测试仿真-移除列车
|
2023-07-28 15:49:44 +08:00
|
|
|
//
|
2023-07-28 16:14:31 +08:00
|
|
|
// @Summary ATS测试仿真-移除列车
|
2023-07-28 15:49:44 +08:00
|
|
|
//
|
|
|
|
// @Security JwtAuth
|
|
|
|
//
|
2023-07-28 16:14:31 +08:00
|
|
|
// @Description ATS测试仿真-移除列车
|
2023-07-28 15:49:44 +08:00
|
|
|
// @Tags ATS测试仿真Api
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
// @Param Authorization header string true "JWT Token"
|
|
|
|
// @Param RemoveTrainDto body dto.RemoveTrainDto true "ATS测试仿真-移除列车"
|
|
|
|
//
|
|
|
|
// @Success 200 {object} string
|
|
|
|
// @Failure 500 {object} dto.ErrorDto
|
|
|
|
// @Router /api/v1/simulation/train/remove [post]
|
|
|
|
func removeTrain(c *gin.Context) {
|
|
|
|
rt := &dto.RemoveTrainDto{}
|
2023-07-31 17:27:05 +08:00
|
|
|
if err := c.ShouldBind(&rt); err != nil {
|
2023-08-30 18:05:11 +08:00
|
|
|
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
|
2023-07-28 15:49:44 +08:00
|
|
|
}
|
2023-07-31 17:27:05 +08:00
|
|
|
zap.S().Debug("ATS测试仿真-移除列车,请求:", rt)
|
2023-08-01 17:08:45 +08:00
|
|
|
simulation := checkDeviceDataAndReturn(rt.SimulationId)
|
|
|
|
memory.RemoveTrainState(simulation, rt.TrainId)
|
2023-07-31 17:27:05 +08:00
|
|
|
//TODO 后续调用列车删除操作
|
|
|
|
c.JSON(http.StatusOK, "ok")
|
2023-07-28 15:49:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 获取ATS测试-操作道岔
|
|
|
|
//
|
|
|
|
// @Summary 获取ATS测试-操作道岔
|
|
|
|
//
|
|
|
|
// @Security JwtAuth
|
|
|
|
//
|
2023-08-30 13:25:57 +08:00
|
|
|
// @Description ATS测试-操作道岔
|
2023-07-28 15:49:44 +08:00
|
|
|
// @Tags ATS测试仿真Api
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
// @Param Authorization header string true "JWT Token"
|
|
|
|
// @Param RemoveTrainDto body dto.SwitchOperationReqDto true "ATS测试仿真-操作道岔"
|
|
|
|
//
|
|
|
|
// @Success 200 {object} string
|
|
|
|
// @Failure 500 {object} dto.ErrorDto
|
|
|
|
// @Router /api/v1/simulation/switch/operation [post]
|
|
|
|
func switchOperation(c *gin.Context) {
|
2023-07-31 17:27:05 +08:00
|
|
|
req := &dto.SwitchOperationReqDto{}
|
|
|
|
if err := c.ShouldBind(&req); err != nil {
|
2023-08-30 18:05:11 +08:00
|
|
|
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
|
2023-07-31 17:27:05 +08:00
|
|
|
}
|
2023-08-01 17:08:45 +08:00
|
|
|
simulation := checkDeviceDataAndReturn(req.SimulationId)
|
|
|
|
zap.S().Info("传入状态参数", req)
|
|
|
|
memory.ChangeTurnoutState(simulation, &state.SwitchState{
|
|
|
|
Id: req.SwitchIndex,
|
|
|
|
Normal: req.TurnNormal,
|
|
|
|
Reverse: req.TurnReverse,
|
|
|
|
})
|
2023-07-31 17:27:05 +08:00
|
|
|
c.JSON(http.StatusOK, "ok")
|
|
|
|
}
|
2023-07-28 15:49:44 +08:00
|
|
|
|
2023-07-31 17:27:05 +08:00
|
|
|
// 获取仿真设备数据并返回
|
2023-08-01 14:54:11 +08:00
|
|
|
func checkDeviceDataAndReturn(simId string) *memory.VerifySimulation {
|
2023-07-31 17:27:05 +08:00
|
|
|
deviceMemory := simulation.FindSimulation(simId)
|
|
|
|
if deviceMemory == nil {
|
|
|
|
panic(&dto.ErrorDto{Code: dto.DataNotExist, Message: fmt.Sprintf("仿真[%s]不存在", simId)})
|
2023-07-28 15:49:44 +08:00
|
|
|
}
|
2023-07-31 17:27:05 +08:00
|
|
|
return deviceMemory
|
2023-07-28 15:49:44 +08:00
|
|
|
}
|
2023-08-22 16:44:34 +08:00
|
|
|
|
|
|
|
// 获取列车主键
|
|
|
|
func getAddTrainPrimaryKey(simulation *memory.VerifySimulation) int {
|
|
|
|
trainMap := &simulation.Memory.Status.TrainStateMap
|
|
|
|
// 获取列车ID
|
|
|
|
i := 1
|
|
|
|
for {
|
|
|
|
t, ok := trainMap.Load(strconv.Itoa(i))
|
|
|
|
if ok {
|
|
|
|
ts := t.(*state.TrainState)
|
|
|
|
if ts.Show {
|
|
|
|
i = -1
|
|
|
|
break
|
|
|
|
}
|
|
|
|
i++
|
|
|
|
} else {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return i
|
|
|
|
}
|