This commit is contained in:
walker 2023-08-07 16:41:22 +08:00
commit 2913ecec13
38 changed files with 4496 additions and 758 deletions

213
api/category.go Normal file
View File

@ -0,0 +1,213 @@
package api
import (
"net/http"
"strconv"
jwt "github.com/appleboy/gin-jwt/v2"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"joylink.club/bj-rtsts-server/dto"
"joylink.club/bj-rtsts-server/middleware"
"joylink.club/bj-rtsts-server/service"
)
func InitCategoryRouter(api *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
authed := api.Group("/v1/category").Use(authMiddleware.MiddlewareFunc())
authed.GET("/paging", pageQueryCategory)
authed.GET("/list", listQueryCategory)
authed.POST("", createCategory)
authed.GET("/:id", queryCategoryInfo)
authed.PUT("/:id", updateCategoryInfo)
authed.DELETE("/:id", deleteCategory)
}
// 分页查询厂家信息
//
// @Summary 分页查询厂家信息
//
// @Security JwtAuth
//
// @Description 可以通过厂家名称过滤,分页查询厂家信息
// @Tags 厂家信息Api
// @Accept json
// @Produce json
// @Param PageCategoryReqDto query dto.PageCategoryReqDto true "厂家查询条件带分页信息"
// @Success 200 {object} dto.PageDto
// @Failure 401 {object} dto.ErrorDto
// @Failure 404 {object} dto.ErrorDto
// @Failure 500 {object} dto.ErrorDto
// @Router /api/v1/category/paging [get]
func pageQueryCategory(c *gin.Context) {
user, _ := c.Get(middleware.IdentityKey)
zap.S().Debug("分页查询厂家", user)
req := dto.PageCategoryReqDto{}
if err := c.ShouldBind(&req); err != nil {
zap.S().Warn("分页查询参数绑定错误,使用默认参数", err)
req.Default()
}
zap.S().Debug("分页查厂家参数", req)
page, err := service.PageCategoryQuery(&req)
if err != nil {
c.JSON(http.StatusInternalServerError, err.Error())
return
}
c.JSON(http.StatusOK, page)
}
// 查询厂家信息列表
//
// @Summary 查询厂家信息列表
//
// @Security JwtAuth
//
// @Description 可以通过厂家名称过滤,查询厂家信息列表
// @Tags 厂家信息Api
// @Accept json
// @Produce json
// @Param PageCategoryReqDto query dto.PageCategoryReqDto true "厂家查询条件"
// @Success 200 {object} dto.PageDto
// @Failure 401 {object} dto.ErrorDto
// @Failure 404 {object} dto.ErrorDto
// @Failure 500 {object} dto.ErrorDto
// @Router /api/v1/category/list [get]
func listQueryCategory(c *gin.Context) {
req := dto.PageCategoryReqDto{}
if err := c.ShouldBind(&req); err != nil {
zap.S().Warn("查询参数绑定错误,使用默认参数", err)
req.Default()
}
zap.S().Debug("查厂家参数", req)
page, err := service.ListCategoryQuery(&req)
if err != nil {
c.JSON(http.StatusInternalServerError, err.Error())
return
}
c.JSON(http.StatusOK, page)
}
// 创建厂家信息
//
// @Summary 创建厂家信息
//
// @Security JwtAuth
//
// @Description 创建厂家数据
// @Tags 厂家信息Api
// @Accept json
// @Produce json
// @Param CategoryDto query dto.CategoryDto true "创建的厂家信息"
// @Success 200 {object} nil
// @Failure 401 {object} dto.ErrorDto
// @Failure 404 {object} dto.ErrorDto
// @Failure 500 {object} dto.ErrorDto
// @Router /api/v1/category [post]
func createCategory(c *gin.Context) {
req := dto.CategoryDto{}
if err := c.ShouldBind(&req); err != nil {
c.JSON(http.StatusBadRequest, "传入参数错误")
return
}
zap.S().Debug("保存数据", req)
data, err := service.CreateCategory(&req)
if err != nil {
c.JSON(http.StatusInternalServerError, err.Error())
return
}
c.JSON(http.StatusOK, data)
}
// 查询厂家信息
//
// @Summary 查询厂家信息
//
// @Security JwtAuth
//
// @Description 查询厂家信息
// @Tags 厂家信息Api
// @Accept json
// @Produce json
// @Param id path int true "厂家ID"
// @Success 200 {object} model.Drafting
// @Failure 401 {object} dto.ErrorDto
// @Failure 404 {object} dto.ErrorDto
// @Failure 500 {object} dto.ErrorDto
// @Router /api/v1/category/:id [get]
func queryCategoryInfo(c *gin.Context) {
id, exist := c.Params.Get("id")
if !exist {
c.JSON(http.StatusBadRequest, "必要参数id不存在")
return
}
zap.S().Debug("传入参数id为" + id)
int64Id, _ := strconv.ParseInt(id, 10, 64)
c.JSON(http.StatusOK, service.QueryCategory(int32(int64Id)))
}
// 修改厂家信息
//
// @Summary 修改厂家信息
//
// @Security JwtAuth
//
// @Description 修改厂家信息
// @Tags 厂家信息Api
// @Accept json
// @Produce json
// @Param id path int true "厂家信息ID"
// @Param CategoryDto query dto.CategoryDto true "修改的厂家信息"
// @Success 200 {object} nil
// @Failure 401 {object} dto.ErrorDto
// @Failure 404 {object} dto.ErrorDto
// @Failure 500 {object} dto.ErrorDto
// @Router /api/v1/category/:id [put]
func updateCategoryInfo(c *gin.Context) {
id, exist := c.Params.Get("id")
if !exist {
c.JSON(http.StatusBadRequest, "必要参数id不存在")
return
}
zap.S().Debug("传入参数id为" + id)
req := dto.CategoryDto{}
if err := c.ShouldBind(&req); err != nil {
c.JSON(http.StatusBadRequest, "保存参数出错")
return
}
int64Id, _ := strconv.ParseInt(id, 10, 64)
result := service.UpdateCategory(int32(int64Id), &req)
if !result {
c.JSON(http.StatusInternalServerError, "保存参数出错")
return
}
c.JSON(http.StatusOK, result)
}
// 删除厂家信息
//
// @Summary 删除厂家信息
//
// @Security JwtAuth
//
// @Description 删除厂家信息
// @Tags 厂家信息Api
// @Accept json
// @Produce json
// @Param id path int true "厂家信息ID"
// @Success 200 {object} nil
// @Failure 401 {object} dto.ErrorDto
// @Failure 404 {object} dto.ErrorDto
// @Failure 500 {object} dto.ErrorDto
// @Router /api/v1/category/:id [delete]
func deleteCategory(c *gin.Context) {
user, _ := c.Get(middleware.IdentityKey)
zap.S().Debug("id删除草稿的图形数据", user)
idStr := c.Param("id")
id, err := strconv.Atoi(idStr)
if err != nil {
c.JSON(http.StatusBadRequest, "id参数解析错误")
panic("id参数解析错误")
}
zap.S().Debug("id查询草稿的图形数据", id)
service.DeleteCategoryById(id)
c.JSON(http.StatusOK, true)
}

44
api/generate.go Normal file
View File

@ -0,0 +1,44 @@
package api
import (
"net/http"
jwt "github.com/appleboy/gin-jwt/v2"
"github.com/gin-gonic/gin"
"github.com/golang/protobuf/proto"
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/memory"
"joylink.club/bj-rtsts-server/dto"
)
func InitGenerateGiRouter(api *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
authed := api.Group("/v1/generate").Use(authMiddleware.MiddlewareFunc())
authed.POST("/calculatelink", generateCalculateLinkData)
}
// 根据地图数据新生成计算的link信息
//
// @Summary 根据地图数据新生成计算的link信息
//
// @Security JwtAuth
//
// @Description 根据地图数据新生成计算的link信息
// @Tags GenerateApi
// @Accept json
// @Produce json
// @Param DraftingMapDataDto query dto.DraftingMapDataDto true "地图信息"
// @Success 200 {object} nil
// @Failure 401 {object} dto.ErrorDto
// @Failure 404 {object} dto.ErrorDto
// @Failure 500 {object} dto.ErrorDto
// @Router /api/v1/generate/calculatelink [post]
func generateCalculateLinkData(c *gin.Context) {
req := dto.DraftingMapDataDto{}
if err := c.ShouldBind(&req); err != nil {
c.JSON(http.StatusBadRequest, "参数获取出错")
return
}
gd := &graphicData.RtssGraphicStorage{}
proto.Unmarshal(req.Proto, gd)
c.JSON(http.StatusOK, memory.BuildCalculateLinkData(gd))
}

View File

@ -1,6 +1,9 @@
package api
import (
"net/http"
"strconv"
jwt "github.com/appleboy/gin-jwt/v2"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
@ -9,8 +12,6 @@ import (
"joylink.club/bj-rtsts-server/dto/publishedGi"
"joylink.club/bj-rtsts-server/middleware"
"joylink.club/bj-rtsts-server/service"
"net/http"
"strconv"
)
func InitPublishedGiRouter(api *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
@ -20,6 +21,7 @@ func InitPublishedGiRouter(api *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddl
authed.GET("/:id", getPublishedGiById)
authed.POST("/publish", publishFromDraft)
authed.DELETE("/:id", deletePublishedGiById)
authed.POST("/saveAsDrafting/:id", saveAsDraftingFromPublish)
}
// 分页查询发布的图形数据
@ -160,3 +162,34 @@ func deletePublishedGiById(c *gin.Context) {
zap.S().Debug("id查询发布的图形数据", id)
service.DeletePublishedGiById(id)
}
// id 从发布数据拉取信息到草稿
//
// @Summary 从发布数据拉取信息到草稿
//
// @Security JwtAuth
//
// @Description 从发布数据拉取信息到草稿
// @Tags 发布的图形数据Api
// @Accept json
// @Produce json
// @Param id path int true "id"
// @Param PublishReqDto query publishedGi.PublishReqDto true "要保存的名称"
// @Success 200 {object} nil
// @Failure 401 {object} dto.ErrorDto
// @Failure 500 {object} dto.ErrorDto
// @Router /api/v1/publishedGi/saveAsDrafting/{id} [post]
func saveAsDraftingFromPublish(c *gin.Context) {
user, _ := c.Get(middleware.IdentityKey)
idStr := c.Param("id")
zap.S().Debugf("用户【%v】拉取发布图形数据【%s】", user, idStr)
id, err := strconv.Atoi(idStr)
if err != nil {
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
}
req := publishedGi.PublishReqDto{}
if err := c.ShouldBind(&req); err != nil {
panic(dto.ErrorDto{Code: dto.ArgumentParseError, Message: err.Error()})
}
service.SaveAsDraftingFromPublish(int32(id), user.(*model.User), req.Name)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,15 @@
package simulation
import (
"net"
"strings"
"fmt"
"go.uber.org/zap"
"joylink.club/bj-rtsts-server/ats/verify/protos/state"
"joylink.club/bj-rtsts-server/config"
"joylink.club/bj-rtsts-server/dynamics"
"net/http"
"strconv"
"sync"
@ -11,6 +17,23 @@ import (
"joylink.club/bj-rtsts-server/dto"
)
var simulationId_prefix = (func() string {
ip := "127.0.0.1"
addrList, err := net.InterfaceAddrs()
if err != nil {
panic(err)
}
for _, address := range addrList {
if ipNet, ok := address.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
if ipNet.IP.To4() != nil {
ip = ipNet.IP.String()
}
}
}
ipArr := strings.Split(ip, ".")
return ipArr[2] + "_" + ipArr[3]
})()
func init() {
dynamics.RegisterTrainInfoHandler(func(info *dynamics.TrainInfo) {
for _, simulation := range GetSimulationArr() {
@ -20,38 +43,9 @@ func init() {
break
}
}
//simulationMap.Range(func(key, value any) bool {
// simulation := value.(*memory.VerifySimulation)
// sta, ok := simulation.Memory.Status.TrainStateMap.Load(strconv.Itoa(int(info.Number)))
// if ok {
// memory.UpdateTrainState(simulation, convert(info, *sta.(*state.TrainState)))
// return false
// }
// return true
//})
})
}
func convert(info *dynamics.TrainInfo, sta state.TrainState) *state.TrainState {
sta.HeadLinkId = strconv.Itoa(int(info.Link))
sta.HeadLinkOffset = int64(info.LinkOffset * 10)
sta.Slope = int32(info.Slope)
sta.Upslope = info.UpSlope
sta.RunningUp = info.Up
sta.RunningResistanceSum = info.TotalResistance
sta.AirResistance = info.AirResistance
sta.RampResistance = info.SlopeResistance
sta.CurveResistance = info.CurveResistance
sta.Speed = info.Speed
sta.HeadSensorSpeed1 = info.HeadSpeed1
sta.HeadSensorSpeed2 = info.HeadSpeed2
sta.TailSensorSpeed1 = info.TailSpeed1
sta.TailSensorSpeed2 = info.TailSpeed2
sta.HeadRadarSpeed = info.HeadRadarSpeed
sta.TailRadarSpeed = info.TailRadarSpeed
return &sta
}
// 仿真存储集合
var simulationMap sync.Map
@ -60,41 +54,35 @@ func CreateSimulation(mapId int32) string {
simulationId := createSimulationId(mapId)
_, e := simulationMap.Load(simulationId)
if !e {
////通知动力学
//httpCode, _, err := dynamics.SendSimulationStartReq()
//if httpCode != http.StatusOK || err != nil {
// panic(dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("动力学接口调用失败:[%d][%s]", httpCode, err)})
//}
verifySimulation := memory.CreateSimulation(mapId, simulationId)
simulationMap.Store(simulationId, verifySimulation)
//道岔状态发送
dynamics.AddTurnoutInfoFunc(simulationId, func() []*dynamics.TurnoutInfo {
stateSlice := memory.GetAllTurnoutState(verifySimulation)
var turnoutInfoSlice []*dynamics.TurnoutInfo
for _, sta := range stateSlice {
code64, err := strconv.ParseUint(sta.Id, 10, 16)
if err != nil {
zap.S().Error("id转uint16报错", err)
}
info := dynamics.TurnoutInfo{
Code: uint16(code64),
NPosition: sta.Normal,
RPosition: sta.Reverse,
}
turnoutInfoSlice = append(turnoutInfoSlice, &info)
}
return turnoutInfoSlice
})
//
startSendTurnoutInfo(simulationId, verifySimulation)
}
return simulationId
}
// 删除仿真对象
func DestroySimulation(simulationId string) {
simulationMap.Delete(simulationId)
//移除道岔状态发送
dynamics.RemoveTurnoutInfoFunc(simulationId)
dynamics.RemoveTurnoutInfoSource(simulationId)
//通知动力学
httpCode, _, err := dynamics.SendSimulationEndReq()
if httpCode != http.StatusOK || err != nil {
panic(dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("动力学接口调用失败:[%d][%s]", httpCode, err)})
}
simulationMap.Delete(simulationId)
}
// 创建时生成仿真Id
func createSimulationId(mapId int32) string {
return strconv.Itoa(int(mapId))
// 当前服务器IP + 端口 + 地图
return simulationId_prefix + "_" + strconv.Itoa(config.Config.Server.Port) + "_" + strconv.Itoa(int(mapId))
}
// 获取仿真列表
@ -129,3 +117,43 @@ func GetSimulationArr() []*memory.VerifySimulation {
})
return result
}
func convert(info *dynamics.TrainInfo, sta state.TrainState) *state.TrainState {
sta.HeadLinkId = strconv.Itoa(int(info.Link))
sta.HeadLinkOffset = int64(info.LinkOffset * 10)
sta.Slope = int32(info.Slope)
sta.Upslope = info.UpSlope
sta.RunningUp = info.Up
sta.RunningResistanceSum = float32(info.TotalResistance) / 1000
sta.AirResistance = float32(info.AirResistance) / 1000
sta.RampResistance = float32(info.SlopeResistance) / 1000
sta.CurveResistance = float32(info.CurveResistance) / 1000
sta.Speed = info.Speed * 3.6
sta.HeadSensorSpeed1 = info.HeadSpeed1 * 3.6
sta.HeadSensorSpeed2 = info.HeadSpeed2 * 3.6
sta.TailSensorSpeed1 = info.TailSpeed1 * 3.6
sta.TailSensorSpeed2 = info.TailSpeed2 * 3.6
sta.HeadRadarSpeed = info.HeadRadarSpeed * 3.6
sta.TailRadarSpeed = info.TailRadarSpeed * 3.6
return &sta
}
func startSendTurnoutInfo(simulationId string, verifySimulation *memory.VerifySimulation) {
dynamics.AddTurnoutInfoSource(simulationId, func() []*dynamics.TurnoutInfo {
stateSlice := memory.GetAllTurnoutState(verifySimulation)
var turnoutInfoSlice []*dynamics.TurnoutInfo
for _, sta := range stateSlice {
code64, err := strconv.ParseUint(sta.Id, 10, 16)
if err != nil {
zap.S().Error("id转uint16报错", err)
}
info := dynamics.TurnoutInfo{
Code: uint16(code64),
NPosition: sta.Normal,
RPosition: sta.Reverse,
}
turnoutInfoSlice = append(turnoutInfoSlice, &info)
}
return turnoutInfoSlice
})
}

