222
liusuyi
2025-02-18 6e33e3f0ee952d768026fda82dc0000204e21c72
222
2 files added
10 files modified
205 ■■■■■ changed files
ard-admin/src/main/resources/application-dev.yml 31 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/resources/application.yml 3 ●●●●● patch | view | raw | blame | history
ard-common/src/main/java/com/ard/common/constant/Constants.java 5 ●●●●● patch | view | raw | blame | history
ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java 2 ●●●●● patch | view | raw | blame | history
ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java 16 ●●●●● patch | view | raw | blame | history
ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java 22 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/tianyu/controller/UavVideoController.java 34 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/tianyu/http/TokenInterceptor.java 34 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/tianyu/http/TyClient.java 20 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java 3 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/tianyu/service/ITyService.java 6 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java 29 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/resources/application-dev.yml
@@ -1,8 +1,11 @@
# 开发环境配置
server:
  # 服务器的HTTP端口,默认为8080
  port: 8081
  port: 8080
# token配置
token:
  # 是否允许账户多终端同时登录(true允许 false不允许)
  soloLogin: false
# 日志配置
logging:
  level:
@@ -22,14 +25,24 @@
    password: ardkj12345
# 天宇服务器配置
#tianyu:
#  # 天宇http服务器地址
#  endpoint: 112.98.106.22:12000
#  accesskeyid: qmfmd3Ws7M4dMcylnrTU
#  accesskeysecret: 5WBU2uEhHZaVefpZdaxpFh4LJW9fZZaa
#  # 天宇tcp服务器地址
#  tcpserver: 123.56.170.94
#  tcpport: 12345
# 天宇服务器配置
tianyu:
  # 天宇http服务器地址
  endpoint: 112.98.106.22:12000
  accesskeyid: qmfmd3Ws7M4dMcylnrTU
  accesskeysecret: 5WBU2uEhHZaVefpZdaxpFh4LJW9fZZaa
  # 天宇tcp服务器地址
  tcpserver: 123.56.170.94
  tcpport: 12345
 # 天宇http服务器地址
 endpoint: 59.110.237.99:8060
 accesskeyid: wuwuwu
 accesskeysecret: 9c9f139f63b343b0a9ef42e05ed29b0b
 # 天宇tcp服务器地址
 tcpserver: 59.110.237.99
 tcpport: 8124
#流媒体配置
mediamtx:
  # 流媒体服务器地址
ard-admin/src/main/resources/application.yml
@@ -51,7 +51,8 @@
  secret: abcdefghijklmnopqrstuvwxyz
  # 令牌有效期(默认30分钟)
  expireTime: 720
  # 是否允许账户多终端同时登录(true允许 false不允许)
  soloLogin: false
# MyBatis配置
mybatis:
  # 搜索指定包别名
ard-common/src/main/java/com/ard/common/constant/Constants.java
@@ -170,4 +170,9 @@
     */
    public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
            "org.springframework", "org.apache", "com.ard.common.utils.file", "com.ard.common.config", "com.ard.generator" };
    /**
     * 登录用户编号 redis key
     */
    public static final String LOGIN_USERID_KEY = "login_userid:";
}
ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java
@@ -44,7 +44,7 @@
        {
            String userName = loginUser.getUsername();
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken());
            tokenService.delLoginUser(loginUser.getToken(), loginUser.getUser().getUserId());
            // 记录用户退出日志
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
        }
ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java
@@ -2,6 +2,7 @@
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -37,6 +38,10 @@
@Component
public class SysLoginService
{
    // 是否允许账户多终端同时登录(true允许 false不允许)
    @Value("${token.soloLogin}")
    private boolean soloLogin;
    @Autowired
    private TokenService tokenService;
@@ -96,6 +101,17 @@
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        recordLoginInfo(loginUser.getUserId());
        if (!soloLogin)
        {
            // 如果用户不允许多终端同时登录,清除缓存信息
            String userIdKey = Constants.LOGIN_USERID_KEY + loginUser.getUser().getUserId();
            String userKey = redisCache.getCacheObject(userIdKey);
            if (StringUtils.isNotEmpty(userKey))
            {
                redisCache.deleteObject(userIdKey);
                redisCache.deleteObject(userKey);
            }
        }
        // 生成token
        return tokenService.createToken(loginUser);
    }
ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java
@@ -45,6 +45,10 @@
    @Value("${token.expireTime}")
    private int expireTime;
    // 是否允许账户多终端同时登录(true允许 false不允许)
    @Value("${token.soloLogin}")
    private boolean soloLogin;
    protected static final long MILLIS_SECOND = 1000;
    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
@@ -96,12 +100,17 @@
    /**
     * 删除用户身份信息
     */
    public void delLoginUser(String token)
    public void delLoginUser(String token, Long userId)
    {
        if (StringUtils.isNotEmpty(token))
        {
            String userKey = getTokenKey(token);
            redisCache.deleteObject(userKey);
        }
        if (!soloLogin && StringUtils.isNotNull(userId))
        {
            String userIdKey = getUserIdKey(userId);
            redisCache.deleteObject(userIdKey);
        }
    }
