From 6e33e3f0ee952d768026fda82dc0000204e21c72 Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Tue, 18 Feb 2025 09:46:05 +0800
Subject: [PATCH] 222

---
 ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java                           |    3 
 ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java                       |   29 ++++++-
 ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java |    2 
 ard-work/src/main/java/com/ard/tianyu/http/TyClient.java                                    |   20 ++--
 ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java              |   16 ++++
 ard-work/src/main/java/com/ard/tianyu/service/ITyService.java                               |    6 +
 ard-admin/src/main/resources/application-dev.yml                                            |   31 +++++--
 ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java                 |   22 +++++
 ard-common/src/main/java/com/ard/common/constant/Constants.java                             |    5 +
 ard-work/src/main/java/com/ard/tianyu/controller/UavVideoController.java                    |   34 ++++++++
 ard-admin/src/main/resources/application.yml                                                |    3 
 ard-work/src/main/java/com/ard/tianyu/http/TokenInterceptor.java                            |   34 ++++++++
 12 files changed, 176 insertions(+), 29 deletions(-)

diff --git a/ard-admin/src/main/resources/application-dev.yml b/ard-admin/src/main/resources/application-dev.yml
index dd65f2e..0a10dd4 100644
--- a/ard-admin/src/main/resources/application-dev.yml
+++ b/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:
   # 流媒体服务器地址
diff --git a/ard-admin/src/main/resources/application.yml b/ard-admin/src/main/resources/application.yml
index d8182d6..bf86b5e 100644
--- a/ard-admin/src/main/resources/application.yml
+++ b/ard-admin/src/main/resources/application.yml
@@ -51,7 +51,8 @@
   secret: abcdefghijklmnopqrstuvwxyz
   # 令牌有效期(默认30分钟)
   expireTime: 720
-
+  # 是否允许账户多终端同时登录(true允许 false不允许)
+  soloLogin: false
 # MyBatis配置
 mybatis:
   # 搜索指定包别名
diff --git a/ard-common/src/main/java/com/ard/common/constant/Constants.java b/ard-common/src/main/java/com/ard/common/constant/Constants.java
index bddbfa1..2addc7a 100644
--- a/ard-common/src/main/java/com/ard/common/constant/Constants.java
+++ b/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:";
 }
diff --git a/ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java b/ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java
index a7c4243..e67220f 100644
--- a/ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java
+++ b/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")));
         }
diff --git a/ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java b/ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java
index d380f42..fd63a77 100644
--- a/ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java
+++ b/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);
     }
diff --git a/ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java b/ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java
index 5250cf1..cf08c40 100644
--- a/ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java
+++ b/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;
+    }
 }
diff --git a/ard-work/src/main/java/com/ard/tianyu/controller/UavVideoController.java b/ard-work/src/main/java/com/ard/tianyu/controller/UavVideoController.java
new file mode 100644
index 0000000..b67e762
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/controller/UavVideoController.java
@@ -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));
+    }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/http/TokenInterceptor.java b/ard-work/src/main/java/com/ard/tianyu/http/TokenInterceptor.java
new file mode 100644
index 0000000..8d664ef
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/http/TokenInterceptor.java
@@ -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
+    }
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java b/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java
index b67b86f..fbfba5a 100644
--- a/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java
+++ b/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);
 }
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java b/ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java
index e226263..430fe92 100644
--- a/ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java
+++ b/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);
             }
         });
         //将连接存入集合
diff --git a/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java b/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
index 0d13271..d1342fa 100644
--- a/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
+++ b/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);
+
 }
diff --git a/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java b/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
index 6f6cdb6..b3a1f2c 100644
--- a/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
+++ b/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());
         }
     }
+
 }
\ No newline at end of file

--
Gitblit v1.9.3