View File

@ -0,0 +1,352 @@
package memory
import (
"container/list"
"reflect"
"sort"
"strings"
"go.uber.org/zap"
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
)
// 参与计算结构体信息
type buildCalcStruct struct {
AxlePointMap map[string]*graphicData.AxleCounting
TurnoutMap map[string]*buildCalcTurnoutStruct
SectionMap map[string]*buildCalcSectionStruct
}
// 参与计算link时的区段结构体
type buildCalcSectionStruct struct {
Data *graphicData.Section
APoint *graphicData.AxleCounting // a点计轴
BPoint *graphicData.AxleCounting // b点计轴
}
// 参与计算的
type buildCalcTurnoutStruct struct {
Data *graphicData.Turnout
APoint *graphicData.AxleCounting //a点计轴
BPoint *graphicData.AxleCounting //b点计轴
CPoint *graphicData.AxleCounting //c点计轴
CrossKilometerSystem *graphicData.KilometerSystem // 道岔岔心位置
}
// 根据地图信息生成calcLink数据
func BuildCalculateLinkData(gd *graphicData.RtssGraphicStorage) []*graphicData.CalculateLink {
gm, startPointQueue := getGraphicDataDeviceMap(gd)
// 这里linkPath是排过序的公里标大小
linkPathMap := getGraphicLinkPath(gm, startPointQueue)
// 根据路径开始包装结果数据
resultArr := []*graphicData.CalculateLink{}
for id, pathArr := range linkPathMap {
item := &graphicData.CalculateLink{
Common: &graphicData.CommonInfo{},
Points: []*graphicData.Point{},
DevicePositions: []*graphicData.CalculateLink_DevicePosition{},
}
item.Index = int32(id)
allTurnout := true
for index, refVal := range pathArr {
var addLen int32
if refVal.DeviceType == graphicData.RelatedRef_Section {
allTurnout = false
section := gm.SectionMap[refVal.Id]
// 放入Points
item.Points = append(item.Points, section.Data.Points...)
// 计算长度
addLen = calcGraphicLenBySection(section)
// 放入设备偏移
item.DevicePositions = append(item.DevicePositions, getGraphicSectionRefDevices(section, item.Length)...)
// 区段时A点取小端B点取大端没有的话赋值 refVal
if index == 0 {
item.ARelatedRef = getGraphicSectionPointRef(section, true, refVal)
} else {
item.BRelatedRef = getGraphicSectionPointRef(section, false, refVal)
}
} else {
allTurnout = allTurnout && true
turnout := gm.TurnoutMap[refVal.Id]
// 放入Points
item.Points = append(item.Points, getGraphicTurnoutPoints(turnout, refVal.DevicePort)...)
// 计算长度
addLen = calcGraphicLenByTurnout(turnout, refVal.DevicePort)
// 放入设备偏移
item.DevicePositions = append(item.DevicePositions, getGraphicTurnoutRefDevices(turnout, item.Length)...)
// 道岔时左右端直接赋值
if index == 0 {
item.ARelatedRef = refVal
} else {
item.BRelatedRef = refVal
}
}
// 最后增加长度
item.Length = item.Length + addLen
}
// 如果全部为道岔,则长度使用岔心减岔心
if allTurnout {
tk1 := gm.TurnoutMap[pathArr[0].Id].CrossKilometerSystem.Kilometer
tk2 := gm.TurnoutMap[pathArr[len(pathArr)-1].Id].CrossKilometerSystem.Kilometer
item.Length = int32(tk2 - tk1)
}
resultArr = append(resultArr, item)
}
return resultArr
}
// 计算区段长度
func calcGraphicLenBySection(section *buildCalcSectionStruct) int32 {
if section.APoint == nil || section.BPoint == nil {
zap.S().Warnf("区段【%s】端点位置缺失\n", section.Data.Common.Id)
return 0
}
start := section.BPoint.KilometerSystem.Kilometer
end := section.APoint.KilometerSystem.Kilometer
if end > start {
return int32(end - start)
} else {
return int32(start - end)
}
}
// 计算道岔端长度
func calcGraphicLenByTurnout(turnout *buildCalcTurnoutStruct, p graphicData.RelatedRef_DevicePort) int32 {
var endPoint *graphicData.AxleCounting
switch p {
case graphicData.RelatedRef_A:
endPoint = turnout.APoint
case graphicData.RelatedRef_B:
endPoint = turnout.BPoint
case graphicData.RelatedRef_C:
endPoint = turnout.CPoint
default:
zap.S().Warnf("道岔【%s】对应端口【%s】数据错误", turnout.Data.Common.Id, p.String())
return 0
}
if turnout.CrossKilometerSystem == nil {
zap.S().Warnf("道岔【%s】数据错误,岔心公里标为空", turnout.Data.Common.Id)
return 0
}
if endPoint == nil {
zap.S().Warnf("道岔【%s】数据错误,无计轴", turnout.Data.Common.Id)
return 0
}
start := turnout.CrossKilometerSystem.Kilometer
end := endPoint.KilometerSystem.Kilometer
if end > start {
return int32(end - start)
} else {
return int32(start - end)
}
}
// 获取道岔坐标点
func getGraphicTurnoutPoints(turnout *buildCalcTurnoutStruct, p graphicData.RelatedRef_DevicePort) []*graphicData.Point {
switch p {
case graphicData.RelatedRef_A:
return turnout.Data.PointA
case graphicData.RelatedRef_B:
return turnout.Data.PointB
case graphicData.RelatedRef_C:
return turnout.Data.PointC
default:
zap.S().Warnf("道岔【%s】对应端口【%s】数据错误\n", turnout.Data.Common.Id, p.String())
return []*graphicData.Point{}
}
}
// 获取关于区段的设备信息
func getGraphicSectionRefDevices(section *buildCalcSectionStruct, offset int32) []*graphicData.CalculateLink_DevicePosition {
// 目前只放入区段的信息
devices := []*graphicData.CalculateLink_DevicePosition{
{DeviceId: section.Data.Common.Id, Offset: offset},
}
return devices
}
// 获取关于道岔的设备信息
func getGraphicTurnoutRefDevices(turnout *buildCalcTurnoutStruct, offset int32) []*graphicData.CalculateLink_DevicePosition {
// 目前只放入区段的信息
devices := []*graphicData.CalculateLink_DevicePosition{
{DeviceId: turnout.Data.Common.Id, Offset: offset},
}
return devices
}
// 获取区段的对应端
func getGraphicSectionPointRef(section *buildCalcSectionStruct, b bool, defaultRelateRef *graphicData.RelatedRef) *graphicData.RelatedRef {
if section.APoint == nil || section.BPoint == nil {
return defaultRelateRef
}
if section.APoint.KilometerSystem.Kilometer < section.BPoint.KilometerSystem.Kilometer && b {
return &graphicData.RelatedRef{DeviceType: graphicData.RelatedRef_Section, Id: section.Data.Common.Id, DevicePort: graphicData.RelatedRef_A}
} else {
return &graphicData.RelatedRef{DeviceType: graphicData.RelatedRef_Section, Id: section.Data.Common.Id, DevicePort: graphicData.RelatedRef_B}
}
}
// 获取link的路径信息
func getGraphicLinkPath(gm *buildCalcStruct, startPointQueue *list.List) map[int][]*graphicData.RelatedRef {
handleMap := make(map[string]bool)
resultMap := make(map[int][]*graphicData.RelatedRef)
id := 1
for i := startPointQueue.Front(); i != nil; i = i.Next() {
relatedRef := i.Value.(*graphicData.RelatedRef)
// 起始连接点
var refInfo *graphicData.RelatedRef
var axleInfo *graphicData.AxleCounting
if relatedRef.DeviceType == graphicData.RelatedRef_Section {
refInfo, axleInfo = getRelatePointInfo(reflect.ValueOf(gm.SectionMap[relatedRef.Id]).Elem(), relatedRef.DevicePort)
} else {
refInfo, axleInfo = getRelatePointInfo(reflect.ValueOf(gm.TurnoutMap[relatedRef.Id]).Elem(), relatedRef.DevicePort)
}
// 查看是否已经被处理过的ID
var handleId string
if axleInfo == nil {
ids := []string{relatedRef.Id, refInfo.Id}
sort.Strings(ids)
handleId = strings.Join(ids, "_")
} else {
handleId = axleInfo.Common.Id
}
if handleMap[handleId] {
continue
}
handleMap[handleId] = true
pathRefArr := []*graphicData.RelatedRef{refInfo}
appendFunc := getRelateAppendMethod(gm, refInfo, relatedRef)
loopRelateRef := relatedRef
for loopRelateRef != nil {
pathRefArr = appendFunc(loopRelateRef, pathRefArr)
switch loopRelateRef.DeviceType {
case graphicData.RelatedRef_Section:
section := gm.SectionMap[loopRelateRef.Id]
if loopRelateRef.DevicePort == graphicData.RelatedRef_A {
loopRelateRef = section.Data.PbRef
} else {
loopRelateRef = section.Data.PaRef
}
case graphicData.RelatedRef_Turnout:
loopRelateRef = nil
}
}
resultMap[id] = pathRefArr
id++ // ID自增
}
return resultMap
}
// 获取link的起始点和包装数据结构方便查找以道岔的各分支的连接点为起点
func getGraphicDataDeviceMap(gd *graphicData.RtssGraphicStorage) (*buildCalcStruct, *list.List) {
gm := &buildCalcStruct{
AxlePointMap: make(map[string]*graphicData.AxleCounting),
TurnoutMap: make(map[string]*buildCalcTurnoutStruct),
SectionMap: make(map[string]*buildCalcSectionStruct),
}
// 起始点列表
startPoints := list.New()
for _, t := range gd.Turnouts {
var op *graphicData.KilometerSystem
for _, k := range t.KilometerSystem {
if k.CoordinateSystem == "MAIN_LINE" && k.Kilometer != 0 {
op = k
}
}
if t.PaRef != nil {
startPoints.PushBack(t.PaRef)
}
if t.PbRef != nil {
startPoints.PushBack(t.PbRef)
}
if t.PcRef != nil {
startPoints.PushBack(t.PcRef)
}
gm.TurnoutMap[t.Common.Id] = &buildCalcTurnoutStruct{Data: t, CrossKilometerSystem: op}
}
// 区段列表
for _, s := range gd.Section {
gm.SectionMap[s.Common.Id] = &buildCalcSectionStruct{Data: s}
}
// 计轴点关联到对应的区段,道岔上
for _, a := range gd.AxleCountings {
gm.AxlePointMap[a.Common.Id] = a
for _, r := range a.AxleCountingRef {
if r.DeviceType == graphicData.RelatedRef_Section {
section := gm.SectionMap[r.Id]
if r.DevicePort == graphicData.RelatedRef_A {
section.APoint = a
} else if r.DevicePort == graphicData.RelatedRef_B {
section.BPoint = a
}
} else if r.DeviceType == graphicData.RelatedRef_Turnout {
if r.DevicePort == graphicData.RelatedRef_A {
gm.TurnoutMap[r.Id].APoint = a
} else if r.DevicePort == graphicData.RelatedRef_B {
gm.TurnoutMap[r.Id].BPoint = a
} else {
gm.TurnoutMap[r.Id].CPoint = a
}
}
}
}
return gm, startPoints
}
// 获取本连接点上一个连接信息以及计轴信息
func getRelatePointInfo(v reflect.Value, p graphicData.RelatedRef_DevicePort) (*graphicData.RelatedRef, *graphicData.AxleCounting) {
var relateInfo reflect.Value
var axlePoint reflect.Value
// 放入计轴点
switch p {
case graphicData.RelatedRef_A:
relateInfo = v.FieldByName("Data").Elem().FieldByName("PaRef")
axlePoint = v.FieldByName("APoint")
case graphicData.RelatedRef_B:
relateInfo = v.FieldByName("Data").Elem().FieldByName("PbRef")
axlePoint = v.FieldByName("BPoint")
case graphicData.RelatedRef_C:
relateInfo = v.FieldByName("Data").Elem().FieldByName("PcRef")
axlePoint = v.FieldByName("CPoint")
}
return relateInfo.Interface().(*graphicData.RelatedRef), axlePoint.Interface().(*graphicData.AxleCounting)
}
// 确定接点追加放肆
func getRelateAppendMethod(gm *buildCalcStruct, sRef, eRef *graphicData.RelatedRef) func(*graphicData.RelatedRef, []*graphicData.RelatedRef) []*graphicData.RelatedRef {
start := 0
switch sRef.DeviceType {
case graphicData.RelatedRef_Section:
section := gm.SectionMap[sRef.Id]
if sRef.DevicePort == graphicData.RelatedRef_A {
start = int(section.APoint.KilometerSystem.Kilometer)
} else {
start = int(section.BPoint.KilometerSystem.Kilometer)
}
case graphicData.RelatedRef_Turnout:
turnout := gm.TurnoutMap[sRef.Id]
start = int(turnout.CrossKilometerSystem.Kilometer)
}
end := 0
switch eRef.DeviceType {
case graphicData.RelatedRef_Section:
section := gm.SectionMap[eRef.Id]
if eRef.DevicePort == graphicData.RelatedRef_A {
end = int(section.APoint.KilometerSystem.Kilometer)
} else {
end = int(section.BPoint.KilometerSystem.Kilometer)
}
case graphicData.RelatedRef_Turnout:
turnout := gm.TurnoutMap[eRef.Id]
end = int(turnout.CrossKilometerSystem.Kilometer)
}
if start > end {
return func(refInfo *graphicData.RelatedRef, linkArr []*graphicData.RelatedRef) []*graphicData.RelatedRef {
return append([]*graphicData.RelatedRef{refInfo}, linkArr...)
}
} else {
return func(refInfo *graphicData.RelatedRef, linkArr []*graphicData.RelatedRef) []*graphicData.RelatedRef {
return append(linkArr, refInfo)
}
}
}

