snss-types 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,227 @@
1
+ <p align="center">
2
+ <a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
3
+ </p>
4
+
5
+ [circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
6
+ [circleci-url]: https://circleci.com/gh/nestjs/nest
7
+
8
+ <p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
9
+
10
+ # PM2 开机自启持久化配置指南
11
+
12
+ PM2 支持生成系统启动脚本,实现服务器重启后**自动恢复进程列表**,支持主流 Linux、macOS、Windows 系统,兼容多种初始化系统。
13
+
14
+ ## 一、支持的初始化系统
15
+
16
+ PM2 可通过 `pm2 startup` 自动检测系统,对应关系如下:
17
+ | 初始化系统 | 适用系统 |
18
+ |------------|----------|
19
+ | systemd | Ubuntu ≥16、CentOS ≥7、Arch、Debian ≥7 |
20
+ | upstart | Ubuntu ≤14 |
21
+ | launchd | macOS(Darwin) |
22
+ | openrc | Gentoo Linux、Arch Linux |
23
+ | rcd | FreeBSD |
24
+ | systemv | CentOS 6、Amazon Linux |
25
+
26
+ ## 二、核心操作命令
27
+
28
+ ### 1. 生成开机自启脚本
29
+
30
+ 直接执行命令,PM2 会提示需要 root 权限:
31
+
32
+ ```bash
33
+ pm2 startup
34
+ ```
35
+
36
+ 执行后会输出**带权限的完整命令**,复制粘贴到终端执行(无需手动修改参数):
37
+
38
+ ```bash
39
+ # 示例输出命令,直接复制执行即可
40
+ sudo su -c "env PATH=$PATH:/home/unitech/.nvm/versions/node/v14.3/bin pm2 startup <distribution> -u <user> --hp <home-path>"
41
+ ```
42
+
43
+ ✅ 可选:自定义服务名称
44
+
45
+ ```bash
46
+ pm2 startup --service-name 自定义服务名
47
+ ```
48
+
49
+ ### 2. 保存当前应用进程列表
50
+
51
+ 启动所有需要持久化的应用后,执行保存命令,重启后会自动恢复:
52
+
53
+ ```bash
54
+ pm2 save
55
+ ```
56
+
57
+ ### 3. 手动恢复进程
58
+
59
+ 如需手动还原已保存的进程列表,执行:
60
+
61
+ ```bash
62
+ pm2 resurrect
63
+ ```
64
+
65
+ ### 4. 禁用开机自启
66
+
67
+ 删除 PM2 启动配置,关闭开机自启:
68
+
69
+ ```bash
70
+ pm2 unstartup
71
+ ```
72
+
73
+ ## 三、进阶配置
74
+
75
+ ### 1. Node.js 版本升级后更新启动脚本
76
+
77
+ 升级 Node 后,需重新生成 PM2 启动脚本,确保使用最新 Node 二进制文件:
78
+
79
+ ```bash
80
+ # 1. 先禁用旧配置
81
+ pm2 unstartup
82
+ # 2. 重新生成新配置
83
+ pm2 startup
84
+ ```
85
+
86
+ ### 2. 指定运行用户
87
+
88
+ 以指定用户执行 PM2 启动脚本(替换用户名和家目录):
89
+
90
+ ```bash
91
+ pm2 startup ubuntu -u www --hp /home/ubuntu
92
+ ```
93
+
94
+ ### 3. 手动指定初始化系统
95
+
96
+ 如需强制指定平台/初始化系统,使用以下命令:
97
+
98
+ ```bash
99
+ pm2 startup [ubuntu|ubuntu14|ubuntu16|ubuntu18|ubuntu20|centos|centos6|arch|macos|systemd|upstart|launchd|openrc|rcd]
100
+ ```
101
+
102
+ ## 四、Systemd 系统检查命令(适用于 Ubuntu16+/CentOS7+)
103
+
104
+ ```bash
105
+ # 查看 PM2 服务是否添加成功
106
+ systemctl list-units | grep pm2
107
+
108
+ # 查看 PM2 服务日志
109
+ journalctl -u pm2-<用户名>
110
+
111
+ # 查看 systemd 配置文件
112
+ systemctl cat pm2-<用户名>
113
+
114
+ # 分析系统启动耗时
115
+ systemd-analyze plot > output.svg
116
+ ```
117
+
118
+ ### Systemd 优化:等待网络联机后启动 PM2
119
+
120
+ 编辑 PM2 系统服务文件,添加以下配置,避免网络未就绪导致应用启动失败:
121
+
122
+ ```ini
123
+ [Unit]
124
+ Wants=network-online.target
125
+ After=network.target network-online.target
126
+
127
+ [Install]
128
+ WantedBy=multi-user.target network-online.target
129
+ ```
130
+
131
+ ## 五、Windows 系统开机自启
132
+
133
+ 1. 执行以下命令并按回车确认
134
+
135
+ ```bash
136
+ npx pm2-service-install -n PM2
137
+ ```
138
+
139
+ 1. 保存当前 PM2 进程列表,安装好服务后,需要把当前正在运行的应用保存下来,这样开机后服务才能自动拉起它们:
140
+
141
+ ```bash
142
+ pm2 save
143
+ ```
144
+
145
+ 以后只要用 PM2 启动或停止了新的应用,记得再次执行 pm2 save 来更新开机自启列表。
146
+
147
+ ## 六、完整操作流程(推荐)
148
+
149
+ 1. 启动所有需要持久化的 Node.js 应用
150
+ 2. 保存进程列表:`pm2 save`
151
+ 3. 生成开机自启脚本:`pm2 startup`(复制输出命令执行)
152
+ 4. 重启服务器验证:`reboot`
153
+ 5. 重启后查看进程:`pm2 list`
154
+
155
+ # package.json
156
+
157
+ ```json
158
+ {
159
+ "name": "satellite-network-simulation-server",
160
+ "private": true,
161
+ "version": "1.0.0",
162
+ "description": "Nest TypeScript starter repository",
163
+ "license": "MIT",
164
+ "scripts": {
165
+ "dev": "nest start --watch",
166
+ "build": "nest build",
167
+ "start": "node dist/src/main.js",
168
+ "pm2:start": "npx pm2 start ecosystem.config.js --name nest-app",
169
+ "pm2:list": "npx pm2 list",
170
+ "pm2:status": "npx pm2 show nest-app",
171
+ "pm2:stop": "npx pm2 stop nest-app",
172
+ "pm2:delete": "npx pm2 delete nest-app",
173
+ "pm2:logs": "npx pm2 logs nest-app --lines 1000"
174
+ },
175
+ "engines": {
176
+ "npm": ">=10.0.0",
177
+ "node": ">=20.0.0"
178
+ },
179
+ "dependencies": {
180
+ "@nestjs/common": "^11.0.17",
181
+ "@nestjs/config": "^4.0.4",
182
+ "@nestjs/core": "^11.0.1",
183
+ "@nestjs/platform-express": "^11.1.11",
184
+ "@nestjs/platform-socket.io": "^11.1.19",
185
+ "@nestjs/platform-ws": "^11.1.19",
186
+ "@nestjs/swagger": "^11.4.2",
187
+ "@nestjs/typeorm": "^11.0.1",
188
+ "@nestjs/websockets": "^11.1.19",
189
+ "class-validator": "^0.15.1",
190
+ "dotenv": "^17.4.2",
191
+ "mysql2": "^3.22.3",
192
+ "reflect-metadata": "^0.2.2",
193
+ "rxjs": "^7.8.1",
194
+ "typeorm": "^0.3.29",
195
+ "ws": "^8.20.1"
196
+ },
197
+ "devDependencies": {
198
+ "@eslint/eslintrc": "^3.2.0",
199
+ "@eslint/js": "^9.18.0",
200
+ "@nestjs/cli": "^11.0.0",
201
+ "@nestjs/schematics": "^11.0.0",
202
+ "@nestjs/testing": "^11.0.1",
203
+ "@swc/cli": "^0.6.0",
204
+ "@swc/core": "^1.10.8",
205
+ "@types/express": "^5.0.0",
206
+ "@types/multer": "^2.1.0",
207
+ "@types/node": "^22.10.7",
208
+ "@types/supertest": "^6.0.2",
209
+ "eslint": "^9.18.0",
210
+ "eslint-config-prettier": "^10.0.1",
211
+ "eslint-plugin-prettier": "^5.2.3",
212
+ "globals": "^15.14.0",
213
+ "pm2": "^7.0.1",
214
+ "prettier": "^3.4.2",
215
+ "source-map-support": "^0.5.21",
216
+ "supertest": "^7.0.0",
217
+ "ts-loader": "^9.5.2",
218
+ "ts-node": "^10.9.2",
219
+ "tsconfig-paths": "^4.2.0",
220
+ "typescript": "5.7.3",
221
+ "typescript-eslint": "^8.20.0"
222
+ },
223
+ "pnpm": {
224
+ "onlyBuiltDependencies": ["@nestjs/core", "@swc/core"]
225
+ }
226
+ }
227
+ ```
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "snss-types",
3
+ "version": "1.0.0",
4
+ "label": "卫星网络仿真文件解析数据传输服务",
5
+ "description": "基于 Nestjs 的 服务端接口,提供文件数据处理解析传输等服务接口",
6
+ "private": false,
7
+ "main": "./src/types/index.ts",
8
+ "files": [
9
+ "./src/types"
10
+ ],
11
+ "scripts": {
12
+ "dev": "nest start --watch",
13
+ "build": "nest build",
14
+ "start": "node dist/src/main.js",
15
+ "pm2:start": "npx pm2 start ecosystem.config.js --name nest-app",
16
+ "pm2:save": "npx pm2 save",
17
+ "pm2:list": "npx pm2 list",
18
+ "pm2:status": "npx pm2 show nest-app",
19
+ "pm2:stop": "npx pm2 stop nest-app",
20
+ "pm2:delete": "npx pm2 delete nest-app",
21
+ "pm2:logs": "npx pm2 logs nest-app --lines 1000"
22
+ },
23
+ "engines": {
24
+ "npm": ">=10.0.0",
25
+ "node": ">=20.0.0"
26
+ },
27
+ "dependencies": {
28
+ "@nestjs/common": "^11.0.17",
29
+ "@nestjs/config": "^4.0.4",
30
+ "@nestjs/core": "^11.1.21",
31
+ "@nestjs/platform-express": "^11.1.11",
32
+ "@nestjs/platform-socket.io": "^11.1.19",
33
+ "@nestjs/platform-ws": "^11.1.19",
34
+ "@nestjs/swagger": "^11.4.2",
35
+ "@nestjs/typeorm": "^11.0.1",
36
+ "@nestjs/websockets": "^11.1.19",
37
+ "class-validator": "^0.15.1",
38
+ "cross-zip": "^4.0.1",
39
+ "dotenv": "^17.4.2",
40
+ "lodash-es": "^4.18.1",
41
+ "mysql2": "^3.22.3",
42
+ "reflect-metadata": "^0.2.2",
43
+ "rxjs": "^7.8.1",
44
+ "typeorm": "^0.3.29",
45
+ "ws": "^8.20.1"
46
+ },
47
+ "devDependencies": {
48
+ "@eslint/eslintrc": "^3.2.0",
49
+ "@eslint/js": "^9.18.0",
50
+ "@nestjs/cli": "^11.0.0",
51
+ "@nestjs/schematics": "^11.0.0",
52
+ "@nestjs/testing": "^11.0.1",
53
+ "@swc/cli": "^0.6.0",
54
+ "@swc/core": "^1.10.8",
55
+ "@types/cross-zip": "^4.0.2",
56
+ "@types/express": "^5.0.0",
57
+ "@types/lodash-es": "^4.17.12",
58
+ "@types/multer": "^2.1.0",
59
+ "@types/node": "^24.12.4",
60
+ "@types/supertest": "^6.0.2",
61
+ "eslint": "^9.18.0",
62
+ "eslint-config-prettier": "^10.0.1",
63
+ "eslint-plugin-prettier": "^5.2.3",
64
+ "globals": "^15.14.0",
65
+ "pm2": "^7.0.1",
66
+ "pm2-windows-service": "^0.2.1",
67
+ "prettier": "^3.4.2",
68
+ "source-map-support": "^0.5.21",
69
+ "supertest": "^7.0.0",
70
+ "ts-loader": "^9.5.2",
71
+ "ts-node": "^10.9.2",
72
+ "tsconfig-paths": "^4.2.0",
73
+ "typescript": "5.7.3",
74
+ "typescript-eslint": "^8.20.0"
75
+ },
76
+ "pnpm": {
77
+ "onlyBuiltDependencies": [
78
+ "@nestjs/core",
79
+ "@swc/core"
80
+ ]
81
+ }
82
+ }
@@ -0,0 +1,86 @@
1
+ import { EvaluationMethod, SceneItem, SceneItemSelfInfo } from './scene'
2
+
3
+ /**
4
+ * 案例类型
5
+ */
6
+ export type CaseType = 'architecture_optimization'
7
+
8
+ /**
9
+ * 优化评估案例
10
+ */
11
+ export interface CaseJsonData {
12
+ /** 案例唯一标识 */
13
+ case_id: string
14
+ /** 案例名称 */
15
+ case_name: string
16
+ /** 案例类型 */
17
+ case_type: CaseType
18
+ /** 案例描述 */
19
+ description: string
20
+ /** 默认展示的场景ID */
21
+ default_scene_id: string
22
+ /** 场景顺序列表(按迭代顺序排列的 scene_id 数组) */
23
+ scene_order: string[]
24
+ /** 场景详情列表 */
25
+ scenes: SceneItemSelfInfo[]
26
+ }
27
+
28
+ /**
29
+ * 案例库树结构对象
30
+ */
31
+ export interface CaseItem {
32
+ label: string
33
+ value: string
34
+ meta: CaseItemMeta
35
+ children: SceneItem[]
36
+ isLeaf?: boolean
37
+ isOnline?: boolean
38
+ [x: string]: any
39
+ }
40
+
41
+ export interface CaseItemMeta {
42
+ case_json?: CaseJsonData
43
+ evaluation_summary_json?: EvaluationSummaryData
44
+ }
45
+
46
+ /**
47
+ * 各维度评分
48
+ */
49
+ export interface DimensionScores {
50
+ /** 网络容量评分 */
51
+ network_capacity: number
52
+ /** 服务质量评分 */
53
+ service_quality: number
54
+ /** 网络韧性评分 */
55
+ network_resilience: number
56
+ /** 网络复杂度评分 */
57
+ network_complexity: number
58
+ // 支持增加新的评估维度
59
+ [x: string]: number
60
+ }
61
+
62
+ /**
63
+ * 场景评估节点
64
+ */
65
+ export interface SceneEvaluation {
66
+ /** 场景唯一标识 */
67
+ scene_id: string
68
+ /** 场景显示名称 */
69
+ scene_name: string
70
+ /** 综合最终得分 */
71
+ final_score: number
72
+ /** 各维度得分详情 */
73
+ dimension_scores: DimensionScores
74
+ }
75
+
76
+ /**
77
+ * 多维度评估结果
78
+ */
79
+ export interface EvaluationSummaryData {
80
+ /** 案例唯一标识 */
81
+ case_id: string
82
+ /** 评估方法 */
83
+ evaluation_method: EvaluationMethod
84
+ /** 场景评估列表 */
85
+ scenes: SceneEvaluation[]
86
+ }
@@ -0,0 +1,70 @@
1
+ import { ModelEntity } from '@/entity/ModelEntity'
2
+ import { CaseItem } from './case'
3
+ import { SceneItemMeta } from './scene'
4
+
5
+ export * from '@/dto/DirPathDto'
6
+ export * from '@/dto/InitCaseCacheDto'
7
+ export * from '@/dto/ModelDto'
8
+ export * from '@/dto/SendMessageDto'
9
+ export * from '@/entity/ModelEntity'
10
+ export * from './case'
11
+ export * from './scene'
12
+
13
+ /**
14
+ * 基础响应结构
15
+ * 所有 API 响应的通用格式
16
+ */
17
+ export interface BaseResponse {
18
+ /** 状态码,通常 200 表示成功,其他表示错误 */
19
+ code: number
20
+ /** 响应数据,可选 */
21
+ data?: any
22
+ /** 响应消息或错误描述 */
23
+ message: string
24
+ }
25
+
26
+ /**
27
+ * 库树结构响应
28
+ * 用于返回层级化的树形结构数据(如目录树、模型库树等)
29
+ */
30
+ export interface CaseTreeResponse extends BaseResponse {
31
+ /** 树形节点数组 */
32
+ data?: CaseItem[]
33
+ }
34
+ /**
35
+ * 场景详细信息响应
36
+ * 通过场景文件夹路径查询并返回场景详细信息
37
+ */
38
+ export interface SceneItemMetaResponse extends BaseResponse {
39
+ /** 树形节点数组 */
40
+ data?: SceneItemMeta
41
+ }
42
+
43
+ /**
44
+ * JSON 文件上传响应
45
+ * 用于返回上传后的文件详细信息
46
+ */
47
+ export interface UploadFileResponse extends BaseResponse {
48
+ /** 上传文件的具体信息 */
49
+ data?: {
50
+ /** 原始文件名 */
51
+ originalName: string
52
+ /** 文件大小(字节) */
53
+ size: number
54
+ /** 文件 MIME 类型 */
55
+ mimetype: string
56
+ /** 服务器存储路径 */
57
+ path: string
58
+ /** 服务器生成的文件名 */
59
+ filename: string
60
+ }
61
+ }
62
+
63
+ /**
64
+ * 模型响应
65
+ * 用于返回单个模型、模型列表或空值
66
+ */
67
+ export interface ModelResponse extends BaseResponse {
68
+ /** 模型实体数据,可能是单个对象、数组或 null */
69
+ data?: ModelEntity | ModelEntity[] | null
70
+ }
@@ -0,0 +1,612 @@
1
+ /**
2
+ * 场景树结构对象类型
3
+ */
4
+ export interface SceneItem {
5
+ label: string
6
+ value: string
7
+ meta: SceneItemMeta
8
+ isLeaf?: boolean
9
+ [x: string]: any
10
+ }
11
+
12
+ /**
13
+ * 场景元数据详细信息类型
14
+ */
15
+ export interface SceneItemMeta {
16
+ scene_json?: SceneItemSelfInfo
17
+ manifest_json?: ManifestData
18
+ constellations_json?: ConstellationsData
19
+ satellites_json?: SatellitesData
20
+ nodes_json?: NodesData
21
+ links_json?: LinksData
22
+ tasks_json?: TasksData
23
+ flows_json?: FlowsData
24
+ timeline_json?: TimelineData
25
+ metrics_json?: MetricsData
26
+ evaluation_json?: EvaluationData
27
+ }
28
+
29
+ /**
30
+ * 场景节点(单个架构版本)
31
+ */
32
+ export interface SceneItemSelfInfo {
33
+ /** 场景唯一标识 */
34
+ scene_id: string
35
+ /** 场景显示名称 */
36
+ scene_name: string
37
+ /** 文件路径 */
38
+ file_path?: string
39
+ /** 场景角色:基线/迭代/最终 */
40
+ scene_role: SceneRole
41
+ /** 场景描述说明 */
42
+ description: string
43
+ /** 上一个场景ID(可选,基线版本没有) */
44
+ prev_scene_id?: string
45
+ /** 下一个场景ID(可选,最终版本没有) */
46
+ next_scene_id?: string
47
+ }
48
+
49
+ /**
50
+ * 场景角色类型
51
+ * - baseline: 基线架构版本
52
+ * - iteration: 优化迭代版本
53
+ * - final: 最终优化版本
54
+ */
55
+ export type SceneRole = 'baseline' | 'iteration' | 'final'
56
+
57
+ // #region manifest.json 类型 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
58
+ // ==================== manifest.json 类型 ====================
59
+ /**
60
+ * 时间配置
61
+ */
62
+ export interface ManifestTime {
63
+ epoch_utc: string // 起始UTC时间,如 "2026-01-01T00:00:00Z"
64
+ start_time_s: number
65
+ end_time_s: number
66
+ time_step_ms: number
67
+ frame_count: number
68
+ }
69
+
70
+ /**
71
+ * 场景清单文件
72
+ */
73
+ export interface ManifestData {
74
+ scene_id: string
75
+ scene_name: string
76
+ description: string
77
+ time: ManifestTime
78
+ }
79
+
80
+ // #endregion ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
81
+
82
+ // #region constellations.json 类型 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
83
+ // ==================== constellations.json 类型 ====================
84
+ /**
85
+ * 星座类型
86
+ */
87
+ export type ConstellationType = 'GEO' | 'MEO' | 'LEO'
88
+
89
+ /**
90
+ * 星座配置
91
+ */
92
+ export interface Constellation {
93
+ constellation_id: string
94
+ constellation_name: string
95
+ layer: ConstellationType
96
+ satellite_count: number
97
+ }
98
+
99
+ /**
100
+ * 星座列表
101
+ */
102
+ export interface ConstellationsData {
103
+ constellations: Constellation[]
104
+ }
105
+
106
+ // #endregion ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
107
+
108
+ // #region satellites.json 类型 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
109
+ // ==================== satellites.json 类型 ====================
110
+ /**
111
+ * 卫星TLE数据
112
+ */
113
+ export interface SatelliteTLE {
114
+ line1: string
115
+ line2: string
116
+ }
117
+
118
+ /**
119
+ * 卫星配置
120
+ */
121
+ export interface Satellite {
122
+ satellite_id: string
123
+ satellite_name: string
124
+ constellation_id: string
125
+ layer: ConstellationType
126
+ satellite_type: TaskType
127
+ orbit_plane: number
128
+ orbit_index: number
129
+ tle: SatelliteTLE
130
+ }
131
+
132
+ /**
133
+ * 卫星列表
134
+ */
135
+ export interface SatellitesData {
136
+ satellites: Satellite[]
137
+ }
138
+ // #endregion ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
139
+
140
+ // #region nodes.json 类型 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
141
+ // ==================== nodes.json 类型 ====================
142
+ /**
143
+ * 地理位置
144
+ */
145
+ export interface GeoPosition {
146
+ lon_deg: number
147
+ lat_deg: number
148
+ alt_km: number
149
+ }
150
+
151
+ /**
152
+ * 容量配置
153
+ */
154
+ export interface Capacity {
155
+ max_access_capacity_mbps: number
156
+ }
157
+
158
+ /**
159
+ * 显示配置
160
+ */
161
+ export interface DisplayOptions {
162
+ show_trajectory?: boolean
163
+ }
164
+
165
+ /**
166
+ * 节点类型
167
+ */
168
+ export type NodeType = 'gateway' | 'user_terminal' | 'control_center' | 'other'
169
+
170
+ /**
171
+ * 终端类型(仅在 node_type = 'user_terminal' 时使用)
172
+ */
173
+ export type TerminalType = 'fixed' | 'mobile' | 'airborne' | 'maritime'
174
+
175
+ /**
176
+ * 移动模型类型
177
+ */
178
+ export type MobilityModel = 'static' | 'waypoint'
179
+
180
+ /**
181
+ * 网关节点
182
+ */
183
+ export interface GatewayNode {
184
+ node_id: string
185
+ node_name: string
186
+ node_type: 'gateway'
187
+ region: string
188
+ geo_position: GeoPosition
189
+ capacity: Capacity
190
+ }
191
+
192
+ /**
193
+ * 固定用户终端
194
+ */
195
+ export interface StaticUserTerminal {
196
+ node_id: string
197
+ node_name: string
198
+ node_type: 'user_terminal'
199
+ terminal_type: 'fixed'
200
+ mobility_model: 'static'
201
+ geo_position: GeoPosition
202
+ display_options?: DisplayOptions
203
+ }
204
+
205
+ /**
206
+ * 移动用户终端
207
+ */
208
+ export interface MobileUserTerminal {
209
+ node_id: string
210
+ node_name: string
211
+ node_type: 'user_terminal'
212
+ terminal_type: 'mobile'
213
+ mobility_model: 'waypoint'
214
+ geo_position: GeoPosition
215
+ display_options?: DisplayOptions
216
+ }
217
+
218
+ /**
219
+ * 其他类型用户终端
220
+ */
221
+ export interface OtherUserTerminal {
222
+ node_id: string
223
+ node_name: string
224
+ node_type: 'user_terminal'
225
+ terminal_type: Exclude<TerminalType, 'fixed' | 'mobile'>
226
+ mobility_model: MobilityModel
227
+ geo_position: GeoPosition
228
+ display_options?: DisplayOptions
229
+ }
230
+
231
+ /**
232
+ * 控制中心节点
233
+ */
234
+ export interface ControlCenterNode {
235
+ node_id: string
236
+ node_name: string
237
+ node_type: 'control_center'
238
+ geo_position: GeoPosition
239
+ }
240
+
241
+ /**
242
+ * 其他类型节点
243
+ */
244
+ export interface OtherNode {
245
+ node_id: string
246
+ node_name: string
247
+ node_type: 'other'
248
+ geo_position: GeoPosition
249
+ }
250
+
251
+ /**
252
+ * 节点联合类型
253
+ */
254
+ export type Node =
255
+ | GatewayNode
256
+ | StaticUserTerminal
257
+ | MobileUserTerminal
258
+ | OtherUserTerminal
259
+ | ControlCenterNode
260
+ | OtherNode
261
+
262
+ /**
263
+ * 节点列表
264
+ */
265
+ export interface NodesData {
266
+ nodes: Node[]
267
+ }
268
+ // #endregion ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
269
+
270
+ // #region links.json 类型 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
271
+ // ==================== links.json 类型 ====================
272
+ /**
273
+ * 链路类型
274
+ */
275
+ export type LinkType = 'ISL' | 'IOL' | 'GSL' | 'BACKHAUL'
276
+
277
+ /**
278
+ * 节点类型
279
+ */
280
+ export type LinkNodeType = 'satellite' | 'gateway'
281
+
282
+ /**
283
+ * 链路实例
284
+ */
285
+ export interface Link {
286
+ link_id: string
287
+ node_a_id: string
288
+ node_a_type: LinkNodeType
289
+ node_b_id: string
290
+ node_b_type: LinkNodeType
291
+ link_type: LinkType
292
+ capacity_mbps: number
293
+ node_a_constellation_id?: string
294
+ node_b_constellation_id?: string
295
+ }
296
+
297
+ /**
298
+ * 批量链路配置规则
299
+ */
300
+ export interface BulkConfigRule {
301
+ constellation_id: string
302
+ link_type: LinkType
303
+ capacity_mbps: number
304
+ }
305
+
306
+ /**
307
+ * 链路列表
308
+ */
309
+ export interface LinksData {
310
+ links: Link[]
311
+ bulk_config_rules: BulkConfigRule[]
312
+ }
313
+ // #endregion ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
314
+
315
+ // #region tasks.json 类型 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
316
+ // ==================== tasks.json 类型 ====================
317
+ /**
318
+ * 任务类型
319
+ */
320
+ export type TaskType = 'emergency_communication'
321
+
322
+ /**
323
+ * 任务优先级
324
+ */
325
+ export type TaskPriority = 'high'
326
+
327
+ /**
328
+ * 任务
329
+ */
330
+ export interface Task {
331
+ task_id: string
332
+ task_name: string
333
+ task_type: TaskType
334
+ priority: TaskPriority
335
+ flow_ids: string[]
336
+ start_time_s: number
337
+ end_time_s: number
338
+ }
339
+
340
+ /**
341
+ * 任务列表
342
+ */
343
+ export interface TasksData {
344
+ tasks: Task[]
345
+ }
346
+ // #endregion ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
347
+
348
+ // #region flows.json 类型 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
349
+ // ==================== flows.json 类型 ====================
350
+ /**
351
+ * 业务类型
352
+ */
353
+ export type ServiceType = 'voice' | 'image_return'
354
+
355
+ /**
356
+ * 业务优先级
357
+ */
358
+ export type FlowPriority = 'high'
359
+
360
+ /**
361
+ * 业务流
362
+ */
363
+ export interface Flow {
364
+ flow_id: string
365
+ flow_name: string
366
+ task_id: string
367
+ service_type: ServiceType
368
+ priority: FlowPriority
369
+ src_node_id: string
370
+ dst_node_id: string
371
+ start_time_s: number
372
+ end_time_s: number
373
+ }
374
+
375
+ /**
376
+ * 业务流列表
377
+ */
378
+ export interface FlowsData {
379
+ flows: Flow[]
380
+ }
381
+ // #endregion ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
382
+
383
+ // #region timeline.json 类型 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
384
+ // ==================== timeline.json 类型 ====================
385
+ /**
386
+ * 地理位置
387
+ */
388
+ export interface GeoPosition {
389
+ lon_deg: number
390
+ lat_deg: number
391
+ alt_km: number
392
+ }
393
+
394
+ /**
395
+ * 速度向量
396
+ */
397
+ export interface VelocityWGS {
398
+ vx: number
399
+ vy: number
400
+ vz: number
401
+ unit: string
402
+ }
403
+
404
+ /**
405
+ * 用户状态
406
+ */
407
+ export interface UserState {
408
+ node_id: string
409
+ geo_position: GeoPosition
410
+ velocity_wgs: VelocityWGS
411
+ }
412
+
413
+ /**
414
+ * 链路状态
415
+ */
416
+ export interface LinkState {
417
+ link_id: string
418
+ status: string
419
+ utilization_ratio: number
420
+ congestion_level: number
421
+ }
422
+
423
+ /**
424
+ * 业务流状态
425
+ */
426
+ export interface FlowState {
427
+ flow_id: string
428
+ status: string
429
+ throughput_mbps: number
430
+ avg_delay_ms: number
431
+ loss_rate: number
432
+ current_path_node_ids: string[]
433
+ is_sla_satisfied: boolean
434
+ }
435
+
436
+ /**
437
+ * 任务状态
438
+ */
439
+ export interface TaskState {
440
+ task_id: string
441
+ status: string
442
+ active_flow_ids: string[]
443
+ }
444
+
445
+ /**
446
+ * 时间轴单帧数据
447
+ */
448
+ export interface TimelineFrame {
449
+ frame_no: number
450
+ timestamp_s: number
451
+ user_states: UserState[]
452
+ links: LinkState[]
453
+ flows: FlowState[]
454
+ tasks: TaskState[]
455
+ }
456
+
457
+ /**
458
+ * 时间轴数据
459
+ */
460
+ export interface TimelineData {
461
+ timelines: TimelineFrame[]
462
+ }
463
+ // #endregion ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
464
+
465
+ // #region metrics.json 类型 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
466
+ // ==================== metrics.json 类型 ====================
467
+ /**
468
+ * 概要统计
469
+ */
470
+ export interface MetricsSummary {
471
+ active_flow_total: number
472
+ high_priority_flow_total: number
473
+ avg_delay_ms: number
474
+ avg_loss_rate: number
475
+ avg_throughput_mbps: number
476
+ congested_link_total: number
477
+ }
478
+
479
+ /**
480
+ * 时序数据点
481
+ */
482
+ export interface TimeseriesPoint {
483
+ timestamp_s: number
484
+ active_flow_count: number
485
+ network_throughput_mbps: number
486
+ avg_delay_ms: number
487
+ avg_loss_rate: number
488
+ congested_link_count: number
489
+ }
490
+
491
+ /**
492
+ * 图表配置
493
+ */
494
+ export interface ChartConfig {
495
+ chart_id: string
496
+ chart_name: string
497
+ chart_type: string
498
+ x_field: string
499
+ y_fields: string[]
500
+ unit: string
501
+ }
502
+
503
+ /**
504
+ * 图表资源
505
+ */
506
+ export interface FigureAsset {
507
+ figure_id: string
508
+ figure_name: string
509
+ figure_type: string
510
+ file_path: string
511
+ description: string
512
+ }
513
+
514
+ /**
515
+ * 指标数据
516
+ */
517
+ export interface MetricsData {
518
+ summary: MetricsSummary
519
+ timeseries: TimeseriesPoint[]
520
+ charts: ChartConfig[]
521
+ figure_assets: FigureAsset[]
522
+ }
523
+ // #endregion ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
524
+
525
+ // #region evaluation.json ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
526
+ // ==================== evaluation.json 类型 ====================
527
+ /**
528
+ * 评估方法类型
529
+ */
530
+ export type EvaluationMethod = 'AHP_ENTROPY'
531
+
532
+ /**
533
+ * 指标方向类型
534
+ */
535
+ export type MetricDirection = 'benefit' | 'cost'
536
+
537
+ /**
538
+ * 评估模型
539
+ */
540
+ export interface EvaluationModel {
541
+ method: EvaluationMethod
542
+ }
543
+
544
+ /**
545
+ * 细分指标
546
+ */
547
+ export interface Metric {
548
+ metric_id: string
549
+ metric_name: string
550
+ direction: MetricDirection
551
+ value: number
552
+ normalized_value: number
553
+ unit: string
554
+ }
555
+
556
+ /**
557
+ * 评估维度
558
+ */
559
+ export interface EvaluationDimension {
560
+ dimension_id: string
561
+ dimension_name: string
562
+ score: number
563
+ ahp_weight: number
564
+ entropy_weight: number
565
+ combined_weight: number
566
+ metrics: Metric[]
567
+ }
568
+
569
+ /**
570
+ * 最终得分
571
+ */
572
+ export interface FinalScore {
573
+ score: number
574
+ score_scale: string
575
+ }
576
+
577
+ /**
578
+ * 评估图表配置
579
+ */
580
+ export interface EvaluationChart {
581
+ chart_id: string
582
+ chart_name: string
583
+ chart_type: string
584
+ label_field: string
585
+ value_field: string
586
+ unit: string
587
+ }
588
+
589
+ /**
590
+ * 评估图表资源
591
+ */
592
+ export interface EvaluationFigureAsset {
593
+ figure_id: string
594
+ figure_name: string
595
+ figure_type: string
596
+ file_path: string
597
+ description: string
598
+ }
599
+
600
+ /**
601
+ * 评估结果
602
+ */
603
+ export interface EvaluationData {
604
+ scene_id: string
605
+ scene_name: string
606
+ evaluation_model: EvaluationModel
607
+ dimensions: EvaluationDimension[]
608
+ final_score: FinalScore
609
+ charts: EvaluationChart[]
610
+ figure_assets: EvaluationFigureAsset[]
611
+ }
612
+ // #endregion ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