zhaowenyu
2026-04-01 b8b5a3895e741d5348ecdd39ad2e5cbd443f8e89
Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
# ard-admin/src/main/resources/application-daqing.yml
# ard-admin/src/main/resources/application-prod.yml
1 files added
11 files modified
193 ■■■■■ changed files
ard-admin/src/main/resources/application-daqing.yml 13 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/resources/application-dev.yml 54 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/resources/application-prod.yml 13 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/resources/application.yml 4 ●●●●● patch | view | raw | blame | history
ard-inspection/src/main/java/com/ard/inspection/service/impl/ArdPointCloudServiceImpl.java 7 ●●●●● patch | view | raw | blame | history
ard-inspection/src/main/java/com/ard/inspection/service/impl/BigFileUploadServiceImpl.java 10 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java 12 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/util/InitializationUtils.java 12 ●●●●● patch | view | raw | blame | history
ard-vtdu/src/main/java/com/ard/vtdu/config/MediamtxSixHeConfig.java 23 ●●●●● patch | view | raw | blame | history
ard-vtdu/src/main/java/com/ard/vtdu/service/impl/ArdArdMediaServiceImpl.java 20 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/component/websocket/handler/UavStreamManager.java 21 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java 4 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/resources/application-daqing.yml
@@ -55,12 +55,12 @@
#流媒体
mediamtx:
  apiHost: 192.168.10.103
  playHost: 192.168.10.103
  pushHost: 192.168.10.103
  playHost: 112.98.104.134
  https: true
  pushHost: 192.168.10.103
  rtmpPort: 1935
  rtspPort: 8554
  webrtcPort: 8889
  webrtcPort: 28889
# mqtt配置
@@ -88,4 +88,9 @@
# 机场单独用的oss配置,要http地址
dock:
  endpoint: http://192.168.10.103:9011
  bucket: dockfile
  bucket: dockfile
pointCloud:
  url : https://192.168.10.103:3001/tileset/
  type : /tileset.json
  folder : /home/inspection/uploadPath/zip/
ard-admin/src/main/resources/application-dev.yml
@@ -2,10 +2,12 @@
server:
  # 服务器的HTTP端口,默认为8080
  port: 8080
# token配置
token:
  # 是否允许账户多终端同时登录(true允许 false不允许)
  soloLogin: true
# 日志配置
logging:
  level:
@@ -23,14 +25,6 @@
    enable: false
    username: admin
    password: ardkj12345
# MyBatis Plus配置
mybatis-plus:
  # 搜索指定包别名
  typeAliasesPackage: com.ard.**.domain
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # 加载全局的配置文件
  configLocation: classpath:mybatis/mybatis-config.xml
# 六合服务器配置
tianyu:
@@ -60,13 +54,6 @@
  #航线KMZ临时存放路径
  waylineSavePath: /home/ard/myworkspace/uav_server/mainserver/waylines
# MinIO
minio:
  url: http://192.168.1.15:9001
  accessKey: admin
  secretKey: xzx12345
  bucketName: kmz
#上云API
cloud-api:
  app:
@@ -75,11 +62,16 @@
    license: khjd7FzUTzJgaArNv97XdA2nKQtYfESOvBHLqjC6MpvPqxCfuQ82nOlTgzoiLp7UoZujARopN2A1ctPFaJ8oHiHQrn3IRV4wqN3hdSM40xXj02YVvTWQBT54WS8Ks+E8Zatp3gk2T0+7cM5a5a3mWzxLMv7CNqw2z9pFBoOBdpY=
    host: 192.168.1.15
    port: 123
#流媒体
mediamtx:
  apiHost: 192.168.1.15
  playHost: 192.168.1.15
  https: false
  https: true
  pushHost: 127.0.0.1
  rtmpPort: 1935
  rtspPort: 8554
  webrtcPort: 8889
# mqtt配置
mqtt:
@@ -89,4 +81,32 @@
  username: admin
  password: public
  client-id: liusuyi
  inbound-topic: sys/product/+/status,thing/product/+/requests
  inbound-topic: sys/product/+/status,thing/product/+/requests
# oss配置 https://192.168.1.3:9001
oss:
  enable: true
  provider: minio
  endpoint: https://127.0.0.1:9001
  access-key: admin
  secret-key: ard12345
  bucket: cloud-bucket
  expire: 3600
  region: us-east-1
  object-dir-prefix: wayline