View File

@ -9,11 +9,13 @@ import (
// 从地图数据构建仿真内存模型
func InitFromMap(status *VerifyStatus, mapInfo *VerifyStructure) {
initFromMapForTest(status, mapInfo)
initTurnoutState(status, mapInfo)
initAxleSectionState(status, mapInfo)
initPhysicalSectionState(status, mapInfo)
}
// 暂时测试用
func initFromMapForTest(status *VerifyStatus, mapInfo *VerifyStructure) {
// 初始化道岔状态
func initTurnoutState(status *VerifyStatus, mapInfo *VerifyStructure) {
for _, turnout := range mapInfo.SwitchDeviceModelMap {
status.SwitchStateMap.Store(turnout.GetIndex(), &state.SwitchState{
Id: turnout.GetIndex(),
@ -22,3 +24,25 @@ func initFromMapForTest(status *VerifyStatus, mapInfo *VerifyStructure) {
})
}
}
// 初始化区段状态
func initAxleSectionState(status *VerifyStatus, mapInfo *VerifyStructure) {
for _, axleSection := range mapInfo.AxleSectionModelMap {
status.AxleSectionStateMap.Store(axleSection.GetIndex(), &state.SectionState{
Id: axleSection.GetIndex(),
Occupied: false,
Type: state.SectionType_Axle,
})
}
}
// 初始化物理区段状态
func initPhysicalSectionState(status *VerifyStatus, mapInfo *VerifyStructure) {
for _, physicalSection := range mapInfo.PhysicalSectionModelMap {
status.PhysicalSectionStateMap.Store(physicalSection.GetIndex(), &state.SectionState{
Id: physicalSection.GetIndex(),
Occupied: false,
Type: state.SectionType_Physic,
})
}
}

View File

@ -1,6 +1,7 @@
package memory
import (
"container/list"
"fmt"
"strconv"
"sync"
@ -18,7 +19,7 @@ import (
// 仿真存储集合 ID
var graphicDataMap sync.Map
// 轨旁仿真模型结构
// 轨旁仿真模型结构,注意这里的key 为 Index
type VerifyStructure struct {
//计轴检测点设备模型集合,key为索引编号
AxlePointDeviceModelMap map[string]face.AxlePointDeviceModeller
@ -36,7 +37,7 @@ type VerifyStructure struct {
SignalDeviceModelMap map[string]face.SignalDeviceModeller
}
// 设备地图ID对应map结构体(建立关系时便于查找使用)
// 设备地图ID对应map结构体(建立关系时便于查找使用)注意这里的key 为 Common.Id
type GraphicInfoMapStructure struct {
AxlePointMap map[string]*graphicData.AxleCounting
TurnoutMap map[string]*graphicData.Turnout
@ -121,7 +122,9 @@ func initGraphicAxlePoints(axlePoints []*graphicData.AxleCounting, data *VerifyS
GraphicId: a.Common.Id,
Index: id,
},
KilometerSystem: *a.GetKilometerSystem(),
KilometerSystem: *a.GetKilometerSystem(),
SwitchDevices: make(map[string]*ref.SwitchRef),
AreaPhysicalSections: make(map[string]face.PhysicalSectionModeller),
}
}
}
@ -166,6 +169,8 @@ func initGraphicAxleSection(axleSections []*graphicData.AxleCountingSection, dat
GraphicId: s.Common.Id,
Index: id,
},
ViaSwitchPositions: list.New(),
ViaLinks: list.New(),
}
}
}
@ -180,7 +185,9 @@ func initGraphicPhysicalSections(physicalSections []*graphicData.Section, data *
GraphicId: s.Common.Id,
Index: id,
},
SwitchArea: len(s.AxleCountings) > 2,
SwitchArea: len(s.AxleCountings) > 2,
AxlePoints: make(map[string]face.AxlePointDeviceModeller),
AxleSections: make(map[string]face.AxleSectionModeller),
}
}
}
@ -204,12 +211,17 @@ func initGraphicSignal(signals []*graphicData.Signal, data *VerifyStructure, gra
for _, s := range signals {
graphicDataMap.SignalMap[s.Common.Id] = s
id := strconv.Itoa(int(s.Index))
kilometerSystem := &graphicData.KilometerSystem{}
if s.KilometerSystem != nil {
kilometerSystem.CoordinateSystem = s.KilometerSystem.CoordinateSystem
kilometerSystem.Kilometer = s.KilometerSystem.Kilometer
}
data.SignalDeviceModelMap[id] = &device.SignalDeviceModel{
DeviceModel: face.DeviceModel{
GraphicId: s.Common.Id,
Index: id,
},
KilometerSystem: *s.GetKilometerSystem(),
KilometerSystem: kilometerSystem,
}
}
}
@ -218,16 +230,24 @@ func initGraphicSignal(signals []*graphicData.Signal, data *VerifyStructure, gra
func buildDeviceRef(graphicData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
// 构建link的关联关系
buildLinkDeviceRef(graphicData, verifyStructure)
// 道岔,分析轨道中轨道与道岔的关系来构建道岔与轨道的关系
buildTurnoutDeviceRef(verifyStructure)
// 计轴区段
buildAxleSectionDeviceRef(graphicData, verifyStructure)
// 物理区段
buildPhysicalSectionsDeviceRef(graphicData, verifyStructure)
// 逻辑区段
buildLogicSectionsDeviceRef(graphicData, verifyStructure)
// 计轴检测点-从计轴点角度(非岔区物理区段和道岔)
buildAxlePointDeviceRef(graphicData, verifyStructure)
// 计轴检测点-从物理区段角度
buildPhysicalAxlePointDeviceRef(verifyStructure)
}
// 构建link的关联关系
// 构建link的关联关系(端点间的轨道)
func buildLinkDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for _, v := range mapData.LinkMap {
lf := verifyStructure.LinkSectionModelMap[strconv.Itoa(int(v.Index))]
if lf == nil { // 无对应ID
continue
}
link := lf.(*section.LinkSectionModel)
link := (verifyStructure.LinkSectionModelMap[strconv.Itoa(int(v.Index))]).(*section.LinkSectionModel)
// 轨道A端端点
linkSimRefBuildCommMethod(v.Common.Id, v.ASimRef, mapData, verifyStructure, func(f face.AxlePointDeviceModeller) {
link.AxlePointA = f
@ -240,20 +260,22 @@ func buildLinkDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *Verif
}, func(t *ref.SwitchRef) {
link.SwitchRefB = t
})
if v.ARef != nil {
if v.ARef.DeviceType == graphicData.RelatedRef_SectionLink {
d := mapData.LinkMap[v.ARef.Id]
if d != nil {
ls := verifyStructure.LinkSectionModelMap[strconv.Itoa(int(d.Index))]
link.LinkRefA = &ref.LinkRef{
LinkSection: ls,
Port: face.PortEnum(v.ARef.DevicePort),
}
}
}
}
// A端点关联设备
linkRefBuildCommMethod(v, mapData, verifyStructure, func() *graphicData.RelatedRef {
return v.ARef
}, func(l *ref.LinkRef) {
link.LinkRefA = l
}, func(pe face.PortEnum) {
link.SwitchRefA.Port = pe
})
// B端点关联设备
linkRefBuildCommMethod(v, mapData, verifyStructure, func() *graphicData.RelatedRef {
return v.BRef
}, func(l *ref.LinkRef) {
link.LinkRefB = l
}, func(pe face.PortEnum) {
link.SwitchRefB.Port = pe
})
}
}
@ -264,17 +286,201 @@ func linkSimRefBuildCommMethod(linkGraphicId string, simRef *graphicData.SimpleR
axlePoint := mapData.AxlePointMap[simRef.Id]
if axlePoint != nil {
fp(verifyStructure.AxlePointDeviceModelMap[strconv.Itoa(int(axlePoint.Index))])
} else {
zap.S().Warnf("id为[%s]的轨道的计轴端点[%s]不存在", linkGraphicId, simRef.Id)
}
case graphicData.SimpleRef_Turnout:
turnout := mapData.TurnoutMap[simRef.Id]
if turnout != nil {
ft(&ref.SwitchRef{SwitchDevice: verifyStructure.SwitchDeviceModelMap[strconv.Itoa(int(turnout.Index))]})
} else {
zap.S().Warnf("id为[%s]的轨道的道岔端点[%s]不存在", linkGraphicId, simRef.Id)
}
default:
zap.S().Warnf("link[%s]端点设备类型[%v]未关联", linkGraphicId, simRef.DeviceType)
}
}
func linkRefBuildCommMethod() {
func linkRefBuildCommMethod(v *graphicData.SectionLink, mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure,
gr func() *graphicData.RelatedRef, lr func(*ref.LinkRef), ft func(face.PortEnum)) {
r := gr()
if r != nil {
switch r.DeviceType {
case graphicData.RelatedRef_SectionLink:
d := mapData.LinkMap[r.Id]
if d != nil {
ls := verifyStructure.LinkSectionModelMap[strconv.Itoa(int(d.Index))]
lr(&ref.LinkRef{LinkSection: ls, Port: face.PortEnum(r.DevicePort)})
} else {
zap.S().Warnf("id为[%s]的轨道的连接的轨道[%s]不存在", v.Common.Id, r.Id)
}
case graphicData.RelatedRef_Turnout:
t := mapData.TurnoutMap[r.Id]
if t != nil {
ft(face.PortEnum(v.ARef.DevicePort))
} else {
zap.S().Warnf("id为[%s]的轨道的连接的道岔[%s]不存在", v.Common.Id, r.Id)
}
default:
zap.S().Warnf("link[%s]端点设备类型[%v]未关联", v.Common.Id, r.DeviceType)
}
}
}
// 道岔,分析轨道中轨道与道岔的关系来构建道岔与轨道的关系
func buildTurnoutDeviceRef(verifyStructure *VerifyStructure) {
for _, v := range verifyStructure.LinkSectionModelMap {
s := v.(*section.LinkSectionModel)
buildTurnoutCommMethod(s, s.SwitchRefA, face.A)
buildTurnoutCommMethod(s, s.SwitchRefB, face.B)
}
}
func buildTurnoutCommMethod(s *section.LinkSectionModel, linkSwitch *ref.SwitchRef, p face.PortEnum) {
if linkSwitch != nil {
switchDevice := (linkSwitch.SwitchDevice).(*device.SwitchDeviceModel)
switch linkSwitch.Port {
case face.A:
switchDevice.LinkRefA = &ref.LinkRef{LinkSection: s, Port: p}
case face.B:
switchDevice.LinkRefB = &ref.LinkRef{LinkSection: s, Port: p}
case face.C:
switchDevice.LinkRefC = &ref.LinkRef{LinkSection: s, Port: p}
}
}
}
// 计轴区段
func buildAxleSectionDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for _, v := range mapData.AxleSectionMap {
axleSectionModel := (verifyStructure.AxleSectionModelMap[strconv.Itoa(int(v.Index))]).(*section.AxleSectionModel)
//计轴区段A端计轴检测点
axleCountingA := mapData.AxlePointMap[v.PaRef.Id]
if axleCountingA != nil {
axlePointDeviceModelA := verifyStructure.AxlePointDeviceModelMap[strconv.Itoa(int(axleCountingA.Index))]
axleSectionModel.AxlePointA = axlePointDeviceModelA
} else {
zap.S().Warnf("id为[%s]的计轴区段的A端关联的计轴点[%s]不存在", v.Common.Id, v.PaRef.Id)
}
//计轴区段B端计轴检测点
axleCountingB := mapData.AxlePointMap[v.PbRef.Id]
if axleCountingB != nil {
axlePointDeviceModelB := verifyStructure.AxlePointDeviceModelMap[strconv.Itoa(int(axleCountingB.Index))]
axleSectionModel.AxlePointB = axlePointDeviceModelB
} else {
zap.S().Warnf("id为[%s]的计轴区段的B端关联的计轴点[%s]不存在", v.Common.Id, v.PbRef.Id)
}
//如果该计轴区段在岔区,则描述在该计轴区段中的道岔的位置
vaildMap := make(map[string]int)
for _, turnoutPosRef := range v.TurnoutPos {
turnout := mapData.TurnoutMap[turnoutPosRef.Id]
if turnout != nil {
switchDeviceModel := (verifyStructure.SwitchDeviceModelMap[strconv.Itoa(int(turnout.Index))]).(*device.SwitchDeviceModel)
positionRef := &ref.SwitchPositionRef{SwitchDevice: switchDeviceModel, Normal: 0 == turnoutPosRef.Position}
// 校验道岔设备只能添加一次 todo
if vaildMap[switchDeviceModel.Index] == 0 {
vaildMap[switchDeviceModel.Index] = 1
} else {
zap.S().Warnf("id为[%s]的计轴区段经过的道岔[%s]的次数大于1", v.Common.Id, turnoutPosRef.Id)
}
axleSectionModel.ViaSwitchPositions.PushBack(positionRef)
} else {
zap.S().Warnf("id为[%s]的计轴区段经过的道岔[%s]不存在", v.Common.Id, turnoutPosRef.Id)
}
}
}
}
// 物理区段
func buildPhysicalSectionsDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for id, physicalSection := range mapData.PhysicalSectionMap {
physicalSectionModel := (verifyStructure.PhysicalSectionModelMap[strconv.Itoa(int(physicalSection.Index))]).(*section.PhysicalSectionModel)
for _, axlePointId := range physicalSection.AxleCountings {
axlePoint := mapData.AxlePointMap[axlePointId]
if axlePoint != nil {
axlePointDevice := (verifyStructure.AxlePointDeviceModelMap[strconv.Itoa(int(axlePoint.Index))]).(*device.AxlePointDeviceModel)
physicalSectionModel.AxlePoints[axlePointDevice.Index] = axlePointDevice
} else {
zap.S().Warnf("id为[%s]的物理区段的关联计轴点[%s]不存在", id, axlePointId)
}
}
pl := len(physicalSectionModel.AxlePoints)
if physicalSectionModel.SwitchArea {
if pl <= 2 {
zap.S().Warnf("id为[%s]的岔区物理区段的计轴检测点数量为[%d]", id, pl)
}
} else {
if pl != 2 {
zap.S().Warnf("id为[%s]的非岔区物理区段的计轴检测点数量为[%d]", id, pl)
}
}
}
}
// 逻辑区段
func buildLogicSectionsDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for id, logicSection := range mapData.LogicSectionMap {
logicalSectionModel := (verifyStructure.LogicalSectionModelMap[strconv.Itoa(int(logicSection.Index))]).(*section.LogicalSectionModel)
axleCountingSection := mapData.AxleSectionMap[logicSection.AxleSectionId]
if axleCountingSection == nil {
zap.S().Warnf("id为[%s]的逻辑区段所在的计轴区段[%s]不存在", id, logicSection.AxleSectionId)
}
axleSectionModel := (verifyStructure.AxleSectionModelMap[strconv.Itoa(int(axleCountingSection.Index))]).(*section.AxleSectionModel)
logicalSectionModel.AxleSection = axleSectionModel
if logicSection.TurnoutId != "" {
turnout := mapData.TurnoutMap[logicSection.TurnoutId]
if turnout != nil {
logicalSectionModel.SwitchDevice = verifyStructure.SwitchDeviceModelMap[strconv.Itoa(int(turnout.Index))]
} else {
zap.S().Warnf("id为[%s]的逻辑区段所在的道岔[%s]不存在", id, logicSection.TurnoutId)
}
}
}
}
// 计轴检测点-从计轴点角度(非岔区物理区段和道岔)
func buildAxlePointDeviceRef(mapData *GraphicInfoMapStructure, verifyStructure *VerifyStructure) {
for id, axlePoint := range mapData.AxlePointMap {
axlePointDeviceModel := (verifyStructure.AxlePointDeviceModelMap[strconv.Itoa(int(axlePoint.Index))]).(*device.AxlePointDeviceModel)
for _, relatedRef := range axlePoint.AxleCountingRef {
switch relatedRef.DeviceType {
case graphicData.RelatedRef_Turnout:
turnout := mapData.TurnoutMap[relatedRef.Id]
if turnout == nil {
zap.S().Warnf("id为[%s]的计轴检测点关联的道岔[%s]不存在", id, relatedRef.Id)
}
switchDeviceModel := (verifyStructure.SwitchDeviceModelMap[strconv.Itoa(int(turnout.Index))]).(*device.SwitchDeviceModel)
axlePointDeviceModel.SwitchDevices[switchDeviceModel.Index] = &ref.SwitchRef{
SwitchDevice: switchDeviceModel,
Port: face.PortEnum(relatedRef.DevicePort),
}
case graphicData.RelatedRef_Section:
s := mapData.PhysicalSectionMap[relatedRef.Id]
if s == nil {
zap.S().Warnf("id为[%s]的计轴检测点关联的物理区段[%s]不存在", id, relatedRef.Id)
}
physicalSectionModel := (verifyStructure.PhysicalSectionModelMap[strconv.Itoa(int(s.Index))]).(*section.PhysicalSectionModel)
if physicalSectionModel.SwitchArea {
zap.S().Warnf("id为[%s]的计轴检测点proto数据关联岔区物理区段[%s]不存在", id, relatedRef.Id)
}
switch relatedRef.DevicePort {
case graphicData.RelatedRef_A:
axlePointDeviceModel.LinePhysicalSectionA = physicalSectionModel
case graphicData.RelatedRef_B:
axlePointDeviceModel.LinePhysicalSectionB = physicalSectionModel
}
}
}
}
}
// 计轴检测点-从物理区段角度
func buildPhysicalAxlePointDeviceRef(verifyStructure *VerifyStructure) {
for _, v := range verifyStructure.PhysicalSectionModelMap {
physicalSection := v.(*section.PhysicalSectionModel)
for _, a := range physicalSection.AxlePoints {
axlePointDeviceModel := a.(*device.AxlePointDeviceModel)
axlePointDeviceModel.AreaPhysicalSections[physicalSection.Index] = physicalSection
}
}
}

