zhaowenyu
2025-11-15 1e2f717393e4053a3b8de11cbf67cd98a8c77ec1
Merge remote-tracking branch 'origin/dev' into dev
1 files added
14 files modified
1 files renamed
190 ■■■■■ changed files
ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteGroupController.java 11 ●●●●● patch | view | raw | blame | history
ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java 8 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/domain/vo/ArdRouteGroupVo.java 23 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/domain/vo/KmzInfoVo.java 2 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/IArdRouteGroupService.java 10 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/UavRouteService.java 6 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteGroupServiceImpl.java 20 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/impl/UavRouteServiceImpl.java 6 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/util/ToolUtils.java 9 ●●●●● patch | view | raw | blame | history
ard-route/src/main/resources/mapper/ArdRouteInfoMapper.xml 7 ●●●●● patch | view | raw | blame | history
ard-work/pom.xml 6 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/component/websocket/WebSocketSessionManager.java 5 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/component/websocket/handler/TyMessageHandler.java 40 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/domain/enums/MessageType.java 1 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java 2 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteGroupController.java
@@ -11,6 +11,7 @@
import com.ard.common.enums.BusinessType;
import com.ard.common.utils.poi.ExcelUtil;
import com.ard.route.domain.route.ArdRouteGroup;
import com.ard.route.domain.vo.ArdRouteGroupVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -111,4 +112,14 @@
        }
    }
    /**
     * 分组列表
     */
    @ApiOperation("分组列表")
    @GetMapping("/groupList")
    public TableDataInfo groupList(ArdRouteGroup ardRouteGroup) {
        List<ArdRouteGroupVo> list = ardRouteGroupService.selectGroupList(ardRouteGroup);
        return getDataTable(list);
    }
}
ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java
@@ -248,4 +248,12 @@
    {
        return Constants.LOGIN_USERID_KEY + userId;
    }
    public LoginUser getLoginUserByUserId(Long userId) {
        String userIdKey = getUserIdKey(userId);
        String tokenKey = redisCache.getCacheObject(userIdKey);
        if (tokenKey == null) return null;
        return redisCache.getCacheObject(tokenKey);
    }
}
ard-route/src/main/java/com/ard/route/domain/vo/ArdRouteGroupVo.java
New file
@@ -0,0 +1,23 @@
package com.ard.route.domain.vo;
import com.ard.common.annotation.Excel;
import com.ard.common.core.domain.BaseEntity;
import lombok.Data;
@Data
public class ArdRouteGroupVo  extends BaseEntity {
    private static final long serialVersionUID = 1L;
    /** ID */
    private String id;
    /** 分组名称 */
    @Excel(name = "分组名称")
    private String groupName;
    /** 序列号 */
    @Excel(name = "序列号")
    private Integer serialNumber;
}
ard-route/src/main/java/com/ard/route/domain/vo/KmzInfoVo.java
File was renamed from ard-route/src/main/java/com/ard/route/domain/vo/KmzInfoVO.java
@@ -10,7 +10,7 @@
 * Date: 2024/12/22 10:46
 **/
@Data
public class KmzInfoVO implements Serializable {
public class KmzInfoVo implements Serializable {
    /**
     * 航线kml信息
ard-route/src/main/java/com/ard/route/service/IArdRouteGroupService.java
@@ -4,6 +4,7 @@
import java.util.Map;
import com.ard.route.domain.route.ArdRouteGroup;
import com.ard.route.domain.vo.ArdRouteGroupVo;
/**
 * 分组Service接口
@@ -60,4 +61,13 @@
     * @return 结果
     */
    public int deleteArdRouteGroupById(String id);
    /**
     * 分组列表
     *
     * @param ardRouteGroup 分组
     * @return 分组集合
     */
    public List<ArdRouteGroupVo> selectGroupList(ArdRouteGroup ardRouteGroup);
}
ard-route/src/main/java/com/ard/route/service/UavRouteService.java
@@ -1,10 +1,8 @@
package com.ard.route.service;
import com.ard.route.domain.UavRouteReq;
import com.ard.route.domain.vo.KmzInfoVO;
import com.ard.route.domain.vo.KmzInfoVo;
import com.ard.route.domain.vo.KmzResultVo;
import java.io.IOException;
public interface UavRouteService {
@@ -22,7 +20,7 @@
    /**
     * 解析kmz文件
     */
    public KmzInfoVO parseKmz(String file);
    public KmzInfoVo parseKmz(String file);
    /**
     * 编辑kmz文件
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteGroupServiceImpl.java
@@ -3,13 +3,16 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.ard.common.annotation.DataScope;
import com.ard.common.utils.DateUtils;
import com.ard.common.utils.uuid.IdUtils;
import com.ard.route.domain.route.ArdRouteGroup;
import com.ard.route.domain.vo.ArdRouteGroupVo;
import com.ard.route.mapper.ArdRouteGroupMapper;
import com.ard.route.mapper.ArdRouteInfoMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ard.route.service.IArdRouteGroupService;
@@ -134,4 +137,21 @@
        return ardRouteGroupMapper.deleteArdRouteGroupById(id);
    }
    /**
     * 分组列表
     *
     * @param ardRouteGroup 分组
     * @return 分组集合
     */
    @Override
    public List<ArdRouteGroupVo> selectGroupList(ArdRouteGroup ardRouteGroup) {
        return ardRouteGroupMapper.selectArdRouteGroupList(ardRouteGroup).stream()
                .map(entity -> {
                    ArdRouteGroupVo vo = new ArdRouteGroupVo();
                    BeanUtils.copyProperties(entity, vo);
                    return vo;
                })
                .collect(Collectors.toList());
    }
}
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
@@ -13,6 +13,7 @@
import com.ard.data.noflyzone.utils.NoFlyZoneUtils;
import com.ard.oss.model.MinioUploadResult;
import com.ard.oss.service.impl.OssServiceContext;
import com.ard.route.domain.CoordinatePointReq;
import com.ard.route.domain.UavRouteReq;
import com.ard.route.domain.route.ArdRouteInfo;
import com.ard.route.domain.vo.KmzResultVo;
@@ -96,6 +97,7 @@
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        ardRouteInfo.getUavRouteReq().setDroneType(subStringDroneType(ardRouteInfo.getAircraft()));
        ardRouteInfo.setRouteData(routeData);
        KmzResultVo kmzResult = routeService.buildKmz(ardRouteInfo.getUavRouteReq(), ardRouteInfo.getName());
        ardRouteInfo.setPath(kmzResult.getPath());
@@ -113,18 +115,21 @@
    @Override
    public int updateArdRouteInfo(ArdRouteInfo ardRouteInfo) {
        ardRouteInfo.setUpdateTime(DateUtils.getNowDate());
        KmzResultVo kmzResult = new KmzResultVo();
        // 获取源文件名字
        ArdRouteInfo route = ardRouteInfoMapper.selectArdRouteInfoById(ardRouteInfo.getId());
        if (route.getName().equals(ardRouteInfo.getName())) {
            kmzResult = routeService.updateKmz(ardRouteInfo.getUavRouteReq(), ardRouteInfo.getName());
        }else {
            kmzResult = routeService.updateKmzNew(ardRouteInfo.getUavRouteReq(), route.getName(), ardRouteInfo.getName());
        // 判断生成kmz文件实体类是否为空,为空就修改航信信息,不修改行点信息。
        if (ardRouteInfo.getUavRouteReq() != null) {
            KmzResultVo kmzResult;
            // 获取源文件名字
            ArdRouteInfo route = ardRouteInfoMapper.selectArdRouteInfoById(ardRouteInfo.getId());
            if (route.getName().equals(ardRouteInfo.getName())) {
                kmzResult = routeService.updateKmz(ardRouteInfo.getUavRouteReq(), ardRouteInfo.getName());
            }else {
                kmzResult = routeService.updateKmzNew(ardRouteInfo.getUavRouteReq(), route.getName(), ardRouteInfo.getName());
            }
            if ("更新航线kmz文件失败".equals(kmzResult.getData())) {
                return 0;
            }
            ardRouteInfo.setPath(kmzResult.getPath());
        }
        if ("更新航线kmz文件失败".equals(kmzResult.getData())) {
            return 0;
        }
        ardRouteInfo.setPath(kmzResult.getPath());
        return ardRouteInfoMapper.updateArdRouteInfo(ardRouteInfo);
    }
@@ -217,6 +222,9 @@
            throw new ControlException("方法参数中未找到有效经纬度字段,无法判断禁飞区!");
        }
        List<ArdNoFlyZone> ardNoFlyZones = ardNoFlyZoneService.selectArdNoFlyZoneList(new ArdNoFlyZone());
        if (!ardNoFlyZones.isEmpty()) {
            Vertex vertex = new Vertex(longitude, latitude);
//            boolean inNoFlyZones = NoFlyZoneUtils.isPointInPolygon(vertex, ardNoFlyZones);
@@ -236,4 +244,8 @@
        ardRouteInfoMapper.insertArdRouteInfo(ardRouteInfo);
    }
    private void verifyNoFlyZone(CoordinatePointReq a,CoordinatePointReq b){
    }
}
ard-route/src/main/java/com/ard/route/service/impl/UavRouteServiceImpl.java
@@ -10,7 +10,7 @@
import com.ard.route.domain.WaypointTurnReq;
import com.ard.route.domain.kml.*;
import com.ard.route.domain.route.ArdRouteInfo;
import com.ard.route.domain.vo.KmzInfoVO;
import com.ard.route.domain.vo.KmzInfoVo;
import com.ard.route.domain.vo.KmzResultVo;
import com.ard.route.enums.kml.ExitOnRCLostEnums;
import com.ard.route.service.IArdRouteInfoService;
@@ -233,8 +233,8 @@
     * 解析kmz文件
     */
    @Override
    public KmzInfoVO parseKmz(String fileUrl){
        KmzInfoVO kmzInfoVO = new KmzInfoVO();
    public KmzInfoVo parseKmz(String fileUrl){
        KmzInfoVo kmzInfoVO = new KmzInfoVo();
        try (InputStream inputStream = ossService.getObject(kmzPath,fileUrl);
             ArchiveInputStream archiveInputStream = new ZipArchiveInputStream(inputStream)){
            ArchiveEntry entry;
ard-route/src/main/java/com/ard/route/util/ToolUtils.java
@@ -120,4 +120,13 @@
        return url.substring(kmzIndex + 5); // +5 是为了跳过 "/kmz/"
    }
    /**
     * 截取字符串
     * 参数: "0-89-0"
     */
    public static Integer subStringDroneType(String str) {
        String[] parts = str.split("-");
        return Integer.valueOf(parts[1]);
    }
}
ard-route/src/main/resources/mapper/ArdRouteInfoMapper.xml
@@ -40,7 +40,7 @@
    <select id="selectArdRouteInfoList" parameterType="ArdRouteInfo" resultMap="ArdRouteInfoResult">
        <include refid="selectArdRouteInfoVo"/>
        <where>  
            <if test="name != null  and kmzName != ''"> and name like concat('%', #{name}, '%')</if>
            <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
            <if test="aircraft != null  and aircraft != ''"> and aircraft = #{aircraft}</if>
            <if test="payload != null  and payload != ''"> and payload = #{payload}</if>
            <if test="type != null  and type != ''"> and type = #{type}</if>
@@ -59,7 +59,7 @@
            <if test="id != null">id,</if>
            <if test="name != null">name,</if>
            <if test="path != null">path,</if>
            <if test="GroupId != null">group_id,</if>
            <if test="groupId != null">group_id,</if>
            <if test="type != null">type,</if>
            <if test="aircraft != null">aircraft,</if>
            <if test="payload != null">payload,</if>
@@ -74,7 +74,7 @@
            <if test="id != null">#{id},</if>
            <if test="name != null">#{name},</if>
            <if test="path != null">#{path},</if>
            <if test="GroupId != null">#{GroupId},</if>
            <if test="groupId != null">#{groupId},</if>
            <if test="type != null">#{type},</if>
            <if test="aircraft != null">#{aircraft},</if>
            <if test="payload != null">#{payload},</if>
@@ -92,6 +92,7 @@
        <trim prefix="SET" suffixOverrides=",">
            <if test="name != null">name = #{name},</if>
            <if test="path != null">path = #{path},</if>
            <if test="groupId != null">group_id = #{groupId},</if>
            <if test="type != null">type = #{type},</if>
            <if test="aircraft != null">aircraft = #{aircraft},</if>
            <if test="payload != null">payload = #{payload},</if>
ard-work/pom.xml
@@ -24,7 +24,11 @@
            <groupId>com.ard</groupId>
            <artifactId>ard-common</artifactId>
        </dependency>
        <!--  framework框架核心-->
        <dependency>
            <groupId>com.ard</groupId>
            <artifactId>ard-framework</artifactId>
        </dependency>
        <!-- Forest -->
        <dependency>
            <groupId>com.dtflys.forest</groupId>
ard-work/src/main/java/com/ard/work/component/websocket/WebSocketSessionManager.java
@@ -28,4 +28,9 @@
    public static int getOnlineUserCount() {
        return ONLINE_USER_SESSIONS.size();
    }
    public static boolean containsUser(Long userId) {
        return ONLINE_USER_SESSIONS.containsKey(userId);
    }
}
ard-work/src/main/java/com/ard/work/component/websocket/handler/TyMessageHandler.java
@@ -2,7 +2,10 @@
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.ard.common.core.domain.model.LoginUser;
import com.ard.framework.web.service.TokenService;
import com.ard.work.component.websocket.WebSocketSessionManager;
import com.ard.work.component.websocket.utils.WebSocketUtil;
import com.ard.work.domain.enums.MessageType;
import com.ard.work.domain.message.*;
import com.ard.work.service.control.UavControlService;
@@ -14,6 +17,7 @@
import org.springframework.web.socket.handler.TextWebSocketHandler;
import javax.annotation.Resource;
import java.util.concurrent.CompletableFuture;
@Component
@@ -34,6 +38,8 @@
    private UavControlManager uavControlManager;
    @Resource
    private UavAllManager uavAllManager;
    @Resource
    private TokenService tokenService;
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
@@ -46,6 +52,9 @@
            BaseMessage<?> baseMessage = JSON.parseObject(payload, BaseMessage.class);
            MessageType messageType = MessageType.fromString(baseMessage.getType());
            switch (messageType) {
                case HEARTBEAT:
                    handleHeartbeatMessage(payload, userId);
                    break;
                case STREAM:
                    handleStreamMessage(payload, userId);
                    break;
@@ -68,6 +77,19 @@
        } catch (Exception e) {
            log.error("Error handling message: {}", message, e);
        }
    }
    /**
     * 处理心跳消息
     * <p>
     * 该方法解析给定的负载数据,以获取无人机流消息,并根据消息类型决定是否开始或停止流
     *
     * @param payload 消息的负载数据,通常为JSON字符串
     * @param userId  接收消息的用户ID
     */
    private void handleHeartbeatMessage(String payload, Long userId) {
        WebSocketUtil.sendMessage(userId, payload);
    }
    /**
@@ -276,7 +298,21 @@
        uavTelemetryManager.removeSubscribe(userId);
        uavSignalManager.removeSubscribe(userId);
        uavControlManager.removeSubscribe(userId);
        // 延迟10秒删除token(若期间没重连)
        CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(10_000); // 延迟10秒
            } catch (InterruptedException ignored) {
            }
            if (!WebSocketSessionManager.containsUser(userId)) {
                LoginUser loginUser = tokenService.getLoginUserByUserId(userId);
                if (loginUser != null) {
                    tokenService.delLoginUser(loginUser.getToken(), userId);
                    log.info("【cmd】用户 [{}] 超时未重连,已删除 token", userId);
                }
            }
        });
    }
}
ard-work/src/main/java/com/ard/work/domain/enums/MessageType.java
@@ -1,6 +1,7 @@
package com.ard.work.domain.enums;
public enum MessageType {
    HEARTBEAT("heartbeat"),
    STREAM("stream"),
    STATE("state"),
    TELEMETRY("telemetry"),
ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java
@@ -873,7 +873,7 @@
            case 0x02:
                // 处理注册消息
                HeartbeatReplyCmd heartbeatReplyCmd = (HeartbeatReplyCmd) tyCommand;
                logPrint("心跳消息", heartbeatReplyCmd.getTimestamp());
                //logPrint("心跳消息", heartbeatReplyCmd.getTimestamp());
                break;
            case 0x03:
                // 处理订阅消息