@@ -151,6 +160,12 @@
        // 根据uuid将loginUser缓存
        String userKey = getTokenKey(loginUser.getToken());
        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
        if (!soloLogin)
        {
            // 缓存用户唯一标识,防止同一帐号,同时登录
            String userIdKey = getUserIdKey(loginUser.getUser().getUserId());
            redisCache.setCacheObject(userIdKey, userKey, expireTime, TimeUnit.MINUTES);
        }
    }
    /**
@@ -228,4 +243,9 @@
    {
        return CacheConstants.LOGIN_TOKEN_KEY + uuid;
    }
    private String getUserIdKey(Long userId)
    {
        return Constants.LOGIN_USERID_KEY + userId;
    }
}
ard-work/src/main/java/com/ard/tianyu/controller/UavVideoController.java
New file
@@ -0,0 +1,34 @@
package com.ard.tianyu.controller;
import com.ard.common.core.domain.AjaxResult;
import com.ard.tianyu.model.receiver.BoxStreamUrlReceiver;
import com.ard.tianyu.service.ITyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
 * @ClassName: UavVideoController
 * @Description: 无人机视频控制器
 * @Author: liusuyi
 * @Date: 2025年02月18日9:16
 **/
@Api(tags = "无人机视频控制器接口")
@RequestMapping("/uav/video")
@RestController
public class UavVideoController {
    @Resource
    private ITyService tyService;
    @ApiOperation("点播")
    @PostMapping("/play/{boxSn}")
    public AjaxResult play(@PathVariable("boxSn") String boxSn) {
        return AjaxResult.success(tyService.play(boxSn));
    }
}
ard-work/src/main/java/com/ard/tianyu/http/TokenInterceptor.java
New file
@@ -0,0 +1,34 @@
package com.ard.tianyu.http;
import com.ard.tianyu.config.TyConfiguration;
import com.ard.tianyu.model.receiver.AccessTokenReceiver;
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.interceptor.Interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
@Slf4j
public class TokenInterceptor<T> implements Interceptor<T> {
    @Resource
    private TyConfiguration tyConfiguration;
    /**
     * 该方法在请求发送之前被调用, 若返回false则不会继续发送请求
     *
     * @Param request Forest请求对象
     */
    @Override
    public boolean beforeExecute(ForestRequest req) {
        log.info("invoke Simple beforeExecute");
        // 执行在发送请求之前处理的代码
        // 从缓存里获取token
        AccessTokenReceiver accessToken = tyConfiguration.getAccessToken();
        req.addHeader("x-cid", accessToken.getCompanyId());
        req.addHeader("x-token", accessToken.getAccessToken());
        // req.addHeader("Authorization", ""));  // 添加Header
        // req.addQuery("username", "foo");  // 添加URL的Query参数
        return true;  // 继续执行请求返回true
    }
}
ard-work/src/main/java/com/ard/tianyu/http/TyClient.java
@@ -29,30 +29,30 @@
    /**
     * 获取云盒列表
     */
    @Get(TyConst.GET_BOX_LIST)
    TyHttpCommonReceiver<List<BoxInfoReceiver>> getBoxList(@Header Map<String, String> headers);
    @Get(value = TyConst.GET_BOX_LIST,interceptor = TokenInterceptor.class)
    TyHttpCommonReceiver<List<BoxInfoReceiver>> getBoxList();
    /**
     * 获取直播地址
     */
    @Get(TyConst.GET_BOX_LIVE_URL)
    TyHttpCommonReceiver<BoxStreamUrlReceiver> getBoxLiveUrl(@Var("boxSn") String boxSn, @Header Map<String, String> headers);
    @Get(value =TyConst.GET_BOX_LIVE_URL,interceptor = TokenInterceptor.class)
    TyHttpCommonReceiver<BoxStreamUrlReceiver> getBoxLiveUrl(@Var("boxSn") String boxSn);
    /**
     * 获取飞行历史
     */
    @Post(TyConst.POST_BOX_HISTORY)
    TyHttpCommonReceiver<List<BoxHistoryReceiver>> getBoxHistory(@JSONBody BoxHistoryDTO boxHistoryDTO, @Header Map<String, String> headers);
    @Post(value =TyConst.POST_BOX_HISTORY,interceptor = TokenInterceptor.class)
    TyHttpCommonReceiver<List<BoxHistoryReceiver>> getBoxHistory(@JSONBody BoxHistoryDTO boxHistoryDTO);
    /**
     * 获取任务照片
     */
    @Post(TyConst.POST_BOX_PHOTOS)
    TyHttpCommonReceiver<List<BoxPhotosReceiver>> getBoxPhotos(@JSONBody BoxPhotosDTO boxPhotosDTO, @Header Map<String, String> headers);
    @Post(value =TyConst.POST_BOX_PHOTOS,interceptor = TokenInterceptor.class)
    TyHttpCommonReceiver<List<BoxPhotosReceiver>> getBoxPhotos(@JSONBody BoxPhotosDTO boxPhotosDTO);
    /**
     * 修改云盒设置
     */
    @Post(TyConst.POST_BOX_UPDATE)
    TyHttpCommonReceiver<?> updateBoxSettings(@JSONBody BoxSettingsDTO boxSettingsDTO, @Header Map<String, String> headers);
    @Post(value =TyConst.POST_BOX_UPDATE,interceptor = TokenInterceptor.class)
    TyHttpCommonReceiver<?> updateBoxSettings(@JSONBody BoxSettingsDTO boxSettingsDTO);
}
ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java
@@ -13,7 +13,6 @@
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
@@ -84,7 +83,7 @@
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, 5, TimeUnit.SECONDS);
                }, 10, TimeUnit.SECONDS);
            }
        });
        //将连接存入集合
ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
@@ -279,4 +279,10 @@
     * 处理回复消息
     */
    void processReplyMessage(String key, BaseCmd tyMessage);
    /**
     * 点播
     */
    String play(String boxSn);
}
ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
@@ -49,6 +49,8 @@
import com.ard.tianyu.netty.protobuf.TelemetryDataPB;
import com.ard.tianyu.service.ITyService;
import com.ard.tianyu.websocket.utils.WebSocketUtil;
import com.ard.vtdu.domain.ArdVtdu;
import com.ard.vtdu.service.IMediaService;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import lombok.extern.slf4j.Slf4j;
@@ -76,6 +78,8 @@
    @Resource
    private TyConfiguration tyConfiguration;
    @Resource
    private IMediaService mediaService;
    /**
     * 获取天宇token信息
@@ -96,7 +100,7 @@
    public List<BoxInfoReceiver> getBoxList() {
        //请求云盒列表
        try {
            TyHttpCommonReceiver<List<BoxInfoReceiver>> boxListReveiver = tyClient.getBoxList(tyConfiguration.getAccessToken().convertFromDTO());
            TyHttpCommonReceiver<List<BoxInfoReceiver>> boxListReveiver = tyClient.getBoxList();
            return boxListReveiver.getContent();
        } catch (Exception e) {
            log.error("获取云盒列表失败:{}", e.getMessage());
@@ -112,7 +116,7 @@
    @Override
    public BoxStreamUrlReceiver getBoxLiveUrl(String boxSn) {
        TyHttpCommonReceiver<BoxStreamUrlReceiver> boxLiveUrl = tyClient.getBoxLiveUrl(boxSn, tyConfiguration.getAccessToken().convertFromDTO());
        TyHttpCommonReceiver<BoxStreamUrlReceiver> boxLiveUrl = tyClient.getBoxLiveUrl(boxSn);
        return boxLiveUrl.getContent();
    }
@@ -123,7 +127,7 @@
     */
    @Override
    public List<BoxHistoryReceiver> getBoxHistory(BoxHistoryDTO boxHistoryDTO) {
        TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(boxHistoryDTO, tyConfiguration.getAccessToken().convertFromDTO());
        TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(boxHistoryDTO);
        return boxHistory.getContent();
    }