View File

@ -0,0 +1,34 @@
package memory
import (
"fmt"
"github.com/golang/protobuf/proto"
"joylink.club/bj-rtsts-server/ats/verify/protos/state"
)
// 计轴区段状态更新
func ChangeAxleSectionState(simulation *VerifySimulation, status *state.SectionState) {
allSectionMap := &simulation.Memory.Status.AxleSectionStateMap
d, ok := allSectionMap.Load(status.Id)
if !ok {
panic(fmt.Sprintf("计轴区段【%s】不存在", status.Id))
}
cur := d.(*state.SectionState)
if !proto.Equal(cur, status) { // 如果信息发送了变化
cur.Occupied = status.Occupied
// 将变更信息放入变更状态队列中
simulation.Memory.ChangeStatus.AxleSectionStateMap.Store(status.Id, proto.Clone(cur))
}
}
// 获取全部的计轴区段状态
func GetAllAxleSectionState(simulation *VerifySimulation) []*state.SectionState {
allSectionMap := &simulation.Memory.Status.AxleSectionStateMap
var sectionArr []*state.SectionState
allSectionMap.Range(func(k, v any) bool {
sectionArr = append(sectionArr, v.(*state.SectionState))
return true
})
return sectionArr
}

View File

@ -0,0 +1,34 @@
package memory
import (
"fmt"
"github.com/golang/protobuf/proto"
"joylink.club/bj-rtsts-server/ats/verify/protos/state"
)
// 物理区段状态更新
func ChangePhysicalSectionState(simulation *VerifySimulation, status *state.SectionState) {
allSectionMap := &simulation.Memory.Status.PhysicalSectionStateMap
d, ok := allSectionMap.Load(status.Id)
if !ok {
panic(fmt.Sprintf("物理区段【%s】不存在", status.Id))
}
cur := d.(*state.SectionState)
if !proto.Equal(cur, status) { // 如果信息发送了变化
cur.Occupied = status.Occupied
// 将变更信息放入变更状态队列中
simulation.Memory.ChangeStatus.PhysicalSectionStateMap.Store(status.Id, proto.Clone(cur))
}
}
// 获取全部的物理区段状态
func GetAllPhysicalSectionState(simulation *VerifySimulation) []*state.SectionState {
allSectionMap := &simulation.Memory.Status.PhysicalSectionStateMap
var sectionArr []*state.SectionState
allSectionMap.Range(func(k, v any) bool {
sectionArr = append(sectionArr, v.(*state.SectionState))
return true
})
return sectionArr
}

View File

@ -34,7 +34,7 @@ func AddTrainState(simulation *VerifySimulation, status *state.TrainState) {
Up: status.Up,
})
if err != nil || httpCode != http.StatusOK {
panic(dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("动力学接口调用失败:%s", err.Error())})
panic(dto.ErrorDto{Code: dto.LogicError, Message: fmt.Sprintf("动力学接口调用失败:[%d][%s]", httpCode, err)})
}
// 将信息合并到当前设备状态中
allTrainMap.Store(status.Id, status)
@ -83,11 +83,7 @@ func GetAllTrainState(simulation *VerifySimulation) []*state.TrainState {
allTrainMap := &simulation.Memory.Status.TrainStateMap
var trainArr []*state.TrainState
allTrainMap.Range(func(k, v any) bool {
d := v.(*state.TrainState)
if d.Show { // 只推送显示的车信息
c := proto.Clone(d).(*state.TrainState)
trainArr = append(trainArr, c)
}
trainArr = append(trainArr, v.(*state.TrainState))
return true
})
return trainArr

View File

@ -30,12 +30,7 @@ func GetAllTurnoutState(simulation *VerifySimulation) []*state.SwitchState {
allSwitchMap := &simulation.Memory.Status.SwitchStateMap
var switchArr []*state.SwitchState
allSwitchMap.Range(func(k, v any) bool {
d := v.(*state.SwitchState)
switchArr = append(switchArr, &state.SwitchState{
Id: d.Id,
Normal: d.Normal,
Reverse: d.Reverse,
})
switchArr = append(switchArr, v.(*state.SwitchState))
return true
})
return switchArr

View File

@ -32,8 +32,9 @@ func (s *VerifySimulation) GetAllState() *state.PushedDevicesStatus {
return &state.PushedDevicesStatus{
All: true,
AllStatus: &state.AllDevicesStatus{
SwitchState: GetAllTurnoutState(s),
TrainState: GetAllTrainState(s),
SwitchState: GetAllTurnoutState(s),
TrainState: GetAllTrainState(s),
SectionState: append(GetAllAxleSectionState(s), GetAllPhysicalSectionState(s)...),
},
}
}

View File

@ -10,5 +10,5 @@ type SignalDeviceModel struct {
//信号机基本信息
face.DeviceModel
//信号机所在公里标,单位为mm
KilometerSystem graphicData.KilometerSystem
KilometerSystem *graphicData.KilometerSystem
}

@ -1 +1 @@
Subproject commit f0da7c7c5c5a9fc8781d0d612a84e3a97f8c0f81
Subproject commit 9830db4a12bdf1018b89ea5d86fff0832a4a8eb0

396
db/dbquery/category.gen.go Normal file
View File

@ -0,0 +1,396 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package dbquery
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"joylink.club/bj-rtsts-server/db/model"
)
func newCategory(db *gorm.DB, opts ...gen.DOOption) category {
_category := category{}
_category.categoryDo.UseDB(db, opts...)
_category.categoryDo.UseModel(&model.Category{})
tableName := _category.categoryDo.TableName()
_category.ALL = field.NewAsterisk(tableName)
_category.ID = field.NewInt32(tableName, "id")
_category.Name = field.NewString(tableName, "name")
_category.Config = field.NewString(tableName, "config")
_category.CreatedAt = field.NewTime(tableName, "created_at")
_category.UpdateAt = field.NewTime(tableName, "update_at")
_category.fillFieldMap()
return _category
}
type category struct {
categoryDo
ALL field.Asterisk
ID field.Int32 // id
Name field.String // 厂家名
Config field.String // 厂家配置
CreatedAt field.Time // 创建时间
UpdateAt field.Time // 修改时间
fieldMap map[string]field.Expr
}
func (c category) Table(newTableName string) *category {
c.categoryDo.UseTable(newTableName)
return c.updateTableName(newTableName)
}
func (c category) As(alias string) *category {
c.categoryDo.DO = *(c.categoryDo.As(alias).(*gen.DO))
return c.updateTableName(alias)
}
func (c *category) updateTableName(table string) *category {
c.ALL = field.NewAsterisk(table)
c.ID = field.NewInt32(table, "id")
c.Name = field.NewString(table, "name")
c.Config = field.NewString(table, "config")
c.CreatedAt = field.NewTime(table, "created_at")
c.UpdateAt = field.NewTime(table, "update_at")
c.fillFieldMap()
return c
}
func (c *category) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := c.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (c *category) fillFieldMap() {
c.fieldMap = make(map[string]field.Expr, 5)
c.fieldMap["id"] = c.ID
c.fieldMap["name"] = c.Name
c.fieldMap["config"] = c.Config
c.fieldMap["created_at"] = c.CreatedAt
c.fieldMap["update_at"] = c.UpdateAt
}
func (c category) clone(db *gorm.DB) category {
c.categoryDo.ReplaceConnPool(db.Statement.ConnPool)
return c
}
func (c category) replaceDB(db *gorm.DB) category {
c.categoryDo.ReplaceDB(db)
return c
}
type categoryDo struct{ gen.DO }
type ICategoryDo interface {
gen.SubQuery
Debug() ICategoryDo
WithContext(ctx context.Context) ICategoryDo
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
ReplaceDB(db *gorm.DB)
ReadDB() ICategoryDo
WriteDB() ICategoryDo
As(alias string) gen.Dao
Session(config *gorm.Session) ICategoryDo
Columns(cols ...field.Expr) gen.Columns
Clauses(conds ...clause.Expression) ICategoryDo
Not(conds ...gen.Condition) ICategoryDo
Or(conds ...gen.Condition) ICategoryDo
Select(conds ...field.Expr) ICategoryDo
Where(conds ...gen.Condition) ICategoryDo
Order(conds ...field.Expr) ICategoryDo
Distinct(cols ...field.Expr) ICategoryDo
Omit(cols ...field.Expr) ICategoryDo
Join(table schema.Tabler, on ...field.Expr) ICategoryDo
LeftJoin(table schema.Tabler, on ...field.Expr) ICategoryDo
RightJoin(table schema.Tabler, on ...field.Expr) ICategoryDo
Group(cols ...field.Expr) ICategoryDo
Having(conds ...gen.Condition) ICategoryDo
Limit(limit int) ICategoryDo
Offset(offset int) ICategoryDo
Count() (count int64, err error)
Scopes(funcs ...func(gen.Dao) gen.Dao) ICategoryDo
Unscoped() ICategoryDo
Create(values ...*model.Category) error
CreateInBatches(values []*model.Category, batchSize int) error
Save(values ...*model.Category) error
First() (*model.Category, error)
Take() (*model.Category, error)
Last() (*model.Category, error)
Find() ([]*model.Category, error)
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Category, err error)
FindInBatches(result *[]*model.Category, batchSize int, fc func(tx gen.Dao, batch int) error) error
Pluck(column field.Expr, dest interface{}) error
Delete(...*model.Category) (info gen.ResultInfo, err error)
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
Updates(value interface{}) (info gen.ResultInfo, err error)
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
UpdateFrom(q gen.SubQuery) gen.Dao
Attrs(attrs ...field.AssignExpr) ICategoryDo
Assign(attrs ...field.AssignExpr) ICategoryDo
Joins(fields ...field.RelationField) ICategoryDo
Preload(fields ...field.RelationField) ICategoryDo
FirstOrInit() (*model.Category, error)
FirstOrCreate() (*model.Category, error)
FindByPage(offset int, limit int) (result []*model.Category, count int64, err error)
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
Scan(result interface{}) (err error)
Returning(value interface{}, columns ...string) ICategoryDo
UnderlyingDB() *gorm.DB
schema.Tabler
}
func (c categoryDo) Debug() ICategoryDo {
return c.withDO(c.DO.Debug())
}
func (c categoryDo) WithContext(ctx context.Context) ICategoryDo {
return c.withDO(c.DO.WithContext(ctx))
}
func (c categoryDo) ReadDB() ICategoryDo {
return c.Clauses(dbresolver.Read)
}
func (c categoryDo) WriteDB() ICategoryDo {
return c.Clauses(dbresolver.Write)
}
func (c categoryDo) Session(config *gorm.Session) ICategoryDo {
return c.withDO(c.DO.Session(config))
}
func (c categoryDo) Clauses(conds ...clause.Expression) ICategoryDo {
return c.withDO(c.DO.Clauses(conds...))
}
func (c categoryDo) Returning(value interface{}, columns ...string) ICategoryDo {
return c.withDO(c.DO.Returning(value, columns...))
}
func (c categoryDo) Not(conds ...gen.Condition) ICategoryDo {
return c.withDO(c.DO.Not(conds...))
}
func (c categoryDo) Or(conds ...gen.Condition) ICategoryDo {
return c.withDO(c.DO.Or(conds...))
}
func (c categoryDo) Select(conds ...field.Expr) ICategoryDo {
return c.withDO(c.DO.Select(conds...))
}
func (c categoryDo) Where(conds ...gen.Condition) ICategoryDo {
return c.withDO(c.DO.Where(conds...))
}
func (c categoryDo) Order(conds ...field.Expr) ICategoryDo {
return c.withDO(c.DO.Order(conds...))
}
func (c categoryDo) Distinct(cols ...field.Expr) ICategoryDo {
return c.withDO(c.DO.Distinct(cols...))
}
func (c categoryDo) Omit(cols ...field.Expr) ICategoryDo {
return c.withDO(c.DO.Omit(cols...))
}
func (c categoryDo) Join(table schema.Tabler, on ...field.Expr) ICategoryDo {
return c.withDO(c.DO.Join(table, on...))
}
func (c categoryDo) LeftJoin(table schema.Tabler, on ...field.Expr) ICategoryDo {
return c.withDO(c.DO.LeftJoin(table, on...))
}
func (c categoryDo) RightJoin(table schema.Tabler, on ...field.Expr) ICategoryDo {
return c.withDO(c.DO.RightJoin(table, on...))
}
func (c categoryDo) Group(cols ...field.Expr) ICategoryDo {
return c.withDO(c.DO.Group(cols...))
}
func (c categoryDo) Having(conds ...gen.Condition) ICategoryDo {
return c.withDO(c.DO.Having(conds...))
}
func (c categoryDo) Limit(limit int) ICategoryDo {
return c.withDO(c.DO.Limit(limit))
}
func (c categoryDo) Offset(offset int) ICategoryDo {
return c.withDO(c.DO.Offset(offset))
}
func (c categoryDo) Scopes(funcs ...func(gen.Dao) gen.Dao) ICategoryDo {
return c.withDO(c.DO.Scopes(funcs...))
}
func (c categoryDo) Unscoped() ICategoryDo {
return c.withDO(c.DO.Unscoped())
}
func (c categoryDo) Create(values ...*model.Category) error {
if len(values) == 0 {
return nil
}
return c.DO.Create(values)
}
func (c categoryDo) CreateInBatches(values []*model.Category, batchSize int) error {
return c.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (c categoryDo) Save(values ...*model.Category) error {
if len(values) == 0 {
return nil
}
return c.DO.Save(values)
}
func (c categoryDo) First() (*model.Category, error) {
if result, err := c.DO.First(); err != nil {
return nil, err
} else {
return result.(*model.Category), nil
}
}
func (c categoryDo) Take() (*model.Category, error) {
if result, err := c.DO.Take(); err != nil {
return nil, err
} else {
return result.(*model.Category), nil
}
}
func (c categoryDo) Last() (*model.Category, error) {
if result, err := c.DO.Last(); err != nil {
return nil, err
} else {
return result.(*model.Category), nil
}
}
func (c categoryDo) Find() ([]*model.Category, error) {
result, err := c.DO.Find()
return result.([]*model.Category), err
}
func (c categoryDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Category, err error) {
buf := make([]*model.Category, 0, batchSize)
err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (c categoryDo) FindInBatches(result *[]*model.Category, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return c.DO.FindInBatches(result, batchSize, fc)
}
func (c categoryDo) Attrs(attrs ...field.AssignExpr) ICategoryDo {
return c.withDO(c.DO.Attrs(attrs...))
}
func (c categoryDo) Assign(attrs ...field.AssignExpr) ICategoryDo {
return c.withDO(c.DO.Assign(attrs...))
}
func (c categoryDo) Joins(fields ...field.RelationField) ICategoryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Joins(_f))
}
return &c
}
func (c categoryDo) Preload(fields ...field.RelationField) ICategoryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Preload(_f))
}
return &c
}
func (c categoryDo) FirstOrInit() (*model.Category, error) {
if result, err := c.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*model.Category), nil
}
}
func (c categoryDo) FirstOrCreate() (*model.Category, error) {
if result, err := c.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*model.Category), nil
}
}
func (c categoryDo) FindByPage(offset int, limit int) (result []*model.Category, count int64, err error) {
result, err = c.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = c.Offset(-1).Limit(-1).Count()
return
}
func (c categoryDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = c.Count()
if err != nil {
return
}
err = c.Offset(offset).Limit(limit).Scan(result)
return
}
func (c categoryDo) Scan(result interface{}) (err error) {
return c.DO.Scan(result)
}
func (c categoryDo) Delete(models ...*model.Category) (result gen.ResultInfo, err error) {
return c.DO.Delete(models)
}
func (c *categoryDo) withDO(do gen.Dao) *categoryDo {
c.DO = *do.(*gen.DO)
return c
}