dock:
  enable: true
  provider: minio
  endpoint: http://127.0.0.1:9011
  access-key: admin
  secret-key: ard12345
  bucket: dockfile
  expire: 3600
  region: us-east-1
  object-dir-prefix: wayline
pointCloud:
  url : https://127.0.10.1:3001/tileset/
  type : /tileset.json
  folder : /home/inspection/uploadPath/zip/
ard-admin/src/main/resources/application-prod.yml
@@ -62,6 +62,12 @@
  rtspPort: 8554
  webrtcPort: 8889
#六合流媒体映射
mediamtx-sixhe:
  enable: true
  playHost: 112.98.104.134
  webrtcPort: 38889
# mqtt配置
mqtt:
  protocol: tcp
@@ -86,4 +92,9 @@
dock:
  endpoint: http://111.40.46.199:9011
  bucket: dockfile
  bucket: dockfile
pointCloud:
  url : https://192.168.1.3:3001/tileset/
  type : /tileset.json
  folder : /home/inspection/uploadPath/zip/
ard-admin/src/main/resources/application.yml
@@ -118,9 +118,9 @@
  servlet:
    multipart:
      # 单个文件大小
      max-file-size: 3GB
      max-file-size: 6144MB
      # 设置总上传的文件大小
      max-request-size: 3GB
      max-request-size: 6144MB
  # 服务模块
  devtools:
    restart:
ard-inspection/src/main/java/com/ard/inspection/service/impl/ArdPointCloudServiceImpl.java
@@ -8,6 +8,7 @@
import com.ard.inspection.domain.NotCould;
import com.ard.inspection.utils.ZipFileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ard.inspection.mapper.ArdPointCloudMapper;
import com.ard.inspection.domain.ArdPointCloud;
@@ -23,6 +24,9 @@
 */
