Przeglądaj źródła

+ 新增redis proxy 代理类

chen.cheng 6 miesięcy temu
rodzic
commit
7aa4d931a8
15 zmienionych plików z 523 dodań i 78 usunięć
  1. 7 7
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/EvtFusionEngine.java
  2. 35 32
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/impl/FenceBreakInEngine.java
  3. 30 26
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/impl/RoomBreakInEngine.java
  4. 133 0
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/impl/VideoTrailEngine.java
  5. 13 3
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/mqtt/UWBLocationListener.java
  6. 1 1
      bd-park/park-backend/park-application/src/main/resources/application-druid.yml
  7. 4 1
      bd-park/park-backend/park-application/src/main/resources/application.yml
  8. 4 2
      bd-park/park-backend/park-cloud/pom.xml
  9. 7 0
      bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/BDConst.java
  10. 27 1
      bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/enums/FenceType.java
  11. 241 0
      bd-park/park-backend/park-core/src/main/java/com/huashe/park/core/redis/RedisProxy.java
  12. 2 2
      bd-park/park-backend/park-core/src/main/resources/mapper/bd/BdFenceInfoMapper.xml
  13. 4 0
      bd-park/park-backend/park-domain/src/main/java/com/huashe/park/domain/dto/VideoFence.java
  14. 9 1
      bd-park/park-backend/park-infrastructure/src/main/java/com/huashe/park/infrastructure/cfg/forest/UWBForestCfg.java
  15. 6 2
      bd-park/park-backend/park-infrastructure/src/main/java/com/huashe/park/infrastructure/socket/client/UWBSocketClient.java

+ 7 - 7
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/EvtFusionEngine.java

@@ -3,7 +3,7 @@ package com.huashe.park.application.engine;
 import com.alibaba.fastjson2.JSONObject;
 import com.huashe.common.utils.StringUtils;
 import com.huashe.park.common.DateTimeUtil;