View File

@ -33,6 +33,7 @@ func newDrafting(db *gorm.DB, opts ...gen.DOOption) drafting {
_drafting.CreatorID = field.NewInt32(tableName, "creator_id")
_drafting.CreatedAt = field.NewTime(tableName, "created_at")
_drafting.UpdateAt = field.NewTime(tableName, "update_at")
_drafting.Category = field.NewInt32(tableName, "category")
_drafting.fillFieldMap()
@ -49,6 +50,7 @@ type drafting struct {
CreatorID field.Int32 // 创建人id
CreatedAt field.Time // 创建时间
UpdateAt field.Time // 修改时间
Category field.Int32 // 厂家id
fieldMap map[string]field.Expr
}
@ -71,6 +73,7 @@ func (d *drafting) updateTableName(table string) *drafting {
d.CreatorID = field.NewInt32(table, "creator_id")
d.CreatedAt = field.NewTime(table, "created_at")
d.UpdateAt = field.NewTime(table, "update_at")
d.Category = field.NewInt32(table, "category")
d.fillFieldMap()
@ -87,13 +90,14 @@ func (d *drafting) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (d *drafting) fillFieldMap() {
d.fieldMap = make(map[string]field.Expr, 6)
d.fieldMap = make(map[string]field.Expr, 7)
d.fieldMap["id"] = d.ID
d.fieldMap["name"] = d.Name
d.fieldMap["proto"] = d.Proto
d.fieldMap["creator_id"] = d.CreatorID
d.fieldMap["created_at"] = d.CreatedAt
d.fieldMap["update_at"] = d.UpdateAt
d.fieldMap["category"] = d.Category
}
func (d drafting) clone(db *gorm.DB) drafting {

View File

@ -17,6 +17,7 @@ import (
var (
Q = new(Query)
Category *category
Drafting *drafting
PublishedGi *publishedGi
User *user
@ -24,6 +25,7 @@ var (
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
*Q = *Use(db, opts...)
Category = &Q.Category
Drafting = &Q.Drafting
PublishedGi = &Q.PublishedGi
User = &Q.User
@ -32,6 +34,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
return &Query{
db: db,
Category: newCategory(db, opts...),
Drafting: newDrafting(db, opts...),
PublishedGi: newPublishedGi(db, opts...),
User: newUser(db, opts...),
@ -41,6 +44,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
type Query struct {
db *gorm.DB
Category category
Drafting drafting
PublishedGi publishedGi
User user
@ -51,6 +55,7 @@ func (q *Query) Available() bool { return q.db != nil }
func (q *Query) clone(db *gorm.DB) *Query {
return &Query{
db: db,
Category: q.Category.clone(db),
Drafting: q.Drafting.clone(db),
PublishedGi: q.PublishedGi.clone(db),
User: q.User.clone(db),
@ -68,6 +73,7 @@ func (q *Query) WriteDB() *Query {
func (q *Query) ReplaceDB(db *gorm.DB) *Query {
return &Query{
db: db,
Category: q.Category.replaceDB(db),
Drafting: q.Drafting.replaceDB(db),
PublishedGi: q.PublishedGi.replaceDB(db),
User: q.User.replaceDB(db),
@ -75,6 +81,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
}
type queryCtx struct {
Category ICategoryDo
Drafting IDraftingDo
PublishedGi IPublishedGiDo
User IUserDo
@ -82,6 +89,7 @@ type queryCtx struct {
func (q *Query) WithContext(ctx context.Context) *queryCtx {
return &queryCtx{
Category: q.Category.WithContext(ctx),
Drafting: q.Drafting.WithContext(ctx),
PublishedGi: q.PublishedGi.WithContext(ctx),
User: q.User.WithContext(ctx),

View File

@ -32,6 +32,9 @@ func newPublishedGi(db *gorm.DB, opts ...gen.DOOption) publishedGi {
_publishedGi.Proto = field.NewBytes(tableName, "proto")
_publishedGi.UserID = field.NewInt32(tableName, "user_id")
_publishedGi.PublishAt = field.NewTime(tableName, "publish_at")
_publishedGi.Category = field.NewInt32(tableName, "category")
_publishedGi.Note = field.NewString(tableName, "note")
_publishedGi.Status = field.NewInt32(tableName, "status")
_publishedGi.fillFieldMap()
@ -47,6 +50,9 @@ type publishedGi struct {
Proto field.Bytes // 图形界面数据
UserID field.Int32 // 发布用户id
PublishAt field.Time // 发布时间
Category field.Int32 // 厂家信息
Note field.String // 发布描述
Status field.Int32 // 显示状态
fieldMap map[string]field.Expr
}
@ -68,6 +74,9 @@ func (p *publishedGi) updateTableName(table string) *publishedGi {
p.Proto = field.NewBytes(table, "proto")
p.UserID = field.NewInt32(table, "user_id")
p.PublishAt = field.NewTime(table, "publish_at")
p.Category = field.NewInt32(table, "category")
p.Note = field.NewString(table, "note")
p.Status = field.NewInt32(table, "status")
p.fillFieldMap()
@ -84,12 +93,15 @@ func (p *publishedGi) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (p *publishedGi) fillFieldMap() {
p.fieldMap = make(map[string]field.Expr, 5)
p.fieldMap = make(map[string]field.Expr, 8)
p.fieldMap["id"] = p.ID
p.fieldMap["name"] = p.Name
p.fieldMap["proto"] = p.Proto
p.fieldMap["user_id"] = p.UserID
p.fieldMap["publish_at"] = p.PublishAt
p.fieldMap["category"] = p.Category
p.fieldMap["note"] = p.Note
p.fieldMap["status"] = p.Status
}
func (p publishedGi) clone(db *gorm.DB) publishedGi {

25
db/model/category.gen.go Normal file
View File

@ -0,0 +1,25 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package model
import (
"time"
)
const TableNameCategory = "category"
// Category mapped from table <category>
type Category struct {
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"` // id
Name string `gorm:"column:name;not null;comment:厂家名" json:"name"` // 厂家名
Config string `gorm:"column:config;comment:厂家配置" json:"config"` // 厂家配置
CreatedAt time.Time `gorm:"column:created_at;not null;comment:创建时间" json:"created_at"` // 创建时间
UpdateAt time.Time `gorm:"column:update_at;comment:修改时间" json:"update_at"` // 修改时间
}
// TableName Category's table name
func (*Category) TableName() string {
return TableNameCategory
}

View File

@ -18,6 +18,7 @@ type Drafting struct {
CreatorID int32 `gorm:"column:creator_id;not null;comment:创建人id" json:"creator_id"` // 创建人id
CreatedAt time.Time `gorm:"column:created_at;not null;comment:创建时间" json:"created_at"` // 创建时间
UpdateAt time.Time `gorm:"column:update_at;comment:修改时间" json:"update_at"` // 修改时间
Category int32 `gorm:"column:category;comment:厂家id" json:"category"` // 厂家id
}
// TableName Drafting's table name

View File

@ -17,6 +17,9 @@ type PublishedGi struct {
Proto []byte `gorm:"column:proto;not null;comment:图形界面数据" json:"proto"` // 图形界面数据
UserID int32 `gorm:"column:user_id;not null;comment:发布用户id" json:"user_id"` // 发布用户id
PublishAt time.Time `gorm:"column:publish_at;not null;comment:发布时间" json:"publish_at"` // 发布时间
Category int32 `gorm:"column:category;comment:厂家信息" json:"category"` // 厂家信息
Note string `gorm:"column:note;comment:发布描述" json:"note"` // 发布描述
Status int32 `gorm:"column:status;default:1;comment:显示状态" json:"status"` // 显示状态
}
// TableName PublishedGi's table name

View File

@ -16,6 +16,374 @@ const docTemplate = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/api/v1/category": {
"post": {
"security": [
{
"JwtAuth": []
}
],
"description": "创建厂家数据",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "创建厂家信息",
"parameters": [
{
"type": "string",
"name": "config",
"in": "query"
},
{
"type": "integer",
"name": "id",
"in": "query"
},
{
"type": "string",
"name": "name",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/category/:id": {
"get": {
"security": [
{
"JwtAuth": []
}
],
"description": "查询厂家信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "查询厂家信息",
"parameters": [
{
"type": "integer",
"description": "厂家ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/model.Drafting"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
},
"put": {
"security": [
{
"JwtAuth": []
}
],
"description": "修改厂家信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "修改厂家信息",
"parameters": [
{
"type": "integer",
"description": "厂家信息ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"name": "config",
"in": "query"
},
{
"type": "integer",
"name": "id",
"in": "query"
},
{
"type": "string",
"name": "name",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
},
"delete": {
"security": [
{
"JwtAuth": []
}
],
"description": "删除厂家信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "删除厂家信息",
"parameters": [
{
"type": "integer",
"description": "厂家信息ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/category/list": {
"get": {
"security": [
{
"JwtAuth": []
}
],
"description": "可以通过厂家名称过滤,查询厂家信息列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "查询厂家信息列表",
"parameters": [
{
"type": "string",
"name": "name",
"in": "query"
},
{
"type": "integer",
"example": 1,
"description": "页码",
"name": "current",
"in": "query",
"required": true
},
{
"type": "integer",
"example": 10,
"description": "页面行数",
"name": "size",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/dto.PageDto"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/category/paging": {
"get": {
"security": [
{
"JwtAuth": []
}
],
"description": "可以通过厂家名称过滤,分页查询厂家信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "分页查询厂家信息",
"parameters": [
{
"type": "string",
"name": "name",
"in": "query"
},
{
"type": "integer",
"example": 1,
"description": "页码",
"name": "current",
"in": "query",
"required": true
},
{
"type": "integer",
"example": 10,
"description": "页面行数",
"name": "size",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/dto.PageDto"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/drafting": {
"post": {
"security": [
@ -35,6 +403,11 @@ const docTemplate = `{
],
"summary": "创建草稿",
"parameters": [
{
"type": "integer",
"name": "category",
"in": "query"
},
{
"type": "integer",
"name": "id",
@ -159,6 +532,11 @@ const docTemplate = `{
"in": "path",
"required": true
},
{
"type": "integer",
"name": "category",
"in": "query"
},
{
"type": "integer",
"name": "id",
@ -280,6 +658,11 @@ const docTemplate = `{
"in": "path",
"required": true
},
{
"type": "integer",
"name": "category",
"in": "query"
},
{
"type": "integer",
"name": "id",
@ -394,6 +777,60 @@ const docTemplate = `{
}
}
},
"/api/v1/generate/calculatelink": {
"post": {
"security": [
{
"JwtAuth": []
}
],
"description": "根据地图数据新生成计算的link信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"GenerateApi"
],
"summary": "根据地图数据新生成计算的link信息",
"parameters": [
{
"type": "array",
"items": {
"type": "integer"
},
"collectionFormat": "csv",
"name": "proto",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/publishedGi/list": {
"get": {
"security": [
@ -562,6 +999,74 @@ const docTemplate = `{
"description": "发布后的名称",
"name": "name",
"in": "query"
},
{
"type": "string",
"name": "note",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/publishedGi/saveAsDrafting/{id}": {
"post": {
"security": [
{
"JwtAuth": []
}
],
"description": "从发布数据拉取信息到草稿",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"发布的图形数据Api"
],
"summary": "从发布数据拉取信息到草稿",
"parameters": [
{
"type": "integer",
"description": "id",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "草稿数据的id",
"name": "draftingId",
"in": "query"
},
{
"type": "string",
"description": "发布后的名称",
"name": "name",
"in": "query"
},
{
"type": "string",
"name": "note",
"in": "query"
}
],
"responses": {
@ -735,7 +1240,7 @@ const docTemplate = `{
"JwtAuth": []
}
],
"description": "创建ATS测试仿真",
"description": "创建并进入仿真后获取仿真的设备信息",
"consumes": [
"application/json"
],
@ -745,7 +1250,7 @@ const docTemplate = `{
"tags": [
"ATS测试仿真Api"
],
"summary": "创建ATS测试仿真",
"summary": "创建并进入仿真后获取仿真的设备信息",
"parameters": [
{
"type": "string",
@ -780,6 +1285,56 @@ const docTemplate = `{
}
}
},
"/api/v1/simulation/destroy/{id}": {
"post": {
"security": [
{
"JwtAuth": []
}
],
"description": "ATS测试仿真-添加列车",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"ATS测试仿真Api"
],
"summary": "ATS仿真销毁",
"parameters": [
{
"type": "string",
"description": "JWT Token",
"name": "Authorization",
"in": "header",
"required": true
},
{
"type": "integer",
"description": "仿真id",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/simulation/list": {
"get": {
"security": [
@ -930,56 +1485,6 @@ const docTemplate = `{
}
}
},
"/api/v1/simulation/train/destroy/{id}": {
"get": {
"security": [
{
"JwtAuth": []
}
],
"description": "ATS测试仿真-添加列车",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"ATS测试仿真Api"
],
"summary": "ATS仿真销毁",
"parameters": [
{
"type": "string",
"description": "JWT Token",
"name": "Authorization",
"in": "header",
"required": true
},
{
"type": "integer",
"description": "仿真id",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/simulation/train/remove": {
"post": {
"security": [
@ -1435,9 +1940,7 @@ const docTemplate = `{
"type": "object",
"required": [
"simulationId",
"switchIndex",
"turnNormal",
"turnReverse"
"switchIndex"
],
"properties": {
"simulationId": {
@ -1471,6 +1974,10 @@ const docTemplate = `{
"model.Drafting": {
"type": "object",
"properties": {
"category": {
"description": "厂家id",
"type": "integer"
},
"created_at": {
"description": "创建时间",
"type": "string"
@ -1503,6 +2010,10 @@ const docTemplate = `{
"model.PublishedGi": {
"type": "object",
"properties": {
"category": {
"description": "厂家信息",
"type": "integer"
},
"id": {
"description": "id",
"type": "integer"
@ -1511,6 +2022,10 @@ const docTemplate = `{
"description": "发布图形界面名称",
"type": "string"
},
"note": {
"description": "发布描述",
"type": "string"
},
"proto": {
"description": "图形界面数据",
"type": "array",
@ -1522,6 +2037,10 @@ const docTemplate = `{
"description": "发布时间",
"type": "string"
},
"status": {
"description": "显示状态",
"type": "integer"
},
"user_id": {
"description": "发布用户id",
"type": "integer"

View File

@ -9,6 +9,374 @@
"host": "localhost:9091",
"basePath": "/",
"paths": {
"/api/v1/category": {
"post": {
"security": [
{
"JwtAuth": []
}
],
"description": "创建厂家数据",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "创建厂家信息",
"parameters": [
{
"type": "string",
"name": "config",
"in": "query"
},
{
"type": "integer",
"name": "id",
"in": "query"
},
{
"type": "string",
"name": "name",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/category/:id": {
"get": {
"security": [
{
"JwtAuth": []
}
],
"description": "查询厂家信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "查询厂家信息",
"parameters": [
{
"type": "integer",
"description": "厂家ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/model.Drafting"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
},
"put": {
"security": [
{
"JwtAuth": []
}
],
"description": "修改厂家信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "修改厂家信息",
"parameters": [
{
"type": "integer",
"description": "厂家信息ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"name": "config",
"in": "query"
},
{
"type": "integer",
"name": "id",
"in": "query"
},
{
"type": "string",
"name": "name",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
},
"delete": {
"security": [
{
"JwtAuth": []
}
],
"description": "删除厂家信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "删除厂家信息",
"parameters": [
{
"type": "integer",
"description": "厂家信息ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/category/list": {
"get": {
"security": [
{
"JwtAuth": []
}
],
"description": "可以通过厂家名称过滤,查询厂家信息列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "查询厂家信息列表",
"parameters": [
{
"type": "string",
"name": "name",
"in": "query"
},
{
"type": "integer",
"example": 1,
"description": "页码",
"name": "current",
"in": "query",
"required": true
},
{
"type": "integer",
"example": 10,
"description": "页面行数",
"name": "size",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/dto.PageDto"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/category/paging": {
"get": {
"security": [
{
"JwtAuth": []
}
],
"description": "可以通过厂家名称过滤,分页查询厂家信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"厂家信息Api"
],
"summary": "分页查询厂家信息",
"parameters": [
{
"type": "string",
"name": "name",
"in": "query"
},
{
"type": "integer",
"example": 1,
"description": "页码",
"name": "current",
"in": "query",
"required": true
},
{
"type": "integer",
"example": 10,
"description": "页面行数",
"name": "size",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/dto.PageDto"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/drafting": {
"post": {
"security": [
@ -28,6 +396,11 @@
],
"summary": "创建草稿",
"parameters": [
{
"type": "integer",
"name": "category",
"in": "query"
},
{
"type": "integer",
"name": "id",
@ -152,6 +525,11 @@
"in": "path",
"required": true
},
{
"type": "integer",
"name": "category",
"in": "query"
},
{
"type": "integer",
"name": "id",
@ -273,6 +651,11 @@
"in": "path",
"required": true
},
{
"type": "integer",
"name": "category",
"in": "query"
},
{
"type": "integer",
"name": "id",
@ -387,6 +770,60 @@
}
}
},
"/api/v1/generate/calculatelink": {
"post": {
"security": [
{
"JwtAuth": []
}
],
"description": "根据地图数据新生成计算的link信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"GenerateApi"
],
"summary": "根据地图数据新生成计算的link信息",
"parameters": [
{
"type": "array",
"items": {
"type": "integer"
},
"collectionFormat": "csv",
"name": "proto",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/publishedGi/list": {
"get": {
"security": [
@ -555,6 +992,74 @@
"description": "发布后的名称",
"name": "name",
"in": "query"
},
{
"type": "string",
"name": "note",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/publishedGi/saveAsDrafting/{id}": {
"post": {
"security": [
{
"JwtAuth": []
}
],
"description": "从发布数据拉取信息到草稿",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"发布的图形数据Api"
],
"summary": "从发布数据拉取信息到草稿",
"parameters": [
{
"type": "integer",
"description": "id",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "草稿数据的id",
"name": "draftingId",
"in": "query"
},
{
"type": "string",
"description": "发布后的名称",
"name": "name",
"in": "query"
},
{
"type": "string",
"name": "note",
"in": "query"
}
],
"responses": {
@ -728,7 +1233,7 @@
"JwtAuth": []
}
],
"description": "创建ATS测试仿真",
"description": "创建并进入仿真后获取仿真的设备信息",
"consumes": [
"application/json"
],
@ -738,7 +1243,7 @@
"tags": [
"ATS测试仿真Api"
],
"summary": "创建ATS测试仿真",
"summary": "创建并进入仿真后获取仿真的设备信息",
"parameters": [
{
"type": "string",
@ -773,6 +1278,56 @@
}
}
},
"/api/v1/simulation/destroy/{id}": {
"post": {
"security": [
{
"JwtAuth": []
}
],
"description": "ATS测试仿真-添加列车",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"ATS测试仿真Api"
],
"summary": "ATS仿真销毁",
"parameters": [
{
"type": "string",
"description": "JWT Token",
"name": "Authorization",
"in": "header",
"required": true
},
{
"type": "integer",
"description": "仿真id",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/simulation/list": {
"get": {
"security": [
@ -923,56 +1478,6 @@
}
}
},
"/api/v1/simulation/train/destroy/{id}": {
"get": {
"security": [
{
"JwtAuth": []
}
],
"description": "ATS测试仿真-添加列车",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"ATS测试仿真Api"
],
"summary": "ATS仿真销毁",
"parameters": [
{
"type": "string",
"description": "JWT Token",
"name": "Authorization",
"in": "header",
"required": true
},
{
"type": "integer",
"description": "仿真id",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/dto.ErrorDto"
}
}
}
}
},
"/api/v1/simulation/train/remove": {
"post": {
"security": [
@ -1428,9 +1933,7 @@
"type": "object",
"required": [
"simulationId",
"switchIndex",
"turnNormal",
"turnReverse"
"switchIndex"
],
"properties": {
"simulationId": {
@ -1464,6 +1967,10 @@
"model.Drafting": {
"type": "object",
"properties": {
"category": {
"description": "厂家id",
"type": "integer"
},
"created_at": {
"description": "创建时间",
"type": "string"
@ -1496,6 +2003,10 @@
"model.PublishedGi": {
"type": "object",
"properties": {
"category": {
"description": "厂家信息",
"type": "integer"
},
"id": {
"description": "id",
"type": "integer"
@ -1504,6 +2015,10 @@
"description": "发布图形界面名称",
"type": "string"
},
"note": {
"description": "发布描述",
"type": "string"
},
"proto": {
"description": "图形界面数据",
"type": "array",
@ -1515,6 +2030,10 @@
"description": "发布时间",
"type": "string"
},
"status": {
"description": "显示状态",
"type": "integer"
},
"user_id": {
"description": "发布用户id",
"type": "integer"

View File

@ -153,8 +153,6 @@ definitions:
required:
- simulationId
- switchIndex
- turnNormal
- turnReverse
type: object
dto.TokenRespDto:
properties:
@ -167,6 +165,9 @@ definitions:
type: object
model.Drafting:
properties:
category:
description: 厂家id
type: integer
created_at:
description: 创建时间
type: string
@ -190,12 +191,18 @@ definitions:
type: object
model.PublishedGi:
properties:
category:
description: 厂家信息
type: integer
id:
description: id
type: integer
name:
description: 发布图形界面名称
type: string
note:
description: 发布描述
type: string
proto:
description: 图形界面数据
items:
@ -204,6 +211,9 @@ definitions:
publish_at:
description: 发布时间
type: string
status:
description: 显示状态
type: integer
user_id:
description: 发布用户id
type: integer
@ -215,12 +225,250 @@ info:
title: CBTC测试系统API
version: "1.0"
paths:
/api/v1/category:
post:
consumes:
- application/json
description: 创建厂家数据
parameters:
- in: query
name: config
type: string
- in: query
name: id
type: integer
- in: query
name: name
type: string
produces:
- application/json
responses:
"200":
description: OK
"401":
description: Unauthorized
schema:
$ref: '#/definitions/dto.ErrorDto'
"404":
description: Not Found
schema:
$ref: '#/definitions/dto.ErrorDto'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: 创建厂家信息
tags:
- 厂家信息Api
/api/v1/category/:id:
delete:
consumes:
- application/json
description: 删除厂家信息
parameters:
- description: 厂家信息ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
"401":
description: Unauthorized
schema:
$ref: '#/definitions/dto.ErrorDto'
"404":
description: Not Found
schema:
$ref: '#/definitions/dto.ErrorDto'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: 删除厂家信息
tags:
- 厂家信息Api
get:
consumes:
- application/json
description: 查询厂家信息
parameters:
- description: 厂家ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/model.Drafting'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/dto.ErrorDto'
"404":
description: Not Found
schema:
$ref: '#/definitions/dto.ErrorDto'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: 查询厂家信息
tags:
- 厂家信息Api
put:
consumes:
- application/json
description: 修改厂家信息
parameters:
- description: 厂家信息ID
in: path
name: id
required: true
type: integer
- in: query
name: config
type: string
- in: query
name: id
type: integer
- in: query
name: name
type: string
produces:
- application/json
responses:
"200":
description: OK
"401":
description: Unauthorized
schema:
$ref: '#/definitions/dto.ErrorDto'
"404":
description: Not Found
schema:
$ref: '#/definitions/dto.ErrorDto'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: 修改厂家信息
tags:
- 厂家信息Api
/api/v1/category/list:
get:
consumes:
- application/json
description: 可以通过厂家名称过滤,查询厂家信息列表
parameters:
- in: query
name: name
type: string
- description: 页码
example: 1
in: query
name: current
required: true
type: integer
- description: 页面行数
example: 10
in: query
name: size
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/dto.PageDto'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/dto.ErrorDto'
"404":
description: Not Found
schema:
$ref: '#/definitions/dto.ErrorDto'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: 查询厂家信息列表
tags:
- 厂家信息Api
/api/v1/category/paging:
get:
consumes:
- application/json
description: 可以通过厂家名称过滤,分页查询厂家信息
parameters:
- in: query
name: name
type: string
- description: 页码
example: 1
in: query
name: current
required: true
type: integer
- description: 页面行数
example: 10
in: query
name: size
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/dto.PageDto'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/dto.ErrorDto'
"404":
description: Not Found
schema:
$ref: '#/definitions/dto.ErrorDto'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: 分页查询厂家信息
tags:
- 厂家信息Api
/api/v1/drafting:
post:
consumes:
- application/json
description: 创建草稿数据
parameters:
- in: query
name: category
type: integer
- in: query
name: id
type: integer
@ -332,6 +580,9 @@ paths:
name: id
required: true
type: integer
- in: query
name: category
type: integer
- in: query
name: id
type: integer
@ -377,6 +628,9 @@ paths:
name: id
required: true
type: integer
- in: query
name: category
type: integer
- in: query
name: id
type: integer
@ -456,6 +710,40 @@ paths:
summary: 分页查询草稿
tags:
- 草稿Api
/api/v1/generate/calculatelink:
post:
consumes:
- application/json
description: 根据地图数据新生成计算的link信息
parameters:
- collectionFormat: csv
in: query
items:
type: integer
name: proto
type: array
produces:
- application/json
responses:
"200":
description: OK
"401":
description: Unauthorized
schema:
$ref: '#/definitions/dto.ErrorDto'
"404":
description: Not Found
schema:
$ref: '#/definitions/dto.ErrorDto'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: 根据地图数据新生成计算的link信息
tags:
- GenerateApi
/api/v1/publishedGi/{id}:
delete:
consumes:
@ -618,6 +906,9 @@ paths:
in: query
name: name
type: string
- in: query
name: note
type: string
produces:
- application/json
responses:
@ -636,6 +927,46 @@ paths:
summary: 从草稿发布数据
tags:
- 发布的图形数据Api
/api/v1/publishedGi/saveAsDrafting/{id}:
post:
consumes:
- application/json
description: 从发布数据拉取信息到草稿
parameters:
- description: id
in: path
name: id
required: true
type: integer
- description: 草稿数据的id
in: query
name: draftingId
type: integer
- description: 发布后的名称
in: query
name: name
type: string
- in: query
name: note
type: string
produces:
- application/json
responses:
"200":
description: OK
"401":
description: Unauthorized
schema:
$ref: '#/definitions/dto.ErrorDto'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: 从发布数据拉取信息到草稿
tags:
- 发布的图形数据Api
/api/v1/simulation/check/data:
post:
consumes:
@ -673,7 +1004,7 @@ paths:
post:
consumes:
- application/json
description: 创建ATS测试仿真
description: 创建并进入仿真后获取仿真的设备信息
parameters:
- description: JWT Token
in: header
@ -699,7 +1030,39 @@ paths:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: 创建ATS测试仿真
summary: 创建并进入仿真后获取仿真的设备信息
tags:
- ATS测试仿真Api
/api/v1/simulation/destroy/{id}:
post:
consumes:
- application/json
description: ATS测试仿真-添加列车
parameters:
- description: JWT Token
in: header
name: Authorization
required: true
type: string
- description: 仿真id
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: ATS仿真销毁
tags:
- ATS测试仿真Api
/api/v1/simulation/list:
@ -797,38 +1160,6 @@ paths:
summary: ATS测试仿真-添加列车
tags:
- ATS测试仿真Api
/api/v1/simulation/train/destroy/{id}:
get:
consumes:
- application/json
description: ATS测试仿真-添加列车
parameters:
- description: JWT Token
in: header
name: Authorization
required: true
type: string
- description: 仿真id
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
type: string
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/dto.ErrorDto'
security:
- JwtAuth: []
summary: ATS仿真销毁
tags:
- ATS测试仿真Api
/api/v1/simulation/train/remove:
post:
consumes:

12
dto/category.go Normal file
View File

@ -0,0 +1,12 @@
package dto
type PageCategoryReqDto struct {
PageQueryDto
Name string `json:"name" form:"name"`
}
type CategoryDto struct {
Id int `json:"id" form:"id"`
Name string `json:"name" form:"name"`
Config string `json:"config" form:"config"`
}

View File

@ -6,7 +6,12 @@ type PageDraftingReqDto struct {
}
type DraftingDto struct {
Id int `json:"id" form:"id"`
Name string `json:"name" form:"name"`
Id int `json:"id" form:"id"`
Name string `json:"name" form:"name"`
Category int32 `json:"category" form:"category"`
Proto []byte `json:"proto" from:"proto"`
}
type DraftingMapDataDto struct {
Proto []byte `json:"proto" from:"proto"`
}

View File

@ -16,8 +16,8 @@ type PublishReqDto struct {
//发布后的名称
Name string `json:"name" form:"name"`
//草稿数据的id
DraftId int32 `json:"draftingId" form:"draftingId"`
DraftId int32 `json:"draftId" form:"draftId"`
Note string `json:"note" form:"note"`
//Time dto.JsonTime `json:"time" form:"time"`
////是否覆盖同名数据
//Overwrite bool `json:"overwrite" form:"overwrite"`
@ -28,6 +28,7 @@ type PublishedGiDto struct {
Name string `json:"name"`
Proto []byte `json:"proto"`
UserID int32 `json:"userID"`
Note string `json:"note"`
PublishAt dto.JsonTime `json:"publishAt" time_format:"2006-01-02 15:04:05"`
}
@ -36,6 +37,7 @@ func ConvertFrom(gi *model.PublishedGi) *PublishedGiDto {
ID: gi.ID,
Name: gi.Name,
Proto: gi.Proto,
Note: gi.Note,
UserID: gi.UserID,
PublishAt: dto.JsonTime(gi.PublishAt),
}

View File

@ -4,25 +4,14 @@ import (
"bytes"
"encoding/json"
"fmt"
"go.uber.org/zap"
"joylink.club/bj-rtsts-server/config"
"net/http"
)
func SendInitTrainReq(info *InitTrainInfo) (int, *[]byte, error) {
defer func() {
if r := recover(); r != nil {
zap.S().Error("发送列车初始化请求失败", r)
}
}()
ip := config.Config.Dynamics.Ip
var port string
if config.Config.Dynamics.HttpPort != 0 {
port = fmt.Sprintf(":%d", config.Config.Dynamics.HttpPort)
}
uri := "/api/aerodynamics/init/train"
url := "http://" + ip + port + uri
baseUrl := getUrlBase()
uri := "/api/aerodynamics/init/train/"
url := baseUrl + uri
data, _ := json.Marshal(info)
resp, err := http.Post(url, "application/json", bytes.NewBuffer(data))
if err != nil {
@ -37,3 +26,56 @@ func SendInitTrainReq(info *InitTrainInfo) (int, *[]byte, error) {
}
return resp.StatusCode, &buf, resp.Body.Close()
}
func SendSimulationStartReq(base *LineBaseInfo) (int, *[]byte, error) {
baseUrl := getUrlBase()
uri := "/api/start/"
url := baseUrl + uri
data, _ := json.Marshal(base)
resp, err := http.Post(url, "application/json", bytes.NewBuffer(data))
if err != nil {
s := err.Error()
println(s)
return 0, nil, err
}
var buf []byte
_, err = resp.Body.Read(buf)
if err != nil {
return resp.StatusCode, nil, err
}
return resp.StatusCode, &buf, resp.Body.Close()
}
func SendSimulationEndReq() (int, *[]byte, error) {
baseUrl := getUrlBase()
uri := "/api/end"
url := baseUrl + uri
resp, err := http.Post(url, "application/json", nil)
if err != nil {
s := err.Error()
println(s)
return 0, nil, err
}
var buf []byte
_, err = resp.Body.Read(buf)
if err != nil {
return resp.StatusCode, nil, err
}
return resp.StatusCode, &buf, resp.Body.Close()
}
var (
urlBase string
)
func getUrlBase() string {
if urlBase == "" {
ip := config.Config.Dynamics.Ip
var port string
if config.Config.Dynamics.HttpPort != 0 {
port = fmt.Sprintf(":%d", config.Config.Dynamics.HttpPort)
}
urlBase = "http://" + ip + port
}
return urlBase
}

View File

@ -8,3 +8,40 @@ type InitTrainInfo struct {
Speed uint16 `json:"speed"`
Up bool `json:"up"`
}
// LineBaseInfo 线路基础信息,提供给动力学作为计算依据
type LineBaseInfo struct {
LinkList []Link `json:"linkList"`
SlopeList []Slope `json:"slopeList"`
CurveList []Curve `json:"curveList"`
}
type Link struct {
ID int32 `json:"id"`
//长度 mm
Len int32 `json:"len"`
ARelTurnoutId int32 `json:"ARelTurnoutId"`
ARelTurnoutPoint string `json:"ARelTurnoutPoint"`
BRelTurnoutId int32 `json:"BRelTurnoutId"`
BRelTurnoutPoint string `json:"BRelTurnoutPoint"`
}
type Slope struct {
ID int32 `json:"id"`
StartLinkId int32 `json:"startLinkId"`
StartLinkOffset int32 `json:"startLinkOffset"`
EndLinkId int32 `json:"endLinkId"`
EndLinkOffset int32 `json:"endLinkOffset"`
//坡度的三角函数(猜是sin)值的*1000
DegreeTrig int32 `json:"degreeTrig"`
}
type Curve struct {
int
ID int32 `json:"id"`
StartLinkId int32 `json:"startLinkId"`
StartLinkOffset int32 `json:"startLinkOffset"`
EndLinkId int32 `json:"endLinkId"`
EndLinkOffset int32 `json:"endLinkOffset"`
Curvature int32 `json:"curvature"`
}

View File

@ -1,6 +1,7 @@
package dynamics
import (
"encoding/json"
"github.com/spf13/viper"
"joylink.club/bj-rtsts-server/config"
"testing"
@ -10,15 +11,91 @@ import (
func TestSendTrainInitReq(t *testing.T) {
viper.AddConfigPath("../")
config.LoadConfig()
for i := 1; i <= 5; i++ {
info := InitTrainInfo{
TrainIndex: uint16(i),
LinkIndex: 2,
LinkOffset: 3,
Speed: 4,
Up: true,
}
time.Sleep(time.Second)
SendInitTrainReq(&info)
info := InitTrainInfo{
TrainIndex: uint16(1),
LinkIndex: 2,
LinkOffset: 3,
Speed: 4,
Up: true,
}
time.Sleep(time.Second)
SendInitTrainReq(&info)
}
func TestSendSimulationStartReq(t *testing.T) {
viper.AddConfigPath("../")
config.LoadConfig()
SendSimulationStartReq(mockLineBaseInfo())
}
func TestSendSimulationEndReq(t *testing.T) {
viper.AddConfigPath("../")
config.LoadConfig()
SendSimulationEndReq()
}
func mockLineBaseInfo() *LineBaseInfo {
var links []Link
for i := 1; i <= 12; i++ {
var atid int32
var btid int32
if i <= 6 {
atid = int32(i - 1)
btid = int32(i)
} else {
atid = int32(i - 2)
btid = int32(i - 1)
}
if i == 1 || i == 7 {
atid = 0
} else if i == 6 || i == 12 {
btid = 0
}
links = append(links, Link{
ID: int32(i),
Len: int32(i * 100000),
ARelTurnoutId: atid,
ARelTurnoutPoint: "A",
BRelTurnoutId: btid,
BRelTurnoutPoint: "B",
})
}
for i := 13; i <= 17; i++ {
links = append(links, Link{
ID: int32(i),
Len: int32(i * 100000),
ARelTurnoutId: int32(i - 12),
ARelTurnoutPoint: "A",
BRelTurnoutId: int32(i - 12 + 5),
BRelTurnoutPoint: "B",
})
}
slopes := []Slope{{
ID: 1,
StartLinkId: 1,
StartLinkOffset: 1,
EndLinkId: 1,
EndLinkOffset: 1,
DegreeTrig: 1,
}}
curves := []Curve{{
ID: 1,
StartLinkId: 1,
StartLinkOffset: 1,
EndLinkId: 1,
EndLinkOffset: 1,
Curvature: 1,
}}
base := LineBaseInfo{
LinkList: links,
SlopeList: slopes,
CurveList: curves,
}
return &base
}
func TestCalculationBase(t *testing.T) {
base := mockLineBaseInfo()
marshal, _ := json.Marshal(base)
println(string(marshal))
}

View File

@ -7,6 +7,7 @@ import (
"github.com/panjf2000/gnet/v2"
"go.uber.org/zap"
"joylink.club/bj-rtsts-server/config"
"math"
"net"
"sync"
"time"
@ -40,11 +41,11 @@ func runSendTurnoutStateTask() {
}()
}
func AddTurnoutInfoFunc(simId string, tiFunc TurnoutInfoFunc) {
func AddTurnoutInfoSource(simId string, tiFunc TurnoutInfoFunc) {
m.Store(simId, tiFunc)
}
func RemoveTurnoutInfoFunc(simId string) {
func RemoveTurnoutInfoSource(simId string) {
m.Delete(simId)
}
@ -95,7 +96,7 @@ type udpServer struct {
func (server *udpServer) OnBoot(eng gnet.Engine) gnet.Action {
server.eng = eng
println("udp server with multi-core=%t is listening on %s\n", server.multicore, server.addr)
fmt.Printf("udp server with multi-core=%t is listening on %s\n", server.multicore, server.addr)
zap.S().Infof("udp server with multi-core=%t is listening on %s\n", server.multicore, server.addr)
return gnet.None
}
@ -114,21 +115,21 @@ func (server *udpServer) OnTraffic(c gnet.Conn) gnet.Action {
trainInfo.Len = binary.BigEndian.Uint16(buf[3:5])
trainInfo.Link = buf[5]
trainInfo.LinkOffset = binary.BigEndian.Uint32(buf[6:10])
trainInfo.Slope = buf[10]
b := buf[11]
trainInfo.Slope = binary.BigEndian.Uint16(buf[10:12])
b := buf[12]
trainInfo.UpSlope = (b & (1 << 7)) != 0
trainInfo.Up = (b & (1 << 6)) != 0
trainInfo.TotalResistance = float32(binary.BigEndian.Uint16(buf[13:15])) / 100
trainInfo.AirResistance = float32(binary.BigEndian.Uint16(buf[15:17])) / 100
trainInfo.SlopeResistance = float32(binary.BigEndian.Uint16(buf[17:19])) / 100
trainInfo.CurveResistance = float32(binary.BigEndian.Uint16(buf[19:21])) / 100
trainInfo.Speed = float32(binary.BigEndian.Uint16(buf[21:23])) / 10
trainInfo.HeadSpeed1 = float32(binary.BigEndian.Uint16(buf[23:25])) / 10
trainInfo.HeadSpeed2 = float32(binary.BigEndian.Uint16(buf[25:27])) / 10
trainInfo.TailSpeed1 = float32(binary.BigEndian.Uint16(buf[27:29])) / 10
trainInfo.TailSpeed2 = float32(binary.BigEndian.Uint16(buf[29:31])) / 10
trainInfo.HeadRadarSpeed = float32(binary.BigEndian.Uint16(buf[31:33])) / 10
trainInfo.TailRadarSpeed = float32(binary.BigEndian.Uint16(buf[33:35])) / 10
trainInfo.TotalResistance = binary.BigEndian.Uint32(buf[14:18])
trainInfo.AirResistance = binary.BigEndian.Uint32(buf[18:22])
trainInfo.SlopeResistance = binary.BigEndian.Uint32(buf[22:26])
trainInfo.CurveResistance = binary.BigEndian.Uint32(buf[26:30])
trainInfo.Speed = math.Float32frombits(binary.BigEndian.Uint32(buf[30:34]))
trainInfo.HeadSpeed1 = math.Float32frombits(binary.BigEndian.Uint32(buf[34:38]))
trainInfo.HeadSpeed2 = math.Float32frombits(binary.BigEndian.Uint32(buf[38:42]))
trainInfo.TailSpeed1 = math.Float32frombits(binary.BigEndian.Uint32(buf[42:46]))
trainInfo.TailSpeed2 = math.Float32frombits(binary.BigEndian.Uint32(buf[46:50]))
trainInfo.HeadRadarSpeed = math.Float32frombits(binary.BigEndian.Uint32(buf[50:54]))
trainInfo.TailRadarSpeed = math.Float32frombits(binary.BigEndian.Uint32(buf[54:58]))
for e := handlerList.Front(); e != nil; e = e.Next() {
handler := e.Value.(TrainInfoHandler)

View File

@ -11,38 +11,38 @@ type TrainInfo struct {
LifeSignal uint16
//列车号(车辆)
Number uint8
//列车长度
//列车长度 cm
Len uint16
//列车所在轨道link
Link uint8
//列车所在link偏移量cm
//列车所在link偏移量mm
LinkOffset uint32
//列车所在位置坡度值(‰)
Slope uint8
Slope uint16
//列车所在位置坡度走势(上/下坡)
UpSlope bool
//列车当前运行方向(上/下行)
Up bool
//实际运行阻力(总)(KN
TotalResistance float32
//阻力1空气阻力KN
AirResistance float32
//阻力2坡道阻力KN
SlopeResistance float32
//阻力3曲线阻力KN
CurveResistance float32
//列车运行速度(km/h
//实际运行阻力(总)(N
TotalResistance uint32
//阻力1空气阻力N
AirResistance uint32
//阻力2坡道阻力N
SlopeResistance uint32
//阻力3曲线阻力N
CurveResistance uint32
//列车运行速度(m/s
Speed float32
//头车速传1速度值km/h
//头车速传1速度值m/s
HeadSpeed1 float32
//头车速度2速度值
//头车速度2速度值m/s
HeadSpeed2 float32
//尾车速传1速度值
//尾车速传1速度值m/s
TailSpeed1 float32
//尾车速度2速度值
//尾车速度2速度值m/s
TailSpeed2 float32
//头车雷达速度值
//头车雷达速度值m/s
HeadRadarSpeed float32
//尾车雷达速度值
//尾车雷达速度值m/s
TailRadarSpeed float32
}

View File

@ -17,7 +17,7 @@ func (t *SimulationServer) getChannelName() string {
// 消息运行间隔
func (t *SimulationServer) getInterval() time.Duration {
return time.Second
return 200 * time.Millisecond
}
// 返回所有数据

View File

@ -2,6 +2,7 @@ package main
import (
"fmt"
swaggerFiles "github.com/swaggo/files" // swagger embed files
ginSwagger "github.com/swaggo/gin-swagger" // gin-swagger middleware
"joylink.club/bj-rtsts-server/api"
@ -31,7 +32,8 @@ func main() {
api.InitDraftingRouter(router, authMiddleware)
api.InitPublishedGiRouter(router, authMiddleware)
api.InitSimulationRouter(router, authMiddleware)
api.InitCategoryRouter(router, authMiddleware)
api.InitGenerateGiRouter(router, authMiddleware)
docs.SwaggerInfo.Title = "CBTC测试系统API"
engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

100
service/category.go Normal file
View File

@ -0,0 +1,100 @@
package service
import (
"fmt"
"time"
"joylink.club/bj-rtsts-server/db/dbquery"
"joylink.club/bj-rtsts-server/db/model"
"joylink.club/bj-rtsts-server/dto"
)
// 查询草稿列表
func PageCategoryQuery(query *dto.PageCategoryReqDto) (*dto.PageDto, error) {
d := dbquery.Category
dq := d.Where()
if query.Name != "" {
dq = dq.Where(d.Name.Like(fmt.Sprintf("%%%s%%", query.Name)))
}
records, total, err := dq.Debug().Select(d.ID, d.Name, d.UpdateAt, d.CreatedAt).FindByPage(query.Offset(), query.Size)
if err != nil {
panic(err)
}
return &dto.PageDto{Total: int(total), PageQueryDto: query.PageQueryDto, Records: records}, nil
}
// 查询草稿列表
func ListCategoryQuery(query *dto.PageCategoryReqDto) ([]*model.Category, error) {
d := dbquery.Category
dq := d.Where()
if query.Name != "" {
dq = dq.Where(d.Name.Like(fmt.Sprintf("%%%s%%", query.Name)))
}
records, err := dq.Debug().Select(d.ID, d.Name, d.UpdateAt, d.CreatedAt).Find()
if err != nil {
panic(err)
}
return records, nil
}
// 创建草稿
func CreateCategory(dto *dto.CategoryDto) (*model.Category, error) {
if err := checkCategoryInfo(dto.Name); err != nil {
panic(err)
}
d := model.Category{
Name: dto.Name,
Config: dto.Config,
CreatedAt: time.Now(),
UpdateAt: time.Now(),
}
err := dbquery.Category.Save(&d)
if err != nil {
panic(err)
}
return dbquery.Category.Where(dbquery.Category.Name.Eq(dto.Name)).Order(dbquery.Category.CreatedAt).Debug().First()
}
func QueryCategory(id int32) *model.Category {
data, err := dbquery.Category.Where(dbquery.Category.ID.Eq(id)).Debug().First()
if err != nil {
panic(err)
}
return data
}
func UpdateCategory(id int32, dto *dto.CategoryDto) bool {
findOldQuery := dbquery.Category
oldD, err := findOldQuery.Where(findOldQuery.ID.Eq(id)).Debug().First()
if oldD == nil || err != nil {
panic(err)
}
if dto.Config != "" {
oldD.Config = dto.Config
}
if len(dto.Name) > 0 {
oldD.Name = dto.Name
}
oldD.UpdateAt = time.Now()
_, error := dbquery.Category.Updates(oldD)
if error != nil {
panic(error)
}
return true
}
func DeleteCategoryById(id int) {
_, _ = dbquery.Category.Debug().Where(dbquery.Category.ID.Eq(int32(id))).Delete()
}
func checkCategoryInfo(name string) error {
findNameQuery := dbquery.Category
count, err := findNameQuery.Where(findNameQuery.Name.Eq(name)).Debug().Count()
if err != nil {
panic(err)
}
if count > 0 {
panic("名称已存在")
}
return err
}

View File

@ -16,7 +16,7 @@ func PageDraftingQuery(query *dto.PageDraftingReqDto) (*dto.PageDto, error) {
if query.Name != "" {
dq = dq.Where(d.Name.Like(fmt.Sprintf("%%%s%%", query.Name)))
}
records, total, err := dq.Debug().Select(d.ID, d.Name, d.UpdateAt, d.CreatedAt, d.CreatorID).FindByPage(query.Offset(), query.Size)
records, total, err := dq.Debug().Select(d.ID, d.Name, d.Category, d.UpdateAt, d.CreatedAt, d.CreatorID).FindByPage(query.Offset(), query.Size)
if err != nil {
panic(err)
}
@ -34,6 +34,7 @@ func CreateDrafting(createId int32, dto *dto.DraftingDto) (*model.Drafting, erro
CreatorID: createId,
CreatedAt: time.Now(),
UpdateAt: time.Now(),
Category: dto.Category,
}
err := dbquery.Drafting.Save(&d)
if err != nil {
@ -60,6 +61,7 @@ func SaveAsDrafting(createId int32, oldId int32, dto *dto.DraftingDto) (*model.D
CreatorID: createId,
CreatedAt: time.Now(),
UpdateAt: time.Now(),
Category: oldD.Category,
}
if err = dbquery.Drafting.Save(&newD); err != nil {
panic(err)

View File

@ -4,6 +4,8 @@ import (
"fmt"
"time"
"google.golang.org/protobuf/proto"
"joylink.club/bj-rtsts-server/ats/verify/protos/graphicData"
"joylink.club/bj-rtsts-server/ats/verify/simulation/wayside/memory"
"joylink.club/bj-rtsts-server/db/dbquery"
"joylink.club/bj-rtsts-server/db/model"
@ -12,9 +14,9 @@ import (
)
func PageQueryPublishedGi(req *publishedGi.PublishedGiReqDto) *dto.PageDto {
where := dbquery.PublishedGi.Where()
where := dbquery.PublishedGi.Where(dbquery.PublishedGi.Status.Eq(1))
if req.Name != "" {
where.Where(dbquery.PublishedGi.Name.Like(fmt.Sprintf("%%%s%%", req.Name)))
where = where.Where(dbquery.PublishedGi.Name.Like(fmt.Sprintf("%%%s%%", req.Name)))
}
result, count, err := where.Debug().FindByPage(req.Offset(), req.Size)
if err != nil {
@ -28,9 +30,9 @@ func PageQueryPublishedGi(req *publishedGi.PublishedGiReqDto) *dto.PageDto {
}
func ListQueryPublishedGi(req *publishedGi.PublishedGiReqDto) []*publishedGi.PublishedGiDto {
where := dbquery.PublishedGi.Where()
where := dbquery.PublishedGi.Where(dbquery.PublishedGi.Status.Eq(1))
if req.Name != "" {
where.Where(dbquery.PublishedGi.Name.Like(fmt.Sprintf("%%%s%%", req.Name)))
where = where.Where(dbquery.PublishedGi.Name.Like(fmt.Sprintf("%%%s%%", req.Name)))
}
find, err := where.Debug().Find()
if err != nil {
@ -40,7 +42,7 @@ func ListQueryPublishedGi(req *publishedGi.PublishedGiReqDto) []*publishedGi.Pub
}
func ListAllPublishedGi() ([]*model.PublishedGi, error) {
return dbquery.PublishedGi.Debug().Find()
return dbquery.PublishedGi.Debug().Where(dbquery.PublishedGi.Status.Eq(1)).Find()
}
func GetPublishedGiById(id int) (*model.PublishedGi, error) {
@ -52,26 +54,32 @@ func PublishFormDraft(req *publishedGi.PublishReqDto, user *model.User) {
if draft.Proto == nil || len(draft.Proto) == 0 {
panic(fmt.Sprintf("草稿[%v]绘图数据信息为空", req.DraftId))
}
entity := model.PublishedGi{
Name: req.Name,
Proto: draft.Proto,
UserID: user.ID,
PublishAt: time.Now(),
}
//删除同名数据
//需要删除的同名数据
oldData, _ := dbquery.PublishedGi.Debug().Where(dbquery.PublishedGi.Name.Eq(req.Name)).Find()
if oldData != nil && len(oldData) > 0 {
dbquery.PublishedGi.Debug().Where(dbquery.PublishedGi.Name.Eq(req.Name)).Delete()
// 逻辑删除
dbquery.PublishedGi.Debug().Where(dbquery.PublishedGi.Name.Eq(req.Name)).UpdateColumn(dbquery.PublishedGi.Status, 0)
for _, v := range oldData {
memory.DeleteMapVerifyStructure(v.ID) // 移除内存中的发布信息
}
}
entity := model.PublishedGi{
Name: req.Name,
Proto: handlerPublishedGiLinkData(draft.Proto, false),
UserID: user.ID,
PublishAt: time.Now(),
Category: draft.Category,
Note: req.Note,
Status: 1,
}
//插入新数据
err := dbquery.PublishedGi.Debug().Create(&entity)
if err != nil {
panic(dto.ErrorDto{Code: dto.DataOperationError, Message: fmt.Sprintf("数据创建失败:\n%s", err.Error())})
}
newData, _ := dbquery.PublishedGi.Where(dbquery.PublishedGi.Name.Eq(req.Name)).First()
newData, _ := dbquery.PublishedGi.
Where(dbquery.PublishedGi.Name.Eq(req.Name), dbquery.PublishedGi.Status.Eq(1)).
Order(dbquery.PublishedGi.PublishAt.Desc()).First()
// 地图信息更新到缓存
if newData != nil {
memory.PublishMapVerifyStructure(newData)
@ -79,6 +87,46 @@ func PublishFormDraft(req *publishedGi.PublishReqDto, user *model.User) {
}
func DeletePublishedGiById(id int) {
_, _ = dbquery.PublishedGi.Debug().Where(dbquery.PublishedGi.ID.Eq(int32(id))).Delete()
dbquery.PublishedGi.Debug().Where(dbquery.PublishedGi.ID.Eq(int32(id))).UpdateColumn(dbquery.PublishedGi.Status, 0)
memory.DeleteMapVerifyStructure(int32(id)) // 移除内存中的发布信息
}
func SaveAsDraftingFromPublish(id int32, user *model.User, name string) {
num, _ := dbquery.Drafting.Where(dbquery.Drafting.Name.Eq(name)).Count()
if num > 0 { // 处理重名情况
panic(dto.ErrorDto{Code: dto.DataOperationError, Message: fmt.Sprintf("草稿【%s】已存在", name)})
}
publishedGi, err := dbquery.PublishedGi.Where(dbquery.PublishedGi.ID.Eq(id)).Debug().First()
if err != nil {
panic(dto.ErrorDto{Code: dto.DataOperationError, Message: err.Error()})
}
drafting := &model.Drafting{
Name: name,
Category: publishedGi.Category,
Proto: handlerPublishedGiLinkData(publishedGi.Proto, true),
CreatorID: user.ID,
CreatedAt: time.Now(),
UpdateAt: time.Now(),
}
err1 := dbquery.Drafting.Save(drafting)
if err1 != nil {
panic(dto.ErrorDto{Code: dto.DataOperationError, Message: err1.Error()})
}
}
// 操作地图数据中的link数据
// del 代表是否删除地图中的link数据
func handlerPublishedGiLinkData(data []byte, del bool) []byte {
gd := &graphicData.RtssGraphicStorage{}
proto.Unmarshal(data, gd)
if del {
gd.CalculateLink = []*graphicData.CalculateLink{}
} else {
gd.CalculateLink = memory.BuildCalculateLinkData(gd)
}
rd, err := proto.Marshal(gd)
if err != nil {
panic(dto.ErrorDto{Code: dto.DataOperationError, Message: err.Error()})
}
return rd
}