This commit is contained in:
windyboy
2024-07-19 20:02:18 +08:00
parent d1d427057e
commit dbbf6133be
26 changed files with 2171 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
package domain
import (
"caatsm/pkg/utils"
"fmt"
"time"
)
// AFTN 定义AFTN报文的结构
type AFTN struct {
Header Header `json:"header"` // 报文头部信息
PriorityAndSender PriorityAndSender `json:"priority_and_sender"` // 优先级和发送地址信息
TimeAndReceiver TimeAndReceiver `json:"time_and_receiver"` // 时间和接收地址信息
Text string `json:"text"` // 报文内容
ReceivedTime time.Time `json:"received_time"` // 收报时间,表示电报接收到的时间
Category string `json:"category"`
BodyData interface{} `json:"body_data"`
}
// Header 定义AFTN报文的报头
type Header struct {
StartSignal string `json:"start_signal"` // 启动信号,表示报文的开始,通常为固定值
SendID string `json:"send_id"` // 发送编号,用于唯一标识报文
SendTime string `json:"send_time"` // 发送时间,格式为DDHHMM
}
// 示例:
// Header{
// StartSignal: "ZCZC",
// SendID: "TMQ2611",
// SendTime: "151524",
// }
// PriorityAndSender 定义优先级和发送地址
type PriorityAndSender struct {
Priority string `json:"priority"` // 优先级
Sender string `json:"sender"` // 发报地址
}
// 示例:
// PriorityAndSender{
// Priority: "FF",
// Sender: "ZBTJZPZX",
// }
// TimeAndReceiver 定义时间和接收地址
type TimeAndReceiver struct {
Time string `json:"time"` // 时间
Receiver string `json:"receiver"` // 收报地址
}
// 示例:
// TimeAndReceiver{
// Time: "151524",
// Receiver: "ZGGGZPZX",
// }
// Origin 定义AFTN报文的来源
type Origin struct {
OriginCode string `json:"origin_code"` // 发报地址代码
FiledTime time.Time `json:"filed_time"` // 签发时间,表示电报生成的时间
}
func (h *Header) Validate() error {
// Validate SendTime format (e.g., DDHHMM)
if len(h.SendTime) != 6 {
err := "invalid send_time format"
utils.Logger.Error(err)
return fmt.Errorf(err)
}
return nil
}
func (a *AFTN) Validate() error {
if err := a.Header.Validate(); err != nil {
return err
}
// Add more validation as needed
return nil
}
+52
View File
@@ -0,0 +1,52 @@
package domain
import (
"encoding/json"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("AFTN", func() {
var original AFTN
BeforeEach(func() {
original = AFTN{
Header: Header{
StartSignal: "ZCZC",
SendID: "TMQ2611",
SendTime: "151524",
},
PriorityAndSender: PriorityAndSender{
Priority: "FF",
Sender: "ZBTJZPZX",
},
TimeAndReceiver: TimeAndReceiver{
Time: "151524",
Receiver: "ZGGGZPZX",
},
Text: "Test message",
ReceivedTime: time.Now(),
Category: "Test",
BodyData: nil,
}
})
Describe("Marshalling and Unmarshalling", func() {
It("should marshal and unmarshal correctly", func() {
data, err := json.Marshal(original)
Expect(err).NotTo(HaveOccurred())
var unmarshalled AFTN
err = json.Unmarshal(data, &unmarshalled)
Expect(err).NotTo(HaveOccurred())
Expect(unmarshalled.Header).To(Equal(original.Header))
Expect(unmarshalled.PriorityAndSender).To(Equal(original.PriorityAndSender))
Expect(unmarshalled.TimeAndReceiver).To(Equal(original.TimeAndReceiver))
Expect(unmarshalled.Text).To(Equal(original.Text))
Expect(unmarshalled.Category).To(Equal(original.Category))
})
})
})
+80
View File
@@ -0,0 +1,80 @@
package domain
import "fmt"
/*
预警报文(ALN)通常包括以下内容:
编组 3:电报类别、编号和参考数据
编组 7:航空器识别标志和 SSR 模式及编码
编组 8:飞行规则和类型
编组 13:起飞机场和时间
编组 16:目的地机场和估计总耗时,目的地备降机场
编组 18:其他信息(如需要)
*/
/*
MessageType (电报类别): Indicates the type of telegram (e.g., "ALN").
AircraftID (航空器识别标志): Unique identifier of the aircraft.
SSRModeAndCode (SSR 模式及编码): SSR (Secondary Surveillance Radar) mode and code.
FlightRulesAndType (飞行规则和类型): Flight rules and type (e.g., IFR).
DepartureAirport (起飞机场): ICAO code of the departure airport.
DepartureTime (起飞时间): Departure time in UTC.
ArrivalAirport (到达机场): ICAO code of the arrival airport.
ArrivalTime (到达时间): Estimated arrival time in UTC.
OtherInfo (其他信息): Optional field for any additional relevant information.
*/
/*
(ALN-CCA1234-IS
-B6513
-A1234
-IFR
-ZBTJ1200
-ZGGG1335
-ESTIMATED TIME EN ROUTE 01:35
-Additional information)
*/
// ALN 电报体中的预警报文结构
type ALN struct {
Category string `json:"category"` // 电报类别
AircraftID string `json:"aircraft_id"` // 航空器识别标志
SSRModeAndCode string `json:"ssr_mode_and_code"` // SSR 模式及编码
FlightRulesAndType string `json:"flight_rules_and_type"` // 飞行规则和类型
DepartureAirport string `json:"departure_airport"` // 起飞机场
DepartureTime string `json:"departure_time"` // 起飞时间
ArrivalAirport string `json:"arrival_airport"` // 到达机场
ArrivalTime string `json:"arrival_time"` // 到达时间
OtherInfo string `json:"other_info,omitempty"` // 其他信息 (optional)
}
// Validate validates the ALN struct fields
func (a *ALN) Validate() error {
if a.Category == "" {
return fmt.Errorf("telegram category is required")
}
if a.AircraftID == "" {
return fmt.Errorf("aircraft id is required")
}
if a.SSRModeAndCode == "" {
return fmt.Errorf("ssr mode and code is required")
}
if a.FlightRulesAndType == "" {
return fmt.Errorf("flight rules and type is required")
}
if a.DepartureAirport == "" {
return fmt.Errorf("departure airport is required")
}
if a.DepartureTime == "" {
return fmt.Errorf("departure time is required")
}
if a.ArrivalAirport == "" {
return fmt.Errorf("arrival airport is required")
}
if a.ArrivalTime == "" {
return fmt.Errorf("arrival time is required")
}
return nil
}
+64
View File
@@ -0,0 +1,64 @@
package domain
import (
"encoding/json"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("ALN", func() {
var original ALN
BeforeEach(func() {
original = ALN{
Category: "AFTN",
AircraftID: "ABCD1234",
SSRModeAndCode: "A1234",
FlightRulesAndType: "IFR",
DepartureAirport: "JFK",
DepartureTime: time.Now().Format("150405"), // HHMMSS format
ArrivalAirport: "LAX",
ArrivalTime: time.Now().Add(5 * time.Hour).Format("150405"), // HHMMSS format
OtherInfo: "Test flight",
}
})
Describe("Marshalling and Unmarshalling", func() {
It("should marshal and unmarshal correctly", func() {
data, err := json.Marshal(original)
Expect(err).NotTo(HaveOccurred())
var unmarshalled ALN
err = json.Unmarshal(data, &unmarshalled)
Expect(err).NotTo(HaveOccurred())
Expect(unmarshalled).To(Equal(original))
})
})
Describe("Validation", func() {
It("should validate successfully for a valid ALN", func() {
err := original.Validate()
Expect(err).NotTo(HaveOccurred())
})
It("should fail validation for missing required fields", func() {
invalidALN := ALN{
Category: "AFTN",
// AircraftID is missing
SSRModeAndCode: "A1234",
FlightRulesAndType: "IFR",
DepartureAirport: "JFK",
DepartureTime: "150405",
ArrivalAirport: "LAX",
ArrivalTime: "180405",
}
err := invalidALN.Validate()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("aircraft id is required"))
})
})
})
+64
View File
@@ -0,0 +1,64 @@
package domain
import "fmt"
/*
ARR 报文的规范和组成如下:
编组 3:电报类别、编号和参考数据
编组 7:航空器识别标志和 SSR 模式及编码
编组 13:起飞机场和时间
编组 16:目的地机场和估计总耗时,目的地备降机场
编组 18:其他信息(如需要)
*/
/*
TelegramCategory: Added for the telegram category (from Group 3).
FlightNumber: Added for the flight number (from Group 3).
ReferenceData: Added for the reference data (from Group 3).
AircraftID: Kept as it was for the aircraft identification (from Group 7).
SSRModeAndCode: Kept as it was for the SSR mode and code (from Group 7).
DepartureAirport: Kept as it was for the departure airport (from Group 13).
DepartureTime: Added for the departure time (from Group 13).
ArrivalAirport: Kept as it was for the arrival airport (from Group 16).
EstimatedElapsedTime: Added for the estimated total elapsed time (from Group 16).
AlternateAirport: Added for the alternate destination airport (from Group 16).
OtherInfo: Kept as it was for any other information (from Group 18).
*/
// ARR 电报体中的到达报文结构
type ARR struct {
Category string `json:"category"` // 电报类别
AircraftID string `json:"aircraft_id"` // 航空器识别标志
SSRModeAndCode string `json:"ssr_mode_and_code"` // SSR 模式及编码(可选)
DepartureAirport string `json:"departure_airport"` // 起飞机场
DepartureTime string `json:"departure_time"` // 起飞时间
ArrivalAirport string `json:"arrival_airport"` // 到达机场
ArrivalTime string `json:"arrival_time"` // 到达时间
EstimatedElapsedTime string `json:"estimated_elapsed_time"` // 估计总耗时(可选)
AlternateAirport string `json:"alternate_airport"` // 目的地备降机场(可选)
OtherInfo string `json:"other_info"` // 其他信息(可选)
}
// Validate validates the ARR struct fields
func (a *ARR) Validate() error {
if a.Category == "" {
return fmt.Errorf("category is required")
}
if a.AircraftID == "" {
return fmt.Errorf("aircraft id is required")
}
if a.DepartureAirport == "" {
return fmt.Errorf("departure airport is required")
}
if a.DepartureTime == "" {
return fmt.Errorf("departure time is required")
}
if a.ArrivalAirport == "" {
return fmt.Errorf("arrival airport is required")
}
if a.ArrivalTime == "" {
return fmt.Errorf("arrival time is required")
}
return nil
}
+61
View File
@@ -0,0 +1,61 @@
package domain
import (
"encoding/json"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("ARR", func() {
var original ARR
BeforeEach(func() {
original = ARR{
Category: "ARR",
AircraftID: "ABCD1234",
SSRModeAndCode: "A1234",
DepartureAirport: "JFK",
DepartureTime: time.Now().Format("150405"), // HHMMSS format
ArrivalAirport: "LAX",
ArrivalTime: time.Now().Add(5 * time.Hour).Format("150405"), // HHMMSS format
OtherInfo: "Test flight",
}
})
Describe("Marshalling and Unmarshalling", func() {
It("should marshal and unmarshal correctly", func() {
data, err := json.Marshal(original)
Expect(err).NotTo(HaveOccurred())
var unmarshalled ARR
err = json.Unmarshal(data, &unmarshalled)
Expect(err).NotTo(HaveOccurred())
Expect(unmarshalled).To(Equal(original))
})
})
Describe("Validation", func() {
It("should validate successfully for a valid ARR", func() {
err := original.Validate()
Expect(err).NotTo(HaveOccurred())
})
It("should fail validation for missing required fields", func() {
invalidARR := ARR{
Category: "ARR",
// AircraftID is missing
DepartureAirport: "JFK",
DepartureTime: "150405",
ArrivalAirport: "LAX",
ArrivalTime: "180405",
}
err := invalidARR.Validate()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("aircraft id is required"))
})
})
})
+112
View File
@@ -0,0 +1,112 @@
package domain
import "fmt"
/*
航班计划修改报文(CHG)一般包括以下内容:
编组 3:电报类别、编号和参考数据
编组 7:航空器识别标志和 SSR 模式及编码
编组 13:起飞机场和时间
编组 16:目的地机场和估计总耗时,目的地备降机场
编组 18:其他信息(如需要)
编组 22:修改部分
*/
/*
Explanation of Each Field
MessageType (电报类别):
Field: MessageType
Description: Indicates the type of telegram (e.g., "CHG").
AircraftID (航空器识别标志):
Field: AircraftID
Description: Unique identifier of the aircraft.
SSRModeAndCode (SSR 模式及编码):
Field: SSRModeAndCode
Description: SSR (Secondary Surveillance Radar) mode and code.
DepartureAirport (起飞机场):
Field: DepartureAirport
Description: ICAO code of the departure airport.
DepartureTime (起飞时间):
Field: DepartureTime
Description: Departure time in UTC.
ArrivalAirport (到达机场):
Field: ArrivalAirport
Description: ICAO code of the arrival airport.
ArrivalTime (到达时间):
Field: ArrivalTime
Description: Estimated arrival time in UTC.
OtherInfo (其他信息):
Field: OtherInfo
Description: Optional field for any additional relevant information.
ChangePart (修改部分):
Field: ChangePart
Description: Indicates the part of the flight plan that is being changed.
*/
/*
(CHG-CCA5678-IS
-B6513
-A1234
-ZBTJ1200
-ZGGG1335
-NEW ROUTE VIA PIAKS G330 PIMOL
-Change reason or additional information)
*/
// CHG 电报体中的航班计划修改报文结构
type CHG struct {
Category string `json:"category"` // 电报类别
AircraftID string `json:"aircraft_id"` // 航空器识别标志
SSRModeAndCode string `json:"ssr_mode_and_code"` // SSR 模式及编码
DepartureAirport string `json:"departure_airport"` // 起飞机场
DepartureTime string `json:"departure_time"` // 起飞时间
ArrivalAirport string `json:"arrival_airport"` // 到达机场
ArrivalTime string `json:"arrival_time"` // 到达时间
EstimatedElapsedTime string `json:"estimated_elapsed_time"` // 估计总耗时
AlternateAirport string `json:"alternate_airport"` // 目的地备降机场 (optional)
OtherInfo string `json:"other_info"` // 其他信息 (optional)
ChangePart string `json:"change_part"` // 修改部分
}
// Validate validates the CHG struct fields
func (c *CHG) Validate() error {
if c.Category == "" {
return fmt.Errorf("category is required")
}
if c.AircraftID == "" {
return fmt.Errorf("aircraft id is required")
}
if c.SSRModeAndCode == "" {
return fmt.Errorf("ssr mode and code is required")
}
if c.DepartureAirport == "" {
return fmt.Errorf("departure airport is required")
}
if c.DepartureTime == "" {
return fmt.Errorf("departure time is required")
}
if c.ArrivalAirport == "" {
return fmt.Errorf("arrival airport is required")
}
if c.ArrivalTime == "" {
return fmt.Errorf("arrival time is required")
}
if c.EstimatedElapsedTime == "" {
return fmt.Errorf("estimated elapsed time is required")
}
if c.ChangePart == "" {
return fmt.Errorf("change part is required")
}
return nil
}
+66
View File
@@ -0,0 +1,66 @@
package domain
import (
"encoding/json"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("CHG", func() {
var original CHG
BeforeEach(func() {
original = CHG{
Category: "CHG",
AircraftID: "ABCD1234",
SSRModeAndCode: "A1234",
DepartureAirport: "JFK",
DepartureTime: time.Now().Format("150405"), // HHMMSS format
ArrivalAirport: "LAX",
ArrivalTime: time.Now().Add(5 * time.Hour).Format("150405"), // HHMMSS format
EstimatedElapsedTime: "0500", // Example time format
ChangePart: "Flight plan",
OtherInfo: "Test flight",
}
})
Describe("Marshalling and Unmarshalling", func() {
It("should marshal and unmarshal correctly", func() {
data, err := json.Marshal(original)
Expect(err).NotTo(HaveOccurred())
var unmarshalled CHG
err = json.Unmarshal(data, &unmarshalled)
Expect(err).NotTo(HaveOccurred())
Expect(unmarshalled).To(Equal(original))
})
})
Describe("Validation", func() {
It("should validate successfully for a valid CHG", func() {
err := original.Validate()
Expect(err).NotTo(HaveOccurred())
})
It("should fail validation for missing required fields", func() {
invalidCHG := CHG{
Category: "CHG",
// AircraftID is missing
SSRModeAndCode: "A1234",
DepartureAirport: "JFK",
DepartureTime: "150405",
ArrivalAirport: "LAX",
ArrivalTime: "180405",
EstimatedElapsedTime: "0500",
ChangePart: "Flight plan",
}
err := invalidCHG.Validate()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("aircraft id is required"))
})
})
})
+129
View File
@@ -0,0 +1,129 @@
package domain
import "fmt"
/*
航班计划变更报文(CPL)通常包括以下内容:
编组 3:电报类别、编号和参考数据
编组 7:航空器识别标志和 SSR 模式及编码
编组 8:飞行规则和类型
编组 9:航机和设备
编组 10:巡航速度和飞行高度
编组 13:起飞机场和时间
编组 15:航路
编组 16:目的地机场和总时间,目的地备降机场
编组 18:其他信息(如需要)
*/
/*
MessageType (电报类别):
Field: MessageType
Description: Indicates the type of telegram (e.g., "CPL").
AircraftID (航空器识别标志):
Field: AircraftID
Description: Unique identifier of the aircraft.
SSRModeAndCode (SSR 模式及编码):
Field: SSRModeAndCode
Description: SSR (Secondary Surveillance Radar) mode and code.
FlightRulesAndType (飞行规则和类型):
Field: FlightRulesAndType
Description: Flight rules and type (e.g., IFR).
AircraftAndEquipment (航机和设备):
Field: AircraftAndEquipment
Description: Aircraft type and equipment.
CruisingSpeedAndLevel (巡航速度和飞行高度):
Field: CruisingSpeedAndLevel
Description: Cruising speed and flight level.
DepartureAirport (起飞机场):
Field: DepartureAirport
Description: ICAO code of the departure airport.
DepartureTime (起飞时间):
Field: DepartureTime
Description: Departure time in UTC.
Route (航路):
Field: Route
Description: Planned route.
DestinationAndTotalTime (目的地机场和总时间):
Field: DestinationAndTotalTime
Description: ICAO code of the destination airport and total elapsed time.
OtherInfo (其他信息):
Field: OtherInfo
Description: Optional field for any additional relevant information.
*/
/*
(CPL-CCA7890-IS
-B6513
-A1234
-IFR
-A332/H
-K0859S1040
-ZBTJ1200
-PIAKS G330 PIMOL A539 BTO W82 DOGAR
-ZGGG0135
-ZBAA
-Additional information)
*/
// CPL 电报体中的航班计划变更报文结构
type CPL struct {
Category string `json:"category"` // 电报类别
AircraftID string `json:"aircraft_id"` // 航空器识别标志
SSRModeAndCode string `json:"ssr_mode_and_code"` // SSR 模式及编码
FlightRulesAndType string `json:"flight_rules_and_type"` // 飞行规则和类型
AircraftAndEquipment string `json:"aircraft_and_equipment"` // 航机和设备
CruisingSpeedAndLevel string `json:"cruising_speed_and_level"` // 巡航速度和飞行高度
DepartureAirport string `json:"departure_airport"` // 起飞机场
DepartureTime string `json:"departure_time"` // 起飞时间
Route string `json:"route"` // 航路
DestinationAndTotalTime string `json:"destination_and_total_time"` // 目的地机场和总时间
AlternateAirport string `json:"alternate_airport,omitempty"` // 目的地备降机场 (optional)
OtherInfo string `json:"other_info,omitempty"` // 其他信息 (optional)
}
// Validate validates the CPL struct fields
func (c *CPL) Validate() error {
if c.Category == "" {
return fmt.Errorf("category is required")
}
if c.AircraftID == "" {
return fmt.Errorf("aircraft id is required")
}
if c.SSRModeAndCode == "" {
return fmt.Errorf("ssr mode and code is required")
}
if c.FlightRulesAndType == "" {
return fmt.Errorf("flight rules and type is required")
}
if c.AircraftAndEquipment == "" {
return fmt.Errorf("aircraft and equipment is required")
}
if c.CruisingSpeedAndLevel == "" {
return fmt.Errorf("cruising speed and level is required")
}
if c.DepartureAirport == "" {
return fmt.Errorf("departure airport is required")
}
if c.DepartureTime == "" {
return fmt.Errorf("departure time is required")
}
if c.Route == "" {
return fmt.Errorf("route is required")
}
if c.DestinationAndTotalTime == "" {
return fmt.Errorf("destination and total time is required")
}
return nil
}
+68
View File
@@ -0,0 +1,68 @@
package domain
import (
"encoding/json"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("CPL", func() {
var original CPL
BeforeEach(func() {
original = CPL{
Category: "CPL",
AircraftID: "ABCD1234",
SSRModeAndCode: "A1234",
FlightRulesAndType: "IFR",
AircraftAndEquipment: "B738",
CruisingSpeedAndLevel: "N0450F350",
DepartureAirport: "JFK",
DepartureTime: time.Now().Format("150405"), // HHMMSS format
Route: "DCT GAYEL J95 BUF DCT",
DestinationAndTotalTime: "LAX0500", // Example format
OtherInfo: "Test flight",
}
})
Describe("Marshalling and Unmarshalling", func() {
It("should marshal and unmarshal correctly", func() {
data, err := json.Marshal(original)
Expect(err).NotTo(HaveOccurred())
var unmarshalled CPL
err = json.Unmarshal(data, &unmarshalled)
Expect(err).NotTo(HaveOccurred())
Expect(unmarshalled).To(Equal(original))
})
})
Describe("Validation", func() {
It("should validate successfully for a valid CPL", func() {
err := original.Validate()
Expect(err).NotTo(HaveOccurred())
})
It("should fail validation for missing required fields", func() {
invalidCPL := CPL{
Category: "CPL",
// AircraftID is missing
SSRModeAndCode: "A1234",
FlightRulesAndType: "IFR",
AircraftAndEquipment: "B738",
CruisingSpeedAndLevel: "N0450F350",
DepartureAirport: "JFK",
DepartureTime: "150405",
Route: "DCT GAYEL J95 BUF DCT",
DestinationAndTotalTime: "LAX0500",
}
err := invalidCPL.Validate()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("aircraft id is required"))
})
})
})
+87
View File
@@ -0,0 +1,87 @@
package domain
import "fmt"
/*
起飞报(DEP)报文的规范和组成如下:
编组 3:电报类别、编号和参考数据
编组 7:航空器识别标志和 SSR 模式及编码
编组 13:起飞机场和时间
编组 16:目的地机场和估计总耗时,目的地备降机场
编组 18:其他信息(如需要)
*/
/*
TelegramCategory (电报类别):
Field: TelegramCategory
Description: This field indicates the type of telegram, which in this case would be "DEP" for departure.
AircraftID (航空器识别标志):
Field: AircraftID
Description: This field contains the unique identifier of the aircraft.
SSRModeAndCode (SSR 模式及编码, optional):
Field: SSRModeAndCode
Description: This field contains the SSR (Secondary Surveillance Radar) mode and code. It is optional and indicated as a pointer.
DepartureAirport (起飞机场):
Field: DepartureAirport
Description: This field contains the ICAO code of the airport from which the aircraft is departing.
DepartureTime (起飞时间):
Field: DepartureTime
Description: This field contains the departure time in UTC.
Destination (目的地机场):
Field: Destination
Description: This field contains the ICAO code of the destination airport.
EstimatedElapsedTime (估计总耗时):
Field: EstimatedElapsedTime
Description: This field contains the estimated total elapsed time of the flight.
AlternateAirport (目的地备降机场, optional):
Field: AlternateAirport
Description: This field contains the ICAO code of the alternate destination airport. It is optional and indicated as a pointer.
OtherInfo (其他信息, optional):
Field: OtherInfo
Description: This field contains any additional relevant information. It is optional and indicated as a pointer.
*/
// DEP 电报体中的起飞报文结构
type DEP struct {
TelegramCategory string `json:"telegram_category"` // 电报类别
AircraftID string `json:"aircraft_id"` // 航空器识别标志
SSRModeAndCode string `json:"ssr_mode_and_code,omitempty"` // SSR 模式及编码(可选)
DepartureAirport string `json:"departure_airport"` // 起飞机场
DepartureTime string `json:"departure_time"` // 起飞时间
Destination string `json:"destination"` // 目的地机场
EstimatedElapsedTime string `json:"estimated_elapsed_time"` // 估计总耗时
AlternateAirport string `json:"alternate_airport,omitempty"` // 目的地备降机场(可选)
OtherInfo string `json:"other_info,omitempty"` // 其他信息(可选)
}
// Validate validates the DEP struct fields
func (d *DEP) Validate() error {
if d.TelegramCategory == "" {
return fmt.Errorf("telegram category is required")
}
if d.AircraftID == "" {
return fmt.Errorf("aircraft id is required")
}
if d.DepartureAirport == "" {
return fmt.Errorf("departure airport is required")
}
if d.DepartureTime == "" {
return fmt.Errorf("departure time is required")
}
if d.Destination == "" {
return fmt.Errorf("destination is required")
}
if d.EstimatedElapsedTime == "" {
return fmt.Errorf("estimated elapsed time is required")
}
return nil
}
+61
View File
@@ -0,0 +1,61 @@
package domain
import (
"encoding/json"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("DEP", func() {
var original DEP
BeforeEach(func() {
original = DEP{
TelegramCategory: "DEP",
AircraftID: "ABCD1234",
SSRModeAndCode: "A1234",
DepartureAirport: "JFK",
DepartureTime: time.Now().Format("150405"), // HHMMSS format
Destination: "LAX",
EstimatedElapsedTime: "0500", // Example format
OtherInfo: "Test flight",
}
})
Describe("Marshalling and Unmarshalling", func() {
It("should marshal and unmarshal correctly", func() {
data, err := json.Marshal(original)
Expect(err).NotTo(HaveOccurred())
var unmarshalled DEP
err = json.Unmarshal(data, &unmarshalled)
Expect(err).NotTo(HaveOccurred())
Expect(unmarshalled).To(Equal(original))
})
})
Describe("Validation", func() {
It("should validate successfully for a valid DEP", func() {
err := original.Validate()
Expect(err).NotTo(HaveOccurred())
})
It("should fail validation for missing required fields", func() {
invalidDEP := DEP{
TelegramCategory: "DEP",
// AircraftID is missing
DepartureAirport: "JFK",
DepartureTime: "150405",
Destination: "LAX",
EstimatedElapsedTime: "0500",
}
err := invalidDEP.Validate()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("aircraft id is required"))
})
})
})
+93
View File
@@ -0,0 +1,93 @@
package domain
import "fmt"
/*
延误报文(DLA)通常包括以下内容:
编组 3:电报类别、编号和参考数据
编组 7:航空器识别标志和 SSR 模式及编码
编组 13:起飞机场和新的起飞时间
编组 16:目的地机场和估计总耗时
编组 18:其他信息(如需要)
*/
/*
MessageType (电报类别):
Field: MessageType
Description: Indicates the type of telegram (e.g., "DLA").
AircraftID (航空器识别标志):
Field: AircraftID
Description: Unique identifier of the aircraft.
SSRModeAndCode (SSR 模式及编码):
Field: SSRModeAndCode
Description: SSR (Secondary Surveillance Radar) mode and code.
DepartureAirport (起飞机场):
Field: DepartureAirport
Description: ICAO code of the departure airport.
NewDepartureTime (新的起飞时间):
Field: NewDepartureTime
Description: New departure time in UTC.
ArrivalAirport (到达机场):
Field: ArrivalAirport
Description: ICAO code of the arrival airport.
EstimatedElapsedTime (估计总耗时):
Field: EstimatedElapsedTime
Description: Estimated total elapsed time.
OtherInfo (其他信息):
Field: OtherInfo
Description: Optional field for any additional relevant information.
*/
/*
(DLA-CCA7890-IS
-B6513
-A1234
-ZBTJ1500
-ZGGG0135
-Weather delay)
*/
// DLA 电报体中的延误报文结构
type DLA struct {
Category string `json:"category"` // 电报类别
AircraftID string `json:"aircraft_id"` // 航空器识别标志
SSRModeAndCode string `json:"ssr_mode_and_code"` // SSR 模式及编码
DepartureAirport string `json:"departure_airport"` // 起飞机场
NewDepartureTime string `json:"new_departure_time"` // 新的起飞时间
ArrivalAirport string `json:"arrival_airport"` // 到达机场
EstimatedElapsedTime string `json:"estimated_elapsed_time"` // 估计总耗时
OtherInfo string `json:"other_info,omitempty"` // 其他信息 (optional)
}
// Validate validates the DLA struct fields
func (d *DLA) Validate() error {
if d.Category == "" {
return fmt.Errorf("telegram category is required")
}
if d.AircraftID == "" {
return fmt.Errorf("aircraft id is required")
}
if d.SSRModeAndCode == "" {
return fmt.Errorf("ssr mode and code is required")
}
if d.DepartureAirport == "" {
return fmt.Errorf("departure airport is required")
}
if d.NewDepartureTime == "" {
return fmt.Errorf("new departure time is required")
}
if d.ArrivalAirport == "" {
return fmt.Errorf("arrival airport is required")
}
if d.EstimatedElapsedTime == "" {
return fmt.Errorf("estimated elapsed time is required")
}
return nil
}
+62
View File
@@ -0,0 +1,62 @@
package domain
import (
"encoding/json"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("DLA", func() {
var original DLA
BeforeEach(func() {
original = DLA{
Category: "DLA",
AircraftID: "ABCD1234",
SSRModeAndCode: "A1234",
DepartureAirport: "JFK",
NewDepartureTime: time.Now().Add(1 * time.Hour).Format("150405"), // HHMMSS format
ArrivalAirport: "LAX",
EstimatedElapsedTime: "0500", // Example format
OtherInfo: "Test flight delay",
}
})
Describe("Marshalling and Unmarshalling", func() {
It("should marshal and unmarshal correctly", func() {
data, err := json.Marshal(original)
Expect(err).NotTo(HaveOccurred())
var unmarshalled DLA
err = json.Unmarshal(data, &unmarshalled)
Expect(err).NotTo(HaveOccurred())
Expect(unmarshalled).To(Equal(original))
})
})
Describe("Validation", func() {
It("should validate successfully for a valid DLA", func() {
err := original.Validate()
Expect(err).NotTo(HaveOccurred())
})
It("should fail validation for missing required fields", func() {
invalidDLA := DLA{
Category: "DLA",
// AircraftID is missing
SSRModeAndCode: "A1234",
DepartureAirport: "JFK",
NewDepartureTime: "150405",
ArrivalAirport: "LAX",
EstimatedElapsedTime: "0500",
}
err := invalidDLA.Validate()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("aircraft id is required"))
})
})
})
+118
View File
@@ -0,0 +1,118 @@
package domain
import "fmt"
/*
飞行计划报文(FPL)通常包括以下内容:
编组 3:电报类别、编号和参考数据
编组 7:航空器识别标志和 SSR 模式及编码
编组 8:飞行规则和类型
编组 9:航机和设备
编组 10:巡航速度和飞行高度
编组 13:起飞机场和时间
编组 15:航路
编组 16:目的地机场和估计总耗时
编组 18:其他信息(如需要)
编组 19:补充信息
*/
/*
Group 3: Telegram category, number, and reference data
Group 7: Aircraft identification and SSR mode and code
Group 8: Flight rules and type
Group 9: Number of aircraft, type of aircraft, and wake turbulence category
Group 10: Equipment and capabilities
Group 13: Departure airport and time
Group 15: Route
Group 16: Destination airport and estimated total elapsed time, alternate destination airport
Group 18: Other information (if needed)
Group 19: Supplementary information (if needed)
*/
/*
MessageType (电报类别): Indicates the type of telegram.
FlightNumber (航班号): Represents the flight number.
ReferenceData (参考数据): Optional field for reference data.
AircraftID (航空器识别标志): Unique identifier of the aircraft.
SSRModeAndCode (SSR 模式及编码): SSR (Secondary Surveillance Radar) mode and code.
FlightRulesAndType (飞行规则和类型): Flight rules and type (e.g., IFR).
AircraftAndEquipment (航机和设备): Aircraft type and equipment.
CruisingSpeedAndLevel (巡航速度和飞行高度): Cruising speed and flight level.
DepartureAirport (起飞机场): ICAO code of the departure airport.
DepartureTime (起飞时间): Departure time in UTC.
Route (航路): Planned route.
DestinationAndTotalTime (目的地机场和估计总耗时): ICAO code of the destination airport and estimated total flight time.
AlternateAirport (目的地备降机场): Optional field for the alternate destination airport.
OtherInfo (其他信息): Optional field for additional relevant information.
SupplementaryInfo (补充信息): Optional field for supplementary information.
*/
/*
(FPL-CCA1532-IS
-A332/H
-SDE3FGHIJ4J5M1RWY/LB101
-ZSSS2035
-K0859S1040 PIAKS G330 PIMOL A539 BTO W82 DOGAR
-ZBAA0153 ZBYN
-PBN/A1B2B3B4B5D1L1 NAV/ABAS REG/B6513 EET/ZBPE0112 SEL/KMAL PER/C RIF/FRT N640 ZBYN RMK/TCAS EQUIPPED)
*/
// FPL 电报体中的飞行计划报文结构
type FPL struct {
Category string `json:"category"` // 电报类别
FlightNumber string `json:"flight_number"` // 航班号
ReferenceData string `json:"reference_data,omitempty"` // 参考数据(可选)
AircraftID string `json:"aircraft_id"` // 航空器识别标志
SSRModeAndCode string `json:"ssr_mode_and_code"` // SSR 模式及编码
FlightRulesAndType string `json:"flight_rules_and_type"` // 飞行规则和类型
AircraftAndEquipment string `json:"aircraft_and_equipment"` // 航机和设备
CruisingSpeedAndLevel string `json:"cruising_speed_and_level"` // 巡航速度和飞行高度
DepartureAirport string `json:"departure_airport"` // 起飞机场
DepartureTime string `json:"departure_time"` // 起飞时间
Route string `json:"route"` // 航路
DestinationAndTotalTime string `json:"destination_and_total_time"` // 目的地机场和估计总耗时
AlternateAirport string `json:"alternate_airport,omitempty"` // 目的地备降机场(可选)
OtherInfo string `json:"other_info,omitempty"` // 其他信息(可选)
SupplementaryInfo string `json:"supplementary_info,omitempty"` // 补充信息(可选)
}
// Validate validates the FPL struct fields
func (f *FPL) Validate() error {
if f.Category == "" {
return fmt.Errorf("telegram category is required")
}
if f.FlightNumber == "" {
return fmt.Errorf("flight number is required")
}
if f.AircraftID == "" {
return fmt.Errorf("aircraft id is required")
}
if f.SSRModeAndCode == "" {
return fmt.Errorf("ssr mode and code is required")
}
if f.FlightRulesAndType == "" {
return fmt.Errorf("flight rules and type is required")
}
if f.AircraftAndEquipment == "" {
return fmt.Errorf("aircraft and equipment is required")
}
if f.CruisingSpeedAndLevel == "" {
return fmt.Errorf("cruising speed and level is required")
}
if f.DepartureAirport == "" {
return fmt.Errorf("departure airport is required")
}
if f.DepartureTime == "" {
return fmt.Errorf("departure time is required")
}
if f.Route == "" {
return fmt.Errorf("route is required")
}
if f.DestinationAndTotalTime == "" {
return fmt.Errorf("destination and total time is required")
}
return nil
}
+71
View File
@@ -0,0 +1,71 @@
package domain
import (
"encoding/json"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("FPL", func() {
var original FPL
BeforeEach(func() {
original = FPL{
Category: "FPL",
FlightNumber: "AB123",
AircraftID: "ABCD1234",
SSRModeAndCode: "A1234",
FlightRulesAndType: "IFR",
AircraftAndEquipment: "B738",
CruisingSpeedAndLevel: "N0450F350",
DepartureAirport: "JFK",
DepartureTime: time.Now().Format("150405"), // HHMMSS format
Route: "DCT GAYEL J95 BUF DCT",
DestinationAndTotalTime: "LAX0500", // Example format
OtherInfo: "Test flight",
SupplementaryInfo: "Supplementary information",
}
})
Describe("Marshalling and Unmarshalling", func() {
It("should marshal and unmarshal correctly", func() {
data, err := json.Marshal(original)
Expect(err).NotTo(HaveOccurred())
var unmarshalled FPL
err = json.Unmarshal(data, &unmarshalled)
Expect(err).NotTo(HaveOccurred())
Expect(unmarshalled).To(Equal(original))
})
})
Describe("Validation", func() {
It("should validate successfully for a valid FPL", func() {
err := original.Validate()
Expect(err).NotTo(HaveOccurred())
})
It("should fail validation for missing required fields", func() {
invalidFPL := FPL{
Category: "FPL",
// FlightNumber is missing
AircraftID: "ABCD1234",
SSRModeAndCode: "A1234",
FlightRulesAndType: "IFR",
AircraftAndEquipment: "B738",
CruisingSpeedAndLevel: "N0450F350",
DepartureAirport: "JFK",
DepartureTime: "150405",
Route: "DCT GAYEL J95 BUF DCT",
DestinationAndTotalTime: "LAX0500",
}
err := invalidFPL.Validate()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("flight number is required"))
})
})
})
+13
View File
@@ -0,0 +1,13 @@
package domain
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestDomain(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Domain Suite")
}