@@ -134,7 +138,7 @@
     */
    @Override
    public List<BoxPhotosReceiver> getBoxPhotos(BoxPhotosDTO boxPhotosDTO) {
        TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(boxPhotosDTO, tyConfiguration.getAccessToken().convertFromDTO());
        TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(boxPhotosDTO);
        return boxPhotos.getContent();
    }
@@ -143,7 +147,7 @@
     */
    @Override
    public Boolean updateBoxSettings(BoxSettingsDTO boxSettingsDTO) {
        TyHttpCommonReceiver<?> result = tyClient.updateBoxSettings(boxSettingsDTO, tyConfiguration.getAccessToken().convertFromDTO());
        TyHttpCommonReceiver<?> result = tyClient.updateBoxSettings(boxSettingsDTO);
        return result.getState() == 1;
    }
@@ -561,6 +565,20 @@
    }
    /**
     * 点播
     */
    @Override
    public String play(String boxSn) {
        BoxStreamUrlReceiver boxLiveUrl = getBoxLiveUrl(boxSn);
        if(boxLiveUrl == null||boxLiveUrl.getRtsp() == null) {
            return "";
        }
        ArdVtdu ardVtdu = ArdVtdu.builder().name(boxSn).rtspSource(boxLiveUrl.getRtsp()).build();
        ardVtdu = mediaService.addPath(ardVtdu);
        return ardVtdu.getWebrtcUrl();
    }
    /**
     * 处理天宇服务器返回的消息
     */
    @Override
@@ -783,4 +801,5 @@
            log.error("发送消息异常:{}", e.getMessage());
        }
    }
}