Compare commits
211 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
618012c9d4 | |
|
|
608f9e1ffd | |
|
|
b4a7b290b7 | |
|
|
ad4b0f46d3 | |
|
|
b2f2601f37 | |
|
|
097682d1b9 | |
|
|
7e8b721a6e | |
|
|
fbc1d4fd22 | |
|
|
789a11bf1d | |
|
|
a6f422f4a9 | |
|
|
b15f6954da | |
|
|
e97ab46ec6 | |
|
|
eac9e611c2 | |
|
|
869e33441e | |
|
|
6eeb40c110 | |
|
|
f0ce72b44c | |
|
|
e8ce003cf0 | |
|
|
a8ff1cbd7c | |
|
|
6318ffae92 | |
|
|
67c071c997 | |
|
|
aae9c3537e | |
|
|
1290d6a524 | |
|
|
48f53231c9 | |
|
|
72b111b13f | |
|
|
3c47e50574 | |
|
|
216b4e5bb3 | |
|
|
fbc35af80c | |
|
|
77202deb58 | |
|
|
b3fd1019f9 | |
|
|
174bedac08 | |
|
|
c256461c59 | |
|
|
d153ed9780 | |
|
|
f21a0b32c2 | |
|
|
ce96ca3988 | |
|
|
4df11ebcc8 | |
|
|
5a57743e05 | |
|
|
1f0f8841ce | |
|
|
3f08e8b117 | |
|
|
e75e390d09 | |
|
|
6cd6cb7167 | |
|
|
e6dc3a2936 | |
|
|
3e1e4d5e95 | |
|
|
da059bf1ad | |
|
|
3a9b077abe | |
|
|
af9aa18353 | |
|
|
e72415754a | |
|
|
3c550c72ea | |
|
|
db3bc20f7d | |
|
|
33b880934e | |
|
|
abd64ed135 | |
|
|
93129f4956 | |
|
|
a61ea65bff | |
|
|
628efcb0b4 | |
|
|
9905d91ea2 | |
|
|
1bd4e7e902 | |
|
|
3953241f97 | |
|
|
246693e0ea | |
|
|
8d6424f800 | |
|
|
0a9d5c6df4 | |
|
|
2b1ac349e0 | |
|
|
e20c2f389e | |
|
|
81c3ff6bb2 | |
|
|
7e837dff3f | |
|
|
efe420b5a9 | |
|
|
249dc49dc5 | |
|
|
841a51e0ee | |
|
|
02a018df38 | |
|
|
0d460b178a | |
|
|
19be5b4bf0 | |
|
|
8ae8df19b1 | |
|
|
e72d969862 | |
|
|
13e98cbcdb | |
|
|
c19a1ad028 | |
|
|
fe975a6681 | |
|
|
a40346be1f | |
|
|
d1536c00bd | |
|
|
2c9ccd6ea4 | |
|
|
38c1643bb0 | |
|
|
222f89a6c1 | |
|
|
3d5f3622f7 | |
|
|
deab72f3cd | |
|
|
b81c02d204 | |
|
|
16d52f13af | |
|
|
cb3af6ee0d | |
|
|
c025f161b0 | |
|
|
d6856ec1c2 | |
|
|
6ae48aee54 | |
|
|
a97844dec1 | |
|
|
ed04b6c4c0 | |
|
|
1de86e9dc0 | |
|
|
4f7f5a2c94 | |
|
|
417f51294d | |
|
|
635a3eeb18 | |
|
|
577cb0314b | |
|
|
09874183d9 | |
|
|
6c676dff9c | |
|
|
8553e4604b | |
|
|
92605877f4 | |
|
|
2efd0a6465 | |
|
|
54fded65d0 | |
|
|
d305ee72b8 | |
|
|
fc5d587b96 | |
|
|
38946a67cd | |
|
|
39ea52589f | |
|
|
57edab1cb2 | |
|
|
b0d956084c | |
|
|
21b8bc2560 | |
|
|
d19de44668 | |
|
|
ddd85bc176 | |
|
|
1dcedf3150 | |
|
|
32eec0a709 | |
|
|
36d0423908 | |
|
|
de86e0f0b7 | |
|
|
e58d28dba1 | |
|
|
345d50b52f | |
|
|
e09fb1ef6f | |
|
|
907d638a8c | |
|
|
6c175a7008 | |
|
|
7b90688164 | |
|
|
80304fcfa8 | |
|
|
59678411af | |
|
|
da82d8ee17 | |
|
|
0db6eecceb | |
|
|
1ef708f925 | |
|
|
11c4fecae2 | |
|
|
488dfc0454 | |
|
|
9758e1800b | |
|
|
1711dd8941 | |
|
|
f8a9b2a827 | |
|
|
6ff528d9b0 | |
|
|
1146dd6773 | |
|
|
231e23329f | |
|
|
e305dc513b | |
|
|
5732553789 | |
|
|
8a24fe8ec2 | |
|
|
05c670a173 | |
|
|
22b37720ca | |
|
|
86fbb0fb80 | |
|
|
40d757fe59 | |
|
|
a03e2b9f0f | |
|
|
c174366b75 | |
|
|
151163031a | |
|
|
31142dff80 | |
|
|
3a63460966 | |
|
|
9c0cfbc185 | |
|
|
da9b5b4378 | |
|
|
58c17c391a | |
|
|
4af39290ef | |
|
|
df640c3582 | |
|
|
d6cd0f003b | |
|
|
fa3a76f6e8 | |
|
|
be476f39e7 | |
|
|
24cf92c0b8 | |
|
|
a207ceaa06 | |
|
|
c9148fad9f | |
|
|
be438fe3dc | |
|
|
c9f43207a1 | |
|
|
82a754b403 | |
|
|
437c5e4f17 | |
|
|
d34c9960df | |
|
|
87bf0d1719 | |
|
|
1485c874c3 | |
|
|
bedad1228b | |
|
|
f67d2cfaf3 | |
|
|
4c31441973 | |
|
|
ec2dbd8cf7 | |
|
|
616838a9a8 | |
|
|
e15423b9f7 | |
|
|
f52c64f3a6 | |
|
|
1211cfcdbd | |
|
|
2560945192 | |
|
|
65ee1cf1ba | |
|
|
f553b46b7b | |
|
|
838a198804 | |
|
|
1ab8622ca6 | |
|
|
6af0532185 | |
|
|
f99c25cede | |
|
|
027ec15c4b | |
|
|
0e8eb02885 | |
|
|
e037e0e11c | |
|
|
d4c00e552b | |
|
|
8d9c9ab8f8 | |
|
|
4bd07e816b | |
|
|
dc662276c2 | |
|
|
e295ad945b | |
|
|
0eb7cce258 | |
|
|
4d78110ee4 | |
|
|
31b0e4e158 | |
|
|
381dcefe8a | |
|
|
85c1f6f3c0 | |
|
|
b4f2b37c9f | |
|
|
74a3a8ad6d | |
|
|
6a19842ad3 | |
|
|
ef5032d2b8 | |
|
|
1f5ba130fb | |
|
|
a0fe9edf59 | |
|
|
c5c65c2a46 | |
|
|
4c97b8655b | |
|
|
e7197e3d19 | |
|
|
c1ba024d8d | |
|
|
11ad503687 | |
|
|
fe7c7e0146 | |
|
|
d00aec5944 | |
|
|
6cd3e13c39 | |
|
|
bf15fb25ad | |
|
|
c851677c61 | |
|
|
b7ab7d8330 | |
|
|
f0adb30707 | |
|
|
4ea396320b | |
|
|
06935d4d0d | |
|
|
301c273a6f |
|
|
@ -0,0 +1,153 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# ============================================================
|
||||||
|
# 清理没有关联机场的大疆无人机
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "清理没有关联机场的大疆无人机"
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
|
# 数据库配置
|
||||||
|
DB_CONTAINER="ruoyi-mysql"
|
||||||
|
DB_USER="root"
|
||||||
|
DB_PASSWORD="password"
|
||||||
|
DB_NAME="ry-cloud"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "第一步:查询所有大疆无人机(用于确认)"
|
||||||
|
echo "=========================================="
|
||||||
|
docker exec ${DB_CONTAINER} mysql -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} -e "
|
||||||
|
SELECT
|
||||||
|
a.aircraft_id,
|
||||||
|
a.aircraft_name,
|
||||||
|
d.device_manufacturer,
|
||||||
|
d.device_sn
|
||||||
|
FROM device_aircraft a
|
||||||
|
LEFT JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
ORDER BY a.aircraft_id;
|
||||||
|
"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "第二步:查询没有关联机场的大疆无人机"
|
||||||
|
echo "=========================================="
|
||||||
|
docker exec ${DB_CONTAINER} mysql -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} -e "
|
||||||
|
SELECT
|
||||||
|
a.aircraft_id,
|
||||||
|
a.aircraft_name,
|
||||||
|
d.device_manufacturer,
|
||||||
|
d.device_sn,
|
||||||
|
d.iot_device_id
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
LEFT JOIN device_dock_aircraft da ON a.aircraft_id = da.aircraft_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
AND da.id IS NULL
|
||||||
|
ORDER BY a.aircraft_id;
|
||||||
|
"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo "即将删除以上无人机记录"
|
||||||
|
echo "请确认是否继续?(y/n)"
|
||||||
|
read -r confirm
|
||||||
|
|
||||||
|
if [[ ! $confirm =~ ^[Yy]$ ]]; then
|
||||||
|
echo "操作已取消"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "第三步:删除无人机挂载关联表中的记录"
|
||||||
|
echo "=========================================="
|
||||||
|
docker exec ${DB_CONTAINER} mysql -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} -e "
|
||||||
|
DELETE FROM device_aircraft_payload
|
||||||
|
WHERE aircraft_id IN (
|
||||||
|
SELECT a.aircraft_id
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
LEFT JOIN device_dock_aircraft da ON a.aircraft_id = da.aircraft_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
AND da.id IS NULL
|
||||||
|
);
|
||||||
|
"
|
||||||
|
|
||||||
|
echo "无人机挂载关联记录删除完成"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "第四步:删除机场无人机关联表中的记录"
|
||||||
|
echo "=========================================="
|
||||||
|
docker exec ${DB_CONTAINER} mysql -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} -e "
|
||||||
|
DELETE FROM device_dock_aircraft
|
||||||
|
WHERE aircraft_id IN (
|
||||||
|
SELECT a.aircraft_id
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
LEFT JOIN device_dock_aircraft da ON a.aircraft_id = da.aircraft_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
AND da.id IS NULL
|
||||||
|
);
|
||||||
|
"
|
||||||
|
|
||||||
|
echo "机场无人机关联记录删除完成"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "第五步:删除无人机表中的记录"
|
||||||
|
echo "=========================================="
|
||||||
|
docker exec ${DB_CONTAINER} mysql -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} -e "
|
||||||
|
DELETE FROM device_aircraft
|
||||||
|
WHERE aircraft_id IN (
|
||||||
|
SELECT temp.aircraft_id
|
||||||
|
FROM (
|
||||||
|
SELECT a.aircraft_id
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
LEFT JOIN device_dock_aircraft da ON a.aircraft_id = da.aircraft_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
AND da.id IS NULL
|
||||||
|
) AS temp
|
||||||
|
);
|
||||||
|
"
|
||||||
|
|
||||||
|
echo "无人机记录删除完成"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "第六步:验证删除结果"
|
||||||
|
echo "=========================================="
|
||||||
|
docker exec ${DB_CONTAINER} mysql -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} -e "
|
||||||
|
SELECT
|
||||||
|
a.aircraft_id,
|
||||||
|
a.aircraft_name,
|
||||||
|
d.device_manufacturer,
|
||||||
|
d.device_sn
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
ORDER BY a.aircraft_id;
|
||||||
|
"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "统计验证:"
|
||||||
|
echo "=========================================="
|
||||||
|
docker exec ${DB_CONTAINER} mysql -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} -e "
|
||||||
|
SELECT
|
||||||
|
'大疆无人机总数' AS statistic_name,
|
||||||
|
COUNT(*) AS count
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
'大疆机场总数' AS statistic_name,
|
||||||
|
COUNT(*) AS count
|
||||||
|
FROM device_dock dock
|
||||||
|
INNER JOIN device_device d ON dock.device_id = d.device_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang';
|
||||||
|
"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo "清理完成"
|
||||||
|
echo "=========================================="
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
-- ============================================================
|
||||||
|
-- 清理没有关联机场的大疆无人机
|
||||||
|
-- ============================================================
|
||||||
|
-- 问题:大疆的机场是7个,无人机是10个,有3个无人机没有关联机场
|
||||||
|
-- 解决方案:删除没有关联机场的大疆无人机记录
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- 第一步:查询所有大疆厂商的无人机(用于确认)
|
||||||
|
SELECT
|
||||||
|
a.aircraft_id,
|
||||||
|
a.aircraft_name,
|
||||||
|
d.device_manufacturer,
|
||||||
|
d.device_sn
|
||||||
|
FROM device_aircraft a
|
||||||
|
LEFT JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
ORDER BY a.aircraft_id;
|
||||||
|
|
||||||
|
-- 第二步:查询没有关联机场的大疆无人机
|
||||||
|
SELECT
|
||||||
|
a.aircraft_id,
|
||||||
|
a.aircraft_name,
|
||||||
|
d.device_manufacturer,
|
||||||
|
d.device_sn,
|
||||||
|
d.iot_device_id
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
LEFT JOIN device_dock_aircraft da ON a.aircraft_id = da.aircraft_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
AND da.id IS NULL
|
||||||
|
ORDER BY a.aircraft_id;
|
||||||
|
|
||||||
|
-- 第三步:确认删除前,再次检查(谨慎操作)
|
||||||
|
-- 执行此查询后,请确认这些无人机确实需要删除
|
||||||
|
SELECT
|
||||||
|
a.aircraft_id,
|
||||||
|
a.aircraft_name,
|
||||||
|
d.device_manufacturer,
|
||||||
|
d.device_sn,
|
||||||
|
d.iot_device_id,
|
||||||
|
'将被删除' AS action
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
LEFT JOIN device_dock_aircraft da ON a.aircraft_id = da.aircraft_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
AND da.id IS NULL;
|
||||||
|
|
||||||
|
-- 第四步:删除没有关联机场的大疆无人机(谨慎操作!)
|
||||||
|
-- 删除顺序:
|
||||||
|
-- 1. 先删除无人机挂载关联表中的记录
|
||||||
|
-- 2. 再删除机场无人机关联表中的记录
|
||||||
|
-- 3. 最后删除无人机表中的记录
|
||||||
|
|
||||||
|
-- 4.1 删除无人机挂载关联表中的记录
|
||||||
|
DELETE FROM device_aircraft_payload
|
||||||
|
WHERE aircraft_id IN (
|
||||||
|
SELECT a.aircraft_id
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
LEFT JOIN device_dock_aircraft da ON a.aircraft_id = da.aircraft_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
AND da.id IS NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 4.2 删除机场无人机关联表中的记录(如果有)
|
||||||
|
DELETE FROM device_dock_aircraft
|
||||||
|
WHERE aircraft_id IN (
|
||||||
|
SELECT a.aircraft_id
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
LEFT JOIN device_dock_aircraft da ON a.aircraft_id = da.aircraft_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
AND da.id IS NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 4.3 删除无人机表中的记录
|
||||||
|
DELETE FROM device_aircraft
|
||||||
|
WHERE aircraft_id IN (
|
||||||
|
SELECT temp.aircraft_id
|
||||||
|
FROM (
|
||||||
|
SELECT a.aircraft_id
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
LEFT JOIN device_dock_aircraft da ON a.aircraft_id = da.aircraft_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
AND da.id IS NULL
|
||||||
|
) AS temp
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 第五步:验证删除结果
|
||||||
|
SELECT
|
||||||
|
a.aircraft_id,
|
||||||
|
a.aircraft_name,
|
||||||
|
d.device_manufacturer,
|
||||||
|
d.device_sn
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
ORDER BY a.aircraft_id;
|
||||||
|
|
||||||
|
-- 统计验证
|
||||||
|
SELECT
|
||||||
|
'大疆无人机总数' AS statistic_name,
|
||||||
|
COUNT(*) AS count
|
||||||
|
FROM device_aircraft a
|
||||||
|
INNER JOIN device_device d ON a.device_id = d.device_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang'
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
'大疆机场总数' AS statistic_name,
|
||||||
|
COUNT(*) AS count
|
||||||
|
FROM device_dock dock
|
||||||
|
INNER JOIN device_device d ON dock.device_id = d.device_id
|
||||||
|
WHERE d.device_manufacturer = 'dajiang';
|
||||||
|
|
@ -12,6 +12,8 @@ main_repository:
|
||||||
monitor:
|
monitor:
|
||||||
poll_interval: 10 # 轮询间隔(秒)
|
poll_interval: 10 # 轮询间隔(秒)
|
||||||
enabled_repos: [] # 空数组表示监听所有仓库,或指定具体仓库名称列表
|
enabled_repos: [] # 空数组表示监听所有仓库,或指定具体仓库名称列表
|
||||||
|
watch_tags: false # 是否监听 tag 变化(打 tag 时触发部署)
|
||||||
|
tag_pattern: "v*" # 监听的 tag 模式,支持通配符(如 v*、release-*)
|
||||||
|
|
||||||
# 部署配置
|
# 部署配置
|
||||||
deploy:
|
deploy:
|
||||||
|
|
@ -22,6 +24,21 @@ logging:
|
||||||
file: .devops/logs/devops.log
|
file: .devops/logs/devops.log
|
||||||
max_size: 10485760 # 10MB
|
max_size: 10485760 # 10MB
|
||||||
|
|
||||||
|
# 钉钉通知配置
|
||||||
|
dingtalk:
|
||||||
|
enabled: true # 是否启用钉钉通知
|
||||||
|
access_token: fccb17a6c74ca862d7994630562d9d3d5be7b60d012d53dce32c64c566b9a3de
|
||||||
|
secret: SEC54a73636473f324b8f77741ee41ee278d22eba4af898bba739c11183d851c8b0
|
||||||
|
|
||||||
|
# 数据库配置(用于数据库管理页面)
|
||||||
|
database:
|
||||||
|
container_name: ruoyi-mysql # MySQL 容器名称
|
||||||
|
host: localhost
|
||||||
|
port: 3306
|
||||||
|
user: root
|
||||||
|
password: password
|
||||||
|
charset: utf8mb4
|
||||||
|
|
||||||
# 基础设施服务配置(只部署一次)
|
# 基础设施服务配置(只部署一次)
|
||||||
infrastructure:
|
infrastructure:
|
||||||
- name: ruoyi-mysql
|
- name: ruoyi-mysql
|
||||||
|
|
@ -30,17 +47,38 @@ infrastructure:
|
||||||
- cp sql/ry_20250523.sql docker/mysql/db/
|
- cp sql/ry_20250523.sql docker/mysql/db/
|
||||||
- cp sql/ry_config_20250902.sql docker/mysql/db/
|
- cp sql/ry_config_20250902.sql docker/mysql/db/
|
||||||
- cp sql/wvp.sql docker/mysql/db/
|
- cp sql/wvp.sql docker/mysql/db/
|
||||||
- cp sql/privileges.sql docker/mysql/db/
|
|
||||||
wait_time: 30 # MySQL 需要更长时间初始化
|
wait_time: 30 # MySQL 需要更长时间初始化
|
||||||
|
|
||||||
- name: ruoyi-redis
|
- name: ruoyi-redis
|
||||||
docker_service: ruoyi-redis
|
docker_service: ruoyi-redis
|
||||||
wait_time: 10 # Redis 启动较快
|
wait_time: 10 # Redis 启动较快
|
||||||
|
|
||||||
|
- name: ruoyi-minio
|
||||||
|
docker_service: ruoyi-minio
|
||||||
|
wait_time: 15 # MinIO 对象存储服务
|
||||||
|
|
||||||
- name: ruoyi-nacos
|
- name: ruoyi-nacos
|
||||||
docker_service: ruoyi-nacos
|
docker_service: ruoyi-nacos
|
||||||
wait_time: 20 # Nacos 需要等待 MySQL 就绪
|
wait_time: 20 # Nacos 需要等待 MySQL 就绪
|
||||||
|
|
||||||
|
- name: zlmediakit
|
||||||
|
docker_service: zlmediakit
|
||||||
|
wait_time: 10 # 流媒体服务器启动较快
|
||||||
|
|
||||||
|
- name: wvp-pro
|
||||||
|
docker_service: wvp-pro
|
||||||
|
pre_deploy_commands:
|
||||||
|
- cd wvpjar && mvn clean package -DskipTests
|
||||||
|
- cp wvpjar/target/wvp-pro-*.jar docker/wvp/wvpjar/jar/
|
||||||
|
wait_time: 30 # WVP 后端需要等待 MySQL、Redis 和 zlmediakit
|
||||||
|
|
||||||
|
- name: wvp-web
|
||||||
|
docker_service: wvp-web
|
||||||
|
pre_deploy_commands:
|
||||||
|
- cd wvpweb && npm install && npm run build:prod
|
||||||
|
- cp -r wvpweb/dist docker/wvp/web/html/dist
|
||||||
|
wait_time: 10 # Nginx 启动较快
|
||||||
|
|
||||||
# Git 仓库配置
|
# Git 仓库配置
|
||||||
repositories:
|
repositories:
|
||||||
# 认证服务
|
# 认证服务
|
||||||
|
|
@ -49,7 +87,7 @@ repositories:
|
||||||
path: ruoyi-auth
|
path: ruoyi-auth
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/auth/jar
|
docker_path: docker/ruoyi/auth/jar
|
||||||
docker_service: ruoyi-auth
|
docker_service: ruoyi-auth
|
||||||
|
|
@ -60,7 +98,7 @@ repositories:
|
||||||
path: ruoyi-gateway
|
path: ruoyi-gateway
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/gateway/jar
|
docker_path: docker/ruoyi/gateway/jar
|
||||||
docker_service: ruoyi-gateway
|
docker_service: ruoyi-gateway
|
||||||
|
|
@ -88,13 +126,24 @@ repositories:
|
||||||
docker_path: docker/a_th_web/html/dist
|
docker_path: docker/a_th_web/html/dist
|
||||||
docker_service: ruoyi-hyf
|
docker_service: ruoyi-hyf
|
||||||
|
|
||||||
|
- name: ruoyi-hxf
|
||||||
|
url: http://th.local.t-aaron.com:13000/THENG/a_th_web.git
|
||||||
|
path: a_th_web
|
||||||
|
type: nodejs
|
||||||
|
build_commands:
|
||||||
|
- pnpm install
|
||||||
|
- pnpm run build-prod:hxf
|
||||||
|
artifact_path: apps/tuoheng_hxf_web/dist
|
||||||
|
docker_path: docker/b_th_web/html/dist
|
||||||
|
docker_service: ruoyi-hxf
|
||||||
|
|
||||||
# 系统服务
|
# 系统服务
|
||||||
- name: ruoyi-system
|
- name: ruoyi-system
|
||||||
url: http://th.local.t-aaron.com:13000/THENG/a-ruoyi-system.git
|
url: http://th.local.t-aaron.com:13000/THENG/a-ruoyi-system.git
|
||||||
path: ruoyi-modules/ruoyi-system
|
path: ruoyi-modules/ruoyi-system
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/modules/system/jar
|
docker_path: docker/ruoyi/modules/system/jar
|
||||||
docker_service: ruoyi-modules-system
|
docker_service: ruoyi-modules-system
|
||||||
|
|
@ -105,7 +154,7 @@ repositories:
|
||||||
path: ruoyi-modules/ruoyi-file
|
path: ruoyi-modules/ruoyi-file
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/modules/file/jar
|
docker_path: docker/ruoyi/modules/file/jar
|
||||||
docker_service: ruoyi-modules-file
|
docker_service: ruoyi-modules-file
|
||||||
|
|
@ -116,7 +165,7 @@ repositories:
|
||||||
path: ruoyi-modules/ruoyi-gen
|
path: ruoyi-modules/ruoyi-gen
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/modules/gen/jar
|
docker_path: docker/ruoyi/modules/gen/jar
|
||||||
docker_service: ruoyi-modules-gen
|
docker_service: ruoyi-modules-gen
|
||||||
|
|
@ -127,7 +176,7 @@ repositories:
|
||||||
path: ruoyi-modules/ruoyi-job
|
path: ruoyi-modules/ruoyi-job
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/modules/job/jar
|
docker_path: docker/ruoyi/modules/job/jar
|
||||||
docker_service: ruoyi-modules-job
|
docker_service: ruoyi-modules-job
|
||||||
|
|
@ -138,7 +187,7 @@ repositories:
|
||||||
path: ruoyi-visual/ruoyi-monitor
|
path: ruoyi-visual/ruoyi-monitor
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/visual/monitor/jar
|
docker_path: docker/ruoyi/visual/monitor/jar
|
||||||
docker_service: ruoyi-visual-monitor
|
docker_service: ruoyi-visual-monitor
|
||||||
|
|
@ -149,7 +198,7 @@ repositories:
|
||||||
path: ruoyi-modules/tuoheng-device
|
path: ruoyi-modules/tuoheng-device
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/modules/device/jar
|
docker_path: docker/ruoyi/modules/device/jar
|
||||||
docker_service: tuoheng-modules-device
|
docker_service: tuoheng-modules-device
|
||||||
|
|
@ -160,7 +209,7 @@ repositories:
|
||||||
path: ruoyi-modules/tuoheng-approval
|
path: ruoyi-modules/tuoheng-approval
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/modules/approval/jar
|
docker_path: docker/ruoyi/modules/approval/jar
|
||||||
docker_service: tuoheng-modules-approval
|
docker_service: tuoheng-modules-approval
|
||||||
|
|
@ -171,7 +220,7 @@ repositories:
|
||||||
path: ruoyi-modules/tuoheng-airline
|
path: ruoyi-modules/tuoheng-airline
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/modules/airline/jar
|
docker_path: docker/ruoyi/modules/airline/jar
|
||||||
docker_service: tuoheng-modules-airline
|
docker_service: tuoheng-modules-airline
|
||||||
|
|
@ -182,7 +231,7 @@ repositories:
|
||||||
path: ruoyi-modules/tuoheng-task
|
path: ruoyi-modules/tuoheng-task
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/modules/task/jar
|
docker_path: docker/ruoyi/modules/task/jar
|
||||||
docker_service: tuoheng-modules-task
|
docker_service: tuoheng-modules-task
|
||||||
|
|
@ -193,7 +242,7 @@ repositories:
|
||||||
path: ruoyi-modules/tuoheng-fms
|
path: ruoyi-modules/tuoheng-fms
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/modules/fms/jar
|
docker_path: docker/ruoyi/modules/fms/jar
|
||||||
docker_service: tuoheng-modules-fms
|
docker_service: tuoheng-modules-fms
|
||||||
|
|
@ -204,7 +253,41 @@ repositories:
|
||||||
path: ruoyi-modules/tuoheng-media
|
path: ruoyi-modules/tuoheng-media
|
||||||
type: java
|
type: java
|
||||||
build_commands:
|
build_commands:
|
||||||
- mvn clean package -DskipTests
|
- export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
artifact_path: target/*.jar
|
artifact_path: target/*.jar
|
||||||
docker_path: docker/ruoyi/modules/media/jar
|
docker_path: docker/ruoyi/modules/media/jar
|
||||||
docker_service: tuoheng-modules-media
|
docker_service: tuoheng-modules-media
|
||||||
|
|
||||||
|
# WVP 后端服务
|
||||||
|
- name: wvp-pro
|
||||||
|
url: http://th.local.t-aaron.com:13000/THENG/a-wvp-java.git
|
||||||
|
path: wvpjar
|
||||||
|
type: java
|
||||||
|
build_commands:
|
||||||
|
- cd wvpjar && export JAVA_HOME=/data/jdk/jdk17 && export PATH=$JAVA_HOME/bin:$PATH && mvn clean package -DskipTests -Dmaven.compiler.source=17 -Dmaven.compiler.target=17
|
||||||
|
artifact_path: target/*.jar
|
||||||
|
docker_path: docker/wvp/wvpjar/jar
|
||||||
|
docker_service: wvp-pro
|
||||||
|
|
||||||
|
# WVP 前端服务
|
||||||
|
- name: wvp-web
|
||||||
|
url: http://th.local.t-aaron.com:13000/THENG/a-wvp-web.git
|
||||||
|
path: wvpweb
|
||||||
|
type: nodejs
|
||||||
|
build_commands:
|
||||||
|
- npm install
|
||||||
|
- npm run build:prod
|
||||||
|
artifact_path: dist
|
||||||
|
docker_path: docker/wvp/web/html/dist
|
||||||
|
docker_service: wvp-web
|
||||||
|
|
||||||
|
# HYF 后端服务
|
||||||
|
- name: hyf-backend
|
||||||
|
url: http://th.local.t-aaron.com:13000/THENG/hyf-backend.git
|
||||||
|
path: hyf-backend
|
||||||
|
type: python
|
||||||
|
build_commands: [] # Python 项目不需要构建,直接复制源码
|
||||||
|
artifact_path: . # 复制整个项目目录
|
||||||
|
docker_path: docker/hyf_backend/src
|
||||||
|
docker_service: hyf-backend
|
||||||
|
docker_build: true # 需要重新构建镜像
|
||||||
|
|
|
||||||
2021
.devops/monitor.py
2021
.devops/monitor.py
File diff suppressed because it is too large
Load Diff
|
|
@ -38,9 +38,30 @@ echo "✓ Python3 已安装: $(python3 --version)"
|
||||||
# 4. 检查 Python 依赖
|
# 4. 检查 Python 依赖
|
||||||
echo ""
|
echo ""
|
||||||
echo "[步骤 4/7] 检查 Python 依赖..."
|
echo "[步骤 4/7] 检查 Python 依赖..."
|
||||||
|
|
||||||
|
# 检查并安装 pip
|
||||||
|
if ! python3 -m pip --version &> /dev/null; then
|
||||||
|
echo "pip 未安装,正在安装 pip..."
|
||||||
|
curl -sS https://bootstrap.pypa.io/get-pip.py | python3 - --user --break-system-packages 2>/dev/null || \
|
||||||
|
curl -sS https://bootstrap.pypa.io/get-pip.py | python3 - --user
|
||||||
|
echo "✓ pip 安装完成"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 使用 python3 -m pip 代替 pip3,添加 --break-system-packages 标志
|
||||||
if ! python3 -c "import yaml" 2>/dev/null; then
|
if ! python3 -c "import yaml" 2>/dev/null; then
|
||||||
echo "安装 PyYAML..."
|
echo "安装 PyYAML..."
|
||||||
pip3 install --user PyYAML
|
python3 -m pip install --user --break-system-packages PyYAML 2>/dev/null || \
|
||||||
|
python3 -m pip install --user PyYAML
|
||||||
|
fi
|
||||||
|
if ! python3 -c "import flask" 2>/dev/null; then
|
||||||
|
echo "安装 Flask..."
|
||||||
|
python3 -m pip install --user --break-system-packages flask 2>/dev/null || \
|
||||||
|
python3 -m pip install --user flask
|
||||||
|
fi
|
||||||
|
if ! python3 -c "import pymysql" 2>/dev/null; then
|
||||||
|
echo "安装 PyMySQL(用于数据库管理功能)..."
|
||||||
|
python3 -m pip install --user --break-system-packages pymysql 2>/dev/null || \
|
||||||
|
python3 -m pip install --user pymysql
|
||||||
fi
|
fi
|
||||||
echo "✓ Python 依赖检查完成"
|
echo "✓ Python 依赖检查完成"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,255 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
钉钉 Webhook 通知模块
|
||||||
|
用于发送构建和部署通知到钉钉群
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
import hmac
|
||||||
|
import hashlib
|
||||||
|
import base64
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class DingTalkNotifier:
|
||||||
|
"""钉钉通知器"""
|
||||||
|
|
||||||
|
def __init__(self, access_token, secret=None):
|
||||||
|
"""
|
||||||
|
初始化钉钉通知器
|
||||||
|
|
||||||
|
Args:
|
||||||
|
access_token: 钉钉机器人的 access_token
|
||||||
|
secret: 钉钉机器人的加签密钥(可选)
|
||||||
|
"""
|
||||||
|
self.access_token = access_token
|
||||||
|
self.secret = secret
|
||||||
|
self.base_url = "https://oapi.dingtalk.com/robot/send"
|
||||||
|
|
||||||
|
def _generate_sign(self, timestamp):
|
||||||
|
"""
|
||||||
|
生成钉钉加签
|
||||||
|
|
||||||
|
Args:
|
||||||
|
timestamp: 当前时间戳(毫秒)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
签名字符串
|
||||||
|
"""
|
||||||
|
if not self.secret:
|
||||||
|
return None
|
||||||
|
|
||||||
|
string_to_sign = f'{timestamp}\n{self.secret}'
|
||||||
|
string_to_sign_enc = string_to_sign.encode('utf-8')
|
||||||
|
secret_enc = self.secret.encode('utf-8')
|
||||||
|
|
||||||
|
hmac_code = hmac.new(
|
||||||
|
secret_enc,
|
||||||
|
string_to_sign_enc,
|
||||||
|
digestmod=hashlib.sha256
|
||||||
|
).digest()
|
||||||
|
|
||||||
|
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
|
||||||
|
return sign
|
||||||
|
|
||||||
|
def _build_url(self):
|
||||||
|
"""
|
||||||
|
构建完整的 webhook URL
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
完整的 URL 字符串
|
||||||
|
"""
|
||||||
|
url = f"{self.base_url}?access_token={self.access_token}"
|
||||||
|
|
||||||
|
if self.secret:
|
||||||
|
timestamp = str(round(time.time() * 1000))
|
||||||
|
sign = self._generate_sign(timestamp)
|
||||||
|
url += f"×tamp={timestamp}&sign={sign}"
|
||||||
|
|
||||||
|
return url
|
||||||
|
|
||||||
|
def send_text(self, content, at_mobiles=None, at_all=False):
|
||||||
|
"""
|
||||||
|
发送文本消息
|
||||||
|
|
||||||
|
Args:
|
||||||
|
content: 消息内容
|
||||||
|
at_mobiles: @的手机号列表
|
||||||
|
at_all: 是否@所有人
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
发送结果 (True/False)
|
||||||
|
"""
|
||||||
|
data = {
|
||||||
|
"msgtype": "text",
|
||||||
|
"text": {
|
||||||
|
"content": content
|
||||||
|
},
|
||||||
|
"at": {
|
||||||
|
"atMobiles": at_mobiles or [],
|
||||||
|
"isAtAll": at_all
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self._send_request(data)
|
||||||
|
|
||||||
|
def send_build_success(self, repo_name, branch, commit_hash, duration):
|
||||||
|
"""
|
||||||
|
发送构建成功通知
|
||||||
|
|
||||||
|
Args:
|
||||||
|
repo_name: 仓库名称
|
||||||
|
branch: 分支名称
|
||||||
|
commit_hash: 提交哈希
|
||||||
|
duration: 构建耗时(秒)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
发送结果 (True/False)
|
||||||
|
"""
|
||||||
|
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
title = f"✅ 构建成功 - {repo_name}"
|
||||||
|
text = f"""### ✅ 构建成功
|
||||||
|
|
||||||
|
**仓库**: {repo_name}
|
||||||
|
**分支**: {branch}
|
||||||
|
**提交**: {commit_hash[:8]}
|
||||||
|
**耗时**: {duration:.1f} 秒
|
||||||
|
**时间**: {now}
|
||||||
|
|
||||||
|
---
|
||||||
|
构建和部署已完成!
|
||||||
|
"""
|
||||||
|
return self.send_markdown(title, text)
|
||||||
|
|
||||||
|
def send_build_failure(self, repo_name, branch, commit_hash, error_msg, at_all=False):
|
||||||
|
"""
|
||||||
|
发送构建失败通知
|
||||||
|
|
||||||
|
Args:
|
||||||
|
repo_name: 仓库名称
|
||||||
|
branch: 分支名称
|
||||||
|
commit_hash: 提交哈希
|
||||||
|
error_msg: 错误信息
|
||||||
|
at_all: 是否@所有人
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
发送结果 (True/False)
|
||||||
|
"""
|
||||||
|
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
title = f"❌ 构建失败 - {repo_name}"
|
||||||
|
# 限制错误信息长度
|
||||||
|
error_display = error_msg[:500] if len(error_msg) > 500 else error_msg
|
||||||
|
text = f"""### ❌ 构建失败
|
||||||
|
|
||||||
|
**仓库**: {repo_name}
|
||||||
|
**分支**: {branch}
|
||||||
|
**提交**: {commit_hash[:8]}
|
||||||
|
**时间**: {now}
|
||||||
|
|
||||||
|
**错误信息**:
|
||||||
|
```
|
||||||
|
{error_display}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
请检查日志并修复问题!
|
||||||
|
"""
|
||||||
|
return self.send_markdown(title, text, at_all=at_all)
|
||||||
|
|
||||||
|
def send_build_start(self, repo_name, branch, commit_hash, commit_message=None, server_ip=None):
|
||||||
|
"""
|
||||||
|
发送构建开始通知
|
||||||
|
|
||||||
|
Args:
|
||||||
|
repo_name: 仓库名称
|
||||||
|
branch: 分支名称
|
||||||
|
commit_hash: 提交哈希
|
||||||
|
commit_message: 提交消息(可选)
|
||||||
|
server_ip: 服务器IP(可选)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
发送结果 (True/False)
|
||||||
|
"""
|
||||||
|
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
title = f"🚀 构建开始 - {repo_name}"
|
||||||
|
|
||||||
|
# 构建消息内容
|
||||||
|
text = f"""### 🚀 构建开始
|
||||||
|
|
||||||
|
**仓库**: {repo_name}
|
||||||
|
**分支**: {branch}
|
||||||
|
**提交**: {commit_hash[:8]}"""
|
||||||
|
|
||||||
|
if commit_message:
|
||||||
|
text += f"\n**消息**: {commit_message}"
|
||||||
|
|
||||||
|
if server_ip:
|
||||||
|
text += f"\n**服务器**: {server_ip}"
|
||||||
|
|
||||||
|
text += f"""
|
||||||
|
**时间**: {now}
|
||||||
|
|
||||||
|
---
|
||||||
|
构建任务已启动,请稍候...
|
||||||
|
"""
|
||||||
|
return self.send_markdown(title, text)
|
||||||
|
|
||||||
|
def _send_request(self, data):
|
||||||
|
"""
|
||||||
|
发送 HTTP 请求到钉钉 webhook
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data: 请求数据字典
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
发送结果 (True/False)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
url = self._build_url()
|
||||||
|
headers = {'Content-Type': 'application/json'}
|
||||||
|
json_data = json.dumps(data).encode('utf-8')
|
||||||
|
|
||||||
|
req = urllib.request.Request(url, data=json_data, headers=headers)
|
||||||
|
response = urllib.request.urlopen(req, timeout=10)
|
||||||
|
result = json.loads(response.read().decode('utf-8'))
|
||||||
|
|
||||||
|
if result.get('errcode') == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"钉钉通知发送失败: {result.get('errmsg')}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"钉钉通知发送异常: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def send_markdown(self, title, text, at_mobiles=None, at_all=False):
|
||||||
|
"""
|
||||||
|
发送 Markdown 消息
|
||||||
|
|
||||||
|
Args:
|
||||||
|
title: 消息标题
|
||||||
|
text: Markdown 格式的消息内容
|
||||||
|
at_mobiles: @的手机号列表
|
||||||
|
at_all: 是否@所有人
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
发送结果 (True/False)
|
||||||
|
"""
|
||||||
|
data = {
|
||||||
|
"msgtype": "markdown",
|
||||||
|
"markdown": {
|
||||||
|
"title": title,
|
||||||
|
"text": text
|
||||||
|
},
|
||||||
|
"at": {
|
||||||
|
"atMobiles": at_mobiles or [],
|
||||||
|
"isAtAll": at_all
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self._send_request(data)
|
||||||
|
|
@ -94,6 +94,11 @@ class Logger:
|
||||||
"""输出警告日志"""
|
"""输出警告日志"""
|
||||||
cls._write_log('WARN', message)
|
cls._write_log('WARN', message)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def warning(cls, message):
|
||||||
|
"""输出警告日志(warn 的别名)"""
|
||||||
|
cls._write_log('WARN', message)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def debug(cls, message):
|
def debug(cls, message):
|
||||||
"""输出调试日志"""
|
"""输出调试日志"""
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ def run_maven(work_dir, maven_commands, source_path, target_dir):
|
||||||
target_dir: 复制的目标目录
|
target_dir: 复制的目标目录
|
||||||
|
|
||||||
返回:
|
返回:
|
||||||
bool: 成功返回 True,失败返回 False
|
tuple: (success: bool, error_message: str) 成功返回 (True, ""),失败返回 (False, "错误信息")
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 转换为绝对路径
|
# 转换为绝对路径
|
||||||
|
|
@ -36,13 +36,15 @@ def run_maven(work_dir, maven_commands, source_path, target_dir):
|
||||||
|
|
||||||
# 检查目录是否存在
|
# 检查目录是否存在
|
||||||
if not work_dir.exists():
|
if not work_dir.exists():
|
||||||
Logger.error(f"目录不存在: {work_dir}")
|
error_msg = f"目录不存在: {work_dir}"
|
||||||
return False
|
Logger.error(error_msg)
|
||||||
|
return False, error_msg
|
||||||
|
|
||||||
# 执行 Maven 命令
|
# 执行 Maven 命令
|
||||||
if not Logger.run_command(maven_commands, work_dir):
|
if not Logger.run_command(maven_commands, work_dir):
|
||||||
Logger.error("Maven 打包失败")
|
error_msg = "Maven 编译失败,请查看日志获取详细错误信息"
|
||||||
return False
|
Logger.error(error_msg)
|
||||||
|
return False, error_msg
|
||||||
|
|
||||||
Logger.info("Maven 打包成功")
|
Logger.info("Maven 打包成功")
|
||||||
|
|
||||||
|
|
@ -61,8 +63,9 @@ def run_maven(work_dir, maven_commands, source_path, target_dir):
|
||||||
# 复制文件
|
# 复制文件
|
||||||
files = glob.glob(str(source_full_path))
|
files = glob.glob(str(source_full_path))
|
||||||
if not files:
|
if not files:
|
||||||
Logger.error(f"未找到构建产物: {source_full_path}")
|
error_msg = f"未找到构建产物: {source_full_path}"
|
||||||
return False
|
Logger.error(error_msg)
|
||||||
|
return False, error_msg
|
||||||
|
|
||||||
for file in files:
|
for file in files:
|
||||||
file_path = Path(file)
|
file_path = Path(file)
|
||||||
|
|
@ -74,8 +77,9 @@ def run_maven(work_dir, maven_commands, source_path, target_dir):
|
||||||
|
|
||||||
Logger.info("构建产物复制成功")
|
Logger.info("构建产物复制成功")
|
||||||
Logger.info("Maven 打包和复制完成")
|
Logger.info("Maven 打包和复制完成")
|
||||||
return True
|
return True, ""
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Logger.error(f"Maven 打包异常: {e}")
|
error_msg = f"Maven 打包异常: {str(e)}"
|
||||||
return False
|
Logger.error(error_msg)
|
||||||
|
return False, error_msg
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ def run_npm(work_dir, npm_commands, source_dir, target_dir):
|
||||||
target_dir: 复制的目标目录
|
target_dir: 复制的目标目录
|
||||||
|
|
||||||
返回:
|
返回:
|
||||||
bool: 成功返回 True,失败返回 False
|
tuple: (success: bool, error_message: str) 成功返回 (True, ""),失败返回 (False, "错误信息")
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 转换为绝对路径
|
# 转换为绝对路径
|
||||||
|
|
@ -36,13 +36,15 @@ def run_npm(work_dir, npm_commands, source_dir, target_dir):
|
||||||
|
|
||||||
# 检查目录是否存在
|
# 检查目录是否存在
|
||||||
if not work_dir.exists():
|
if not work_dir.exists():
|
||||||
Logger.error(f"目录不存在: {work_dir}")
|
error_msg = f"目录不存在: {work_dir}"
|
||||||
return False
|
Logger.error(error_msg)
|
||||||
|
return False, error_msg
|
||||||
|
|
||||||
# 执行 NPM 命令
|
# 执行 NPM 命令
|
||||||
if not Logger.run_command(npm_commands, work_dir):
|
if not Logger.run_command(npm_commands, work_dir):
|
||||||
Logger.error("NPM 打包失败")
|
error_msg = "NPM/PNPM 编译失败,请查看日志获取详细错误信息"
|
||||||
return False
|
Logger.error(error_msg)
|
||||||
|
return False, error_msg
|
||||||
|
|
||||||
Logger.info("NPM 打包成功")
|
Logger.info("NPM 打包成功")
|
||||||
|
|
||||||
|
|
@ -57,8 +59,9 @@ def run_npm(work_dir, npm_commands, source_dir, target_dir):
|
||||||
|
|
||||||
# 检查源目录是否存在
|
# 检查源目录是否存在
|
||||||
if not source_full_path.exists():
|
if not source_full_path.exists():
|
||||||
Logger.error(f"源目录不存在: {source_full_path}")
|
error_msg = f"源目录不存在: {source_full_path}"
|
||||||
return False
|
Logger.error(error_msg)
|
||||||
|
return False, error_msg
|
||||||
|
|
||||||
# 清空目标目录(保留 .gitkeep)
|
# 清空目标目录(保留 .gitkeep)
|
||||||
target_path = Path(target_dir)
|
target_path = Path(target_dir)
|
||||||
|
|
@ -84,8 +87,9 @@ def run_npm(work_dir, npm_commands, source_dir, target_dir):
|
||||||
|
|
||||||
Logger.info("构建产物复制成功")
|
Logger.info("构建产物复制成功")
|
||||||
Logger.info("NPM 打包和复制完成")
|
Logger.info("NPM 打包和复制完成")
|
||||||
return True
|
return True, ""
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Logger.error(f"NPM 打包异常: {e}")
|
error_msg = f"NPM 打包异常: {str(e)}"
|
||||||
return False
|
Logger.error(error_msg)
|
||||||
|
return False, error_msg
|
||||||
|
|
|
||||||
|
|
@ -44,12 +44,20 @@ if [ -z "$VIRTUAL_ENV" ]; then
|
||||||
echo "警告: 未找到 PyYAML,尝试安装..."
|
echo "警告: 未找到 PyYAML,尝试安装..."
|
||||||
pip3 install --user PyYAML || echo "请手动安装: pip3 install --user PyYAML"
|
pip3 install --user PyYAML || echo "请手动安装: pip3 install --user PyYAML"
|
||||||
fi
|
fi
|
||||||
|
if ! python3 -c "import flask" 2>/dev/null; then
|
||||||
|
echo "警告: 未找到 Flask,尝试安装..."
|
||||||
|
pip3 install --user flask || echo "请手动安装: pip3 install --user flask"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo "检测到虚拟环境: $VIRTUAL_ENV"
|
echo "检测到虚拟环境: $VIRTUAL_ENV"
|
||||||
if ! python3 -c "import yaml" 2>/dev/null; then
|
if ! python3 -c "import yaml" 2>/dev/null; then
|
||||||
echo "安装 PyYAML..."
|
echo "安装 PyYAML..."
|
||||||
pip install PyYAML
|
pip install PyYAML
|
||||||
fi
|
fi
|
||||||
|
if ! python3 -c "import flask" 2>/dev/null; then
|
||||||
|
echo "安装 Flask..."
|
||||||
|
pip install flask
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 进入项目根目录
|
# 进入项目根目录
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ nbdist/
|
||||||
*.log
|
*.log
|
||||||
*.xml.versionsBackup
|
*.xml.versionsBackup
|
||||||
*.swp
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
!*/build/*.java
|
!*/build/*.java
|
||||||
!*/build/*.html
|
!*/build/*.html
|
||||||
|
|
@ -56,6 +57,12 @@ docker/minio/data/
|
||||||
docker/minio/config/
|
docker/minio/config/
|
||||||
docker/nginx/html/dist/*
|
docker/nginx/html/dist/*
|
||||||
!docker/nginx/html/dist/.gitkeep
|
!docker/nginx/html/dist/.gitkeep
|
||||||
|
docker/wvp/web/html/dist/*
|
||||||
|
!docker/wvp/web/html/dist/.gitkeep
|
||||||
|
docker/a_th_web/html/dist/*
|
||||||
|
!docker/a_th_web/html/dist/.gitkeep
|
||||||
|
docker/b_th_web/html/dist/*
|
||||||
|
!docker/b_th_web/html/dist/.gitkeep
|
||||||
runtime/*
|
runtime/*
|
||||||
!runtime/.gitkeep
|
!runtime/.gitkeep
|
||||||
*.jar
|
*.jar
|
||||||
|
|
@ -63,5 +70,12 @@ runtime/*
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
!docker/ruoyi/**/jar/.gitkeep
|
!docker/ruoyi/**/jar/.gitkeep
|
||||||
|
|
||||||
|
# hyf_backend source files (except .readme)
|
||||||
|
docker/hyf_backend/src/*
|
||||||
|
!docker/hyf_backend/src/.readme
|
||||||
|
docker/hyf_backend/pgdata/
|
||||||
|
docker/hyf_backend/data/
|
||||||
|
docker/hyf_backend/logs/
|
||||||
|
|
||||||
# K8s generated files
|
# K8s generated files
|
||||||
k8s/**/secrets/
|
k8s/**/secrets/
|
||||||
|
|
@ -56,3 +56,6 @@
|
||||||
[submodule "thingsboard"]
|
[submodule "thingsboard"]
|
||||||
path = thingsboard
|
path = thingsboard
|
||||||
url = http://221.226.114.142:13000/THENG/thingsboard.git
|
url = http://221.226.114.142:13000/THENG/thingsboard.git
|
||||||
|
[submodule "hyf-backend"]
|
||||||
|
path = hyf-backend
|
||||||
|
url = http://th.local.t-aaron.com:13000/THENG/hyf-backend.git
|
||||||
|
|
|
||||||
2
a_th_web
2
a_th_web
|
|
@ -1 +1 @@
|
||||||
Subproject commit b3c50f6011df27cf3993ddf8a56cb1638b6abb04
|
Subproject commit 0a0b9741cca600b27b6ab15905f02ae3d71e29e2
|
||||||
|
|
@ -6,4 +6,3 @@ RTP_TCP_PORT=10000
|
||||||
RTP_UDP_PORT=10000
|
RTP_UDP_PORT=10000
|
||||||
WEBRTC_UDP_PORT1=8000
|
WEBRTC_UDP_PORT1=8000
|
||||||
WEBRTC_UDP_PORT2=9000
|
WEBRTC_UDP_PORT2=9000
|
||||||
RESTART_POLICY=unless-stopped
|
|
||||||
|
|
@ -14,18 +14,47 @@ http {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
|
|
||||||
|
location /waypoint/ {
|
||||||
|
root /home/ruoyi/projects/ruoyi-ui;
|
||||||
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
root /home/ruoyi/projects/ruoyi-ui;
|
root /home/ruoyi/projects/ruoyi-ui;
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
index index.html index.htm;
|
index index.html index.htm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# WebSocket 配置 (必须放在 /prod-api/ 之前)
|
||||||
|
location /prod-api/websocket/ {
|
||||||
|
proxy_pass http://ruoyi-gateway:8080/websocket/;
|
||||||
|
|
||||||
|
# WebSocket 必需的配置
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
# 其他代理头
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
|
||||||
|
# 超时设置(WebSocket 长连接)
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 600s;
|
||||||
|
proxy_read_timeout 600s;
|
||||||
|
}
|
||||||
|
|
||||||
location /prod-api/{
|
location /prod-api/{
|
||||||
proxy_set_header Host $http_host;
|
proxy_set_header Host $http_host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header REMOTE-HOST $remote_addr;
|
proxy_set_header REMOTE-HOST $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_pass http://ruoyi-gateway:8080/;
|
proxy_pass http://ruoyi-gateway:8080/;
|
||||||
|
|
||||||
|
# 支持长时间命令执行
|
||||||
|
proxy_connect_timeout 300s;
|
||||||
|
proxy_send_timeout 300s;
|
||||||
|
proxy_read_timeout 300s;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /minio/ {
|
location /minio/ {
|
||||||
|
|
@ -40,6 +69,14 @@ http {
|
||||||
proxy_pass http://ruoyi-minio:9000/;
|
proxy_pass http://ruoyi-minio:9000/;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# WVP-PRO 配置
|
||||||
|
location /wvp/ {
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_pass http://ruoyi-gateway:8080/wvp/;
|
||||||
|
}
|
||||||
|
|
||||||
# 避免actuator暴露
|
# 避免actuator暴露
|
||||||
if ($uri ~ "/actuator") {
|
if ($uri ~ "/actuator") {
|
||||||
return 403;
|
return 403;
|
||||||
|
|
|
||||||
|
|
@ -13,3 +13,5 @@ WORKDIR /home/ruoyi/projects/ruoyi-ui
|
||||||
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
|
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
|
||||||
# 复制html文件到路径
|
# 复制html文件到路径
|
||||||
COPY ./html/dist /home/ruoyi/projects/ruoyi-ui
|
COPY ./html/dist /home/ruoyi/projects/ruoyi-ui
|
||||||
|
# 复制waypoint文件到路径
|
||||||
|
COPY ./waypoint/default.waypoints /home/ruoyi/projects/ruoyi-ui/waypoint/default.waypoints
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
QGC WPL 110
|
||||||
|
0 1 0 16 0 0 0 0 31.8293035 118.7635779 100.000000 1
|
||||||
|
1 0 3 22 0.00000000 0.00000000 0.00000000 0.00000000 31.82938020 118.76653610 100.000000 1
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
worker_processes 1;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /home/ruoyi/projects/ruoyi-ui;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
index index.html index.htm;
|
||||||
|
}
|
||||||
|
|
||||||
|
# WebSocket 配置 (必须放在 /prod-api/ 之前)
|
||||||
|
location /prod-api/websocket/ {
|
||||||
|
proxy_pass http://ruoyi-gateway:8080/websocket/;
|
||||||
|
|
||||||
|
# WebSocket 必需的配置
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
# 其他代理头
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
|
||||||
|
# 超时设置(WebSocket 长连接)
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 600s;
|
||||||
|
proxy_read_timeout 600s;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /prod-api/{
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header REMOTE-HOST $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_pass http://ruoyi-gateway:8080/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /minio/ {
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_connect_timeout 300;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Connection "";
|
||||||
|
chunked_transfer_encoding off;
|
||||||
|
proxy_pass http://ruoyi-minio:9000/;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 避免actuator暴露
|
||||||
|
if ($uri ~ "/actuator") {
|
||||||
|
return 403;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
# 基础镜像
|
||||||
|
FROM registry.t-aaron.com/nginx:latest
|
||||||
|
# author
|
||||||
|
MAINTAINER ruoyi
|
||||||
|
|
||||||
|
# 挂载目录
|
||||||
|
VOLUME /home/ruoyi/projects/ruoyi-ui
|
||||||
|
# 创建目录
|
||||||
|
RUN mkdir -p /home/ruoyi/projects/ruoyi-ui
|
||||||
|
# 指定路径
|
||||||
|
WORKDIR /home/ruoyi/projects/ruoyi-ui
|
||||||
|
# 复制conf文件到路径
|
||||||
|
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
# 复制html文件到路径
|
||||||
|
COPY ./html/dist /home/ruoyi/projects/ruoyi-ui
|
||||||
|
|
@ -62,3 +62,9 @@ cp ../ruoyi-modules/tuoheng-fms/target/tuoheng-fms.jar ./ruoyi/modules/fms/jar
|
||||||
echo "begin copy tuoheng-media "
|
echo "begin copy tuoheng-media "
|
||||||
cp ../ruoyi-modules/tuoheng-media/target/tuoheng-media.jar ./ruoyi/modules/media/jar
|
cp ../ruoyi-modules/tuoheng-media/target/tuoheng-media.jar ./ruoyi/modules/media/jar
|
||||||
|
|
||||||
|
|
||||||
|
echo "begin copy wvp-jar"
|
||||||
|
cp ../wvpjar/target/wvp-pro-2.7.4.jar ./wvp/wvpjar/jar
|
||||||
|
|
||||||
|
echo "begin copy wvp-web"
|
||||||
|
cp -r ../wvpweb/dist/* ./wvp/web/html/dist/
|
||||||
|
|
@ -50,6 +50,9 @@ docker-compose build --no-cache tuoheng-modules-airline && docker-compose up -d
|
||||||
docker-compose build --no-cache tuoheng-modules-task && docker-compose up -d tuoheng-modules-task
|
docker-compose build --no-cache tuoheng-modules-task && docker-compose up -d tuoheng-modules-task
|
||||||
docker-compose build --no-cache tuoheng-modules-fms && docker-compose up -d tuoheng-modules-fms
|
docker-compose build --no-cache tuoheng-modules-fms && docker-compose up -d tuoheng-modules-fms
|
||||||
docker-compose build --no-cache tuoheng-modules-media && docker-compose up -d tuoheng-modules-media
|
docker-compose build --no-cache tuoheng-modules-media && docker-compose up -d tuoheng-modules-media
|
||||||
|
# cp ../wvpjar/target/wvp-pro-2.7.4.jar ./wvp/wvpjar/jar/
|
||||||
|
docker-compose build --no-cache wvp-pro && docker-compose up -d wvp-pro
|
||||||
|
docker-compose build --no-cache wvp-web && docker-compose up -d wvp-web
|
||||||
|
|
||||||
# 关闭所有环境/模块
|
# 关闭所有环境/模块
|
||||||
stop(){
|
stop(){
|
||||||
|
|
@ -83,3 +86,14 @@ case "$1" in
|
||||||
usage
|
usage
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
# cd /Users/sunpeng/workspace/hyf_project/RuoYi-Cloud/wvpweb
|
||||||
|
#
|
||||||
|
# # 1. 安装依赖(如果还没安装)
|
||||||
|
# npm install
|
||||||
|
#
|
||||||
|
# # 2. 生产环境打包
|
||||||
|
# npm run build:prod
|
||||||
|
#
|
||||||
|
# 打包完成后,生成的文件会在 dist 目录中。
|
||||||
|
|
@ -103,6 +103,24 @@ services:
|
||||||
- ruoyi-gateway
|
- ruoyi-gateway
|
||||||
links:
|
links:
|
||||||
- ruoyi-gateway
|
- ruoyi-gateway
|
||||||
|
ruoyi-hxf:
|
||||||
|
container_name: ruoyi-hxf
|
||||||
|
image: hxf-runtime
|
||||||
|
build:
|
||||||
|
context: ./b_th_web
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
ports:
|
||||||
|
- "9898:80"
|
||||||
|
volumes:
|
||||||
|
- ./b_th_web/html/dist:/home/ruoyi/projects/ruoyi-ui
|
||||||
|
- ./b_th_web/conf/nginx.conf:/etc/nginx/nginx.conf
|
||||||
|
- ./b_th_web/logs:/var/log/nginx
|
||||||
|
- ./b_th_web/conf.d:/etc/nginx/conf.d
|
||||||
|
depends_on:
|
||||||
|
- ruoyi-gateway
|
||||||
|
links:
|
||||||
|
- ruoyi-gateway
|
||||||
ruoyi-gateway:
|
ruoyi-gateway:
|
||||||
container_name: ruoyi-gateway
|
container_name: ruoyi-gateway
|
||||||
image: gateway-runtime
|
image: gateway-runtime
|
||||||
|
|
@ -293,3 +311,224 @@ services:
|
||||||
links:
|
links:
|
||||||
- ruoyi-redis
|
- ruoyi-redis
|
||||||
- ruoyi-mysql
|
- ruoyi-mysql
|
||||||
|
# ============================================================================
|
||||||
|
# WVP-PRO 视频管理平台
|
||||||
|
# ============================================================================
|
||||||
|
# WVP是基于GB28181协议的视频管理平台,使用ZLMediaKit作为流媒体服务器
|
||||||
|
# 端口说明:
|
||||||
|
# - 18080:18978 → WVP的HTTP API端口,外部通过18080访问
|
||||||
|
# - 5060:5060/udp → SIP信令端口,用于GB28181设备注册和控制
|
||||||
|
# ============================================================================
|
||||||
|
wvp-pro:
|
||||||
|
container_name: wvp-pro
|
||||||
|
image: wvp-pro-runtime
|
||||||
|
build:
|
||||||
|
context: ./wvp/wvpjar
|
||||||
|
dockerfile: dockerfile
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
# Redis 配置
|
||||||
|
- REDIS_HOST=ruoyi-redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
# MySQL 数据库配置
|
||||||
|
- DATABASE_HOST=ruoyi-mysql
|
||||||
|
- DATABASE_PORT=3306
|
||||||
|
- DATABASE_USER=ylcx
|
||||||
|
- DATABASE_PASSWORD=Tuoheng@2025
|
||||||
|
# SIP 配置
|
||||||
|
- SIP_ShowIP=127.0.0.1
|
||||||
|
- SIP_Port=5060
|
||||||
|
- SIP_Domain=3502000000
|
||||||
|
- SIP_Id=35020000002000000001
|
||||||
|
- SIP_Password=wvp_sip_password
|
||||||
|
# ========== ZLM 媒体服务器配置 ==========
|
||||||
|
# ZLM_HOST: WVP调用ZLM API时使用的地址(容器内部服务名)
|
||||||
|
# 用途:wvp-pro通过 http://zlmediakit:80/index/api/xxx 调用ZLM的RESTful API
|
||||||
|
- ZLM_HOST=zlmediakit
|
||||||
|
# ZLM_HOOK_HOST: ZLM回调WVP时使用的地址(容器内部服务名)
|
||||||
|
# 用途:zlmediakit通过 http://wvp-pro:18978/index/hook/on_publish 回调WVP
|
||||||
|
- ZLM_HOOK_HOST=wvp-pro
|
||||||
|
# ZLM_SERCERT: ZLM的API密钥,必须与zlmediakit/config.ini中的api.secret一致
|
||||||
|
- ZLM_SERCERT=fgVdaI75GcSBPeSBvg8NL7aRrlkCtGPv
|
||||||
|
# ========== 流媒体地址配置 ==========
|
||||||
|
# Stream_IP: 生成播放地址时使用的IP(宿主机外网IP或域名)
|
||||||
|
# 用途:WVP生成的播放地址格式为 http://45.120.103.238:9090/live/123.live.flv
|
||||||
|
# 对应application.yml中的media.stream-ip配置
|
||||||
|
- Stream_IP=45.120.103.238
|
||||||
|
# SDP_IP: WVP在国标信令中使用的IP
|
||||||
|
# 用途:GB28181设备通过此IP与WVP进行媒体流传输
|
||||||
|
# 对应application.yml中的media.sdp-ip配置
|
||||||
|
- SDP_IP=45.120.103.238
|
||||||
|
# ========== 流媒体端口配置(宿主机外部端口) ==========
|
||||||
|
# 以下端口用于生成客户端播放地址,必须与zlmediakit容器的端口映射一致
|
||||||
|
#
|
||||||
|
# MediaHttp: HTTP播放端口(对应zlmediakit的9090:80映射)
|
||||||
|
# 用途:生成HTTP-FLV/HLS/TS/RTC播放地址
|
||||||
|
# 示例:http://45.120.103.238:9090/live/123.live.flv
|
||||||
|
# 对应application.yml中的media.flv-port和media.ws-flv-port配置
|
||||||
|
- MediaHttp=9090
|
||||||
|
# MediaHttps: HTTPS播放端口(对应zlmediakit的8443:443映射)
|
||||||
|
# 用途:生成HTTPS-FLV/HLS/TS播放地址
|
||||||
|
# 示例:https://45.120.103.238:8443/live/123.live.flv
|
||||||
|
# 对应application.yml中的media.flv-ssl-port和media.ws-flv-ssl-port配置
|
||||||
|
- MediaHttps=8443
|
||||||
|
# MediaRtp: RTP代理端口(对应zlmediakit的10000:10000映射)
|
||||||
|
# 用途:GB28181设备的RTP流传输
|
||||||
|
# 对应application.yml中的media.rtp-proxy-port配置
|
||||||
|
# 对应zlmediakit config.ini中的rtp_proxy.port=10000
|
||||||
|
- MediaRtp=10000
|
||||||
|
# MediaRtmp: RTMP推流端口(对应zlmediakit的1935:1935映射)
|
||||||
|
# 用途:OBS等推流工具推流地址
|
||||||
|
# 示例:rtmp://45.120.103.238:1935/live/123
|
||||||
|
# 对应application.yml中的media.rtmp-port配置
|
||||||
|
# 对应zlmediakit config.ini中的rtmp.port=1935
|
||||||
|
- MediaRtmp=1935
|
||||||
|
# MediaRtsp: RTSP推流/拉流端口(对应zlmediakit的8554:554映射)
|
||||||
|
# 用途:RTSP协议的推流和拉流
|
||||||
|
# 示例:rtsp://45.120.103.238:8554/live/123
|
||||||
|
# 对应application.yml中的media.rtsp-port配置
|
||||||
|
# 对应zlmediakit config.ini中的rtsp.port=554
|
||||||
|
- MediaRtsp=8554
|
||||||
|
# 录像配置
|
||||||
|
- RecordPushLive=false
|
||||||
|
- RecordSip=false
|
||||||
|
ports:
|
||||||
|
- "18080:18978"
|
||||||
|
- "5060:5060/udp"
|
||||||
|
# - "6379:6379"
|
||||||
|
volumes:
|
||||||
|
- ./wvp/logs:/home/ruoyi/logs
|
||||||
|
depends_on:
|
||||||
|
- ruoyi-redis
|
||||||
|
- ruoyi-mysql
|
||||||
|
- zlmediakit
|
||||||
|
links:
|
||||||
|
- ruoyi-redis
|
||||||
|
- ruoyi-mysql
|
||||||
|
- zlmediakit
|
||||||
|
restart: unless-stopped
|
||||||
|
# ============================================================================
|
||||||
|
# ZLMediaKit 流媒体服务器
|
||||||
|
# ============================================================================
|
||||||
|
# ZLMediaKit是高性能的流媒体服务器,支持RTMP/RTSP/HLS/HTTP-FLV等多种协议
|
||||||
|
#
|
||||||
|
# 端口映射说明(格式:宿主机端口:容器内部端口):
|
||||||
|
# 1. API访问端口:
|
||||||
|
# - 9090:80 → HTTP API端口,WVP通过容器内部的80端口访问ZLM API
|
||||||
|
# - 8443:443 → HTTPS API端口(通常不启用)
|
||||||
|
#
|
||||||
|
# 2. 客户端播放端口:
|
||||||
|
# - 9090:80 → HTTP-FLV/HLS/TS/RTC播放,客户端通过9090端口播放
|
||||||
|
# - 8443:443 → HTTPS播放端口
|
||||||
|
#
|
||||||
|
# 3. 推流/拉流协议端口:
|
||||||
|
# - 1935:1935 → RTMP推流端口,OBS推流地址:rtmp://IP:1935/live/stream
|
||||||
|
# - 8554:554 → RTSP推流/拉流端口
|
||||||
|
# - 10000:10000 → RTP代理端口(TCP/UDP),用于GB28181设备
|
||||||
|
# - 8000:8000/udp → WebRTC UDP端口
|
||||||
|
# - 9900:9000/udp → WebRTC UDP端口(注意避免与minio 9000端口冲突)
|
||||||
|
#
|
||||||
|
# 配置文件映射:
|
||||||
|
# - ./zlmediakit/config.ini → /opt/media/conf/config.ini
|
||||||
|
# 重要配置项:
|
||||||
|
# * general.mediaServerId=polaris(必须与数据库wvp_media_server表的id字段一致)
|
||||||
|
# * api.secret=fgVdaI75GcSBPeSBvg8NL7aRrlkCtGPv(必须与ZLM_SERCERT一致)
|
||||||
|
# * http.port=80(容器内部HTTP端口)
|
||||||
|
# * rtmp.port=1935(RTMP端口)
|
||||||
|
# * rtsp.port=554(RTSP端口)
|
||||||
|
# * rtp_proxy.port=10000(RTP代理端口)
|
||||||
|
# ============================================================================
|
||||||
|
zlmediakit:
|
||||||
|
container_name: zlmediakit
|
||||||
|
image: registry.t-aaron.com/zlmediakit/zlmediakit:Release.latest
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
ports:
|
||||||
|
# RTMP推流端口(容器内部1935映射到宿主机1935)
|
||||||
|
# OBS推流地址:rtmp://45.120.103.238:1935/live/streamId
|
||||||
|
# 对应config.ini中的rtmp.port=1935
|
||||||
|
- "1935:1935"
|
||||||
|
# HTTP端口(容器内部80映射到宿主机9090)
|
||||||
|
# 用途1:WVP通过http://zlmediakit:80访问ZLM API
|
||||||
|
# 用途2:客户端通过http://45.120.103.238:9090播放HTTP-FLV/HLS/TS
|
||||||
|
# 对应config.ini中的http.port=80
|
||||||
|
- "9090:80"
|
||||||
|
# HTTPS端口(容器内部443映射到宿主机8443)
|
||||||
|
# 客户端通过https://45.120.103.238:8443播放
|
||||||
|
# 对应config.ini中的http.sslport=443
|
||||||
|
- "8443:443"
|
||||||
|
# RTSP端口(容器内部554映射到宿主机8554)
|
||||||
|
# RTSP地址:rtsp://45.120.103.238:8554/live/streamId
|
||||||
|
# 对应config.ini中的rtsp.port=554
|
||||||
|
- "8554:554"
|
||||||
|
# RTP代理端口TCP(容器内部10000映射到宿主机10000)
|
||||||
|
# 用于GB28181设备的RTP流传输
|
||||||
|
# 对应config.ini中的rtp_proxy.port=10000
|
||||||
|
- "10000:10000"
|
||||||
|
# RTP代理端口UDP(容器内部10000映射到宿主机10000)
|
||||||
|
- "10000:10000/udp"
|
||||||
|
# WebRTC UDP端口(容器内部8000映射到宿主机8000)
|
||||||
|
# 对应config.ini中的rtc.port=8000
|
||||||
|
- "8000:8000/udp"
|
||||||
|
# WebRTC UDP端口(容器内部9000映射到宿主机9900)
|
||||||
|
# 注意:宿主机使用9900避免与minio的9000端口冲突
|
||||||
|
- "9900:9000/udp"
|
||||||
|
volumes:
|
||||||
|
- ./zlmediakit/config.ini:/opt/media/conf/config.ini
|
||||||
|
restart: unless-stopped
|
||||||
|
wvp-web:
|
||||||
|
container_name: wvp-web
|
||||||
|
image: wvp-web-runtime
|
||||||
|
build:
|
||||||
|
context: ./wvp/web
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
ports:
|
||||||
|
- "28181:80"
|
||||||
|
volumes:
|
||||||
|
- ./wvp/web/html/dist:/home/ruoyi/projects/wvp-ui
|
||||||
|
- ./wvp/web/conf/nginx.conf:/etc/nginx/nginx.conf
|
||||||
|
- ./wvp/web/logs:/var/log/nginx
|
||||||
|
- ./wvp/web/conf.d:/etc/nginx/conf.d
|
||||||
|
depends_on:
|
||||||
|
- wvp-pro
|
||||||
|
links:
|
||||||
|
- wvp-pro
|
||||||
|
pgvector-db:
|
||||||
|
container_name: hyf-pgvector-db
|
||||||
|
image: registry.t-aaron.com/pgvector/pgvector:pg16
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: drgraph
|
||||||
|
POSTGRES_PASSWORD: yingping
|
||||||
|
POSTGRES_DB: th_agenter
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
ports:
|
||||||
|
- "5433:5432"
|
||||||
|
volumes:
|
||||||
|
- ./hyf_backend/pgdata:/var/lib/postgresql/data
|
||||||
|
- ./hyf_backend/initdb:/docker-entrypoint-initdb.d
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U drgraph -d th_agenter"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
hyf-backend:
|
||||||
|
container_name: hyf-backend
|
||||||
|
image: hyf-backend-runtime
|
||||||
|
build:
|
||||||
|
context: ./hyf_backend
|
||||||
|
dockerfile: dockerfile
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- DATABASE_URL=postgresql+asyncpg://drgraph:yingping@pgvector-db:5432/th_agenter
|
||||||
|
ports:
|
||||||
|
- "8800:8000"
|
||||||
|
volumes:
|
||||||
|
- ./hyf_backend/data/uploads:/app/data/uploads
|
||||||
|
- ./hyf_backend/data/chroma:/app/data/chroma
|
||||||
|
- ./hyf_backend/logs:/app/webIOs/output/logs
|
||||||
|
depends_on:
|
||||||
|
pgvector-db:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: unless-stopped
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
FROM registry.t-aaron.com/hyf-backend-base:latest
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 复制项目代码(源码在 src 目录下)
|
||||||
|
COPY src/ .
|
||||||
|
|
||||||
|
# 暴露端口
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# 启动命令:先执行数据库迁移,再创建管理员用户,最后启动 uvicorn
|
||||||
|
CMD ["sh", "-c", "alembic upgrade head 2>/dev/null || true && python scripts/seed_admin.py 2>/dev/null || true && uvicorn main:app --host 0.0.0.0 --port 8000"]
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
-- 自动创建 pgvector 扩展
|
||||||
|
CREATE EXTENSION IF NOT EXISTS vector;
|
||||||
|
|
||||||
|
-- 验证扩展已安装
|
||||||
|
SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';
|
||||||
|
|
@ -20,15 +20,17 @@ http {
|
||||||
index index.html index.htm;
|
index index.html index.htm;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /prod-api/{
|
location /prod-api/ {
|
||||||
proxy_set_header Host $http_host;
|
proxy_set_header Host $http_host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header REMOTE-HOST $remote_addr;
|
proxy_set_header REMOTE-HOST $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_pass http://ruoyi-gateway:8080/;
|
proxy_pass http://ruoyi-gateway:8080/;
|
||||||
|
proxy_connect_timeout 300s;
|
||||||
|
proxy_send_timeout 300s;
|
||||||
|
proxy_read_timeout 300s;
|
||||||
}
|
}
|
||||||
|
|
||||||
# 避免actuator暴露
|
|
||||||
if ($uri ~ "/actuator") {
|
if ($uri ~ "/actuator") {
|
||||||
return 403;
|
return 403;
|
||||||
}
|
}
|
||||||
|
|
@ -38,4 +40,4 @@ http {
|
||||||
root html;
|
root html;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,4 @@ WORKDIR /home/ruoyi
|
||||||
# 复制jar文件到路径
|
# 复制jar文件到路径
|
||||||
COPY ./jar/tuoheng-device.jar /home/ruoyi/tuoheng-device.jar
|
COPY ./jar/tuoheng-device.jar /home/ruoyi/tuoheng-device.jar
|
||||||
# 启动系统服务
|
# 启动系统服务
|
||||||
ENTRYPOINT ["java","-jar","tuoheng-device.jar"]
|
ENTRYPOINT ["java","-jar","tuoheng-device.jar","--spring.flyway.validate-on-migrate=false"]
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,11 @@
|
||||||
"key": "cover_state",
|
"key": "cover_state",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"value": "${data.cover_state}"
|
"value": "${data.cover_state}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "drone_charge_state.capacity_percent",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.drone_charge_state.capacity_percent}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -187,12 +192,27 @@
|
||||||
{
|
{
|
||||||
"key": "distance_limit_status.distance_limit",
|
"key": "distance_limit_status.distance_limit",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"value": "${distance_limit_status.distance_limit}"
|
"value": "${data.distance_limit_status.distance_limit}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "battery",
|
"key": "battery",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "${data.battery}"
|
"value": "${data.battery}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "position_state.rtk_number",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.position_state.rtk_number}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "total_flight_time",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.total_flight_time}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "position_state.gps_number",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.position_state.gps_number}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -341,7 +361,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"name": "DOCK",
|
"name": "dajiang",
|
||||||
"id": "28239240-5e44-4fb8-9f66-c29c638903ae",
|
"id": "28239240-5e44-4fb8-9f66-c29c638903ae",
|
||||||
"logLevel": "INFO",
|
"logLevel": "INFO",
|
||||||
"enableRemoteLogging": false,
|
"enableRemoteLogging": false,
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,9 @@ services:
|
||||||
thingsboard-ce:
|
thingsboard-ce:
|
||||||
restart: always
|
restart: always
|
||||||
image: "registry.t-aaron.com/thingsboard/tb-node:4.2.1.1"
|
image: "registry.t-aaron.com/thingsboard/tb-node:4.2.1.1"
|
||||||
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- "18080:8080"
|
- "28080:8080"
|
||||||
- "7070:7070"
|
- "7070:7070"
|
||||||
- "1883:1883"
|
- "1883:1883"
|
||||||
- "8883:8883"
|
- "8883:8883"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
会加入ruoyi的默认网络docker_default
|
会加入ruoyi的默认网络docker_default
|
||||||
|
docker-compose down -v
|
||||||
|
#docker volume rm tb-postgres-data
|
||||||
|
#docker network create docker_default
|
||||||
#第一次的时候执行这个
|
#第一次的时候执行这个
|
||||||
docker-compose run --rm -e INSTALL_TB=true -e LOAD_DEMO=true thingsboard-ce
|
docker-compose run --rm -e INSTALL_TB=true -e LOAD_DEMO=true thingsboard-ce
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,454 @@
|
||||||
|
{
|
||||||
|
"broker": {
|
||||||
|
"host": "mqtt.t-aaron.com",
|
||||||
|
"port": 10883,
|
||||||
|
"version": 5,
|
||||||
|
"clientId": "ThingsBoard_gateway_tuoheng",
|
||||||
|
"security": {
|
||||||
|
"type": "basic",
|
||||||
|
"username": "admin",
|
||||||
|
"password": "admin"
|
||||||
|
},
|
||||||
|
"maxNumberOfWorkers": 100,
|
||||||
|
"maxMessageNumberPerWorker": 10
|
||||||
|
},
|
||||||
|
"mapping": [
|
||||||
|
{
|
||||||
|
"topicFilter": "/topic/v1/airportNest/+/realTime/basic",
|
||||||
|
"subscriptionQos": 1,
|
||||||
|
"converter": {
|
||||||
|
"type": "json",
|
||||||
|
"deviceInfo": {
|
||||||
|
"deviceNameExpression": "(?<=airportNest/)[^/]+(?=/realTime)",
|
||||||
|
"deviceNameExpressionSource": "topic",
|
||||||
|
"deviceProfileExpressionSource": "constant",
|
||||||
|
"deviceProfileExpression": "default"
|
||||||
|
},
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"key": "airportID",
|
||||||
|
"type": "string",
|
||||||
|
"value": "${data.airportID}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "mac",
|
||||||
|
"type": "string",
|
||||||
|
"value": "${data.mac}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "software_version",
|
||||||
|
"type": "string",
|
||||||
|
"value": "${data.version.software}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "hardware_version",
|
||||||
|
"type": "string",
|
||||||
|
"value": "${data.version.hardware}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "sender",
|
||||||
|
"type": "string",
|
||||||
|
"value": "${sender}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeseries": [
|
||||||
|
{
|
||||||
|
"key": "status",
|
||||||
|
"type": "string",
|
||||||
|
"value": "${data.status}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "send_timestamp",
|
||||||
|
"type": "long",
|
||||||
|
"value": "${send_timestamp}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"topicFilter": "/topic/v1/airportNest/+/realTime/data",
|
||||||
|
"subscriptionQos": 0,
|
||||||
|
"converter": {
|
||||||
|
"type": "json",
|
||||||
|
"deviceInfo": {
|
||||||
|
"deviceNameExpression": "(?<=airportNest/)[^/]+(?=/realTime)",
|
||||||
|
"deviceNameExpressionSource": "topic",
|
||||||
|
"deviceProfileExpressionSource": "constant",
|
||||||
|
"deviceProfileExpression": "default"
|
||||||
|
},
|
||||||
|
"attributes": [],
|
||||||
|
"timeseries": [
|
||||||
|
{
|
||||||
|
"key": "weather_rainfall",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${nestWeather.data.rainfall}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "weather_windLevel",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${nestWeather.data.windLevel}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "weather_windDir",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${nestWeather.data.windDir}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "weather_windSpeed",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${nestWeather.data.windSpeed}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "weather_rainFlag",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${nestWeather.data.rainFlag}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "weather_windAngle",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${nestWeather.data.windAngle}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "battery_level",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${droneBattery.data.Battery_level}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "battery_health",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${droneBattery.data.Battery_health}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "battery_totalVoltage",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${droneBattery.data.totalVoltage}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "battery_cellTemp",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${droneBattery.data.cellTemp}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "battery_mosTemp",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${droneBattery.data.mosTemp}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "battery_num_cycles",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${droneBattery.data.num_cycles}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "battery_discharge_current",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${droneBattery.data.Discharge_current}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "battery_bCharging",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${droneBattery.data.bCharging}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "nest_innerHum",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${nestInnerSensor.data.innerHum}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "nest_innerTemp",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${nestInnerSensor.data.innerTemp}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "charger_current",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${nestCharger.data.current}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "charger_voltage",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${nestCharger.data.voltage}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "charger_capacity",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${nestCharger.data.capacity}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "charger_bCharging",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${nestCharger.data.bCharging}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"topicFilter": "/topic/v1/heartbeat/+/message",
|
||||||
|
"subscriptionQos": 1,
|
||||||
|
"converter": {
|
||||||
|
"type": "json",
|
||||||
|
"deviceInfo": {
|
||||||
|
"deviceNameExpression": "(?<=heartbeat/)[^/]+(?=/message)",
|
||||||
|
"deviceNameExpressionSource": "topic",
|
||||||
|
"deviceProfileExpressionSource": "constant",
|
||||||
|
"deviceProfileExpression": "default"
|
||||||
|
},
|
||||||
|
"attributes": [],
|
||||||
|
"timeseries": [
|
||||||
|
{
|
||||||
|
"key": "nest_door_status",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${nestDoor.data.status}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"topicFilter": "/topic/v1/airportDrone/+/realTime/data",
|
||||||
|
"subscriptionQos": 1,
|
||||||
|
"converter": {
|
||||||
|
"type": "json",
|
||||||
|
"deviceInfo": {
|
||||||
|
"deviceNameExpression": "(?<=airportDrone/)[^/]+(?=/realTime)",
|
||||||
|
"deviceNameExpressionSource": "topic",
|
||||||
|
"deviceProfileExpressionSource": "constant",
|
||||||
|
"deviceProfileExpression": "default"
|
||||||
|
},
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"key": "deviceid",
|
||||||
|
"type": "string",
|
||||||
|
"value": "${data.deviceid}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeseries": [
|
||||||
|
{
|
||||||
|
"key": "latitude",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.lat}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "longitude",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.lon}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "altitude",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.alt}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "altitude_asl",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.altasl}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "roll",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.roll}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "pitch",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.pitch}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "yaw",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.yaw}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "horizontal_speed",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.hspeed}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "vertical_speed",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.vspeed}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "battery_remain",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.battery_remain}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "voltage",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.voltage}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "gps_signal",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.gpssingal}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "sat_count",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.satcount}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "mode",
|
||||||
|
"type": "string",
|
||||||
|
"value": "${data.mode}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "armed",
|
||||||
|
"type": "string",
|
||||||
|
"value": "${data.armed}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "tsingal",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.tsingal}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "flight_time",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.flytime}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "mileage",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.mileage}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "distance_to_home",
|
||||||
|
"type": "double",
|
||||||
|
"value": "${data.distToHome}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"topicFilter": "/topic/v1/airportFly/+/control/data",
|
||||||
|
"subscriptionQos": 1,
|
||||||
|
"converter": {
|
||||||
|
"type": "json",
|
||||||
|
"deviceInfo": {
|
||||||
|
"deviceNameExpression": "(?<=airportFly/)[^/]+(?=/control)",
|
||||||
|
"deviceNameExpressionSource": "topic",
|
||||||
|
"deviceProfileExpressionSource": "constant",
|
||||||
|
"deviceProfileExpression": "default"
|
||||||
|
},
|
||||||
|
"attributes": [],
|
||||||
|
"timeseries": [
|
||||||
|
{
|
||||||
|
"key": "lifter_status",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.lifter}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "holder_x_status",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.holderX}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "holder_y_status",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.holderY}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "controller_status",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.controller}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "hatch_status",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.hatch}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "drone_status",
|
||||||
|
"type": "integer",
|
||||||
|
"value": "${data.drone}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestsMapping": {
|
||||||
|
"connectRequests": [
|
||||||
|
{
|
||||||
|
"topicFilter": "sensor/connect",
|
||||||
|
"deviceInfo": {
|
||||||
|
"deviceNameExpressionSource": "message",
|
||||||
|
"deviceNameExpression": "${serialNumber}",
|
||||||
|
"deviceProfileExpressionSource": "constant",
|
||||||
|
"deviceProfileExpression": "Thermometer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"topicFilter": "sensor/+/connect",
|
||||||
|
"deviceInfo": {
|
||||||
|
"deviceNameExpressionSource": "topic",
|
||||||
|
"deviceNameExpression": "(?<=sensor/)(.*?)(?=/connect)",
|
||||||
|
"deviceProfileExpressionSource": "constant",
|
||||||
|
"deviceProfileExpression": "Thermometer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"disconnectRequests": [
|
||||||
|
{
|
||||||
|
"topicFilter": "sensor/disconnect",
|
||||||
|
"deviceInfo": {
|
||||||
|
"deviceNameExpressionSource": "message",
|
||||||
|
"deviceNameExpression": "${serialNumber}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"topicFilter": "sensor/+/disconnect",
|
||||||
|
"deviceInfo": {
|
||||||
|
"deviceNameExpressionSource": "topic",
|
||||||
|
"deviceNameExpression": "(?<=sensor/)(.*?)(?=/connect)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"attributeRequests": [
|
||||||
|
{
|
||||||
|
"retain": false,
|
||||||
|
"topicFilter": "v1/devices/me/attributes/request",
|
||||||
|
"deviceInfo": {
|
||||||
|
"deviceNameExpressionSource": "message",
|
||||||
|
"deviceNameExpression": "${serialNumber}"
|
||||||
|
},
|
||||||
|
"attributeNameExpressionSource": "message",
|
||||||
|
"attributeNameExpression": "${versionAttribute}, ${pduAttribute}",
|
||||||
|
"topicExpression": "devices/${deviceName}/attrs",
|
||||||
|
"valueExpression": "${attributeKey}: ${attributeValue}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"attributeUpdates": [
|
||||||
|
{
|
||||||
|
"retain": true,
|
||||||
|
"deviceNameFilter": ".*",
|
||||||
|
"attributeFilter": "firmwareVersion",
|
||||||
|
"topicExpression": "sensor/${deviceName}/${attributeKey}",
|
||||||
|
"valueExpression": "{\"${attributeKey}\":\"${attributeValue}\"}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"serverSideRpc": [
|
||||||
|
{
|
||||||
|
"type": "twoWay",
|
||||||
|
"deviceNameFilter": ".*",
|
||||||
|
"methodFilter": "echo",
|
||||||
|
"requestTopicExpression": "sensor/${deviceName}/request/${methodName}/${requestId}",
|
||||||
|
"responseTopicExpression": "sensor/${deviceName}/response/${methodName}/${requestId}",
|
||||||
|
"responseTopicQoS": 1,
|
||||||
|
"responseTimeout": 10000,
|
||||||
|
"valueExpression": "${params}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "oneWay",
|
||||||
|
"deviceNameFilter": ".*",
|
||||||
|
"methodFilter": "no-reply",
|
||||||
|
"requestTopicExpression": "sensor/${deviceName}/request/${methodName}/${requestId}",
|
||||||
|
"valueExpression": "${params}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name": "tuoheng",
|
||||||
|
"id": "tuoheng-gateway-001",
|
||||||
|
"logLevel": "INFO",
|
||||||
|
"enableRemoteLogging": false,
|
||||||
|
"configVersion": "3.7.8"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
worker_processes 1;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
# WVP 后端 API 代理(优先匹配)
|
||||||
|
location /api/ {
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header REMOTE-HOST $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_pass http://wvp-pro:18978;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 后端静态资源代理(快照图片等,来自后端服务)
|
||||||
|
location /snap/ {
|
||||||
|
proxy_pass http://wvp-pro:18978;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
|
|
||||||
|
# WebSocket 代理支持
|
||||||
|
location /ws/ {
|
||||||
|
proxy_pass http://wvp-pro:18978;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 前端静态资源(CSS、JS、图片等)
|
||||||
|
location /static/ {
|
||||||
|
root /home/ruoyi/projects/wvp-ui;
|
||||||
|
expires 30d;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 前端页面(最后匹配)
|
||||||
|
location / {
|
||||||
|
root /home/ruoyi/projects/wvp-ui;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
index index.html index.htm;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 避免actuator暴露
|
||||||
|
if ($uri ~ "/actuator") {
|
||||||
|
return 403;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
# 基础镜像
|
||||||
|
FROM registry.t-aaron.com/nginx:latest
|
||||||
|
# author
|
||||||
|
MAINTAINER ruoyi
|
||||||
|
|
||||||
|
# 挂载目录
|
||||||
|
VOLUME /home/ruoyi/projects/wvp-ui
|
||||||
|
# 创建目录
|
||||||
|
RUN mkdir -p /home/ruoyi/projects/wvp-ui
|
||||||
|
# 指定路径
|
||||||
|
WORKDIR /home/ruoyi/projects/wvp-ui
|
||||||
|
# 复制conf文件到路径
|
||||||
|
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
# 复制html文件到路径
|
||||||
|
COPY ./html/dist /home/ruoyi/projects/wvp-ui
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
d
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
# 基础镜像
|
||||||
|
FROM registry.t-aaron.com/eclipse-temurin:21.0.9_10-jre-alpine-3.23
|
||||||
|
# author
|
||||||
|
MAINTAINER ruoyi
|
||||||
|
|
||||||
|
# 创建目录
|
||||||
|
RUN mkdir -p /home/ruoyi
|
||||||
|
# 指定路径
|
||||||
|
WORKDIR /home/ruoyi
|
||||||
|
# 复制jar文件到路径
|
||||||
|
COPY ./jar/wvp-pro-2.7.4.jar /home/ruoyi/wvp-pro-2.7.4.jar
|
||||||
|
# 启动系统服务
|
||||||
|
ENTRYPOINT ["java","-jar","wvp-pro-2.7.4.jar"]
|
||||||
|
|
@ -0,0 +1,464 @@
|
||||||
|
#!!!!此配置文件为范例配置文件,意在告诉读者,各个配置项的具体含义和作用,
|
||||||
|
#!!!!该配置文件在执行cmake时,会拷贝至release/${操作系统类型}/${编译类型}(例如release/linux/Debug) 文件夹。
|
||||||
|
#!!!!该文件夹(release/${操作系统类型}/${编译类型})同时也是可执行程序生成目标路径,在执行MediaServer进程时,它会默认加载同目录下的config.ini文件作为配置文件,
|
||||||
|
#!!!!你如果修改此范例配置文件(conf/config.ini),并不会被MediaServer进程加载,因为MediaServer进程默认加载的是release/${操作系统类型}/${编译类型}/config.ini。
|
||||||
|
#!!!!当然,你每次执行cmake,该文件确实会被拷贝至release/${操作系统类型}/${编译类型}/config.ini,
|
||||||
|
#!!!!但是一般建议你直接修改release/${操作系统类型}/${编译类型}/config.ini文件,修改此文件一般不起作用,除非你运行MediaServer时使用-c参数指定到此文件。
|
||||||
|
[api]
|
||||||
|
#是否调试http api,启用调试后,会打印每次http请求的内容和回复
|
||||||
|
apiDebug=1
|
||||||
|
#一些比较敏感的http api在访问时需要提供secret,否则无权限调用
|
||||||
|
#如果是通过127.0.0.1访问,那么可以不提供secret
|
||||||
|
secret=fgVdaI75GcSBPeSBvg8NL7aRrlkCtGPv
|
||||||
|
#截图保存路径根目录,截图通过http api(/index/api/getSnap)生成和获取
|
||||||
|
snapRoot=./www/snap/
|
||||||
|
#默认截图图片,在启动FFmpeg截图后但是截图还未生成时,可以返回默认的预设图片
|
||||||
|
defaultSnap=./www/logo.png
|
||||||
|
#downloadFile http接口可访问文件的根目录,支持多个目录,不同目录通过分号(;)分隔
|
||||||
|
downloadRoot=./www
|
||||||
|
|
||||||
|
[ffmpeg]
|
||||||
|
#FFmpeg可执行程序路径,支持相对路径/绝对路径
|
||||||
|
bin=/usr/bin/ffmpeg
|
||||||
|
#FFmpeg拉流再推流的命令模板,通过该模板可以设置再编码的一些参数
|
||||||
|
cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s
|
||||||
|
#FFmpeg生成截图的命令,可以通过修改该配置改变截图分辨率或质量
|
||||||
|
snap=%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s
|
||||||
|
#FFmpeg日志的路径,如果置空则不生成FFmpeg日志
|
||||||
|
#可以为相对(相对于本可执行程序目录)或绝对路径
|
||||||
|
log=./ffmpeg/ffmpeg.log
|
||||||
|
# 自动重启的时间(秒), 默认为0, 也就是不自动重启. 主要是为了避免长时间ffmpeg拉流导致的不同步现象
|
||||||
|
restart_sec=0
|
||||||
|
#转协议相关开关;如果addStreamProxy api和on_publish hook回复未指定转协议参数,则采用这些配置项
|
||||||
|
[protocol]
|
||||||
|
#转协议时,是否开启帧级时间戳覆盖
|
||||||
|
# 0:采用源视频流绝对时间戳,不做任何改变
|
||||||
|
# 1:采用zlmediakit接收数据时的系统时间戳(有平滑处理)
|
||||||
|
# 2:采用源视频流时间戳相对时间戳(增长量),有做时间戳跳跃和回退矫正
|
||||||
|
modify_stamp=2
|
||||||
|
#转协议是否开启音频
|
||||||
|
enable_audio=1
|
||||||
|
#添加acc静音音频,在关闭音频时,此开关无效
|
||||||
|
add_mute_audio=1
|
||||||
|
#无人观看时,是否直接关闭(而不是通过on_none_reader hook返回close)
|
||||||
|
#此配置置1时,此流如果无人观看,将不触发on_none_reader hook回调,
|
||||||
|
#而是将直接关闭流
|
||||||
|
auto_close=0
|
||||||
|
#推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。
|
||||||
|
#置0关闭此特性(推流断开会导致立即断开播放器)
|
||||||
|
#此参数不应大于播放器超时时间;单位毫秒
|
||||||
|
continue_push_ms=3000
|
||||||
|
#平滑发送定时器间隔,单位毫秒,置0则关闭;开启后影响cpu性能同时增加内存
|
||||||
|
#该配置开启后可以解决一些流发送不平滑导致zlmediakit转发也不平滑的问题
|
||||||
|
paced_sender_ms=0
|
||||||
|
#是否开启转换为hls(mpegts)
|
||||||
|
enable_hls=1
|
||||||
|
#是否开启转换为hls(fmp4)
|
||||||
|
enable_hls_fmp4=0
|
||||||
|
#是否开启MP4录制
|
||||||
|
enable_mp4=0
|
||||||
|
#是否开启转换为rtsp/webrtc
|
||||||
|
enable_rtsp=1
|
||||||
|
#是否开启转换为rtmp/flv
|
||||||
|
enable_rtmp=1
|
||||||
|
#是否开启转换为http-ts/ws-ts
|
||||||
|
enable_ts=1
|
||||||
|
#是否开启转换为http-fmp4/ws-fmp4
|
||||||
|
enable_fmp4=1
|
||||||
|
#是否将mp4录制当做观看者
|
||||||
|
mp4_as_player=0
|
||||||
|
#mp4切片大小,单位秒
|
||||||
|
mp4_max_second=3600
|
||||||
|
#mp4录制保存路径
|
||||||
|
mp4_save_path=/opt/media/bin/www
|
||||||
|
#hls录制保存路径
|
||||||
|
hls_save_path=./www
|
||||||
|
###### 以下是按需转协议的开关,在测试ZLMediaKit的接收推流性能时,请把下面开关置1
|
||||||
|
###### 如果某种协议你用不到,你可以把以下开关置1以便节省资源(但是还是可以播放,只是第一个播放者体验稍微差点),
|
||||||
|
###### 如果某种协议你想获取最好的用户体验,请置0(第一个播放者可以秒开,且不花屏)
|
||||||
|
#hls协议是否按需生成,如果hls.segNum配置为0(意味着hls录制),那么hls将一直生成(不管此开关)
|
||||||
|
hls_demand=0
|
||||||
|
#rtsp[s]协议是否按需生成
|
||||||
|
rtsp_demand=0
|
||||||
|
#rtmp[s]、http[s]-flv、ws[s]-flv协议是否按需生成
|
||||||
|
rtmp_demand=0
|
||||||
|
#http[s]-ts协议是否按需生成
|
||||||
|
ts_demand=0
|
||||||
|
#http[s]-fmp4、ws[s]-fmp4协议是否按需生成
|
||||||
|
fmp4_demand=0
|
||||||
|
|
||||||
|
[general]
|
||||||
|
#是否启用虚拟主机
|
||||||
|
enableVhost=0
|
||||||
|
#播放器或推流器在断开后会触发hook.on_flow_report事件(使用多少流量事件),
|
||||||
|
#flowThreshold参数控制触发hook.on_flow_report事件阈值,使用流量超过该阈值后才触发,单位KB
|
||||||
|
flowThreshold=1024
|
||||||
|
#播放最多等待时间,单位毫秒
|
||||||
|
#播放在播放某个流时,如果该流不存在,
|
||||||
|
#ZLMediaKit会最多让播放器等待maxStreamWaitMS毫秒
|
||||||
|
#如果在这个时间内,该流注册成功,那么会立即返回播放器播放成功
|
||||||
|
#否则返回播放器未找到该流,该机制的目的是可以先播放再推流
|
||||||
|
maxStreamWaitMS=15000
|
||||||
|
#某个流无人观看时,触发hook.on_stream_none_reader事件的最大等待时间,单位毫秒
|
||||||
|
#在配合hook.on_stream_none_reader事件时,可以做到无人观看自动停止拉流或停止接收推流
|
||||||
|
streamNoneReaderDelayMS=20000
|
||||||
|
#拉流代理时如果断流再重连成功是否删除前一次的媒体流数据,如果删除将重新开始,
|
||||||
|
#如果不删除将会接着上一次的数据继续写(录制hls/mp4时会继续在前一个文件后面写)
|
||||||
|
resetWhenRePlay=1
|
||||||
|
#合并写缓存大小(单位毫秒),合并写指服务器缓存一定的数据后才会一次性写入socket,这样能提高性能,但是会提高延时
|
||||||
|
#开启后会同时关闭TCP_NODELAY并开启MSG_MORE
|
||||||
|
mergeWriteMS=0
|
||||||
|
#服务器唯一id,用于触发hook时区别是哪台服务器
|
||||||
|
mediaServerId=polaris
|
||||||
|
#最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track
|
||||||
|
wait_track_ready_ms=10000
|
||||||
|
#最多等待音频Track收到数据时间,单位毫秒,超时且完全没收到音频数据,忽略音频Track
|
||||||
|
#加快某些带封装的流metadata说明有音频,但是实际上没有的流ready时间(比如很多厂商的GB28181 PS)
|
||||||
|
wait_audio_track_data_ms=1000
|
||||||
|
#如果流只有单Track,最多等待若干毫秒,超时后未收到其他Track的数据,则认为是单Track
|
||||||
|
#如果协议元数据有声明特定track数,那么无此等待时间
|
||||||
|
wait_add_track_ms=3000
|
||||||
|
#如果track未就绪,我们先缓存帧数据,但是有最大个数限制,防止内存溢出
|
||||||
|
unready_frame_cache=100
|
||||||
|
#是否启用观看人数变化事件广播,置1则启用,置0则关闭
|
||||||
|
broadcast_player_count_changed=0
|
||||||
|
#绑定的本地网卡ip
|
||||||
|
listen_ip=::
|
||||||
|
|
||||||
|
[hls]
|
||||||
|
#hls写文件的buf大小,调整参数可以提高文件io性能
|
||||||
|
fileBufSize=65536
|
||||||
|
#hls最大切片时间
|
||||||
|
segDur=2
|
||||||
|
#m3u8索引中,hls保留切片个数(实际保留切片个数+segRetain个)
|
||||||
|
#如果设置为0,则不删除切片且m3u8文件全量记录切片列表
|
||||||
|
segNum=3
|
||||||
|
#HLS切片延迟个数,大于0将生成hls_delay.m3u8文件,0则不生成
|
||||||
|
segDelay=0
|
||||||
|
#HLS切片从m3u8文件中移除后,继续保留在磁盘上的个数
|
||||||
|
segRetain=5
|
||||||
|
#是否广播 hls切片(ts/fmp4)完成通知(on_record_ts)
|
||||||
|
broadcastRecordTs=0
|
||||||
|
#直播hls文件删除延时,单位秒,issue: #913
|
||||||
|
deleteDelaySec=10
|
||||||
|
#此选项开启后m3u8文件还是表现为直播,但是切片文件会被全部保留为点播用
|
||||||
|
#segDur设置为0或segKeep设置为1的情况下,每个切片文件夹下会生成一个vod.m3u8文件用于点播该时间段的录像
|
||||||
|
segKeep=0
|
||||||
|
#如果设置为1,则第一个切片长度强制设置为1个GOP。当GOP小于segDur,可以提高首屏速度
|
||||||
|
fastRegister=0
|
||||||
|
|
||||||
|
[hook]
|
||||||
|
#是否启用hook事件,启用后,推拉流都将进行鉴权
|
||||||
|
enable=1
|
||||||
|
#播放器或推流器使用流量事件,置空则关闭
|
||||||
|
on_flow_report=
|
||||||
|
#访问http文件鉴权事件,置空则关闭鉴权
|
||||||
|
on_http_access=
|
||||||
|
#播放鉴权事件,置空则关闭鉴权
|
||||||
|
on_play=http://wvp-pro:18978/index/hook/on_play
|
||||||
|
#推流鉴权事件,置空则关闭鉴权
|
||||||
|
on_publish=http://wvp-pro:18978/index/hook/on_publish
|
||||||
|
#录制mp4切片完成事件
|
||||||
|
on_record_mp4=http://wvp-pro:18978/index/hook/on_record_mp4
|
||||||
|
# 录制 hls ts(或fmp4) 切片完成事件
|
||||||
|
on_record_ts=
|
||||||
|
#rtsp播放鉴权事件,此事件中比对rtsp的用户名密码
|
||||||
|
on_rtsp_auth=
|
||||||
|
#rtsp播放是否开启专属鉴权事件,置空则关闭rtsp鉴权。rtsp播放鉴权还支持url方式鉴权
|
||||||
|
#建议开发者统一采用url参数方式鉴权,rtsp用户名密码鉴权一般在设备上用的比较多
|
||||||
|
#开启rtsp专属鉴权后,将不再触发on_play鉴权事件
|
||||||
|
on_rtsp_realm=
|
||||||
|
#远程telnet调试鉴权事件
|
||||||
|
on_shell_login=
|
||||||
|
#直播流注册或注销事件
|
||||||
|
on_stream_changed=http://wvp-pro:18978/index/hook/on_stream_changed
|
||||||
|
#过滤on_stream_changed hook的协议类型,可以选择只监听某些感兴趣的协议;置空则不过滤协议
|
||||||
|
stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4
|
||||||
|
#无人观看流事件,通过该事件,可以选择是否关闭无人观看的流。配合general.streamNoneReaderDelayMS选项一起使用
|
||||||
|
on_stream_none_reader=http://wvp-pro:18978/index/hook/on_stream_none_reader
|
||||||
|
#播放时,未找到流事件,通过配合hook.on_stream_none_reader事件可以完成按需拉流
|
||||||
|
on_stream_not_found=http://wvp-pro:18978/index/hook/on_stream_not_found
|
||||||
|
#服务器启动报告,可以用于服务器的崩溃重启事件监听
|
||||||
|
on_server_started=http://wvp-pro:18978/index/hook/on_server_started
|
||||||
|
#服务器退出报告,当服务器正常退出时触发
|
||||||
|
on_server_exited=
|
||||||
|
#server保活上报
|
||||||
|
on_server_keepalive=http://wvp-pro:18978/index/hook/on_server_keepalive
|
||||||
|
#发送rtp(startSendRtp)被动关闭时回调
|
||||||
|
on_send_rtp_stopped=http://wvp-pro:18978/index/hook/on_send_rtp_stopped
|
||||||
|
#rtp server 超时未收到数据
|
||||||
|
on_rtp_server_timeout=http://wvp-pro:18978/index/hook/on_rtp_server_timeout
|
||||||
|
#hook api最大等待回复时间,单位秒
|
||||||
|
timeoutSec=30
|
||||||
|
#keepalive hook触发间隔,单位秒,float类型
|
||||||
|
alive_interval=10.0
|
||||||
|
#hook通知失败重试次数,正整数。为0不重试,1时重试一次,以此类推
|
||||||
|
retry=1
|
||||||
|
#hook通知失败重试延时,单位秒,float型
|
||||||
|
retry_delay=3.0
|
||||||
|
|
||||||
|
[cluster]
|
||||||
|
#设置源站拉流url模板, 格式跟printf类似,第一个%s指定app,第二个%s指定stream_id,
|
||||||
|
#开启集群模式后,on_stream_not_found和on_stream_none_reader hook将无效.
|
||||||
|
#溯源模式支持以下类型:
|
||||||
|
#rtmp方式: rtmp://127.0.0.1:1935/%s/%s
|
||||||
|
#rtsp方式: rtsp://127.0.0.1:554/%s/%s
|
||||||
|
#hls方式: http://127.0.0.1:80/%s/%s/hls.m3u8
|
||||||
|
#http-ts方式: http://127.0.0.1:80/%s/%s.live.ts
|
||||||
|
#支持多个源站,不同源站通过分号(;)分隔
|
||||||
|
origin_url=
|
||||||
|
#溯源总超时时长,单位秒,float型;假如源站有3个,那么单次溯源超时时间为timeout_sec除以3
|
||||||
|
#单次溯源超时时间不要超过general.maxStreamWaitMS配置
|
||||||
|
timeout_sec=15
|
||||||
|
#溯源失败尝试次数,-1时永久尝试
|
||||||
|
retry_count=3
|
||||||
|
|
||||||
|
[http]
|
||||||
|
#http服务器字符编码集
|
||||||
|
charSet=utf-8
|
||||||
|
#http链接超时时间
|
||||||
|
keepAliveSecond=30
|
||||||
|
#http请求体最大字节数,如果post的body太大,则不适合缓存body在内存
|
||||||
|
maxReqSize=40960
|
||||||
|
#404网页内容,用户可以自定义404网页
|
||||||
|
#notFound=<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>您访问的资源不存在!</h1></center><hr><center>ZLMediaKit-4.0</center></body></html>
|
||||||
|
#http服务器监听端口
|
||||||
|
port=80
|
||||||
|
#http文件服务器根目录
|
||||||
|
#可以为相对(相对于本可执行程序目录)或绝对路径
|
||||||
|
rootPath=./www
|
||||||
|
#http文件服务器读文件缓存大小,单位BYTE,调整该参数可以优化文件io性能
|
||||||
|
sendBufSize=65536
|
||||||
|
#https服务器监听端口
|
||||||
|
sslport=443
|
||||||
|
#是否显示文件夹菜单,开启后可以浏览文件夹
|
||||||
|
dirMenu=1
|
||||||
|
#虚拟目录, 虚拟目录名和文件路径使用","隔开,多个配置路径间用";"隔开
|
||||||
|
#例如赋值为 app_a,/path/to/a;app_b,/path/to/b 那么
|
||||||
|
#访问 http://127.0.0.1/app_a/file_a 对应的文件路径为 /path/to/a/file_a
|
||||||
|
#访问 http://127.0.0.1/app_b/file_b 对应的文件路径为 /path/to/b/file_b
|
||||||
|
#访问其他http路径,对应的文件路径还是在rootPath内
|
||||||
|
virtualPath=
|
||||||
|
#禁止后缀的文件使用mmap缓存,使用“,”隔开
|
||||||
|
#例如赋值为 .mp4,.flv
|
||||||
|
#那么访问后缀为.mp4与.flv 的文件不缓存
|
||||||
|
forbidCacheSuffix=
|
||||||
|
#可以把http代理前真实客户端ip放在http头中:https://github.com/ZLMediaKit/ZLMediaKit/issues/1388
|
||||||
|
#切勿暴露此key,否则可能导致伪造客户端ip
|
||||||
|
forwarded_ip_header=
|
||||||
|
#默认允许所有跨域请求
|
||||||
|
allow_cross_domains=1
|
||||||
|
#允许访问http api和http文件索引的ip地址范围白名单,置空情况下不做限制
|
||||||
|
allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255
|
||||||
|
|
||||||
|
[multicast]
|
||||||
|
#rtp组播截止组播ip地址
|
||||||
|
addrMax=239.255.255.255
|
||||||
|
#rtp组播起始组播ip地址
|
||||||
|
addrMin=239.0.0.0
|
||||||
|
#组播udp ttl
|
||||||
|
udpTTL=64
|
||||||
|
|
||||||
|
[record]
|
||||||
|
#mp4录制或mp4点播的应用名,通过限制应用名,可以防止随意点播
|
||||||
|
#点播的文件必须放置在此文件夹下
|
||||||
|
appName=record
|
||||||
|
#mp4录制写文件缓存,单位BYTE,调整参数可以提高文件io性能
|
||||||
|
fileBufSize=65536
|
||||||
|
#mp4点播每次流化数据量,单位毫秒,
|
||||||
|
#减少该值可以让点播数据发送量更平滑,增大该值则更节省cpu资源
|
||||||
|
sampleMS=500
|
||||||
|
#mp4录制完成后是否进行二次关键帧索引写入头部
|
||||||
|
fastStart=0
|
||||||
|
#MP4点播(rtsp/rtmp/http-flv/ws-flv)是否循环播放文件
|
||||||
|
fileRepeat=0
|
||||||
|
#MP4录制写文件格式是否采用fmp4,启用的话,断电未完成录制的文件也能正常打开
|
||||||
|
enableFmp4=0
|
||||||
|
|
||||||
|
[rtmp]
|
||||||
|
#rtmp必须在此时间内完成握手,否则服务器会断开链接,单位秒
|
||||||
|
handshakeSecond=15
|
||||||
|
#rtmp超时时间,如果该时间内未收到客户端的数据,
|
||||||
|
#或者tcp发送缓存超过这个时间,则会断开连接,单位秒
|
||||||
|
keepAliveSecond=15
|
||||||
|
#rtmp服务器监听端口
|
||||||
|
port=1935
|
||||||
|
#rtmps服务器监听地址
|
||||||
|
sslport=0
|
||||||
|
# rtmp是否直接代理模式
|
||||||
|
directProxy=1
|
||||||
|
#h265/opus/vp8/vp9/av1 rtmp打包采用增强型rtmp标准还是国内拓展标准
|
||||||
|
enhanced=1
|
||||||
|
|
||||||
|
[rtp]
|
||||||
|
#音频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400
|
||||||
|
#加大该值会明显增加直播延时
|
||||||
|
audioMtuSize=600
|
||||||
|
#视频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400
|
||||||
|
videoMtuSize=1400
|
||||||
|
#rtp包最大长度限制,单位KB,主要用于识别TCP上下文破坏时,获取到错误的rtp
|
||||||
|
rtpMaxSize=10
|
||||||
|
# rtp 打包时,低延迟开关,默认关闭(为0),h264存在一帧多个slice(NAL)的情况,在这种情况下,如果开启可能会导致画面花屏
|
||||||
|
lowLatency=0
|
||||||
|
# H264 rtp打包模式是否采用stap-a模式(为了在老版本浏览器上兼容webrtc)还是采用Single NAL unit packet per H.264 模式
|
||||||
|
# 有些老的rtsp设备不支持stap-a rtp,设置此配置为0可提高兼容性
|
||||||
|
h264_stap_a=1
|
||||||
|
|
||||||
|
[rtp_proxy]
|
||||||
|
#导出调试数据(包括rtp/ps/h264)至该目录,置空则关闭数据导出
|
||||||
|
dumpDir=
|
||||||
|
#udp和tcp代理服务器,支持rtp(必须是ts或ps类型)代理
|
||||||
|
port=10000
|
||||||
|
#rtp超时时间,单位秒
|
||||||
|
timeoutSec=15
|
||||||
|
#随机端口范围,最少确保36个端口
|
||||||
|
#该范围同时限制rtsp服务器udp端口范围
|
||||||
|
port_range=30000-30500
|
||||||
|
#rtp h264 负载的pt
|
||||||
|
h264_pt=98
|
||||||
|
#rtp h265 负载的pt
|
||||||
|
h265_pt=99
|
||||||
|
#rtp ps 负载的pt
|
||||||
|
ps_pt=96
|
||||||
|
#rtp opus 负载的pt
|
||||||
|
opus_pt=100
|
||||||
|
#startSendRtp、startRecord相关功能是否提前开启gop缓存优化级联秒开体验,默认开启, 并缓存1个GOP
|
||||||
|
#如果不调用startSendRtp、startRecord后相关接口,可以置0节省内存;如果缓存多个gop,可以加大该参数
|
||||||
|
gop_cache=1
|
||||||
|
#国标发送g711 rtp 打包时,每个包的语音时长是多少,默认是100 ms,范围为20~180ms (gb28181-2016,c.2.4规定),
|
||||||
|
#最好为20 的倍数,程序自动向20的倍数取整
|
||||||
|
rtp_g711_dur_ms=100
|
||||||
|
#udp接收数据socket buffer大小配置
|
||||||
|
#4*1024*1024=4196304
|
||||||
|
udp_recv_socket_buffer=4194304
|
||||||
|
#ps/ts解析后是否等待下一帧以判断本帧是否完整,开启后提高兼容性,但是可能增加延时
|
||||||
|
merge_frame=1
|
||||||
|
|
||||||
|
[rtc]
|
||||||
|
#webrtc 信令服务器端口
|
||||||
|
signalingPort=3000
|
||||||
|
signalingSslPort=3001
|
||||||
|
#STUN/TURN服务器端口
|
||||||
|
icePort=3478
|
||||||
|
iceTcpPort=3478
|
||||||
|
#STUN/TURN端口是否使能TURN服务
|
||||||
|
enableTurn=1
|
||||||
|
#ICE传输策略:0=不限制(默认),1=仅支持Relay转发,2=仅支持P2P直连
|
||||||
|
iceTransportPolicy=0
|
||||||
|
#STUN/TURN 服务Ice密码
|
||||||
|
iceUfrag=ZLMediaKit
|
||||||
|
icePwd=ZLMediaKit
|
||||||
|
#webrtc datachannel是否回显数据,测试用
|
||||||
|
datachannel_echo=1
|
||||||
|
max_stun_retry=7
|
||||||
|
#TURN服务分配端口池
|
||||||
|
port_range=49152-65535
|
||||||
|
#rtc播放推流、播放超时时间
|
||||||
|
timeoutSec=15
|
||||||
|
#本机对rtc客户端的可见ip,作为服务器时一般为公网ip,可有多个,用','分开,当置空时,会自动获取网卡ip
|
||||||
|
#同时支持环境变量,以$开头,如"$EXTERN_IP"; 请参考:https://github.com/ZLMediaKit/ZLMediaKit/pull/1786
|
||||||
|
externIP=
|
||||||
|
#当指定了interfaces,ICE服务器会使用指定网卡bind socket
|
||||||
|
#以解决公网IP使用弹性公网IP配置实现(部署机器无法bind该公网ip的问题)
|
||||||
|
#支持环境变量,以$开头,如"$PRIVATE_IP"
|
||||||
|
interfaces=
|
||||||
|
#rtc udp服务器监听端口号,所有rtc客户端将通过该端口传输stun/dtls/srtp/srtcp数据,
|
||||||
|
#该端口是多线程的,同时支持客户端网络切换导致的连接迁移
|
||||||
|
#需要注意的是,如果服务器在nat内,需要做端口映射时,必须确保外网映射端口跟该端口一致
|
||||||
|
port=8000
|
||||||
|
#rtc tcp服务器监听端口号,在udp 不通的情况下,会使用tcp传输数据
|
||||||
|
#该端口是多线程的,同时支持客户端网络切换导致的连接迁移
|
||||||
|
#需要注意的是,如果服务器在nat内,需要做端口映射时,必须确保外网映射端口跟该端口一致
|
||||||
|
tcpPort=8000
|
||||||
|
#设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
|
||||||
|
#目前已经实现twcc自动调整码率,关闭remb根据真实网络状况调整码率
|
||||||
|
rembBitRate=0
|
||||||
|
#rtc支持的音频codec类型,在前面的优先级更高
|
||||||
|
#以下范例为所有支持的音频codec
|
||||||
|
preferredCodecA=PCMA,PCMU,opus,mpeg4-generic
|
||||||
|
#rtc支持的视频codec类型,在前面的优先级更高
|
||||||
|
#以下范例为所有支持的视频codec
|
||||||
|
preferredCodecV=H264,H265,AV1,VP9,VP8
|
||||||
|
#webrtc比特率设置
|
||||||
|
start_bitrate=0
|
||||||
|
max_bitrate=0
|
||||||
|
min_bitrate=0
|
||||||
|
#nack接收端, rtp发送端,zlm发送rtc流
|
||||||
|
#rtp重发缓存列队最大长度,单位毫秒
|
||||||
|
maxRtpCacheMS=5000
|
||||||
|
#rtp重发缓存列队最大长度,单位个数
|
||||||
|
maxRtpCacheSize=2048
|
||||||
|
#nack发送端,rtp接收端,zlm接收rtc推流
|
||||||
|
#最大保留的rtp丢包状态个数
|
||||||
|
nackMaxSize=2048
|
||||||
|
#rtp丢包状态最长保留时间
|
||||||
|
nackMaxMS=3000
|
||||||
|
#nack最多请求重传次数
|
||||||
|
nackMaxCount=15
|
||||||
|
#nack重传频率,rtt的倍数
|
||||||
|
nackIntervalRatio=1.0
|
||||||
|
#视频nack包中rtp个数,减小此值可以让nack包响应更灵敏
|
||||||
|
nackRtpSize=8
|
||||||
|
#音频nack包中rtp个数,减小此值可以让nack包响应更灵敏
|
||||||
|
nackAudioRtpSize=4
|
||||||
|
#是否尝试过滤 b帧
|
||||||
|
bfilter=0
|
||||||
|
# 是否优先采用webrtc over tcp模式
|
||||||
|
preferred_tcp=0
|
||||||
|
|
||||||
|
[srt]
|
||||||
|
#srt播放推流、播放超时时间,单位秒
|
||||||
|
timeoutSec=5
|
||||||
|
#srt udp服务器监听端口号,所有srt客户端将通过该端口传输srt数据,
|
||||||
|
#该端口是多线程的,同时支持客户端网络切换导致的连接迁移
|
||||||
|
port=9000
|
||||||
|
#srt 协议中延迟缓存的估算参数,在握手阶段估算rtt ,然后latencyMul*rtt 为最大缓存时长,此参数越大,表示等待重传的时长就越大
|
||||||
|
latencyMul=4
|
||||||
|
#包缓存的大小
|
||||||
|
pktBufSize=8192
|
||||||
|
#srt udp服务器的密码,为空表示不加密
|
||||||
|
passPhrase=
|
||||||
|
|
||||||
|
[rtsp]
|
||||||
|
#rtsp专有鉴权方式是采用base64还是md5方式
|
||||||
|
authBasic=0
|
||||||
|
#rtsp拉流、推流代理是否是直接代理模式
|
||||||
|
#直接代理后支持任意编码格式,但是会导致GOP缓存无法定位到I帧,可能会导致开播花屏
|
||||||
|
#并且如果是tcp方式拉流,如果rtp大于mtu会导致无法使用udp方式代理
|
||||||
|
#假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理
|
||||||
|
#如果你是rtsp推拉流,但是webrtc播放,也建议关闭直接代理模式,
|
||||||
|
#因为直接代理时,rtp中可能没有sps pps,会导致webrtc无法播放; 另外webrtc也不支持Single NAL Unit Packets类型rtp
|
||||||
|
#默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的
|
||||||
|
directProxy=1
|
||||||
|
#rtsp必须在此时间内完成握手,否则服务器会断开链接,单位秒
|
||||||
|
handshakeSecond=15
|
||||||
|
#rtsp超时时间,如果该时间内未收到客户端的数据,
|
||||||
|
#或者tcp发送缓存超过这个时间,则会断开连接,单位秒
|
||||||
|
keepAliveSecond=15
|
||||||
|
#rtsp服务器监听地址
|
||||||
|
port=554
|
||||||
|
#rtsps服务器监听地址
|
||||||
|
sslport=0
|
||||||
|
#rtsp 转发是否使用低延迟模式,当开启时,不会缓存rtp包,来提高并发,可以降低一帧的延迟
|
||||||
|
lowLatency=0
|
||||||
|
#强制协商rtp传输方式 (0:TCP,1:UDP,2:MULTICAST,-1:不限制)
|
||||||
|
#当客户端发起RTSP SETUP的时候如果传输类型和此配置不一致则返回461 Unsupported transport
|
||||||
|
#迫使客户端重新SETUP并切换到对应协议。目前支持FFMPEG和VLC
|
||||||
|
rtpTransportType=-1
|
||||||
|
|
||||||
|
[shell]
|
||||||
|
#调试telnet服务器接受最大buffer大小
|
||||||
|
maxReqSize=1024
|
||||||
|
#调试telnet服务器监听端口
|
||||||
|
port=0
|
||||||
|
# onvif搜索用
|
||||||
|
[onvif]
|
||||||
|
port=3702
|
||||||
|
|
||||||
|
[general]
|
||||||
|
check_nvidia_dev=1
|
||||||
|
enable_ffmpeg_log=0
|
||||||
|
|
||||||
|
[http]
|
||||||
|
notFound=<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>您访问的资源不存在!</h1></center><hr><center>ZLMediaKit(git hash:/,branch:,build time:2026-01-14T08:09:34)</center></body></html>
|
||||||
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
# 此镜像为github持续集成自动编译推送,跟代码(master分支)保持最新状态
|
|
||||||
services:
|
|
||||||
zlmediakit:
|
|
||||||
image: registry.t-aaron.com/zlmediakit/zlmediakit:Release.latest
|
|
||||||
container_name: zlmediakit
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "${RTMP_PORT:-1935}:1935" # RTMP
|
|
||||||
- "${HTTP_PORT:-9090}:80" # HTTP
|
|
||||||
- "${HTTPS_PORT:-8443}:443" # HTTPS
|
|
||||||
- "${RTSP_PORT:-8554}:554" # RTSP
|
|
||||||
- "${RTP_TCP_PORT:-10000}:10000" # RTP TCP
|
|
||||||
- "${RTP_UDP_PORT:-10000}:10000/udp" # RTP UDP
|
|
||||||
- "${WEBRTC_UDP_PORT1:-8000}:8000/udp" # WebRTC UDP
|
|
||||||
- "${WEBRTC_UDP_PORT2:-9000}:9000/udp" # WebRTC UDP
|
|
||||||
|
|
||||||
networks:
|
|
||||||
default:
|
|
||||||
external: true
|
|
||||||
name: docker_default
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 6f0ac0c588c9a1711ddbe833c638206eed4bb3c4
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.ruoyi.system.api;
|
||||||
|
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader;
|
||||||
|
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||||
|
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.system.api.domain.SysDictData;
|
||||||
|
import com.ruoyi.system.api.factory.RemoteDictFallbackFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字典服务
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@FeignClient(contextId = "remoteDictService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteDictFallbackFactory.class)
|
||||||
|
public interface RemoteDictService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 根据字典类型查询字典数据
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@GetMapping("/dict/data/type/{dictType}")
|
||||||
|
public R<List<SysDictData>> getDictDataByType(@PathVariable("dictType") String dictType, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典类型和值获取字典标签
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @param dictValue 字典值
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@GetMapping("/dict/data/label/{dictType}/{dictValue}")
|
||||||
|
public R<String> getDictLabel(@PathVariable("dictType") String dictType, @PathVariable("dictValue") String dictValue, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.ruoyi.system.api.factory;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.system.api.RemoteDictService;
|
||||||
|
import com.ruoyi.system.api.domain.SysDictData;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字典服务降级处理
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class RemoteDictFallbackFactory implements FallbackFactory<RemoteDictService>
|
||||||
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(RemoteDictFallbackFactory.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteDictService create(Throwable throwable)
|
||||||
|
{
|
||||||
|
log.error("数据字典服务调用失败: {}", throwable.getMessage());
|
||||||
|
return new RemoteDictService()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public R<List<SysDictData>> getDictDataByType(String dictType, String source)
|
||||||
|
{
|
||||||
|
log.error("根据字典类型查询字典数据失败: {}", dictType);
|
||||||
|
return R.fail("根据字典类型查询字典数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<String> getDictLabel(String dictType, String dictValue, String source)
|
||||||
|
{
|
||||||
|
log.error("根据字典类型和值获取字典标签失败: {} - {}", dictType, dictValue);
|
||||||
|
return R.fail("根据字典类型和值获取字典标签失败");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
com.ruoyi.system.api.factory.RemoteUserFallbackFactory
|
com.ruoyi.system.api.factory.RemoteUserFallbackFactory
|
||||||
com.ruoyi.system.api.factory.RemoteLogFallbackFactory
|
com.ruoyi.system.api.factory.RemoteLogFallbackFactory
|
||||||
com.ruoyi.system.api.factory.RemoteFileFallbackFactory
|
com.ruoyi.system.api.factory.RemoteFileFallbackFactory
|
||||||
|
com.ruoyi.system.api.factory.RemoteDictFallbackFactory
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.ruoyi.airline.api;
|
||||||
import com.ruoyi.common.core.constant.SecurityConstants;
|
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||||
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.airline.api.domain.AirlineFileVO;
|
||||||
import com.ruoyi.airline.api.domain.AirlineTempVO;
|
import com.ruoyi.airline.api.domain.AirlineTempVO;
|
||||||
import com.ruoyi.airline.api.factory.RemoteAirlineFallbackFactory;
|
import com.ruoyi.airline.api.factory.RemoteAirlineFallbackFactory;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
|
@ -29,4 +30,7 @@ public interface RemoteAirlineService
|
||||||
// TODO
|
// TODO
|
||||||
@GetMapping("/airline/{groupId}")
|
@GetMapping("/airline/{groupId}")
|
||||||
R<AirlineTempVO> getAirlineByGroupId(@PathVariable("groupId") String groupId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
R<AirlineTempVO> getAirlineByGroupId(@PathVariable("groupId") String groupId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
@GetMapping("/file/{id}")
|
||||||
|
R<AirlineFileVO> getFileById(@PathVariable("id") Long id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
}
|
}
|
||||||
|
|
@ -75,4 +75,24 @@ public class AirLinePointVO implements Serializable {
|
||||||
* 转动方向 -1逆时针 1相对机场方向 (硬件定义的)
|
* 转动方向 -1逆时针 1相对机场方向 (硬件定义的)
|
||||||
*/
|
*/
|
||||||
private Integer rotateDirection;
|
private Integer rotateDirection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 间隔拍照时间(秒)- 命令5000
|
||||||
|
*/
|
||||||
|
private Integer photoTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 间隔拍照距离(米)- 命令6000
|
||||||
|
*/
|
||||||
|
private Integer photoDistance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 照片类型(数组1,2,3)- 命令5000/6000
|
||||||
|
*/
|
||||||
|
private Integer photoType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 飞行器偏航角 - 命令4000
|
||||||
|
*/
|
||||||
|
private String droneYaw;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.ruoyi.airline.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域分组详情 VO
|
||||||
|
*
|
||||||
|
* @author 拓恒
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class AirlineAreaGroupDetailVO extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 分组ID
|
||||||
|
*/
|
||||||
|
private Long groupId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域列表
|
||||||
|
*/
|
||||||
|
private List<AirlineAreaVO> airspaceList;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
.append("groupId", getGroupId())
|
||||||
|
.append("airspaceList", getAirspaceList())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.ruoyi.airline.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域分组 VO
|
||||||
|
*
|
||||||
|
* @author 拓恒
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class AirlineAreaGroupVO extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 用户ID
|
||||||
|
*/
|
||||||
|
private Long groupId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分组名称
|
||||||
|
*/
|
||||||
|
private String groupName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID,分组自带用户归属。后期权限都是基于用户ID进行
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组关联的空域
|
||||||
|
*/
|
||||||
|
private List<AirlineAreaVO> groupInfos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域数量
|
||||||
|
*/
|
||||||
|
private Integer areaCount;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
.append("groupId", getGroupId())
|
||||||
|
.append("groupName", getGroupName())
|
||||||
|
.append("userId", getUserId())
|
||||||
|
.append("areaCount", getAreaCount())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.ruoyi.airline.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域时间规则 VO
|
||||||
|
*
|
||||||
|
* @author 拓恒
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class AirlineAreaTimeRuleVO extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域ID
|
||||||
|
*/
|
||||||
|
private Long areaId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限制类型:0是永久 1:单次,2:自定义
|
||||||
|
*/
|
||||||
|
private Integer restrictType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期范围
|
||||||
|
*/
|
||||||
|
private Object dateRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间范围
|
||||||
|
*/
|
||||||
|
private Object timeRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重复粒度值:0,1,2:日,周,月 restrictType=0时生效
|
||||||
|
*/
|
||||||
|
private Integer granularity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 粒度循环周期:整数值,每1天、每1周,每1个月
|
||||||
|
*/
|
||||||
|
private Integer repetFrequency;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重复粒度具体时间 granularity = 0时,该值为空,不生效;granularity = 1时,granularityTimes最多7个值(1,2,3,4,5,6,7分别周一周二。。。周日),granularity = 2时,granularityTimes最多12个值,(1,2,3,4,5,6,7。。12分别是1月,2月.。。12月)
|
||||||
|
*/
|
||||||
|
private Object granularityTimes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
.append("id", getId())
|
||||||
|
.append("areaId", getAreaId())
|
||||||
|
.append("restrictType", getRestrictType())
|
||||||
|
.append("dateRange", getDateRange())
|
||||||
|
.append("timeRange", getTimeRange())
|
||||||
|
.append("granularity", getGranularity())
|
||||||
|
.append("repetFrequency", getRepetFrequency())
|
||||||
|
.append("granularityTimes", getGranularityTimes())
|
||||||
|
.append("remark", getRemark())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
package com.ruoyi.airline.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域 VO
|
||||||
|
*
|
||||||
|
* @author 拓恒
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class AirlineAreaVO extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域类型
|
||||||
|
*/
|
||||||
|
private String areaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1 启用 0 停用。默认启用。
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域点列表
|
||||||
|
*/
|
||||||
|
private List<PointInfo> points;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 形状
|
||||||
|
*/
|
||||||
|
private String shape;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 面积
|
||||||
|
*/
|
||||||
|
private Double areaArea;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 周长
|
||||||
|
*/
|
||||||
|
private Double areaPerimeter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 半径
|
||||||
|
*/
|
||||||
|
private Double radius;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最小高度
|
||||||
|
*/
|
||||||
|
private Double minHeight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大高度
|
||||||
|
*/
|
||||||
|
private Double maxHeight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间规则列表
|
||||||
|
*/
|
||||||
|
private List<AirlineAreaTimeRuleVO> timeRules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 坐标点信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class PointInfo {
|
||||||
|
/**
|
||||||
|
* 纬度
|
||||||
|
*/
|
||||||
|
private Double latitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经度
|
||||||
|
*/
|
||||||
|
private Double longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
.append("id", getId())
|
||||||
|
.append("name", getName())
|
||||||
|
.append("areaType", getAreaType())
|
||||||
|
.append("status", getStatus())
|
||||||
|
.append("points", getPoints())
|
||||||
|
.append("areaArea", getAreaArea())
|
||||||
|
.append("areaPerimeter", getAreaPerimeter())
|
||||||
|
.append("radius", getRadius())
|
||||||
|
.append("minHeight", getMinHeight())
|
||||||
|
.append("maxHeight", getMaxHeight())
|
||||||
|
.append("timeRules", getTimeRules())
|
||||||
|
.append("remark", getRemark())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,8 @@ public class AirlineFileGroupInfoVO extends BaseEntity {
|
||||||
* id,主键,用于order by 排序
|
* id,主键,用于order by 排序
|
||||||
*/
|
*/
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
private Long airlineId;
|
||||||
/**
|
/**
|
||||||
* 用户ID
|
* 用户ID
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import lombok.EqualsAndHashCode;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 航线分组
|
* 航线分组
|
||||||
*
|
*
|
||||||
|
|
@ -23,18 +25,22 @@ public class AirlineFileGroupVO extends BaseEntity {
|
||||||
* 分组名称
|
* 分组名称
|
||||||
*/
|
*/
|
||||||
private String groupName;
|
private String groupName;
|
||||||
/**
|
|
||||||
* 用户ID,分组自带用户归属。 后期权限都是基于用户ID进行
|
|
||||||
*/
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组关联的航线
|
||||||
|
*/
|
||||||
|
private List<AirlineFileVO> groupInfos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 航线数量
|
||||||
|
*/
|
||||||
|
private Integer airlineCount;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||||
.append("groupId", getGroupId())
|
.append("groupId", groupId)
|
||||||
.append("groupName", getGroupName())
|
.append("groupName", groupName)
|
||||||
.append("userId", getUserId())
|
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,10 @@ public class AirlineFileVO {
|
||||||
* 主键ID
|
* 主键ID
|
||||||
*/
|
*/
|
||||||
private Long id;
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 航线名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
/**
|
/**
|
||||||
* 用户ID
|
* 用户ID
|
||||||
*/
|
*/
|
||||||
|
|
@ -33,7 +36,15 @@ public class AirlineFileVO {
|
||||||
* waypoint文件地址
|
* waypoint文件地址
|
||||||
*/
|
*/
|
||||||
private String fileUrl;
|
private String fileUrl;
|
||||||
|
/**
|
||||||
|
* 飞行器厂商
|
||||||
|
*/
|
||||||
|
private String airVendor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 飞行器类型
|
||||||
|
*/
|
||||||
|
private String airType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 原始航线url
|
* 原始航线url
|
||||||
|
|
@ -42,27 +53,61 @@ public class AirlineFileVO {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 航线类型:1,航点航线;2,指点航线;3,指面航线
|
* 航线类型:waypoint,航点航线;指点航线;指面航线
|
||||||
*/
|
*/
|
||||||
private Integer type;
|
private String type;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 航线点列表
|
* 航线点列表
|
||||||
*/
|
*/
|
||||||
private List<AirLinePointVO> linePointDtoList;
|
private List<AirLinePointVO> linePointVOList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1 启用 0 停用
|
* 1 启用 0 停用
|
||||||
*/
|
*/
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 爬升模式
|
||||||
|
*/
|
||||||
|
private String climbMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 海拔高度
|
||||||
|
*/
|
||||||
|
private Double altitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 飞行速度
|
||||||
|
*/
|
||||||
|
private Double flightSpeed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局航点高度
|
||||||
|
*/
|
||||||
|
private Double globalWaypointHeight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拍照模式
|
||||||
|
*/
|
||||||
|
private String photoMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kmz航线的全局高度
|
* kmz航线的全局高度
|
||||||
*/
|
*/
|
||||||
private Integer djiRthAltitude;
|
private Integer djiRthAltitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分组ID
|
||||||
|
*/
|
||||||
|
private Long groupId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分组名称
|
||||||
|
*/
|
||||||
|
private String groupName;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.ruoyi.airline.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域分组详情 VO
|
||||||
|
*
|
||||||
|
* @author 拓恒
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class AirlineMarkerGroupDetailVO extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 分组ID
|
||||||
|
*/
|
||||||
|
private Long groupId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空域列表
|
||||||
|
*/
|
||||||
|
private List<AirlineMarkerVO> airspaceList;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
.append("groupId", getGroupId())
|
||||||
|
.append("airspaceList", getAirspaceList())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.ruoyi.airline.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标注分组 VO
|
||||||
|
*
|
||||||
|
* @author 拓恒
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class AirlineMarkerGroupVO extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 分组ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分组名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组关联的标注
|
||||||
|
*/
|
||||||
|
private List<AirlineMarkerVO> groupInfos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标注数量
|
||||||
|
*/
|
||||||
|
private Integer markerCount;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
.append("id", getId())
|
||||||
|
.append("name", getName())
|
||||||
|
.append("markerCount", getMarkerCount())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
package com.ruoyi.airline.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标注 VO
|
||||||
|
*
|
||||||
|
* @author 拓恒
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class AirlineMarkerVO extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标注名称
|
||||||
|
*/
|
||||||
|
private String markerName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标注类型
|
||||||
|
*/
|
||||||
|
private String markerType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1 启用 0 停用。默认启用。
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 颜色
|
||||||
|
*/
|
||||||
|
private String color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标
|
||||||
|
*/
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字体大小
|
||||||
|
*/
|
||||||
|
private Integer fontSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经纬度,格式:[经,纬,asl高度]
|
||||||
|
*/
|
||||||
|
private List<PointInfo> coordinates;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分组ID
|
||||||
|
*/
|
||||||
|
private Long groupId;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class PointInfo {
|
||||||
|
/**
|
||||||
|
* 纬度
|
||||||
|
*/
|
||||||
|
private Double latitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经度
|
||||||
|
*/
|
||||||
|
private Double longitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 海拔高度
|
||||||
|
*/
|
||||||
|
private Double asl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
.append("id", getId())
|
||||||
|
.append("markerName", getMarkerName())
|
||||||
|
.append("markerType", getMarkerType())
|
||||||
|
.append("status", getStatus())
|
||||||
|
.append("color", getColor())
|
||||||
|
.append("icon", getIcon())
|
||||||
|
.append("fontSize", getFontSize())
|
||||||
|
.append("coordinates", getCoordinates())
|
||||||
|
.append("description", getDescription())
|
||||||
|
.append("groupId", getGroupId())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.ruoyi.airline.api.factory;
|
package com.ruoyi.airline.api.factory;
|
||||||
|
|
||||||
import com.ruoyi.airline.api.RemoteAirlineService;
|
import com.ruoyi.airline.api.RemoteAirlineService;
|
||||||
|
import com.ruoyi.airline.api.domain.AirlineFileVO;
|
||||||
|
import com.ruoyi.airline.api.domain.AirlineTempVO;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
@ -22,6 +24,16 @@ public class RemoteAirlineFallbackFactory implements FallbackFactory<RemoteAirli
|
||||||
public RemoteAirlineService create(Throwable throwable)
|
public RemoteAirlineService create(Throwable throwable)
|
||||||
{
|
{
|
||||||
log.error("航线服务调用失败:{}", throwable.getMessage());
|
log.error("航线服务调用失败:{}", throwable.getMessage());
|
||||||
return (id, source) -> R.fail("获取航线信息失败:" + throwable.getMessage());
|
return new RemoteAirlineService() {
|
||||||
|
@Override
|
||||||
|
public R<AirlineTempVO> getAirlineByGroupId(String groupId, String source) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<AirlineFileVO> getFileById(Long id, String source) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
com.ruoyi.airline.api.factory.RemoteAirlineFallbackFactory
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
package com.ruoyi.device.api;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||||
|
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.device.api.domain.DroneCurrentStatusVO;
|
||||||
|
import com.ruoyi.device.api.domain.DroneFlightControlRequest;
|
||||||
|
import com.ruoyi.device.api.domain.DroneRealtimeInfoVO;
|
||||||
|
import com.ruoyi.device.api.domain.DroneTakeoffResponseVO;
|
||||||
|
import com.ruoyi.device.api.domain.MachineStateVO;
|
||||||
|
import com.ruoyi.device.api.factory.RemoteAircraftFlyFallbackFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机飞控服务
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-04
|
||||||
|
*/
|
||||||
|
@FeignClient(contextId = "remoteAircraftFlyService", value = ServiceNameConstants.DEVICE_SERVICE, fallbackFactory = RemoteAircraftFlyFallbackFactory.class)
|
||||||
|
public interface RemoteAircraftFlyService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 无人机飞控命令
|
||||||
|
*
|
||||||
|
* @param request 飞控命令请求
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/drone/flight-control")
|
||||||
|
R<Void> flightControl(@RequestBody DroneFlightControlRequest request, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机实时信息展示
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 实时信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/drone/realtime-info/{taskId}")
|
||||||
|
R<DroneRealtimeInfoVO> getRealtimeInfo(@PathVariable("taskId") Long taskId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机当前状态查询
|
||||||
|
*
|
||||||
|
* @param dockId 机场ID
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 当前状态
|
||||||
|
*/
|
||||||
|
@GetMapping("/drone/current-status/{dockId}")
|
||||||
|
R<DroneCurrentStatusVO> getCurrentStatus(@PathVariable("dockId") Long dockId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机起飞接口
|
||||||
|
*
|
||||||
|
* @param sn 机场SN号
|
||||||
|
* @return 起飞响应
|
||||||
|
*/
|
||||||
|
@PostMapping("/drone/takeoff/{sn}")
|
||||||
|
R<String> takeoff(@PathVariable("sn") String sn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机开机接口
|
||||||
|
*
|
||||||
|
* @param sn 机场SN号
|
||||||
|
* @return 开机响应
|
||||||
|
*/
|
||||||
|
@PostMapping("/drone/power-on/{sn}")
|
||||||
|
R<String> powerOn(@PathVariable("sn") String sn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机关机接口
|
||||||
|
*
|
||||||
|
* @param sn 机场SN号
|
||||||
|
* @return 关机响应
|
||||||
|
*/
|
||||||
|
@PostMapping("/drone/power-off/{sn}")
|
||||||
|
R<String> powerOff(@PathVariable("sn") String sn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询设备状态
|
||||||
|
*
|
||||||
|
* @param sn 设备SN号
|
||||||
|
* @return 设备状态信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/drone/machine-state/{sn}")
|
||||||
|
R<MachineStateVO> getMachineState(@PathVariable("sn") String sn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出舱接口
|
||||||
|
*
|
||||||
|
* @param sn 机场SN号
|
||||||
|
* @return 出舱响应
|
||||||
|
*/
|
||||||
|
@PostMapping("/drone/cover-open/{sn}")
|
||||||
|
R<String> coverOpen(@PathVariable("sn") String sn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回舱接口
|
||||||
|
*
|
||||||
|
* @param sn 机场SN号
|
||||||
|
* @return 回舱响应
|
||||||
|
*/
|
||||||
|
@PostMapping("/drone/cover-close/{sn}")
|
||||||
|
R<String> coverClose(@PathVariable("sn") String sn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机返航接口
|
||||||
|
*
|
||||||
|
* @param sn 机场SN号
|
||||||
|
* @return 返航响应
|
||||||
|
*/
|
||||||
|
@PostMapping("/drone/return-home/{sn}")
|
||||||
|
R<String> returnHome(@PathVariable("sn") String sn);
|
||||||
|
}
|
||||||
|
|
@ -4,10 +4,13 @@ import com.ruoyi.common.core.constant.SecurityConstants;
|
||||||
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.device.api.domain.AircraftDetailVO;
|
import com.ruoyi.device.api.domain.AircraftDetailVO;
|
||||||
|
import com.ruoyi.device.api.domain.DockAircraftVO;
|
||||||
import com.ruoyi.device.api.factory.RemoteAircraftFallbackFactory;
|
import com.ruoyi.device.api.factory.RemoteAircraftFallbackFactory;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 无人机服务
|
* 无人机服务
|
||||||
*
|
*
|
||||||
|
|
@ -26,4 +29,13 @@ public interface RemoteAircraftService
|
||||||
*/
|
*/
|
||||||
@GetMapping("/aircraft/detail/{aircraftId}")
|
@GetMapping("/aircraft/detail/{aircraftId}")
|
||||||
R<AircraftDetailVO> getAircraftDetail(@PathVariable("aircraftId") Long aircraftId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
R<AircraftDetailVO> getAircraftDetail(@PathVariable("aircraftId") Long aircraftId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有机场和机场的无人机
|
||||||
|
*
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@GetMapping("/aircraft/dock-aircraft-list")
|
||||||
|
R<List<DockAircraftVO>> getDockAircraftList(@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机负载类型VO
|
||||||
|
*
|
||||||
|
* @author 拓恒
|
||||||
|
* @date 2026-03-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AirLoadTypeVO implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 负载名称 */
|
||||||
|
private String loadName;
|
||||||
|
|
||||||
|
/** 负载系列 */
|
||||||
|
private String loadSeries;
|
||||||
|
|
||||||
|
/** 负载分类:0-负载,1-配件 */
|
||||||
|
private Integer loadCategory;
|
||||||
|
|
||||||
|
/** 槽:1、2 或者-1(-1代表全部槽位可用) */
|
||||||
|
private Integer slot;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机分类分组VO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-09
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class AirTypeCategoryGroupVO extends BaseEntity {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类标签
|
||||||
|
*/
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机类型列表
|
||||||
|
*/
|
||||||
|
private List<AirTypeGeneralEnumVO> airTypeList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机类型通用枚举VO
|
||||||
|
* Controller 层输入参数
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-01-28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AirTypeGeneralEnumVO implements Serializable
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 主键 */
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 名称 */
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 厂商ID */
|
||||||
|
private Long vendorId;
|
||||||
|
|
||||||
|
/** 领域 */
|
||||||
|
private Long domain;
|
||||||
|
|
||||||
|
/** 主类型 */
|
||||||
|
private Long type;
|
||||||
|
|
||||||
|
/** 子类型 */
|
||||||
|
private Long subType;
|
||||||
|
|
||||||
|
/** 类型编码(domain-type-subType) */
|
||||||
|
private String airType;
|
||||||
|
|
||||||
|
/** 图标 */
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
/** 分类 */
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
/** 是否生效:0-失效,1-生效 */
|
||||||
|
private Integer enabled;
|
||||||
|
|
||||||
|
/** 槽位数 */
|
||||||
|
private Integer slotCount;
|
||||||
|
|
||||||
|
/** 负载数量限制 */
|
||||||
|
private Integer loadLimit;
|
||||||
|
|
||||||
|
/** 配件限制数量 */
|
||||||
|
private Integer accessoryLimit;
|
||||||
|
|
||||||
|
/** 可用负载列表(按系列分组) */
|
||||||
|
private Map<String, List<AirLoadTypeVO>> loadList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成类型编码(domain-type-subType)
|
||||||
|
*/
|
||||||
|
public void generateTypeCode() {
|
||||||
|
this.airType = String.format("%d-%d-%d", domain, type, subType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机厂商分组VO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-01-29
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class AirTypeVendorGroupVO extends BaseEntity {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 厂商标签
|
||||||
|
*/
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 厂商值
|
||||||
|
*/
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机分类分组列表
|
||||||
|
*/
|
||||||
|
private List<AirTypeCategoryGroupVO> categoryGroups;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机类型列表
|
||||||
|
*/
|
||||||
|
private List<AirTypeGeneralEnumVO> airTypeList;
|
||||||
|
}
|
||||||
|
|
@ -69,7 +69,11 @@ public class AircraftDetailVO extends AircraftVO {
|
||||||
/** RTK信号 */
|
/** RTK信号 */
|
||||||
@Schema(description = "RTK信号")
|
@Schema(description = "RTK信号")
|
||||||
@Excel(name = "RTK信号")
|
@Excel(name = "RTK信号")
|
||||||
private Double rtkSignal;
|
private Integer rtkSignal;
|
||||||
|
|
||||||
|
@Schema(description = "GPS信号")
|
||||||
|
@Excel(name = "GPS信号")
|
||||||
|
private Integer gpsSignal;
|
||||||
|
|
||||||
/** 限高 */
|
/** 限高 */
|
||||||
@Schema(description = "限高")
|
@Schema(description = "限高")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 机场无人机VO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-03-13
|
||||||
|
*/
|
||||||
|
public class DockAircraftVO {
|
||||||
|
|
||||||
|
/** 无人机设备SN */
|
||||||
|
private String deviceSn;
|
||||||
|
|
||||||
|
/** 无人机名称 */
|
||||||
|
private String aircraftName;
|
||||||
|
|
||||||
|
/** 机场名称 */
|
||||||
|
private String dockName;
|
||||||
|
|
||||||
|
public String getDeviceSn() {
|
||||||
|
return deviceSn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceSn(String deviceSn) {
|
||||||
|
this.deviceSn = deviceSn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAircraftName() {
|
||||||
|
return aircraftName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAircraftName(String aircraftName) {
|
||||||
|
this.aircraftName = aircraftName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDockName() {
|
||||||
|
return dockName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDockName(String dockName) {
|
||||||
|
this.dockName = dockName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -147,9 +147,7 @@ public class DockDetailVO extends DockVO {
|
||||||
/**
|
/**
|
||||||
* 机场状态
|
* 机场状态
|
||||||
*/
|
*/
|
||||||
@Schema(description = "机场运行状态: IDLE-空闲中, Debugging-现场调试/远程调试, Upgrading-固件升级中, Working-作业中, UNKNOWN-待标定, OFFLINE-离线",
|
@Excel(name = "机场是否正常")
|
||||||
allowableValues = {"IDLE", "Debugging", "Upgrading", "Working", "UNKNOWN", "OFFLINE"})
|
|
||||||
@Excel(name = "机场运行状态")
|
|
||||||
private String dockRunStatus;
|
private String dockRunStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -169,10 +167,18 @@ public class DockDetailVO extends DockVO {
|
||||||
/**
|
/**
|
||||||
* 充放电状态
|
* 充放电状态
|
||||||
*/
|
*/
|
||||||
@Schema(description = "充放电状态")
|
@Schema(description = "充放电状态 空闲: FREE 充电中: CHARGING")
|
||||||
@Excel(name = "充放电状态")
|
@Excel(name = "充放电状态")
|
||||||
private String chargingStatus;
|
private String chargingStatus;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电量百分比
|
||||||
|
*/
|
||||||
|
@Schema(description = "电量百分比")
|
||||||
|
@Excel(name = "电量百分比")
|
||||||
|
private Integer capacity_percent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 舱内温度
|
* 舱内温度
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -91,4 +92,9 @@ public class DockVO implements Serializable {
|
||||||
@Schema(description = "挂载列表")
|
@Schema(description = "挂载列表")
|
||||||
private List<PayloadVO> payloadList;
|
private List<PayloadVO> payloadList;
|
||||||
|
|
||||||
|
/** 最后活跃时间 */
|
||||||
|
@Schema(description = "最后活跃时间")
|
||||||
|
@Excel(name = "最后活跃时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date lastActiveTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,4 +82,24 @@ public class DockWithGPSVO implements Serializable {
|
||||||
@Schema(description = "经度")
|
@Schema(description = "经度")
|
||||||
private Double longitude;
|
private Double longitude;
|
||||||
|
|
||||||
|
/** 电量 */
|
||||||
|
@Schema(description = "电量百分比")
|
||||||
|
private Integer capacity_percent;
|
||||||
|
|
||||||
|
/** 充放电状态 */
|
||||||
|
@Schema(description = "充放电状态")
|
||||||
|
private String chargingStatus;
|
||||||
|
|
||||||
|
@Schema(description = "无人机SN号")
|
||||||
|
private String snNumber;
|
||||||
|
|
||||||
|
@Schema(description = "舱内视频地址")
|
||||||
|
private String cabinVideoUrl;
|
||||||
|
|
||||||
|
@Schema(description = "舱外视频地址")
|
||||||
|
private String outsideVideoUrl;
|
||||||
|
|
||||||
|
@Schema(description = "直播视频地址")
|
||||||
|
private String liveVideoUrl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.device.api.enums.DroneCurrentStatusEnum;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机当前状态查询对象
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "无人机当前状态查询对象")
|
||||||
|
public class DroneCurrentStatusVO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 机场ID */
|
||||||
|
@Schema(description = "机场ID", example = "1")
|
||||||
|
private Long dockId;
|
||||||
|
|
||||||
|
/** 当前状态 */
|
||||||
|
@Schema(description = "当前状态: TAKEOFF_FAILED-起飞失败, FLYING-飞行中, POINTING-指点中, HOVERING-悬停中, RETURNING-返航中, LANDING-降落中",
|
||||||
|
allowableValues = {"TAKEOFF_FAILED", "FLYING", "POINTING", "HOVERING", "RETURNING", "LANDING"},
|
||||||
|
example = "HOVERING")
|
||||||
|
private DroneCurrentStatusEnum currentStatus;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.device.api.enums.DroneCommandEnum;
|
||||||
|
import com.ruoyi.device.api.enums.DroneSpeedEnum;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机飞控命令请求对象
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "无人机飞控命令请求对象")
|
||||||
|
public class DroneFlightControlRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 机场SN号 */
|
||||||
|
@Schema(description = "机场SN号", example = "THJSQ03B2309DN7VQN43")
|
||||||
|
private String sn;
|
||||||
|
|
||||||
|
/** 任务ID */
|
||||||
|
@Schema(description = "任务ID", example = "1")
|
||||||
|
private Long taskId;
|
||||||
|
|
||||||
|
/** 飞控命令 */
|
||||||
|
@Schema(description = "飞控命令: FORWARD-前进, BACKWARD-后退, LEFT-左移, RIGHT-右移, ROTATE_LEFT-左旋, ROTATE_RIGHT-右旋, UP-上升, DOWN-下降, RETURN_HOME-返航, EMERGENCY_STOP-急停, AIRLINE_FLIGHT-航线飞行, HOVER-悬停, CONTINUE_TASK-继续任务",
|
||||||
|
allowableValues = {"FORWARD", "BACKWARD", "LEFT", "RIGHT", "ROTATE_LEFT", "ROTATE_RIGHT", "UP", "DOWN", "RETURN_HOME", "EMERGENCY_STOP", "AIRLINE_FLIGHT", "HOVER", "CONTINUE_TASK"},
|
||||||
|
example = "FORWARD")
|
||||||
|
private DroneCommandEnum command;
|
||||||
|
|
||||||
|
/** 速度调整:快、默认、慢 */
|
||||||
|
@Schema(description = "速度调整: FAST-快, NORMAL-默认, SLOW-慢",
|
||||||
|
allowableValues = {"FAST", "NORMAL", "SLOW"},
|
||||||
|
example = "NORMAL")
|
||||||
|
private DroneSpeedEnum speed;
|
||||||
|
|
||||||
|
/** 幅度调整:数值类型 */
|
||||||
|
@Schema(description = "幅度调整(数值类型,单位:米)", example = "10")
|
||||||
|
private Integer amplitude;
|
||||||
|
|
||||||
|
/** 消息ID */
|
||||||
|
@Schema(description = "消息ID", example = "9056")
|
||||||
|
private Long messageID;
|
||||||
|
|
||||||
|
/** 扩展值(用于云台控制等) */
|
||||||
|
@Schema(description = "扩展值(用于云台控制等)", example = "90")
|
||||||
|
private String evalue;
|
||||||
|
|
||||||
|
/** 值(用于云台控制等) */
|
||||||
|
@Schema(description = "值(用于云台控制等)", example = "04")
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
//专门用于云台变焦命令的,用于指定相机的灯光模式。
|
||||||
|
/** 灯光模式(用于相机控制) */
|
||||||
|
@Schema(description = "灯光模式(用于相机控制)", example = "visibleLight")
|
||||||
|
private String lightMode;
|
||||||
|
|
||||||
|
/** 航线文件URL(用于航线飞行) */
|
||||||
|
@Schema(description = "航线文件URL(用于航线飞行)", example = "https://minio-jndsj.t-aaron.com:2443/th-airport/testFile/55e8cc5b-d145-43ff-9386-8daabcb5b816.waypoints")
|
||||||
|
private String airlineFileUrl;
|
||||||
|
|
||||||
|
/** 最低飞行电池电量(用于航线飞行) */
|
||||||
|
@Schema(description = "最低飞行电池电量(用于航线飞行)", example = "0.3")
|
||||||
|
private Double flyBatteryMin;
|
||||||
|
|
||||||
|
/** 是否必须飞行(用于航线飞行) */
|
||||||
|
@Schema(description = "是否必须飞行(用于航线飞行)", example = "0")
|
||||||
|
private Integer isMustFly;
|
||||||
|
|
||||||
|
/** 指令类型(用于悬停和继续任务) */
|
||||||
|
@Schema(description = "指令类型(用于悬停和继续任务)", example = "01")
|
||||||
|
private String zhilin;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.device.api.enums.DroneMissionStatusEnum;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机实时信息展示对象
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "无人机实时信息展示对象")
|
||||||
|
public class DroneRealtimeInfoVO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 爬升速度 */
|
||||||
|
@Schema(description = "爬升速度(单位:m/s)", example = "5")
|
||||||
|
private Integer climbSpeed;
|
||||||
|
|
||||||
|
/** 平飞速度 */
|
||||||
|
@Schema(description = "平飞速度(单位:m/s)", example = "15")
|
||||||
|
private Integer cruiseSpeed;
|
||||||
|
|
||||||
|
/** 距离机场 */
|
||||||
|
@Schema(description = "距离机场(单位:米)", example = "1000")
|
||||||
|
private Integer distanceToAirport;
|
||||||
|
|
||||||
|
/** 无人机高度 */
|
||||||
|
@Schema(description = "无人机高度(单位:米)", example = "100")
|
||||||
|
private Integer altitude;
|
||||||
|
|
||||||
|
/** 无人机俯仰角 */
|
||||||
|
@Schema(description = "无人机俯仰角(单位:度,范围:-90~90)", example = "0")
|
||||||
|
private Integer pitch;
|
||||||
|
|
||||||
|
/** 无人机偏航角 */
|
||||||
|
@Schema(description = "无人机偏航角(单位:度,范围:0~360)", example = "180")
|
||||||
|
private Integer yaw;
|
||||||
|
|
||||||
|
/** 云台俯仰角 */
|
||||||
|
@Schema(description = "云台俯仰角(单位:度,范围:-90~90)", example = "-45")
|
||||||
|
private Integer gimbalPitch;
|
||||||
|
|
||||||
|
/** 云台偏航角 */
|
||||||
|
@Schema(description = "云台偏航角(单位:度,范围:0~360)", example = "90")
|
||||||
|
private Integer gimbalYaw;
|
||||||
|
|
||||||
|
/** 无人机任务状态 */
|
||||||
|
@Schema(description = "无人机任务状态: IDLE-空闲, SELF_CHECKING-自检中, SELF_CHECK_FAILED-自检失败, TAKING_OFF-起飞中, TAKEOFF_FAILED-起飞失败, FLYING-飞行中, POINTING-指点中, HOVERING-悬停中, RETURNING-返航中, LANDING-降落中",
|
||||||
|
allowableValues = {"IDLE", "SELF_CHECKING", "SELF_CHECK_FAILED", "TAKING_OFF", "TAKEOFF_FAILED", "FLYING", "POINTING", "HOVERING", "RETURNING", "LANDING"},
|
||||||
|
example = "FLYING")
|
||||||
|
private DroneMissionStatusEnum missionStatus;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机返航请求对象
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-27
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "无人机返航请求对象")
|
||||||
|
public class DroneReturnHomeRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 机场SN号 */
|
||||||
|
@Schema(description = "机场SN号", example = "THJSQ03B2309DN7VQN43")
|
||||||
|
private String sn;
|
||||||
|
//
|
||||||
|
// /** 消息ID */
|
||||||
|
// @Schema(description = "消息ID", example = "9056")
|
||||||
|
// private Long messageID;
|
||||||
|
//
|
||||||
|
// /** 任务ID */
|
||||||
|
// @Schema(description = "任务ID", example = "9074")
|
||||||
|
// private Long taskId;
|
||||||
|
|
||||||
|
// /** 返航类型 */
|
||||||
|
// @Schema(description = "返航类型", example = "03")
|
||||||
|
// private String zhilin;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机起飞请求对象
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-27
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "无人机起飞请求对象")
|
||||||
|
public class DroneTakeoffRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 机场SN号 */
|
||||||
|
@Schema(description = "机场SN号", example = "THJSQ03B2309DN7VQN43")
|
||||||
|
private String sn;
|
||||||
|
//
|
||||||
|
// /** 消息ID */
|
||||||
|
// @Schema(description = "消息ID", example = "9056")
|
||||||
|
// private Long messageID;
|
||||||
|
|
||||||
|
// /** 航线文件URL */
|
||||||
|
// @Schema(description = "航线文件URL", example = "https://minio-jndsj.t-aaron.com:2443/th-airport/testFile/13912c62-b96f-4df5-ab65-813c8c4b04eb.waypoints")
|
||||||
|
// private String airlineFileUrl;
|
||||||
|
|
||||||
|
/** 最低电池电量 */
|
||||||
|
@Schema(description = "最低电池电量", example = "0.3")
|
||||||
|
private Double flyBatteryMin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务ID
|
||||||
|
*/
|
||||||
|
private Long taskId;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.device.api.enums.DroneMissionStatusEnum;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机起飞响应对象
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "无人机起飞响应对象")
|
||||||
|
public class DroneTakeoffResponseVO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 任务ID */
|
||||||
|
@Schema(description = "任务ID", example = "1001")
|
||||||
|
private Long taskId;
|
||||||
|
|
||||||
|
/** 无人机任务状态 */
|
||||||
|
@Schema(description = "无人机任务状态: IDLE-空闲, SELF_CHECKING-自检中, SELF_CHECK_FAILED-自检失败, TAKING_OFF-起飞中, TAKEOFF_FAILED-起飞失败, FLYING-飞行中, POINTING-指点中, HOVERING-悬停中, RETURNING-返航中, LANDING-降落中",
|
||||||
|
allowableValues = {"IDLE", "SELF_CHECKING", "SELF_CHECK_FAILED", "TAKING_OFF", "TAKEOFF_FAILED", "FLYING", "POINTING", "HOVERING", "RETURNING", "LANDING"},
|
||||||
|
example = "TAKING_OFF")
|
||||||
|
private DroneMissionStatusEnum missionStatus;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
package com.ruoyi.device.api.domain;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备状态视图对象
|
||||||
|
* API 层 VO,用于前后端数据交互
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-10
|
||||||
|
*/
|
||||||
|
public class MachineStateVO implements Serializable
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 设备SN号 */
|
||||||
|
private String sn;
|
||||||
|
|
||||||
|
/** 无人机状态 */
|
||||||
|
private String droneState;
|
||||||
|
|
||||||
|
/** 机场状态 */
|
||||||
|
private String airportState;
|
||||||
|
|
||||||
|
/** 舱门状态 */
|
||||||
|
private String coverState;
|
||||||
|
|
||||||
|
/** DRC状态 */
|
||||||
|
private String drcState;
|
||||||
|
|
||||||
|
/** 调试模式状态 */
|
||||||
|
private String debugModeState;
|
||||||
|
|
||||||
|
public String getSn()
|
||||||
|
{
|
||||||
|
return sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSn(String sn)
|
||||||
|
{
|
||||||
|
this.sn = sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDroneState()
|
||||||
|
{
|
||||||
|
return droneState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDroneState(String droneState)
|
||||||
|
{
|
||||||
|
this.droneState = droneState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAirportState()
|
||||||
|
{
|
||||||
|
return airportState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAirportState(String airportState)
|
||||||
|
{
|
||||||
|
this.airportState = airportState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCoverState()
|
||||||
|
{
|
||||||
|
return coverState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCoverState(String coverState)
|
||||||
|
{
|
||||||
|
this.coverState = coverState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDrcState()
|
||||||
|
{
|
||||||
|
return drcState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDrcState(String drcState)
|
||||||
|
{
|
||||||
|
this.drcState = drcState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDebugModeState()
|
||||||
|
{
|
||||||
|
return debugModeState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDebugModeState(String debugModeState)
|
||||||
|
{
|
||||||
|
this.debugModeState = debugModeState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "MachineStateVO{" +
|
||||||
|
"sn='" + sn + '\'' +
|
||||||
|
", droneState='" + droneState + '\'' +
|
||||||
|
", airportState='" + airportState + '\'' +
|
||||||
|
", coverState='" + coverState + '\'' +
|
||||||
|
", drcState='" + drcState + '\'' +
|
||||||
|
", debugModeState='" + debugModeState + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,8 @@ import java.util.List;
|
||||||
@Data
|
@Data
|
||||||
public class SwitchDockGroupRequest
|
public class SwitchDockGroupRequest
|
||||||
{
|
{
|
||||||
|
@Excel(name = "机场ID 列表")
|
||||||
|
private Long dockId;
|
||||||
|
|
||||||
@Excel(name = "机场ID 列表")
|
@Excel(name = "机场ID 列表")
|
||||||
private List<Long> dockIds;
|
private List<Long> dockIds;
|
||||||
|
|
|
||||||
|
|
@ -16,17 +16,17 @@ public enum DockStatusEnum {
|
||||||
/**
|
/**
|
||||||
* 现场调试/远程调试
|
* 现场调试/远程调试
|
||||||
*/
|
*/
|
||||||
Debugging("Debugging", "现场调试/远程调试"),
|
Debugging("DEBUGGING", "现场调试/远程调试"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 固件升级中
|
* 固件升级中
|
||||||
*/
|
*/
|
||||||
FIRMWARE_UPGRADING("Upgrading", "固件升级中"),
|
FIRMWARE_UPGRADING("UPGRADING", "固件升级中"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 作业中
|
* 作业中
|
||||||
*/
|
*/
|
||||||
WORKING("Working", "作业中"),
|
WORKING("WORKING", "作业中"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 待标定/未知
|
* 待标定/未知
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
package com.ruoyi.device.api.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机飞控命令枚举
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-04
|
||||||
|
*/
|
||||||
|
public enum DroneCommandEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前进
|
||||||
|
*/
|
||||||
|
FORWARD("FORWARD", "前进"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后退
|
||||||
|
*/
|
||||||
|
BACKWARD("BACKWARD", "后退"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 左移
|
||||||
|
*/
|
||||||
|
LEFT("LEFT", "左移"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 右移
|
||||||
|
*/
|
||||||
|
RIGHT("RIGHT", "右移"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 左旋
|
||||||
|
*/
|
||||||
|
ROTATE_LEFT("ROTATE_LEFT", "左旋"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 右旋
|
||||||
|
*/
|
||||||
|
ROTATE_RIGHT("ROTATE_RIGHT", "右旋"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上升
|
||||||
|
*/
|
||||||
|
UP("UP", "上升"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下降
|
||||||
|
*/
|
||||||
|
DOWN("DOWN", "下降"),
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 返航
|
||||||
|
// */
|
||||||
|
// RETURN_HOME("RETURN_HOME", "返航"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 急停
|
||||||
|
*/
|
||||||
|
EMERGENCY_STOP("EMERGENCY_STOP", "急停"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换可见光
|
||||||
|
*/
|
||||||
|
SWITCH_VISIBLE_LIGHT("SWITCH_VISIBLE_LIGHT", "切换可见光"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云台变焦
|
||||||
|
*/
|
||||||
|
GIMBAL_ZOOM("GIMBAL_ZOOM", "云台变焦"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换红外
|
||||||
|
*/
|
||||||
|
SWITCH_IR("SWITCH_IR", "切换红外"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换广角
|
||||||
|
*/
|
||||||
|
SWITCH_WIDE_ANGLE("SWITCH_WIDE_ANGLE", "切换广角"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云台右移
|
||||||
|
*/
|
||||||
|
GIMBAL_MOVE_RIGHT("GIMBAL_MOVE_RIGHT", "云台右移"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云台左移
|
||||||
|
*/
|
||||||
|
GIMBAL_MOVE_LEFT("GIMBAL_MOVE_LEFT", "云台左移"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云台俯仰(上)
|
||||||
|
*/
|
||||||
|
GIMBAL_PITCH_UP("GIMBAL_PITCH_UP", "云台俯仰(上)"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云台俯仰(下)
|
||||||
|
*/
|
||||||
|
GIMBAL_PITCH_DOWN("GIMBAL_PITCH_DOWN", "云台俯仰(下)"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云台复位
|
||||||
|
*/
|
||||||
|
GIMBAL_RESET("GIMBAL_RESET", "云台复位"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 航线飞行
|
||||||
|
*/
|
||||||
|
AIRLINE_FLIGHT("AIRLINE_FLIGHT", "航线飞行"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 悬停
|
||||||
|
*/
|
||||||
|
HOVER("HOVER", "悬停"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 继续任务
|
||||||
|
*/
|
||||||
|
CONTINUE_TASK("CONTINUE_TASK", "继续任务");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
DroneCommandEnum(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.ruoyi.device.api.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机当前状态枚举
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-04
|
||||||
|
*/
|
||||||
|
public enum DroneCurrentStatusEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 起飞失败
|
||||||
|
*/
|
||||||
|
TAKEOFF_FAILED("TAKEOFF_FAILED", "起飞失败"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 飞行中
|
||||||
|
*/
|
||||||
|
FLYING("FLYING", "飞行中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指点中
|
||||||
|
*/
|
||||||
|
POINTING("POINTING", "指点中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 悬停中
|
||||||
|
*/
|
||||||
|
HOVERING("HOVERING", "悬停中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返航中
|
||||||
|
*/
|
||||||
|
RETURNING("RETURNING", "返航中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 降落中
|
||||||
|
*/
|
||||||
|
LANDING("LANDING", "降落中");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
DroneCurrentStatusEnum(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.ruoyi.device.api.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机任务状态枚举
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-04
|
||||||
|
*/
|
||||||
|
public enum DroneMissionStatusEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空闲
|
||||||
|
*/
|
||||||
|
IDLE("IDLE", "空闲"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自检中
|
||||||
|
*/
|
||||||
|
SELF_CHECKING("SELF_CHECKING", "自检中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自检失败
|
||||||
|
*/
|
||||||
|
SELF_CHECK_FAILED("SELF_CHECK_FAILED", "自检失败"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 起飞中
|
||||||
|
*/
|
||||||
|
TAKING_OFF("TAKING_OFF", "起飞中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 起飞失败
|
||||||
|
*/
|
||||||
|
TAKEOFF_FAILED("TAKEOFF_FAILED", "起飞失败"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 飞行中
|
||||||
|
*/
|
||||||
|
FLYING("FLYING", "飞行中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指点中
|
||||||
|
*/
|
||||||
|
POINTING("POINTING", "指点中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 悬停中
|
||||||
|
*/
|
||||||
|
HOVERING("HOVERING", "悬停中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返航中
|
||||||
|
*/
|
||||||
|
RETURNING("RETURNING", "返航中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 降落中
|
||||||
|
*/
|
||||||
|
LANDING("LANDING", "降落中");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
DroneMissionStatusEnum(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.ruoyi.device.api.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机速度调整枚举
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-04
|
||||||
|
*/
|
||||||
|
public enum DroneSpeedEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快速
|
||||||
|
*/
|
||||||
|
FAST("FAST", "快"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认
|
||||||
|
*/
|
||||||
|
NORMAL("NORMAL", "默认"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 慢速
|
||||||
|
*/
|
||||||
|
SLOW("SLOW", "慢");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
DroneSpeedEnum(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,11 +3,14 @@ package com.ruoyi.device.api.factory;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.device.api.RemoteAircraftService;
|
import com.ruoyi.device.api.RemoteAircraftService;
|
||||||
import com.ruoyi.device.api.domain.AircraftDetailVO;
|
import com.ruoyi.device.api.domain.AircraftDetailVO;
|
||||||
|
import com.ruoyi.device.api.domain.DockAircraftVO;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 无人机服务降级处理
|
* 无人机服务降级处理
|
||||||
*
|
*
|
||||||
|
|
@ -30,6 +33,12 @@ public class RemoteAircraftFallbackFactory implements FallbackFactory<RemoteAirc
|
||||||
{
|
{
|
||||||
return R.fail("查看无人机详情失败:" + throwable.getMessage());
|
return R.fail("查看无人机详情失败:" + throwable.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<List<DockAircraftVO>> getDockAircraftList(String source)
|
||||||
|
{
|
||||||
|
return R.fail("获取机场无人机列表失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
package com.ruoyi.device.api.factory;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.device.api.RemoteAircraftFlyService;
|
||||||
|
import com.ruoyi.device.api.domain.DroneCurrentStatusVO;
|
||||||
|
import com.ruoyi.device.api.domain.DroneFlightControlRequest;
|
||||||
|
import com.ruoyi.device.api.domain.DroneRealtimeInfoVO;
|
||||||
|
import com.ruoyi.device.api.domain.DroneTakeoffResponseVO;
|
||||||
|
import com.ruoyi.device.api.domain.MachineStateVO;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机飞控服务降级处理
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-02-04
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class RemoteAircraftFlyFallbackFactory implements FallbackFactory<RemoteAircraftFlyService>
|
||||||
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(RemoteAircraftFlyFallbackFactory.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteAircraftFlyService create(Throwable throwable)
|
||||||
|
{
|
||||||
|
log.error("无人机飞控服务调用失败:{}", throwable.getMessage());
|
||||||
|
return new RemoteAircraftFlyService()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public R<Void> flightControl(DroneFlightControlRequest request, String source)
|
||||||
|
{
|
||||||
|
return R.fail("无人机飞控命令执行失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<DroneRealtimeInfoVO> getRealtimeInfo(Long taskId, String source)
|
||||||
|
{
|
||||||
|
return R.fail("获取无人机实时信息失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<DroneCurrentStatusVO> getCurrentStatus(Long dockId, String source)
|
||||||
|
{
|
||||||
|
return R.fail("查询无人机当前状态失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<String> takeoff(String sn)
|
||||||
|
{
|
||||||
|
return R.fail("无人机起飞失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<String> powerOn(String sn)
|
||||||
|
{
|
||||||
|
return R.fail("无人机开机失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<String> powerOff(String sn)
|
||||||
|
{
|
||||||
|
return R.fail("无人机关机失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<MachineStateVO> getMachineState(String sn)
|
||||||
|
{
|
||||||
|
return R.fail("查询设备状态失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<String> coverOpen(String sn)
|
||||||
|
{
|
||||||
|
return R.fail("出舱失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<String> coverClose(String sn)
|
||||||
|
{
|
||||||
|
return R.fail("回舱失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<String> returnHome(String sn)
|
||||||
|
{
|
||||||
|
return R.fail("返航失败:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
com.ruoyi.device.api.factory.RemoteAircraftFallbackFactory
|
||||||
|
com.ruoyi.device.api.factory.RemoteAircraftFlyFallbackFactory
|
||||||
|
com.ruoyi.device.api.factory.RemoteDeviceFallbackFactory
|
||||||
|
com.ruoyi.device.api.factory.RemoteDockFallbackFactory
|
||||||
|
com.ruoyi.device.api.factory.RemoteGroupFallbackFactory
|
||||||
|
com.ruoyi.device.api.factory.RemoteStatisticsFallbackFactory
|
||||||
|
|
@ -22,6 +22,20 @@
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi-common-core</artifactId>
|
<artifactId>ruoyi-common-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Cloud OpenFeign -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.ruoyi.task.api;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||||
|
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.task.api.domain.TaskPlanDTO;
|
||||||
|
import com.ruoyi.task.api.domain.TaskPlanQueryDTO;
|
||||||
|
import com.ruoyi.task.api.factory.RemoteTaskPlanFallbackFactory;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务计划服务
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-03-06
|
||||||
|
*/
|
||||||
|
@FeignClient(contextId = "remoteTaskPlanService", value = ServiceNameConstants.TASK_SERVICE, fallbackFactory = RemoteTaskPlanFallbackFactory.class)
|
||||||
|
public interface RemoteTaskPlanService {
|
||||||
|
/**
|
||||||
|
* 创建定时任务计划
|
||||||
|
*
|
||||||
|
* @param taskPlanDTO 任务计划DTO
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/task/plan/timed")
|
||||||
|
R<Long> createTimedTaskPlan(@RequestBody TaskPlanDTO taskPlanDTO, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建周期任务计划
|
||||||
|
*
|
||||||
|
* @param taskPlanDTO 任务计划DTO
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/task/plan/cycle")
|
||||||
|
R<Long> createCycleTaskPlan(@RequestBody TaskPlanDTO taskPlanDTO, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID获取任务计划
|
||||||
|
*
|
||||||
|
* @param planId 计划ID
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@GetMapping("/task/plan/{planId}")
|
||||||
|
R<TaskPlanDTO> getTaskPlanById(@PathVariable("planId") Long planId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询任务计划列表
|
||||||
|
*
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/task/plan/list")
|
||||||
|
R<List<TaskPlanDTO>> getTaskPlanList(@RequestBody TaskPlanQueryDTO queryDTO, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新任务计划
|
||||||
|
*
|
||||||
|
* @param taskPlanDTO 任务计划DTO
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PutMapping("/task/plan")
|
||||||
|
R<Boolean> updateTaskPlan(@RequestBody TaskPlanDTO taskPlanDTO, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除任务计划
|
||||||
|
*
|
||||||
|
* @param planId 计划ID
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/task/plan/{planId}")
|
||||||
|
R<Boolean> deleteTaskPlan(@PathVariable("planId") Long planId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
}
|
||||||
|
|
@ -3,12 +3,14 @@ package com.ruoyi.task.api;
|
||||||
import com.ruoyi.common.core.constant.SecurityConstants;
|
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||||
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.task.api.domain.TaskVO;
|
||||||
import com.ruoyi.task.api.domain.TaskTempVO;
|
import com.ruoyi.task.api.domain.TaskTempVO;
|
||||||
|
import com.ruoyi.task.api.enums.StatusEnum;
|
||||||
import com.ruoyi.task.api.factory.RemoteTaskFallbackFactory;
|
import com.ruoyi.task.api.factory.RemoteTaskFallbackFactory;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestHeader;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务服务
|
* 任务服务
|
||||||
|
|
@ -20,12 +22,105 @@ import org.springframework.web.bind.annotation.RequestHeader;
|
||||||
public interface RemoteTaskService
|
public interface RemoteTaskService
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 根据ID查询任务信息
|
* 根据ID查询任务临时表信息
|
||||||
*
|
*
|
||||||
* @param id 任务ID
|
* @param id 任务临时表ID
|
||||||
* @param source 请求来源
|
* @param source 请求来源
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@GetMapping("/task/temp/{id}")
|
@GetMapping("/task/temp/{id}")
|
||||||
R<TaskTempVO> getTaskById(@PathVariable("id") String id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
R<TaskTempVO> getTaskTempById(@PathVariable("id") String id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建无关联计划的任务
|
||||||
|
*
|
||||||
|
* @param taskVO 任务DTO
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/task")
|
||||||
|
R<Long> createTaskWithoutPlan(@RequestBody TaskVO taskVO, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID获取任务
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@GetMapping("/task/{taskId}")
|
||||||
|
R<TaskVO> getTaskById(@PathVariable("taskId") Long taskId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 查询任务列表
|
||||||
|
// *
|
||||||
|
// * @param queryDTO 查询条件
|
||||||
|
// * @param source 请求来源
|
||||||
|
// * @return 结果
|
||||||
|
// */
|
||||||
|
// @PostMapping("/task/list")
|
||||||
|
// R<List<TaskDTO>> getTaskList(@RequestBody TaskQueryVO queryDTO, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新任务
|
||||||
|
*
|
||||||
|
* @param taskVO 任务DTO
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PutMapping("/task")
|
||||||
|
R<Boolean> updateTask(@RequestBody TaskVO taskVO, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除任务
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/task/{taskId}")
|
||||||
|
R<Boolean> deleteTask(@PathVariable("taskId") Long taskId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据无人机ID查询任务列表
|
||||||
|
*
|
||||||
|
* @param uavId 无人机ID
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@GetMapping("/task/uav/{uavId}")
|
||||||
|
R<List<TaskVO>> getTaskByUavId(@PathVariable("uavId") String uavId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据无人机ID获取最新的一条任务
|
||||||
|
*
|
||||||
|
* @param uavId 无人机ID
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@GetMapping("/task/uav/current/{uavId}")
|
||||||
|
R<TaskVO> getCurrentTaskByUavId(@PathVariable("uavId") String uavId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改执行状态
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @param status 任务状态
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PutMapping("/task/status/{taskId}")
|
||||||
|
R<Boolean> updateTaskStatus(@PathVariable("taskId") Long taskId, @RequestParam("status") StatusEnum status, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置 recovery 为 true
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @param source 请求来源
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PutMapping("/task/recovery/{taskId}")
|
||||||
|
R<Boolean> updateTaskRecovery(@PathVariable("taskId") Long taskId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.ruoyi.task.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.task.api.enums.*;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务计划DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-03-06
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TaskPlanDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务计划ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计划名称
|
||||||
|
*/
|
||||||
|
private String planName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计划类型
|
||||||
|
*/
|
||||||
|
private PlanTypeEnum planType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行类型
|
||||||
|
*/
|
||||||
|
private ExecuteTypeEnum executeType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 周期类型
|
||||||
|
*/
|
||||||
|
private CycleTypeEnum cycleType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 周期值
|
||||||
|
*/
|
||||||
|
private String cycleValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
private Date startDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
private Date endDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行时间
|
||||||
|
*/
|
||||||
|
private Date executeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 航线ID
|
||||||
|
*/
|
||||||
|
private Long routeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机ID
|
||||||
|
*/
|
||||||
|
private String uavId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态
|
||||||
|
*/
|
||||||
|
private StatusEnum status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 持续时间(分钟)
|
||||||
|
*/
|
||||||
|
private Integer duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 航线文件URL
|
||||||
|
*/
|
||||||
|
private String routeUrl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.ruoyi.task.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.task.api.enums.CycleTypeEnum;
|
||||||
|
import com.ruoyi.task.api.enums.PlanTypeEnum;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务计划查询DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-03-06
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TaskPlanQueryDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务计划ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计划类型
|
||||||
|
*/
|
||||||
|
private PlanTypeEnum planType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 周期类型
|
||||||
|
*/
|
||||||
|
private CycleTypeEnum cycleType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 航线ID
|
||||||
|
*/
|
||||||
|
private Long routeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机ID
|
||||||
|
*/
|
||||||
|
private String uavId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间起始
|
||||||
|
*/
|
||||||
|
private Date startDateStart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间结束
|
||||||
|
*/
|
||||||
|
private Date startDateEnd;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.ruoyi.task.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.task.api.enums.CycleTypeEnum;
|
||||||
|
import com.ruoyi.task.api.enums.PlanTypeEnum;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务查询DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-03-06
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TaskQueryVO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计划类型
|
||||||
|
*/
|
||||||
|
private PlanTypeEnum planType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 周期类型
|
||||||
|
*/
|
||||||
|
private CycleTypeEnum cycleType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 航线ID
|
||||||
|
*/
|
||||||
|
private Long routeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机ID
|
||||||
|
*/
|
||||||
|
private Long uavId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间起始
|
||||||
|
*/
|
||||||
|
private Date startDateStart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间结束
|
||||||
|
*/
|
||||||
|
private Date startDateEnd;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.ruoyi.task.api.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按年月统计任务DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-03-09
|
||||||
|
*/
|
||||||
|
public class TaskStatByMonthVO {
|
||||||
|
|
||||||
|
/** 总数 */
|
||||||
|
private Integer total;
|
||||||
|
|
||||||
|
/** 每日任务列表 key:日期(1-31) value:任务列表 */
|
||||||
|
private Map<Integer, List<TaskStatItemVO>> days;
|
||||||
|
|
||||||
|
public Integer getTotal() {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotal(Integer total) {
|
||||||
|
this.total = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Integer, List<TaskStatItemVO>> getDays() {
|
||||||
|
return days;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDays(Map<Integer, List<TaskStatItemVO>> days) {
|
||||||
|
this.days = days;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.ruoyi.task.api.domain;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按年统计任务DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-03-09
|
||||||
|
*/
|
||||||
|
public class TaskStatByYearDTO {
|
||||||
|
|
||||||
|
/** 总数 */
|
||||||
|
private Integer total;
|
||||||
|
|
||||||
|
/** 每月统计 key:月份(1-12) value:任务数量 */
|
||||||
|
private Map<Integer, Integer> months;
|
||||||
|
|
||||||
|
public Integer getTotal() {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotal(Integer total) {
|
||||||
|
this.total = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Integer, Integer> getMonths() {
|
||||||
|
return months;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMonths(Map<Integer, Integer> months) {
|
||||||
|
this.months = months;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
package com.ruoyi.task.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.task.api.enums.StatusEnum;
|
||||||
|
import com.ruoyi.task.api.enums.TaskCategoryEnum;
|
||||||
|
import com.ruoyi.task.api.enums.TaskTypeEnum;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务统计项DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-03-09
|
||||||
|
*/
|
||||||
|
public class TaskStatItemVO {
|
||||||
|
|
||||||
|
private Long taskId;
|
||||||
|
private Long planId;
|
||||||
|
private String taskName;
|
||||||
|
private String planName;
|
||||||
|
private String routeName;
|
||||||
|
private String airVendor;
|
||||||
|
private String airType;
|
||||||
|
private Date planStartDate;
|
||||||
|
private Date planEndDate;
|
||||||
|
private Date startTime;
|
||||||
|
private Date endTime;
|
||||||
|
private Date actualStartTime;
|
||||||
|
private Date actualEndTime;
|
||||||
|
private StatusEnum status;
|
||||||
|
private TaskTypeEnum taskType;
|
||||||
|
private TaskCategoryEnum taskCategory;
|
||||||
|
private String airlineType;
|
||||||
|
private Date taskCreateTime;
|
||||||
|
private String taskCreateBy;
|
||||||
|
|
||||||
|
public Long getTaskId() {
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskId(Long taskId) {
|
||||||
|
this.taskId = taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getPlanId() {
|
||||||
|
return planId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlanId(Long planId) {
|
||||||
|
this.planId = planId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskName() {
|
||||||
|
return taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskName(String taskName) {
|
||||||
|
this.taskName = taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlanName() {
|
||||||
|
return planName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlanName(String planName) {
|
||||||
|
this.planName = planName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRouteName() {
|
||||||
|
return routeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRouteName(String routeName) {
|
||||||
|
this.routeName = routeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAirVendor() {
|
||||||
|
return airVendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAirVendor(String airVendor) {
|
||||||
|
this.airVendor = airVendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAirType() {
|
||||||
|
return airType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAirType(String airType) {
|
||||||
|
this.airType = airType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getPlanStartDate() {
|
||||||
|
return planStartDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlanStartDate(Date planStartDate) {
|
||||||
|
this.planStartDate = planStartDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getPlanEndDate() {
|
||||||
|
return planEndDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlanEndDate(Date planEndDate) {
|
||||||
|
this.planEndDate = planEndDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getStartTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartTime(Date startTime) {
|
||||||
|
this.startTime = startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getEndTime() {
|
||||||
|
return endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndTime(Date endTime) {
|
||||||
|
this.endTime = endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getActualStartTime() {
|
||||||
|
return actualStartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActualStartTime(Date actualStartTime) {
|
||||||
|
this.actualStartTime = actualStartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getActualEndTime() {
|
||||||
|
return actualEndTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActualEndTime(Date actualEndTime) {
|
||||||
|
this.actualEndTime = actualEndTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusEnum getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(StatusEnum status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskTypeEnum getTaskType() {
|
||||||
|
return taskType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskType(TaskTypeEnum taskType) {
|
||||||
|
this.taskType = taskType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskCategoryEnum getTaskCategory() {
|
||||||
|
return taskCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskCategory(TaskCategoryEnum taskCategory) {
|
||||||
|
this.taskCategory = taskCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAirlineType() {
|
||||||
|
return airlineType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAirlineType(String airlineType) {
|
||||||
|
this.airlineType = airlineType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getTaskCreateTime() {
|
||||||
|
return taskCreateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskCreateTime(Date taskCreateTime) {
|
||||||
|
this.taskCreateTime = taskCreateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskCreateBy() {
|
||||||
|
return taskCreateBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskCreateBy(String taskCreateBy) {
|
||||||
|
this.taskCreateBy = taskCreateBy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
package com.ruoyi.task.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.task.api.enums.StatusEnum;
|
||||||
|
import com.ruoyi.task.api.enums.TaskCategoryEnum;
|
||||||
|
import com.ruoyi.task.api.enums.TaskTypeEnum;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务统计查询DTO
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-03-09
|
||||||
|
*/
|
||||||
|
public class TaskStatQueryVO {
|
||||||
|
|
||||||
|
/** 年份 */
|
||||||
|
private Integer year;
|
||||||
|
|
||||||
|
/** 月份 */
|
||||||
|
private Integer month;
|
||||||
|
|
||||||
|
/** 开始日期 */
|
||||||
|
private Date startTime;
|
||||||
|
|
||||||
|
/** 结束日期 */
|
||||||
|
private Date endTime;
|
||||||
|
|
||||||
|
/** 任务类别 */
|
||||||
|
private TaskCategoryEnum taskCategory;
|
||||||
|
|
||||||
|
/** 任务类型 */
|
||||||
|
private TaskTypeEnum taskType;
|
||||||
|
|
||||||
|
/** 状态列表 */
|
||||||
|
private List<StatusEnum> statusList;
|
||||||
|
|
||||||
|
/** 航线ID列表 */
|
||||||
|
private List<Long> routeIdList;
|
||||||
|
|
||||||
|
/** 无人机ID列表 */
|
||||||
|
private List<String> uavIdList;
|
||||||
|
|
||||||
|
public Integer getYear() {
|
||||||
|
return year;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYear(Integer year) {
|
||||||
|
this.year = year;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getMonth() {
|
||||||
|
return month;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMonth(Integer month) {
|
||||||
|
this.month = month;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getStartTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartTime(Date startTime) {
|
||||||
|
this.startTime = startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getEndTime() {
|
||||||
|
return endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndTime(Date endTime) {
|
||||||
|
this.endTime = endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskCategoryEnum getTaskCategory() {
|
||||||
|
return taskCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskCategory(TaskCategoryEnum taskCategory) {
|
||||||
|
this.taskCategory = taskCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskTypeEnum getTaskType() {
|
||||||
|
return taskType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskType(TaskTypeEnum taskType) {
|
||||||
|
this.taskType = taskType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<StatusEnum> getStatusList() {
|
||||||
|
return statusList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatusList(List<StatusEnum> statusList) {
|
||||||
|
this.statusList = statusList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Long> getRouteIdList() {
|
||||||
|
return routeIdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRouteIdList(List<Long> routeIdList) {
|
||||||
|
this.routeIdList = routeIdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getUavIdList() {
|
||||||
|
return uavIdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUavIdList(List<String> uavIdList) {
|
||||||
|
this.uavIdList = uavIdList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,226 @@
|
||||||
|
package com.ruoyi.task.api.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.task.api.enums.ExecuteTypeEnum;
|
||||||
|
import com.ruoyi.task.api.enums.StatusEnum;
|
||||||
|
import com.ruoyi.task.api.enums.TaskCategoryEnum;
|
||||||
|
import com.ruoyi.task.api.enums.TaskTypeEnum;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务数据传输对象
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-03-05
|
||||||
|
*/
|
||||||
|
public class TaskVO {
|
||||||
|
|
||||||
|
/** 任务ID */
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 计划ID(可为空,如一键起飞) */
|
||||||
|
private Long planId;
|
||||||
|
|
||||||
|
/** 任务名称 */
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
/** 任务类别(如人工执飞) */
|
||||||
|
private TaskCategoryEnum taskCategory;
|
||||||
|
|
||||||
|
/** 任务类型(如一键起飞) */
|
||||||
|
private TaskTypeEnum taskType;
|
||||||
|
|
||||||
|
/** 执行类型(单次执行、连续执行) */
|
||||||
|
private ExecuteTypeEnum executeType;
|
||||||
|
|
||||||
|
/** 航线ID */
|
||||||
|
private Long routeId;
|
||||||
|
|
||||||
|
/** 无人机ID */
|
||||||
|
private String uavId;
|
||||||
|
|
||||||
|
/** 状态 */
|
||||||
|
private StatusEnum status;
|
||||||
|
|
||||||
|
/** 错误是否恢复 */
|
||||||
|
private Boolean recovery;
|
||||||
|
|
||||||
|
/** 开始时间 */
|
||||||
|
private Date startTime;
|
||||||
|
|
||||||
|
/** 结束时间 */
|
||||||
|
private Date endTime;
|
||||||
|
|
||||||
|
/** 实际开始时间 */
|
||||||
|
private Date actualStartTime;
|
||||||
|
|
||||||
|
/** 实际结束时间 */
|
||||||
|
private Date actualEndTime;
|
||||||
|
|
||||||
|
/** 描述 */
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/** 航线文件URL */
|
||||||
|
private String routeUrl;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getPlanId() {
|
||||||
|
return planId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlanId(Long planId) {
|
||||||
|
this.planId = planId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskName() {
|
||||||
|
return taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskName(String taskName) {
|
||||||
|
this.taskName = taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskCategoryEnum getTaskCategory() {
|
||||||
|
return taskCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskCategory(TaskCategoryEnum taskCategory) {
|
||||||
|
this.taskCategory = taskCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskTypeEnum getTaskType() {
|
||||||
|
return taskType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskType(TaskTypeEnum taskType) {
|
||||||
|
this.taskType = taskType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecuteTypeEnum getExecuteType() {
|
||||||
|
return executeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExecuteType(ExecuteTypeEnum executeType) {
|
||||||
|
this.executeType = executeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getRouteId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRouteId(Long routeId) {
|
||||||
|
this.routeId = routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUavId() {
|
||||||
|
return uavId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUavId(String uavId) {
|
||||||
|
this.uavId = uavId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusEnum getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(StatusEnum status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getRecovery() {
|
||||||
|
return recovery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecovery(Boolean recovery) {
|
||||||
|
this.recovery = recovery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getStartTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartTime(Date startTime) {
|
||||||
|
this.startTime = startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getEndTime() {
|
||||||
|
return endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndTime(Date endTime) {
|
||||||
|
this.endTime = endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getActualStartTime() {
|
||||||
|
return actualStartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActualStartTime(Date actualStartTime) {
|
||||||
|
this.actualStartTime = actualStartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getActualEndTime() {
|
||||||
|
return actualEndTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActualEndTime(Date actualEndTime) {
|
||||||
|
this.actualEndTime = actualEndTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemark() {
|
||||||
|
return remark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemark(String remark) {
|
||||||
|
this.remark = remark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRouteUrl() {
|
||||||
|
return routeUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRouteUrl(String routeUrl) {
|
||||||
|
this.routeUrl = routeUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TaskDTO{" +
|
||||||
|
"id=" + id +
|
||||||
|
", planId=" + planId +
|
||||||
|
", taskName='" + taskName + '\'' +
|
||||||
|
", taskCategory=" + taskCategory +
|
||||||
|
", taskType=" + taskType +
|
||||||
|
", executeType=" + executeType +
|
||||||
|
", routeId=" + routeId +
|
||||||
|
", uavId=" + uavId +
|
||||||
|
", status=" + status +
|
||||||
|
", startTime=" + startTime +
|
||||||
|
", endTime=" + endTime +
|
||||||
|
", actualStartTime=" + actualStartTime +
|
||||||
|
", actualEndTime=" + actualEndTime +
|
||||||
|
", description='" + description + '\'' +
|
||||||
|
", routeUrl='" + routeUrl + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.ruoyi.task.api.enums;
|
||||||
|
|
||||||
|
public enum CycleTypeEnum {
|
||||||
|
DAILY("daily", "日周期"),
|
||||||
|
WEEKLY("weekly", "周周期"),
|
||||||
|
MONTHLY("monthly", "月周期");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
CycleTypeEnum(String code, String name) {
|
||||||
|
this.code = code;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CycleTypeEnum getByCode(String code) {
|
||||||
|
for (CycleTypeEnum type : values()) {
|
||||||
|
if (type.code.equals(code)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.ruoyi.task.api.enums;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue;
|
||||||
|
|
||||||
|
public enum ExecuteTypeEnum {
|
||||||
|
ONCE("once", "单次执行"),
|
||||||
|
CONTINUOUS("continuous", "连续执行");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
ExecuteTypeEnum(String code, String name) {
|
||||||
|
this.code = code;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonValue
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public static ExecuteTypeEnum getByCode(String value) {
|
||||||
|
if (value == null || value.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (ExecuteTypeEnum type : values()) {
|
||||||
|
if (type.code.equals(value) || type.name().equals(value)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.ruoyi.task.api.enums;
|
||||||
|
|
||||||
|
public enum PlanTypeEnum {
|
||||||
|
TIMED("timed", "定时任务"),
|
||||||
|
CYCLE("cycle", "周期任务"),
|
||||||
|
IMMEDIATELY("immediately", "立即任务");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
PlanTypeEnum(String code, String name) {
|
||||||
|
this.code = code;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlanTypeEnum getByCode(String code) {
|
||||||
|
for (PlanTypeEnum type : values()) {
|
||||||
|
if (type.code.equals(code)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue