瀏覽代碼

+ 北斗园区业务代码

chen.cheng 6 月之前
父節點
當前提交
4b5a96cf06
共有 23 個文件被更改,包括 478 次插入46 次删除
  1. 7 3
      bd-park/park-backend/park-application/pom.xml
  2. 1 1
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/BDApplication.java
  3. 2 2
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/EvtFusionEngine.java
  4. 15 11
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/impl/FenceBreakInEngine.java
  5. 5 5
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/impl/PointFusionEngine.java
  6. 161 0
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/impl/RoomBreakInEngine.java
  7. 16 2
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/mqtt/UWBLocationSubscribeListener.java
  8. 87 0
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/socket/client/UWBSocketClient.java
  9. 2 6
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/socket/server/FenceVioEvtSocketServer.java
  10. 2 6
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/socket/server/PointWebSocketServer.java
  11. 102 0
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/socket/server/UWBVideoTraceSocketServer.java
  12. 2 2
      bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/web/controller/bd/BdDevcTrailUwbController.java
  13. 1 1
      bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/DateTimeUtil.java
  14. 9 1
      bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/BDConst.java
  15. 1 1
      bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/enums/EvtStatus.java
  16. 4 2
      bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/enums/EvtType.java
  17. 22 0
      bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/enums/FenceType.java
  18. 1 1
      bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/geo/CoordinateConverter.java
  19. 1 1
      bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/geo/GeoUtils.java
  20. 1 1
      bd-park/park-backend/park-core/src/main/java/com/huashe/park/core/service/impl/BdFenceInfoServiceImpl.java
  21. 10 0
      bd-park/park-backend/park-infrastructure/pom.xml
  22. 11 0
      bd-park/park-backend/park-infrastructure/src/main/java/com/huashe/park/infrastructure/uwb/UWBWebService.java
  23. 15 0
      bd-park/park-backend/pom.xml

+ 7 - 3
bd-park/park-backend/park-application/pom.xml

@@ -10,7 +10,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <artifactId>park-appliication</artifactId>
-    <version>1.0-SNAPSHOT</version>
+    <version>${park.version}</version>
 
     <description>
         park-appliication核心模块
@@ -73,12 +73,16 @@
         <dependency>
             <groupId>com.huashe.park</groupId>
             <artifactId>park-common</artifactId>
-            <version>1.0-SNAPSHOT</version>
+            <version>${park.version}</version>
         </dependency>
         <dependency>
             <groupId>com.huashe.park</groupId>
             <artifactId>park-core</artifactId>
-            <version>1.0-SNAPSHOT</version>
+            <version>${park.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.java-websocket</groupId>
+            <artifactId>Java-WebSocket</artifactId>
         </dependency>
     </dependencies>
     <build>

+ 1 - 1
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/BDApplication.java

@@ -14,7 +14,7 @@ import org.springframework.context.annotation.ComponentScan;
  */
 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
 @ComponentScan(basePackages = {"com.ruoyi"})
-@ForestScan(basePackages = "com.ruoyi.system.rest")
+@ForestScan(basePackages = {"com.huashe.park.infrastructure"})
 public class BDApplication {
     public static void main(String[] args) {
         // System.setProperty("spring.devtools.restart.enabled", "false");

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

@@ -1,7 +1,7 @@
 package com.huashe.park.application.engine;
 
 import com.alibaba.fastjson2.JSONObject;
-import com.huashe.park.application.common.DateTimeUtil;
+import com.huashe.park.common.DateTimeUtil;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.utils.StringUtils;
 import org.slf4j.Logger;
@@ -21,7 +21,7 @@ public abstract class EvtFusionEngine implements IFusionEngine {
 
     private String engineName;
 
-    @Value("${evt-fusion.thread-pool-size:5}")
+    @Value("${evt-fusion.thread-pool-size:2}")
     private int threadPoolSize;
 
     @Resource(name = "threadPoolTaskExecutor")

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

@@ -2,20 +2,21 @@ package com.huashe.park.application.engine.impl;
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
-import com.huashe.park.application.common.DateTimeUtil;
-import com.huashe.park.application.common.geo.GeoUtils;
+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.consts.enums.FenceType;
 import com.huashe.park.core.service.IBdFenceInfoService;
 import com.huashe.park.core.service.IBdFenceVioEvtService;
-import com.huashe.park.application.engine.EvtFusionEngine;
-import com.huashe.park.application.engine.LocationInfo;
-import com.huashe.park.application.bd.socket.FenceVioEvtSocketServer;
-import com.huashe.park.application.common.BDConst;
 import com.huashe.park.domain.entity.BdFenceInfo;
 import com.huashe.park.domain.entity.BdFenceVioEvt;
 import com.ruoyi.common.core.redis.RedisCache;
-import com.huashe.park.application.common.enums.EvtStatus;
-import com.huashe.park.application.common.enums.EvtType;
 import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate;
 import org.apache.commons.lang3.ObjectUtils;
 import org.locationtech.jts.geom.Polygon;
@@ -27,6 +28,7 @@ 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;
@@ -42,7 +44,7 @@ public class FenceBreakInEngine extends EvtFusionEngine {
     @Autowired
     private IBdFenceVioEvtService vioEvtService;
 
-    @Autowired
+    @Resource
     private RedisCache redisCache;
 
     @Autowired
@@ -64,9 +66,11 @@ public class FenceBreakInEngine extends EvtFusionEngine {
     @PostConstruct
     public void init() {
         super.init();
-        this.setEngineName("围栏闯禁事件融合");
+        this.setEngineName("室外围栏闯禁事件融合");
         if (!redisCache.hasKey(BDConst.REDIS_KEY.FENCE)) {
-            List<BdFenceInfo> bdFenceInfos = fenceInfoService.selectBdFenceInfoList(new BdFenceInfo());
+            List<BdFenceInfo> bdFenceInfos = fenceInfoService.selectBdFenceInfoList(new BdFenceInfo() {{
+                setFenceType(FenceType.OUT_SIDE_FENCE_IN.getCode());
+            }});
             if (CollectionUtils.isEmpty(bdFenceInfos)) {
                 return;
             }

+ 5 - 5
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/engine/impl/PointFusionEngine.java

@@ -1,13 +1,13 @@
 package com.huashe.park.application.engine.impl;
 
 import com.alibaba.fastjson2.JSONObject;
-import com.huashe.park.application.common.DateTimeUtil;
-import com.huashe.park.core.service.IBdDevcTrailUwbService;
-import com.huashe.park.application.bd.socket.PointWebSocketServer;
-import com.huashe.park.application.common.BDConst;
-import com.huashe.park.application.web.core.config.MqttCfg;
 import com.huashe.park.application.engine.EvtFusionEngine;
 import com.huashe.park.application.engine.LocationInfo;
+import com.huashe.park.application.socket.server.PointWebSocketServer;
+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.core.service.IBdDevcTrailUwbService;
 import com.huashe.park.domain.entity.BdDevcTrailUwb;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;

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

@@ -0,0 +1,161 @@
+package com.huashe.park.application.engine.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+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.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;
+
+/**
+ * The type Room break in engine.
+ */
+@Service
+@ConditionalOnBean(MqttCfg.class)
+public class RoomBreakInEngine extends EvtFusionEngine {
+    private static final Logger logger = LoggerFactory.getLogger(RoomBreakInEngine.class);
+
+    @Autowired
+    private IBdFenceInfoService fenceInfoService;
+
+    @Autowired
+    private IBdFenceVioEvtService vioEvtService;
+
+    @Resource
+    private RedisCache redisCache;
+
+    @Autowired
+    private MqttClientTemplate client;
+
+    @Value("${evt-fusion.fusion-time.room-location:300}")
+    private int MAX_EVT_TIME_GAP;
+
+
+    @Autowired
+    private FenceVioEvtSocketServer fenceVioEvtSocketServer;
+
+    private final List<LinkedBlockingQueue<JSONObject>> messageQueueList = new ArrayList<>(5);
+
+    @PostConstruct
+    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 (CollectionUtils.isEmpty(bdFenceInfos)) {
+                return;
+            }
+            bdFenceInfos.removeIf(item -> ObjectUtils.isEmpty(item.getPoly()) || ObjectUtils.isEmpty(GeoUtils.getPolygon(item.getPoly())));
+
+            redisCache.setCacheList(BDConst.REDIS_KEY.FENCE_ROOM, 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_ROOM_BREAK_IN_KEY + msg.getMsg().getString("deviceId");
+    }
+
+    @Override
+    public void getBizId(LocationInfo msg) {
+        BdFenceVioEvt bdFenceVioEvt = new BdFenceVioEvt();
+        bdFenceVioEvt.setFenceId(msg.getMsg().getLong("fenceId"));
+        bdFenceVioEvt.setLat(msg.getLatitude());
+        bdFenceVioEvt.setLng(msg.getLongitude());
+        bdFenceVioEvt.setLocationId(msg.getMsg().getLong("roomId"));
+        bdFenceVioEvt.setEvtStatus(EvtStatus.NEW.getCode());
+        bdFenceVioEvt.setEvtType(EvtType.FENCE_ROOM_IN.getCode());
+        bdFenceVioEvt.setEvtTime(DateTimeUtil.getDateFromMills(msg.getSrcTimestamp()));
+        bdFenceVioEvt.setEvtDesc(String.format("室内围栏闯禁: %s", msg.getMsg().getString("fenceName")));
+        vioEvtService.insertBdFenceVioEvt(bdFenceVioEvt);
+        msg.setBizId(bdFenceVioEvt.getId().toString());
+    }
+
+    @Override
+    public void processOlderData(LocationInfo msg) {
+        vioEvtService.updateBdFenceVioEvt(new BdFenceVioEvt() {
+            {
+                setFenceId(msg.getMsg().getLong("fenceId"));
+                setEvtStatus(EvtStatus.DISAPPEAR.getCode());
+            }
+        });
+    }
+
+    @Override
+    public void newEvtCallback(LocationInfo msg) {
+        fenceVioEvtSocketServer.broadcast(msg);
+    }
+
+    public void generateEvt(JSONObject msg, byte[] payload) {
+        List<BdFenceInfo> cacheList = redisCache.getCacheList(BDConst.REDIS_KEY.FENCE_ROOM);
+        if (CollectionUtils.isEmpty(cacheList)) {
+            return;
+        }
+        Polygon polygon;
+        logger.info("fence info size: {}", msg);
+        for (BdFenceInfo fenceInfo : cacheList) {
+            polygon = GeoUtils.getPolygon(fenceInfo.getPoly());
+            if (GeoUtils.isPointInGeoFence(polygon, msg.getString("longitude"), msg.getString("latitude"))) {
+                logger.info("?>>>>>fence info size: {}", msg);
+                msg.put("fenceId", fenceInfo.getId());
+                msg.put("fenceName", fenceInfo.getDefenceName());
+                msg.put("roomId", fenceInfo.getLocationId());
+                client.publish(BDConst.MQTT_TOPIC.EVT_ROOM_LOCATION_TOPIC, JSON.toJSONBytes(msg));
+                break;
+            }
+        }
+    }
+}

+ 16 - 2
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/mqtt/UWBLocationSubscribeListener.java

@@ -2,10 +2,11 @@ package com.huashe.park.application.mqtt;
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
-import com.huashe.park.application.common.BDConst;
-import com.huashe.park.application.web.core.config.MqttCfg;
 import com.huashe.park.application.engine.impl.FenceBreakInEngine;
 import com.huashe.park.application.engine.impl.PointFusionEngine;
+import com.huashe.park.application.engine.impl.RoomBreakInEngine;
+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.spring.client.MqttClientSubscribe;
 import org.slf4j.Logger;
@@ -28,10 +29,14 @@ public class UWBLocationSubscribeListener {
     @Autowired
     private FenceBreakInEngine fenceBreakInEngine;
 
+    @Autowired
+    private RoomBreakInEngine roomBreakInEngine;
+
     @PostConstruct
     public void init() {
         pointFusionEngine.start();
         fenceBreakInEngine.start();
+        roomBreakInEngine.start();
     }
 
     @MqttClientSubscribe(value = BDConst.MQTT_TOPIC.POINT_LOCATION_TOPIC)
@@ -40,6 +45,7 @@ public class UWBLocationSubscribeListener {
         JSONObject jsonObject = JSON.parseObject(payload);
         pointFusionEngine.push(jsonObject);
         fenceBreakInEngine.generateEvt(JSON.parseObject(payload), payload);
+        roomBreakInEngine.generateEvt(JSON.parseObject(payload), payload);
     }
 
     @MqttClientSubscribe(value = BDConst.MQTT_TOPIC.EVT_LOCATION_TOPIC, qos = MqttQoS.QOS0)
@@ -47,4 +53,12 @@ public class UWBLocationSubscribeListener {
         logger.debug("topic:{} payload:{}", topic, new String(payload, StandardCharsets.UTF_8));
         fenceBreakInEngine.push(JSON.parseObject(payload));
     }
+
+    @MqttClientSubscribe(value = BDConst.MQTT_TOPIC.EVT_ROOM_LOCATION_TOPIC, qos = MqttQoS.QOS0)
+    public void subQos2(String topic, byte[] payload) {
+        logger.debug("topic:{} payload:{}", topic, new String(payload, StandardCharsets.UTF_8));
+        roomBreakInEngine.push(JSON.parseObject(payload));
+    }
+
+
 }

+ 87 - 0
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/socket/client/UWBSocketClient.java

@@ -0,0 +1,87 @@
+package com.huashe.park.application.socket.client;
+
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.Map;
+
+import com.huashe.park.common.consts.BDConst;
+import com.huashe.park.domain.dto.UWBAuth;
+import org.java_websocket.drafts.Draft;
+import org.java_websocket.handshake.ServerHandshake;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+
+import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate;
+
+public class UWBSocketClient extends org.java_websocket.client.WebSocketClient {
+
+    private static final Logger log = LoggerFactory.getLogger(UWBSocketClient.class);
+
+    @Autowired
+    private MqttClientTemplate client;
+
+    private UWBAuth authToken;
+
+    public UWBAuth getAuthToken() {
+        return authToken;
+    }
+
+    public void setAuthToken(UWBAuth authToken) {
+        this.authToken = authToken;
+    }
+
+    public UWBSocketClient(URI serverUri) {
+        super(serverUri);
+    }
+
+    public UWBSocketClient(URI serverUri, Draft protocolDraft) {
+        super(serverUri, protocolDraft);
+    }
+
+    public UWBSocketClient(URI serverUri, Draft protocolDraft, Map<String, String> httpHeaders, int connectTimeout) {
+        super(serverUri, protocolDraft, httpHeaders, connectTimeout);
+    }
+
+    @Override
+    public void onOpen(ServerHandshake serverHandshake) {
+        log.debug("[websocket] 连接成功,{}", JSON.toJSONString(this.authToken));
+        send(JSON.toJSONString(this.authToken));
+    }
+
+    @Override
+    public void onMessage(String message) {
+        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));
+            // TODO 推送轨迹
+            // client.publish(String.format(BDConst.MQTT_TOPIC.UWB_VIDEO_TRACE, "847F3"), JSON.toJSONBytes(data));
+            return;
+        }
+        this.authToken.setTagId("847F3");
+        log.debug("[websocket] 推送={}", JSON.toJSONString(this.authToken));
+        // tagId要去掉前缀0
+        send(JSON.toJSONString(this.authToken));
+    }
+
+    @Override
+    public void onMessage(ByteBuffer bytes) {
+        log.debug("[websocket] 收到消息={}", JSON.parseObject(bytes.array()));
+
+    }
+
+    @Override
+    public void onClose(int i, String s, boolean b) {
+        log.info("[websocket] 退出连接");
+    }
+
+    @Override
+    public void onError(Exception e) {
+        log.info("[websocket] 连接错误={}", e.getMessage());
+    }
+
+}

+ 2 - 6
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/bd/socket/FenceVioEvtSocketServer.java → bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/socket/server/FenceVioEvtSocketServer.java

@@ -1,4 +1,4 @@
-package com.huashe.park.application.bd.socket;
+package com.huashe.park.application.socket.server;
 
 import com.alibaba.fastjson2.JSON;
 import org.slf4j.Logger;
@@ -7,11 +7,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.web.bind.annotation.CrossOrigin;
 
 import javax.annotation.PostConstruct;
-import javax.websocket.OnClose;
-import javax.websocket.OnError;
-import javax.websocket.OnMessage;
-import javax.websocket.OnOpen;
-import javax.websocket.Session;
+import javax.websocket.*;
 import javax.websocket.server.PathParam;
 import javax.websocket.server.ServerEndpoint;
 import java.io.IOException;

+ 2 - 6
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/bd/socket/PointWebSocketServer.java → bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/socket/server/PointWebSocketServer.java

@@ -1,4 +1,4 @@
-package com.huashe.park.application.bd.socket;
+package com.huashe.park.application.socket.server;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -6,11 +6,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.web.bind.annotation.CrossOrigin;
 
 import javax.annotation.PostConstruct;
-import javax.websocket.OnClose;
-import javax.websocket.OnError;
-import javax.websocket.OnMessage;
-import javax.websocket.OnOpen;
-import javax.websocket.Session;
+import javax.websocket.*;
 import javax.websocket.server.PathParam;
 import javax.websocket.server.ServerEndpoint;
 import java.io.IOException;

+ 102 - 0
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/socket/server/UWBVideoTraceSocketServer.java

@@ -0,0 +1,102 @@
+package com.huashe.park.application.socket.server;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.CrossOrigin;
+
+import javax.annotation.PostConstruct;
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@ServerEndpoint("/ws/video/trace/{client}/{device}")
+@CrossOrigin(origins = "*")
+@Component
+public class UWBVideoTraceSocketServer {
+    private static final Logger logger = LoggerFactory.getLogger(UWBVideoTraceSocketServer.class);
+
+    // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
+    private static AtomicInteger onlineNum = new AtomicInteger();
+
+    // concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
+    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
+
+    public static final String SESSION_KEY_TEMPLATE = "%s-%s";
+
+    @PostConstruct
+    public void init() {
+        logger.info("WebSocketServer init");
+    }
+
+    // 发送消息
+    public void sendMessage(Session session, String message) throws IOException {
+        if (session != null) {
+            synchronized (session) {
+                logger.info("发送数据:{}", message);
+                session.getBasicRemote().sendText(message);
+            }
+        }
+    }
+
+    // 群发消息
+    public void broadcast(String message) {
+        for (Session session : sessionPools.values()) {
+            try {
+                sendMessage(session, message);
+            }
+            catch (Exception e) {
+                logger.info("server get {}", e.getMessage());
+            }
+        }
+    }
+
+    // 建立连接成功调用
+    @OnOpen
+    public void onOpen(Session session, @PathParam(value = "client") String client,
+        @PathParam(value = "device") String device) {
+        sessionPools.put(String.format(SESSION_KEY_TEMPLATE, client, device), session);
+        addOnlineCount();
+    }
+
+    // 关闭连接时调用
+    @OnClose
+    public void onClose( @PathParam(value = "client") String client,
+                         @PathParam(value = "device") String device) {
+        sessionPools.remove(String.format(SESSION_KEY_TEMPLATE, client, device));
+        subOnlineCount();
+        logger.info("{}断开webSocket连接!当前人数为:{}", device, onlineNum);
+    }
+
+    // 收到客户端信息后,根据接收人的username把消息推下去或者群发
+    // to=-1群发消息
+    @OnMessage
+    public void onMessage(String message) throws IOException {
+        logger.info("server get {}", message);
+    }
+
+    // 错误时调用
+    @OnError
+    public void onError(Session session, Throwable throwable) {
+        logger.info("server get {}", throwable.getMessage());
+    }
+
+    public static void addOnlineCount() {
+        onlineNum.incrementAndGet();
+    }
+
+    public static void subOnlineCount() {
+        onlineNum.decrementAndGet();
+    }
+
+    public static AtomicInteger getOnlineNumber() {
+        return onlineNum;
+    }
+
+    public static ConcurrentHashMap<String, Session> getSessionPools() {
+        return sessionPools;
+    }
+}

+ 2 - 2
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/web/controller/bd/BdDevcTrailUwbController.java

@@ -1,8 +1,8 @@
 package com.huashe.park.application.web.controller.bd;
 
 import com.alibaba.fastjson2.JSON;
-import com.huashe.park.application.common.BDConst;
-import com.huashe.park.application.common.DateTimeUtil;
+import com.huashe.park.common.DateTimeUtil;
+import com.huashe.park.common.consts.BDConst;
 import com.huashe.park.core.service.IBdDevcTrailUwbService;
 import com.huashe.park.domain.entity.BdDevcTrailUwb;
 import com.ruoyi.common.annotation.Anonymous;

+ 1 - 1
bd-park/park-backend/park-common/src/main/java/com/huashe/park/application/common/DateTimeUtil.java → bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/DateTimeUtil.java

@@ -1,4 +1,4 @@
-package com.huashe.park.application.common;
+package com.huashe.park.common;
 
 import org.apache.commons.lang3.StringUtils;
 

+ 9 - 1
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/common/BDConst.java → bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/BDConst.java

@@ -1,17 +1,25 @@
-package com.huashe.park.application.common;
+package com.huashe.park.common.consts;
 
 public interface BDConst {
     public interface REDIS_KEY {
         String BD_POINT_KEY = "bd:point:";
         String FENCE_BREAK_IN_KEY = "fence:break:in:";
         String FENCE = "fence";
+
+        String FENCE_ROOM = "fence:room";
+
+        String FENCE_ROOM_BREAK_IN_KEY = "fence:room:break:in:";
     }
 
     public interface MQTT_TOPIC {
         String POINT_LOCATION_TOPIC = "/uwb/point/#";
         String EVT_LOCATION_TOPIC = "/uwb/evt";
 
+        String EVT_ROOM_LOCATION_TOPIC = "/uwb/room/evt";
+
         String DEVICE_LOCATION_TOPIC = "/uwb/point/%s";
 
+        String UWB_VIDEO_TRACE_POINT = "/uwb/video-trace/point/%s";
+
     }
 }

+ 1 - 1
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/common/enums/EvtStatus.java → bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/enums/EvtStatus.java

@@ -1,4 +1,4 @@
-package com.huashe.park.application.common.enums;
+package com.huashe.park.common.consts.enums;
 
 public enum EvtStatus {
     NEW("0", "新增"), DISAPPEAR("1", "消散");

+ 4 - 2
bd-park/park-backend/park-application/src/main/java/com/huashe/park/application/common/enums/EvtType.java → bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/consts/enums/EvtType.java

@@ -1,7 +1,9 @@
-package com.huashe.park.application.common.enums;
+package com.huashe.park.common.consts.enums;
 
 public enum EvtType {
-    FENCE_IN("1", "围栏闯禁");
+    FENCE_IN("1", "围栏闯禁"),
+
+    FENCE_ROOM_IN("2", "室内围栏闯禁");
 
     private final String code;
     private final String info;

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

@@ -0,0 +1,22 @@
+package com.huashe.park.common.consts.enums;
+
+public enum FenceType {
+    OUT_SIDE_FENCE_IN("1", "室外围栏闯禁"),
+    INSIDE_FENCE_IN("2", "室外围栏闯禁");
+
+    private final String code;
+    private final String info;
+
+    FenceType(String code, String info) {
+        this.code = code;
+        this.info = info;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getInfo() {
+        return info;
+    }
+}

+ 1 - 1
bd-park/park-backend/park-common/src/main/java/com/huashe/park/application/common/geo/CoordinateConverter.java → bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/geo/CoordinateConverter.java

@@ -1,4 +1,4 @@
-package com.huashe.park.application.common.geo;
+package com.huashe.park.common.geo;
 
 import org.apache.commons.math3.linear.*;
 

+ 1 - 1
bd-park/park-backend/park-common/src/main/java/com/huashe/park/application/common/geo/GeoUtils.java → bd-park/park-backend/park-common/src/main/java/com/huashe/park/common/geo/GeoUtils.java

@@ -1,4 +1,4 @@
-package com.huashe.park.application.common.geo;
+package com.huashe.park.common.geo;
 
 import org.locationtech.jts.geom.*;
 import org.locationtech.jts.io.ParseException;

+ 1 - 1
bd-park/park-backend/park-core/src/main/java/com/huashe/park/core/service/impl/BdFenceInfoServiceImpl.java

@@ -1,6 +1,6 @@
 package com.huashe.park.core.service.impl;
 
-import com.huashe.park.application.common.geo.GeoUtils;
+import com.huashe.park.common.geo.GeoUtils;
 import com.huashe.park.core.mapper.BdFenceInfoMapper;
 import com.huashe.park.core.service.IBdFenceInfoService;
 import com.huashe.park.domain.entity.BdFenceInfo;

+ 10 - 0
bd-park/park-backend/park-infrastructure/pom.xml

@@ -16,5 +16,15 @@
         <maven.compiler.target>8</maven.compiler.target>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.huashe.park</groupId>
+            <artifactId>park-domain</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.dtflys.forest</groupId>
+            <artifactId>forest-spring-boot-starter</artifactId>
+        </dependency>
+    </dependencies>
 
 </project>

+ 11 - 0
bd-park/park-backend/park-infrastructure/src/main/java/com/huashe/park/infrastructure/uwb/UWBWebService.java

@@ -0,0 +1,11 @@
+package com.huashe.park.infrastructure.uwb;
+
+import com.dtflys.forest.annotation.JSONBody;
+import com.dtflys.forest.annotation.Post;
+
+import java.util.Map;
+
+public interface UWBWebService {
+    @Post(url = "{uwbBaseUrl}/stage-api/auth/login", dataType = "json")
+    Map exchangeToken(@JSONBody Map<String, Object> data);
+}

+ 15 - 0
bd-park/park-backend/pom.xml

@@ -45,6 +45,8 @@
         <mqttstarter.version>2.3.7</mqttstarter.version>
         <math.version>3.6.1</math.version>
         <park.version>1.0-SNAPSHOT</park.version>
+        <java.ws.version>1.5.2</java.ws.version>
+        <hutool.version>5.8.26</hutool.version>
     </properties>
 
     <!-- 依赖声明 -->
@@ -226,6 +228,19 @@
                 <artifactId>park-domain</artifactId>
                 <version>${park.version}</version>
             </dependency>
+            <dependency>
+                <groupId>cn.hutool</groupId>
+                <artifactId>hutool-bom</artifactId>
+                <version>${hutool.version}</version>
+                <type>pom</type>
+                <!-- 注意这里是import -->
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.java-websocket</groupId>
+                <artifactId>Java-WebSocket</artifactId>
+                <version>${java.ws.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
     <repositories>