@Service
public class ArdPointCloudServiceImpl implements IArdPointCloudService {
    @Value(value = "${pointCloud.folder}")
    private String cloudFolder;
    @Autowired
    private ArdPointCloudMapper ardPointCloudMapper;
@@ -87,11 +91,10 @@
    @Override
    public int deleteArdPointCloudByIds(String[] ids) {
        // 删除点云文件
        String folderPath = "/home/inspection/uploadPath/zip/";
        int count = 0;
        for (String id : ids) {
            ArdPointCloud ardPointCloud = ardPointCloudMapper.selectArdPointCloudById(id);
            if (zipFileUtils.deleteZipFile(folderPath + ardPointCloud.getFolderName())){
            if (zipFileUtils.deleteZipFile(cloudFolder + ardPointCloud.getFolderName())){
                ardPointCloudMapper.deleteArdPointCloudById(id);
                count++;
            }
ard-inspection/src/main/java/com/ard/inspection/service/impl/BigFileUploadServiceImpl.java
@@ -1,7 +1,6 @@
package com.ard.inspection.service.impl;
import com.ard.common.core.domain.AjaxResult;
import com.ard.common.utils.uuid.IdUtils;
import com.ard.inspection.domain.ArdPointCloud;
import com.ard.inspection.domain.UploadFileEntity;
import com.ard.inspection.service.IArdPointCloudService;
@@ -9,6 +8,7 @@
import com.ard.inspection.utils.ZipFileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@@ -28,7 +28,11 @@
@Slf4j
public class BigFileUploadServiceImpl implements IBigFileUploadService {
    public static final String CLOUD_FILE_PATH = "https://192.168.1.3:3001/tileset/";
    @Value(value = "${pointCloud.url}")
    private String cloudUrl;
    @Value(value = "${pointCloud.type}")
    private String cloudType;
    @Autowired
    private IArdPointCloudService ardPointCloudService;
@@ -256,7 +260,7 @@
            ardPointCloud.setFileSize(formatFileSize(file.getSize()));
            int dotIndex = originalFilename.lastIndexOf('.');
            String folderName = (dotIndex > 0) ? originalFilename.substring(0, dotIndex) : originalFilename;
            String zipP = CLOUD_FILE_PATH + folderName + "/tileset.json";
            String zipP = cloudUrl + folderName + cloudType;
            ardPointCloud.setFilePath(zipP);
            ardPointCloud.setFolderName(folderName);
            return AjaxResult.success("文件上传并解压成功", ardPointCloud);
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
@@ -169,6 +169,11 @@
        if (ardRouteInfo.getGroupId() == null){
            ardRouteInfo.setGroupId("0");
        }
        if ("3".equals(ardRouteInfo.getType())){
            ardRouteInfo.getUavRouteReq().setHeightMode("EGM96");
        }else {
            ardRouteInfo.getUavRouteReq().setHeightMode("relativeToStartPoint");
        }
        ardRouteInfo.getUavRouteReq().setDroneType(subStringDroneType(ardRouteInfo.getAircraft()));
        KmzResultVo kmzResult = routeService.buildKmz(ardRouteInfo.getUavRouteReq(),ardRouteInfo.getName());
        zoomProcessing(ardRouteInfo);
@@ -465,13 +470,6 @@
        // 1.1通过航线数据,转换。
        ArdRouteInfo route = ardRouteInfoMapper.selectArdRouteInfoById(id);
        try {
//            if ("3".equals(route.getType())) {
//                UavRouteReq uavRouteReq = new UavRouteReq();
//                BeanUtils.copyProperties(deserialize(route.getRouteData()), uavRouteReq);
//                route.setUavRouteReq((UavRouteReq) deserialize(route.getRouteData()));
//            }else {
//                route.setUavRouteReq((UavRouteReq) deserialize(route.getRouteData()));
//            }
            route.setUavRouteReq((UavRouteReq) deserialize(route.getRouteData()));
            if (route.getCloudData() != null){
                route.setArdPointCloudList(deserializeLs(route.getCloudData()));
ard-route/src/main/java/com/ard/route/util/InitializationUtils.java
@@ -34,7 +34,8 @@
        if (uavRouteReq.getTakeOffRefPoint() == null){
            uavRouteReq.setTakeOffRefPoint(
                    uavRouteReq.getRoutePointList().get(0).getLatitude() + "," +
                            uavRouteReq.getRoutePointList().get(0).getLongitude() + "," + "0");
                            uavRouteReq.getRoutePointList().get(0).getLongitude() + "," +
                            uavRouteReq.getRoutePointList().get(0).getHeight());
        }
        //uavRouteReq.setDroneType(89);
        uavRouteReq.setSubDroneType(0);
@@ -56,7 +57,6 @@
        }
        uavRouteReq.setWaypointTurnReq(waypointTurnReq);
        uavRouteReq.setGimbalPitchMode("usePointSetting");
        uavRouteReq.setHeightMode("EGM96");
        if (M350_RTK.getValue().equals(uavRouteReq.getDroneType())) {
            // 变焦数值加工
            buildZoom(uavRouteReq);
@@ -91,9 +91,11 @@
     * 根据起飞点高度减去当前航点高度
     */
    public void buildHeight(UavRouteReq uavRouteReq){
        double takeOffHeight = getDoublePoint(uavRouteReq.getTakeOffRefPoint(),"alt");
        for (RoutePointReq routePointReq : uavRouteReq.getRoutePointList()) {
            routePointReq.setHeight(routePointReq.getHeight() - takeOffHeight);
        if (!"EGM96".equals(uavRouteReq.getHeightMode())){
            double takeOffHeight = getDoublePoint(uavRouteReq.getTakeOffRefPoint(),"alt");
            for (RoutePointReq routePointReq : uavRouteReq.getRoutePointList()) {
                routePointReq.setHeight(routePointReq.getHeight() - takeOffHeight);
            }
        }
    }
ard-vtdu/src/main/java/com/ard/vtdu/config/MediamtxSixHeConfig.java
New file
@@ -0,0 +1,23 @@
package com.ard.vtdu.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
 * MediamtxConfig
 *
 * @author liusuyi
 * @date 2024年11月09日16:18
 **/
@Configuration
@Data
@ConfigurationProperties(prefix = "mediamtx-sixhe")
public class MediamtxSixHeConfig {
    //是否启动映射转换
    private Boolean enable;
    //播放ip地址
    private String playHost;
    //webrtc端口
    private Integer webrtcPort;
}
ard-vtdu/src/main/java/com/ard/vtdu/service/impl/ArdArdMediaServiceImpl.java
@@ -58,21 +58,23 @@
            String protocol = mediamtxConfig.isHttps() ? "https://" : "http://";
            String webrtcUrl =
                    protocol + mediamtxConfig.getPlayHost() + ":" + mediamtxConfig.getWebrtcPort() + "/" + ardVtdu.getName();
            String source = ardVtdu.getRtspSource();
            Conf conf = new Conf();
            conf.setSource(ardVtdu.getRtspSource());
            if(!"publisher".equalsIgnoreCase(conf.getSource())) {
                conf.setSourceOnDemand(true);
            conf.setName(ardVtdu.getName());
            conf.setSource(source);
            // 如果是拉流则配置按需
            if (!"publisher".equalsIgnoreCase(source)) {
                conf.setSourceOnDemand(true); // 按需拉
                conf.setRunOnDemandCloseAfter("5s"); // 无观众 5 秒断开
            }
            conf.setRunOnDemandRestart(false);
            conf.setRunOnDemandCloseAfter("5s");
            conf.setMaxReaders(100);
            conf.setSourceProtocol("tcp");
            if (checkNameExist(ardVtdu.getName())) {
                mediaClient.removePath(ardVtdu.getName());
            if (!checkNameExist(ardVtdu.getName())) {
                mediaClient.addPath(ardVtdu.getName(), conf);
            } else {
                mediaClient.editPath(ardVtdu.getName(), conf);
            }
            mediaClient.addPath(ardVtdu.getName(), conf);
            ardVtdu.setCameraId(ardVtdu.getName().split("_")[0]);
            ardVtdu.setRtspUrl(rtspUrl);
ard-work/src/main/java/com/ard/work/component/websocket/handler/UavStreamManager.java
@@ -2,6 +2,7 @@
import com.alibaba.fastjson2.JSON;
import com.ard.vtdu.config.MediamtxSixHeConfig;
import com.ard.vtdu.domain.ArdVtdu;
import com.ard.work.component.websocket.utils.WebSocketUtil;
import com.ard.work.domain.message.BaseMessage;
@@ -27,6 +28,8 @@
    @Resource
    private ITyService tyService;
    @Resource
    private MediamtxSixHeConfig mediamtxSixHeConfig;
    // 盒子拉流地址缓存 key:boxSn value: webrtcUrl
    public static final ConcurrentMap<String, String> BOX_STREAM_PULL_MAP = new ConcurrentHashMap<>();
@@ -123,6 +126,24 @@
        if (boxLiveUrl == null) {
            throw new RuntimeException("未获取到盒子直播地址:" + boxSn);
        }
        // 2. 获取原始 URL 字符串
        String originalUrl = boxLiveUrl.getRtc();
        if (mediamtxSixHeConfig.getEnable() && originalUrl != null && !originalUrl.isEmpty()) {
            // --- 开始替换逻辑 ---
            // 配置你的外网地址
            String targetHost = mediamtxSixHeConfig.getPlayHost() + ":" + mediamtxSixHeConfig.getWebrtcPort();
            // 正则解释:
            // (^https?://)  -> 捕获组1:匹配 http:// 或 https://
            // ([^/:]+)     -> 捕获组2:匹配 IP 地址或域名 (非 / 和 : 的字符)
            // (:\d+)?      -> 捕获组3:匹配 :端口号 (可选)
            // (/.*)        -> 捕获组4:匹配后面的路径参数
            String regex = "(^https?://)([^/:]+)(:\\d+)?(/.*)";
            // 替换为:协议 + 外网IP:端口 + 路径
            // $1 代表协议, $4 代表路径
            String newUrl = originalUrl.replaceAll(regex, "$1" + targetHost + "$4");
            // 将新 URL 设置回去
            boxLiveUrl.setRtc(newUrl);
        }
        boxLiveUrl.setBoxSn(boxSn);
        return boxLiveUrl;
    }
ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java
@@ -1,6 +1,7 @@
package com.ard.work.service.impl;
import com.ard.common.exception.ControlException;
import com.ard.vtdu.config.MediamtxConfig;
import com.ard.work.aspect.annotation.CheckControlRight;
import com.ard.work.aspect.annotation.CheckDroneStatus;
import com.ard.work.aspect.annotation.CheckNoFlyZone;
@@ -87,7 +88,8 @@
    private RouteStateMachineService stateMachineService;
    @Autowired
    private IArdFlightTaskPartService ardFlightTaskPartService;
    @Resource
    private MediamtxConfig mediamtxConfig;
    /**
     * 获取边缘服务器token信息
     *