-import com.ruoyi.common.core.redis.RedisCache;
+import com.huashe.park.core.redis.RedisProxy;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
@@ -17,7 +17,7 @@ public abstract class EvtFusionEngine implements IFusionEngine {
     private final static Logger logger = LoggerFactory.getLogger(EvtFusionEngine.class);
 
     @Resource
-    private RedisCache redisCache;
+    private RedisProxy redisService;
 
     private String engineName;
 
@@ -61,24 +61,24 @@ public abstract class EvtFusionEngine implements IFusionEngine {
                         LocationInfo locationInfoNew = new LocationInfo(msg.getDouble("latitude"), msg.getDouble("longitude"), msg.getLong("srcTimestamp"));
                         locationInfoNew.setMsg(msg);
                         String key = getKey(locationInfoNew);
-                        if (!redisCache.hasKey(key)) {
+                        if (!redisService.hasKey(key)) {
                             getBizId(locationInfoNew);
-                            redisCache.setCacheObject(key, locationInfoNew);
+                            redisService.setCacheObject(key, locationInfoNew);
                             newEvtCallback(locationInfoNew);
                             continue;
                         }
-                        LocationInfo locationInfo = redisCache.getCacheObject(key);
+                        LocationInfo locationInfo = redisService.getCacheObject(key);
                         locationInfoNew.setEvtTimestamp(DateTimeUtil.timestampMillis());
                         // 判断消息是否需要融合
                         if (check(locationInfo, locationInfoNew)) {
                             locationInfo.setSrcTimestamp(locationInfoNew.getSrcTimestamp());
                             locationInfo.setHandleTimestamp(DateTimeUtil.timestampMillis());
-                            redisCache.setCacheObject(key, locationInfo);
+                            redisService.setCacheObject(key, locationInfo);
                         } else {
                             // 老数据释放
                             processOlderData(locationInfo);
                             getBizId(locationInfoNew);
-                            redisCache.setCacheObject(key, locationInfoNew);
+                            redisService.setCacheObject(key, locationInfoNew);
                             newEvtCallback(locationInfoNew);
                         }
                     } catch (InterruptedException e) {

+ 35 - 32
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/impl/FenceBreakInEngine.java

@@ -1,37 +1,39 @@
 package com.huashe.park.application.engine.impl;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import javax.annotation.PostConstruct;
+
+import com.huashe.park.core.redis.RedisProxy;
+import org.apache.commons.lang3.ObjectUtils;
+import org.locationtech.jts.geom.Polygon;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
-import com.huashe.park.common.DateTimeUtil;
-import com.huashe.park.common.consts.BDConst;
-import com.huashe.park.common.consts.enums.EvtStatus;
-import com.huashe.park.common.consts.enums.EvtType;
-import com.huashe.park.common.geo.GeoUtils;
 import com.huashe.park.application.engine.EvtFusionEngine;
 import com.huashe.park.application.engine.LocationInfo;
 import com.huashe.park.application.socket.server.FenceVioEvtSocketServer;
 import com.huashe.park.application.web.core.config.MqttCfg;
+import com.huashe.park.common.DateTimeUtil;
+import com.huashe.park.common.consts.BDConst;
+import com.huashe.park.common.consts.enums.EvtStatus;
+import com.huashe.park.common.consts.enums.EvtType;
 import com.huashe.park.common.consts.enums.FenceType;
+import com.huashe.park.common.geo.GeoUtils;
 import com.huashe.park.core.service.IBdFenceInfoService;
 import com.huashe.park.core.service.IBdFenceVioEvtService;
 import com.huashe.park.domain.entity.BdFenceInfo;
 import com.huashe.park.domain.entity.BdFenceVioEvt;
-import com.ruoyi.common.core.redis.RedisCache;
-import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate;
-import org.apache.commons.lang3.ObjectUtils;
-import org.locationtech.jts.geom.Polygon;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
 
-import javax.annotation.PostConstruct;
-import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.LinkedBlockingQueue;
+import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate;
 
 @Service
 @ConditionalOnBean(MqttCfg.class)
@@ -44,15 +46,14 @@ public class FenceBreakInEngine extends EvtFusionEngine {
     @Autowired
     private IBdFenceVioEvtService vioEvtService;
 
-    @Resource
-    private RedisCache redisCache;
+    @Autowired
+    private RedisProxy redisService;
 
     @Autowired
     private MqttClientTemplate client;
 
     /**
-     * The constant MAX_EVT_TIME_GAP.
-     * 单位:秒
+     * The constant MAX_EVT_TIME_GAP. 单位:秒
      *
      * @author chen.cheng
      */
@@ -67,16 +68,19 @@ public class FenceBreakInEngine extends EvtFusionEngine {
     public void init() {
         super.init();
         this.setEngineName("室外围栏闯禁事件融合");
-        if (!redisCache.hasKey(BDConst.REDIS_KEY.FENCE)) {
-            List<BdFenceInfo> bdFenceInfos = fenceInfoService.selectBdFenceInfoList(new BdFenceInfo() {{
-                setFenceType(FenceType.OUT_SIDE_FENCE_IN.getCode());
-            }});
+        if (!redisService.hasKey(BDConst.REDIS_KEY.FENCE)) {
+            List<BdFenceInfo> bdFenceInfos = fenceInfoService.selectBdFenceInfoList(new BdFenceInfo() {
+                {
+                    setFenceType(FenceType.OUT_SIDE_FENCE_IN.getCode());
+                }
+            });
             if (CollectionUtils.isEmpty(bdFenceInfos)) {
                 return;
             }
-            bdFenceInfos.removeIf(item -> ObjectUtils.isEmpty(item.getPoly()) || ObjectUtils.isEmpty(GeoUtils.getPolygon(item.getPoly())));
+            bdFenceInfos.removeIf(item -> ObjectUtils.isEmpty(item.getPoly())
+                || ObjectUtils.isEmpty(GeoUtils.getPolygon(item.getPoly())));
 
-            redisCache.setCacheList(BDConst.REDIS_KEY.FENCE, bdFenceInfos);
+            redisService.setCacheList(BDConst.REDIS_KEY.FENCE, bdFenceInfos);
         }
     }
 
@@ -101,7 +105,6 @@ public class FenceBreakInEngine extends EvtFusionEngine {
         return BDConst.REDIS_KEY.FENCE_BREAK_IN_KEY + msg.getMsg().getString("deviceId");
     }
 
-
     @Override
     public void getBizId(LocationInfo msg) {
         BdFenceVioEvt bdFenceVioEvt = new BdFenceVioEvt();
@@ -132,7 +135,7 @@ public class FenceBreakInEngine extends EvtFusionEngine {
     }
 
     public void generateEvt(JSONObject msg, byte[] payload) {
-        List<BdFenceInfo> cacheList = redisCache.getCacheList(BDConst.REDIS_KEY.FENCE);
+        List<BdFenceInfo> cacheList = redisService.getCacheList(BDConst.REDIS_KEY.FENCE);
         if (CollectionUtils.isEmpty(cacheList)) {
             return;
         }

+ 30 - 26
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/impl/RoomBreakInEngine.java

@@ -1,5 +1,23 @@
 package com.huashe.park.application.engine.impl;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+
+import com.huashe.park.core.redis.RedisProxy;
+import org.apache.commons.lang3.ObjectUtils;
+import org.locationtech.jts.geom.Polygon;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.huashe.park.application.engine.EvtFusionEngine;
@@ -16,23 +34,8 @@ import com.huashe.park.core.service.IBdFenceInfoService;
 import com.huashe.park.core.service.IBdFenceVioEvtService;
 import com.huashe.park.domain.entity.BdFenceInfo;
 import com.huashe.park.domain.entity.BdFenceVioEvt;
-import com.ruoyi.common.core.redis.RedisCache;
-import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate;
-import org.apache.commons.lang3.ObjectUtils;
-import org.locationtech.jts.geom.Polygon;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
 
-import javax.annotation.PostConstruct;
-import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.LinkedBlockingQueue;
+import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate;
 
 /**
  * The type Room break in engine.
@@ -49,7 +52,7 @@ public class RoomBreakInEngine extends EvtFusionEngine {
     private IBdFenceVioEvtService vioEvtService;
 
     @Resource
-    private RedisCache redisCache;
+    private RedisProxy redisService;
 
     @Autowired
     private MqttClientTemplate client;
@@ -57,7 +60,6 @@ public class RoomBreakInEngine extends EvtFusionEngine {
     @Value("${evt-fusion.fusion-time.room-location:300}")
     private int MAX_EVT_TIME_GAP;
 
-
     @Autowired
     private FenceVioEvtSocketServer fenceVioEvtSocketServer;
 
@@ -67,16 +69,19 @@ public class RoomBreakInEngine extends EvtFusionEngine {
     public void init() {
         super.init();
         this.setEngineName("室内围栏闯禁事件融合");
-        if (!redisCache.hasKey(BDConst.REDIS_KEY.FENCE_ROOM)) {
-            List<BdFenceInfo> bdFenceInfos = fenceInfoService.selectBdFenceInfoList(new BdFenceInfo() {{
-                setFenceType(FenceType.INSIDE_FENCE_IN.getCode());
-            }});
+        if (!redisService.hasKey(BDConst.REDIS_KEY.FENCE_ROOM)) {
+            List<BdFenceInfo> bdFenceInfos = fenceInfoService.selectBdFenceInfoList(new BdFenceInfo() {
+                {
+                    setFenceType(FenceType.INSIDE_FENCE_IN.getCode());
+                }
+            });
             if (CollectionUtils.isEmpty(bdFenceInfos)) {
                 return;
             }
-            bdFenceInfos.removeIf(item -> ObjectUtils.isEmpty(item.getPoly()) || ObjectUtils.isEmpty(GeoUtils.getPolygon(item.getPoly())));
+            bdFenceInfos.removeIf(item -> ObjectUtils.isEmpty(item.getPoly())
+                || ObjectUtils.isEmpty(GeoUtils.getPolygon(item.getPoly())));
 
-            redisCache.setCacheList(BDConst.REDIS_KEY.FENCE_ROOM, bdFenceInfos);
+            redisService.setCacheList(BDConst.REDIS_KEY.FENCE_ROOM, bdFenceInfos);
         }
     }
 
@@ -96,7 +101,6 @@ public class RoomBreakInEngine extends EvtFusionEngine {
         return messageQueueList;
     }
 
-
     /**
      * Gets key. 获取融合对象在redis中的key
      *
@@ -140,7 +144,7 @@ public class RoomBreakInEngine extends EvtFusionEngine {
     }
 
     public void generateEvt(JSONObject msg, byte[] payload) {
-        List<BdFenceInfo> cacheList = redisCache.getCacheList(BDConst.REDIS_KEY.FENCE_ROOM);
+        List<BdFenceInfo> cacheList = redisService.getCacheList(BDConst.REDIS_KEY.FENCE_ROOM);
         if (CollectionUtils.isEmpty(cacheList)) {
             return;
         }

+ 133 - 0
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/impl/VideoTrailEngine.java

@@ -0,0 +1,133 @@
+package com.huashe.park.application.engine.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+
+import com.huashe.park.core.redis.RedisProxy;
+import org.apache.commons.lang3.ObjectUtils;
+import org.locationtech.jts.geom.Polygon;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.huashe.park.application.engine.EvtFusionEngine;
+import com.huashe.park.application.engine.LocationInfo;
+import com.huashe.park.application.web.core.config.MqttCfg;
+import com.huashe.park.common.consts.BDConst;
+import com.huashe.park.common.consts.enums.FenceType;
+import com.huashe.park.common.geo.GeoUtils;
+import com.huashe.park.core.service.IBdFenceInfoService;
+import com.huashe.park.domain.entity.BdFenceInfo;
+import com.huashe.park.infrastructure.socket.server.UwbVideoTraceSocketServer;
+
+import cn.hutool.core.lang.UUID;
+
+/**
+ * The type Room break in engine.
+ */
+@Service
+@ConditionalOnBean(MqttCfg.class)
+public class VideoTrailEngine extends EvtFusionEngine {
+    private static final Logger logger = LoggerFactory.getLogger(VideoTrailEngine.class);
+
+    @Autowired
+    private IBdFenceInfoService fenceInfoService;
+
+    @Resource
+    private RedisProxy redisService;
+
+    @Value("${evt-fusion.fusion-time.video-trail:300}")
+    private int MAX_EVT_TIME_GAP;
+
+    @Resource
+    private UwbVideoTraceSocketServer videoTraceSocketServer;
+
+    private final List<LinkedBlockingQueue<JSONObject>> messageQueueList = new ArrayList<>(5);
+
+    @PostConstruct
+    public void init() {
+        super.init();
+        this.setEngineName("视频跟随");
+        if (!redisService.hasKey(BDConst.REDIS_KEY.FENCE_VIDEO_TRACE)) {
+            List<BdFenceInfo> bdFenceInfos = fenceInfoService.selectBdFenceInfoList(new BdFenceInfo() {
+                {
+                    setFenceType(FenceType.VIDEO_FENCE_IN.getCode());
+                }
+            });
+            if (CollectionUtils.isEmpty(bdFenceInfos)) {
+                return;
+            }
+            bdFenceInfos.removeIf(item -> ObjectUtils.isEmpty(item.getPoly())
+                || ObjectUtils.isEmpty(GeoUtils.getPolygon(item.getPoly())));
+
+            redisService.setCacheList(BDConst.REDIS_KEY.FENCE_VIDEO_TRACE, bdFenceInfos);
+        }
+    }
+
+    @Override
+    public Boolean check(LocationInfo older, LocationInfo newer) {
+        long gap = newer.getSrcTimestamp() - older.getSrcTimestamp();
+        // 将gap 转换为秒
+        gap = gap / 1000;
+
+        String oldFenceId = older.getMsg().getString("fenceId");
+        String newerFenceId = newer.getMsg().getString("fenceId");
+        return gap <= MAX_EVT_TIME_GAP && oldFenceId.equals(newerFenceId);
+    }
+
+    @Override
+    public List<LinkedBlockingQueue<JSONObject>> getQueue() {
+        return messageQueueList;
+    }
+
+    /**
+     * Gets key. 获取融合对象在redis中的key
+     *
+     * @param msg the msg
+     * @return the key
+     * @author chen.cheng
+     */
+    @Override
+    public String getKey(LocationInfo msg) {
+        return BDConst.REDIS_KEY.FENCE_VIDEO_TRACE_KEY + msg.getMsg().getString("deviceId");
+    }
+
+    @Override
+    public void getBizId(LocationInfo msg) {
+        msg.setBizId(UUID.fastUUID().toString());
+    }
+
+    @Override
+    public void newEvtCallback(LocationInfo msg) {
+        videoTraceSocketServer.sendMessage(msg.getMsg().getString("deviceId"), JSONObject.from(msg));
+    }
+
+    public void generateEvt(JSONObject msg, byte[] payload) {
+        List<BdFenceInfo> cacheList = redisService.getCacheList(BDConst.REDIS_KEY.FENCE_VIDEO_TRACE);
+        if (CollectionUtils.isEmpty(cacheList)) {
+            return;
+        }
+        Polygon polygon;
+        logger.debug("fence info size: {}", msg);
+        for (BdFenceInfo fenceInfo : cacheList) {
+            polygon = GeoUtils.getPolygon(fenceInfo.getPoly());
+            if (GeoUtils.isPointInGeoFence(polygon, msg.getString("longitude"), msg.getString("latitude"))) {
+                logger.debug("?>>>>>fence info size: {}", msg);
+                msg.put("fenceId", fenceInfo.getId());
+                msg.put("fenceName", fenceInfo.getDefenceName());
+                msg.put("videoId", fenceInfo.getLocationId());
+//                client.publish(BDConst.MQTT_TOPIC.EVT_ROOM_LOCATION_TOPIC, JSON.toJSONBytes(msg));
+                break;
+            }
+        }
+    }
+}

+ 13 - 3
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/mqtt/UWBLocationListener.java

@@ -1,15 +1,25 @@
 package com.huashe.park.application.mqtt;
 
-import net.dreamlu.iot.mqtt.core.client.MqttClientCreator;
-import net.dreamlu.iot.mqtt.spring.client.event.MqttConnectedEvent;
-import net.dreamlu.iot.mqtt.spring.client.event.MqttDisconnectEvent;
+import com.huashe.park.application.engine.impl.VideoTrailEngine;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.context.event.EventListener;
 import org.springframework.stereotype.Service;
 
+import com.alibaba.fastjson2.JSON;
+import com.huashe.park.application.web.core.config.MqttCfg;
+import com.huashe.park.common.consts.BDConst;
+
+import net.dreamlu.iot.mqtt.codec.MqttQoS;
+import net.dreamlu.iot.mqtt.core.client.MqttClientCreator;
+import net.dreamlu.iot.mqtt.spring.client.MqttClientSubscribe;
+import net.dreamlu.iot.mqtt.spring.client.event.MqttConnectedEvent;
+import net.dreamlu.iot.mqtt.spring.client.event.MqttDisconnectEvent;
+
 @Service
+@ConditionalOnBean(MqttCfg.class)
 public class UWBLocationListener {
     private static final Logger logger = LoggerFactory.getLogger(UWBLocationListener.class);
 

+ 1 - 1
bd-park/park-backend/park-application/src/main/resources/application-druid.yml

@@ -101,4 +101,4 @@ mqtt:
       enabled: false
 bd:
   mqtt:
-    enabled: false
+    enabled: true

+ 4 - 1
bd-park/park-backend/park-application/src/main/resources/application.yml

@@ -37,6 +37,8 @@ logging:
     com.ruoyi: debug
     com.huashe: debug
     org.springframework: warn
+    com:
+      huashe.park.infrastructure.socket.client: info
 
 # 用户配置
 user:
@@ -88,6 +90,7 @@ forest:
     uwb:
       enabled: true
       uwb-socket: ws://172.192.13.80:2223/socket/websocket/pollingArea
+      test-tag: 845D3
       uwb-usr: admin
       uwb-pwd: admin123
       uwb-host: http://172.192.13.80:2223
@@ -138,5 +141,5 @@ xss:
 evt-fusion:
   # 默认为false
   enabled: false
-  thread-pool-size: 5
+  thread-pool-size: 2
 

+ 4 - 2
bd-park/park-backend/park-cloud/pom.xml

@@ -65,8 +65,10 @@
             <groupId>com.huashe.cloud</groupId>
             <artifactId>ruoyi-common-datasource</artifactId>
         </dependency>
-
-
+        <dependency>
+        <groupId>com.huashe.cloud</groupId>
+        <artifactId>ruoyi-common-redis</artifactId>
+    </dependency>
         <!-- RuoYi Common DataScope -->
         <dependency>
             <groupId>com.huashe.cloud</groupId>

+ 7 - 0
bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/BDConst.java

@@ -9,6 +9,11 @@ public interface BDConst {
         String FENCE_ROOM = "fence:room";
 
         String FENCE_ROOM_BREAK_IN_KEY = "fence:room:break:in:";
+
+
+        String FENCE_VIDEO_TRACE = "fence:video";
+
+        String FENCE_VIDEO_TRACE_KEY = "fence:video:in:";
     }
 
     public interface MQTT_TOPIC {
@@ -21,5 +26,7 @@ public interface BDConst {
 
         String UWB_VIDEO_TRACE_POINT = "/uwb/video-trace/point/%s";
 
+        String UWB_VIDEO_TRACE_POINT_TOPIC = "/uwb/video-trace/point/#";
+
     }
 }

+ 27 - 1
bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/enums/FenceType.java

@@ -1,10 +1,26 @@
 package com.huashe.park.common.consts.enums;
 
+/**
+ * The enum Fence type.
+ */
 public enum FenceType {
+    /**
+     * Out side fence in fence type.
+     */
     OUT_SIDE_FENCE_IN("1", "室外围栏闯禁"),
-    INSIDE_FENCE_IN("2", "室外围栏闯禁");
+
+    /**
+     * Inside fence in fence type.
+     */
+    INSIDE_FENCE_IN("2", "室外围栏闯禁"),
+
+    /**
+     * Video fence in fence type.
+     */
+    VIDEO_FENCE_IN("3", "摄像机跟随");
 
     private final String code;
+
     private final String info;
 
     FenceType(String code, String info) {
@@ -12,10 +28,20 @@ public enum FenceType {
         this.info = info;
     }
 
+    /**
+     * Gets code.
+     *
+     * @return the code
+     */
     public String getCode() {
         return code;
     }
 
+    /**
+     * Gets info.
+     *
+     * @return the info
+     */
     public String getInfo() {
         return info;
     }

+ 241 - 0
bd-park/park-backend/park-core/src/main/java/com/huashe/park/core/redis/RedisProxy.java

@@ -0,0 +1,241 @@
+package com.huashe.park.core.redis;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.BoundSetOperations;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RedisProxy {
+    @Autowired
+    public RedisTemplate redisTemplate;
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key 缓存的键值
+     * @param value 缓存的值
+     */
+    public <T> void setCacheObject(final String key, final T value) {
+        redisTemplate.opsForValue().set(key, value);
+    }
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key 缓存的键值
+     * @param value 缓存的值
+     * @param timeout 时间
+     * @param timeUnit 时间颗粒度
+     */
+    public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) {
+        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key Redis键
+     * @param timeout 超时时间
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout) {
+        return expire(key, timeout, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key Redis键
+     * @param timeout 超时时间
+     * @param unit 时间单位
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
+        return redisTemplate.expire(key, timeout, unit);
+    }
+
+    /**
+     * 获取有效时间
+     *
+     * @param key Redis键
+     * @return 有效时间
+     */
+    public long getExpire(final String key) {
+        return redisTemplate.getExpire(key);
+    }
+
+    /**
+     * 判断 key是否存在
+     *
+     * @param key 键
+     * @return true 存在 false不存在
+     */
+    public Boolean hasKey(String key) {
+        return redisTemplate.hasKey(key);
+    }
+
+    /**
+     * 获得缓存的基本对象。
+     *
+     * @param key 缓存键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> T getCacheObject(final String key) {
+        ValueOperations<String, T> operation = redisTemplate.opsForValue();
+        return operation.get(key);
+    }
+
+    /**
+     * 删除单个对象
+     *
+     * @param key
+     */
+    public boolean deleteObject(final String key) {
+        return redisTemplate.delete(key);
+    }
+
+    /**
+     * 删除集合对象
+     *
+     * @param collection 多个对象
+     * @return
+     */
+    public boolean deleteObject(final Collection collection) {
+        return redisTemplate.delete(collection) > 0;
+    }
+
+    /**
+     * 缓存List数据
+     *
+     * @param key 缓存的键值
+     * @param dataList 待缓存的List数据
+     * @return 缓存的对象
+     */
+    public <T> long setCacheList(final String key, final List<T> dataList) {
+        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+        return count == null ? 0 : count;
+    }
+
+    /**
+     * 获得缓存的list对象
+     *
+     * @param key 缓存的键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> List<T> getCacheList(final String key) {
+        return redisTemplate.opsForList().range(key, 0, -1);
+    }
+
+    /**
+     * 缓存Set
+     *
+     * @param key 缓存键值
+     * @param dataSet 缓存的数据
+     * @return 缓存数据的对象
+     */
+    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
+        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
+        Iterator<T> it = dataSet.iterator();
+        while (it.hasNext()) {
+            setOperation.add(it.next());
+        }
+        return setOperation;
+    }
+
+    /**
+     * 获得缓存的set
+     *
+     * @param key
+     * @return
+     */
+    public <T> Set<T> getCacheSet(final String key) {
+        return redisTemplate.opsForSet().members(key);
+    }
+
+    /**
+     * 缓存Map
+     *
+     * @param key
+     * @param dataMap
+     */
+    public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
+        if (dataMap != null) {
+            redisTemplate.opsForHash().putAll(key, dataMap);
+        }
+    }
+
+    /**
+     * 获得缓存的Map
+     *
+     * @param key
+     * @return
+     */
+    public <T> Map<String, T> getCacheMap(final String key) {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    /**
+     * 往Hash中存入数据
+     *
+     * @param key Redis键
+     * @param hKey Hash键
+     * @param value 值
+     */
+    public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
+        redisTemplate.opsForHash().put(key, hKey, value);
+    }
+
+    /**
+     * 获取Hash中的数据
+     *
+     * @param key Redis键
+     * @param hKey Hash键
+     * @return Hash中的对象
+     */
+    public <T> T getCacheMapValue(final String key, final String hKey) {
+        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
+        return opsForHash.get(key, hKey);
+    }
+
+    /**
+     * 获取多个Hash中的数据
+     *
+     * @param key Redis键
+     * @param hKeys Hash键集合
+     * @return Hash对象集合
+     */
+    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
+        return redisTemplate.opsForHash().multiGet(key, hKeys);
+    }
+
+    /**
+     * 删除Hash中的某条数据
+     *
+     * @param key Redis键
+     * @param hKey Hash键
+     * @return 是否成功
+     */
+    public boolean deleteCacheMapValue(final String key, final String hKey) {
+        return redisTemplate.opsForHash().delete(key, hKey) > 0;
+    }
+
+    /**
+     * 获得缓存的基本对象列表
+     *
+     * @param pattern 字符串前缀
+     * @return 对象列表
+     */
+    public Collection<String> keys(final String pattern) {
+        return redisTemplate.keys(pattern);
+    }
+}

+ 2 - 2
bd-park/park-backend/park-core/src/main/resources/mapper/bd/BdFenceInfoMapper.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.huashe.park.core.mapper.BdFenceInfoMapper">
 
     <resultMap type="BdFenceInfo" id="BdFenceInfoResult">

+ 4 - 0
bd-park/park-backend/park-domain/src/main/java/com/huashe/park/domain/dto/VideoFence.java

@@ -0,0 +1,4 @@
+package com.huashe.park.domain.dto;
+
+public class VideoFence {
+}

+ 9 - 1
bd-park/park-backend/park-infrastructure/src/main/java/com/huashe/park/infrastructure/cfg/forest/UWBForestCfg.java

@@ -6,7 +6,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Configuration;
 
-
 @Configuration
 @ConfigurationProperties(prefix = "forest.custom.uwb")
 @ConditionalOnProperty(name = "forest.custom.uwb.enabled", havingValue = "true")
@@ -21,6 +20,8 @@ public class UWBForestCfg {
 
     private String uwbHost;
 
+    private String testTag;
+
     public String getUwbHost() {
         return uwbHost;
     }
@@ -53,4 +54,11 @@ public class UWBForestCfg {
         this.uwbPwd = uwbPwd;
     }
 
+    public String getTestTag() {
+        return testTag;
+    }
+
+    public void setTestTag(String testTag) {
+        this.testTag = testTag;
+    }
 }

+ 6 - 2
bd-park/park-backend/park-infrastructure/src/main/java/com/huashe/park/infrastructure/socket/client/UWBSocketClient.java

@@ -6,6 +6,7 @@ import java.util.Map;
 
 import com.huashe.park.common.consts.BDConst;
 import com.huashe.park.domain.dto.UWBAuth;
+import com.huashe.park.infrastructure.cfg.forest.UWBForestCfg;
 import org.java_websocket.drafts.Draft;
 import org.java_websocket.handshake.ServerHandshake;
 import org.slf4j.Logger;
@@ -24,6 +25,9 @@ public class UWBSocketClient extends org.java_websocket.client.WebSocketClient {
     @Autowired
     private MqttClientTemplate client;
 
+    @Autowired
+    private UWBForestCfg uwbForestCfg;
+
     private UWBAuth authToken;
 
     public UWBAuth getAuthToken() {
@@ -57,12 +61,12 @@ public class UWBSocketClient extends org.java_websocket.client.WebSocketClient {
         log.debug("[websocket] 收到消息={}", message);
         JSONObject data = JSON.parseObject(message);
         if (!"handshake".equals(data.getString("message"))) {
-            client.publish(String.format(BDConst.MQTT_TOPIC.UWB_VIDEO_TRACE_POINT, "847F3"), JSON.toJSONBytes(data));
+            client.publish(String.format(BDConst.MQTT_TOPIC.UWB_VIDEO_TRACE_POINT, uwbForestCfg.getTestTag()), JSON.toJSONBytes(data));
             // TODO 推送轨迹
             // client.publish(String.format(BDConst.MQTT_TOPIC.UWB_VIDEO_TRACE, "847F3"), JSON.toJSONBytes(data));
             return;
         }
-        this.authToken.setTagId("847F3");
+        this.authToken.setTagId(uwbForestCfg.getTestTag());
         log.debug("[websocket] 推送={}", JSON.toJSONString(this.authToken));
         // tagId要去掉前缀0
         send(JSON.toJSONString(this.authToken));