Переглянути джерело

2023-10-18 蓝牙网关和信标基础功能实现。

chaiyunlong 2 роки тому
батько
коміт
85a11942aa
21 змінених файлів з 907 додано та 22 видалено
  1. 28 3
      zd-api/zd-airbottle-api/src/main/java/com/zd/airbottle/api/feign/RemoteAirBottleService.java
  2. 25 0
      zd-api/zd-airbottle-api/src/main/java/com/zd/airbottle/api/feign/fallback/RemoteAirBottleFallbackFactory.java
  3. 20 0
      zd-model/src/main/java/com/zd/model/constant/BaseConstants.java
  4. 3 0
      zd-model/src/main/java/com/zd/model/constant/MqttConstants.java
  5. 4 0
      zd-model/src/main/java/com/zd/model/domain/per/PerPrefix.java
  6. 150 0
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/controller/DbBluetoothGatewayController.java
  7. 29 2
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/controller/DbStockController.java
  8. 51 0
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/domain/DbBluetoothGateway.java
  9. 62 0
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/mapper/DbBluetoothGatewayMapper.java
  10. 63 0
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/service/DbBluetoothGatewayService.java
  11. 77 0
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/service/impl/DbBluetoothGatewayServiceImpl.java
  12. 125 0
      zd-modules/zd-airbottle/src/main/resources/mapper/airbottle/DbBluetoothGatewayMapper.xml
  13. 4 0
      zd-modules/zd-modules-laboratory/pom.xml
  14. 4 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/vo/LabBuildFloorLayoutVo.java
  15. 64 4
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/event/RedisExpiredAndWorkListener.java
  16. 13 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mqtt/service/impl/SubMessageSendManager.java
  17. 11 9
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/netty/NettyServerHandler.java
  18. 14 4
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabExitLineVertexServiceImpl.java
  19. 13 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/socket/service/BeaconMate.java
  20. 128 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/socket/service/impl/BeaconMateImpl.java
  21. 19 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/utils/JsonUtils.java

+ 28 - 3
zd-api/zd-airbottle-api/src/main/java/com/zd/airbottle/api/feign/RemoteAirBottleService.java

@@ -3,11 +3,13 @@ package com.zd.airbottle.api.feign;
 import com.zd.airbottle.api.feign.fallback.RemoteAirBottleFallbackFactory;
 import com.zd.model.constant.ApplicationConstants;
 import com.zd.model.domain.R;
+import com.zd.model.domain.ResultData;
 import com.zd.model.entity.InventoryTag;
 import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * @author Administrator
@@ -29,4 +31,27 @@ public interface RemoteAirBottleService {
     @GetMapping(value = "/alarm/record/qpTimeOut")
     void qpTimeOut();
 
+    /**
+     * 蓝牙网关修改状态
+     */
+    @PostMapping(value = "/bluetooth/setOnline")
+    R setBluetoothGateway(@RequestBody Map <String,Object> appSubQuery);
+
+    /**
+     * 根据mac地址查询实验室id
+     */
+    @GetMapping(value = "/bluetooth/getSubByMac")
+    ResultData<Map<String,Object>> getSubByMac(@RequestParam("mac") String mac);
+
+    /**
+     * 根据实验室id查询蓝牙网关列表
+     */
+    @GetMapping(value = "/bluetooth/getBluetoothBySubId")
+    ResultData<List <Map<String,Object>>> getBluetoothBySubId(@RequestParam("subId") Long subId);
+
+    /**
+     * 根据实验室id查询信标列表
+     */
+    @GetMapping(value = "/stock/findBySubId")
+    ResultData<List <Map<String,Object>>> findBySubId(@RequestParam("subId") Long subId);
 }

+ 25 - 0
zd-api/zd-airbottle-api/src/main/java/com/zd/airbottle/api/feign/fallback/RemoteAirBottleFallbackFactory.java

@@ -2,12 +2,16 @@ package com.zd.airbottle.api.feign.fallback;
 
 import com.zd.airbottle.api.feign.RemoteAirBottleService;
 import com.zd.model.domain.R;
+import com.zd.model.domain.ResultData;
 import com.zd.model.entity.InventoryTag;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
 import org.springframework.stereotype.Component;
 
+import java.util.List;
+import java.util.Map;
+
 @Component
 public class RemoteAirBottleFallbackFactory implements FallbackFactory<RemoteAirBottleService> {
 
@@ -27,6 +31,27 @@ public class RemoteAirBottleFallbackFactory implements FallbackFactory<RemoteAir
             public void qpTimeOut() {
                 log.error("气瓶超时调用失败:{}" ,throwable.getMessage());
             }
+
+            @Override
+            public R setBluetoothGateway(Map <String,Object> appSubQuery) {
+                log.error("蓝牙网关调用失败:{}" ,throwable.getMessage());
+                return R.fail("蓝牙网关调用失败:" + throwable.getMessage());
+            }
+
+            @Override
+            public ResultData<Map<String,Object>> getSubByMac(String mac) {
+                return ResultData.fail("获取实验室信息失败"+throwable.getMessage());
+            }
+
+            @Override
+            public ResultData <List<Map <String, Object>>> getBluetoothBySubId(Long subId) {
+                return ResultData.fail("获取蓝牙网关列表失败"+throwable.getMessage());
+            }
+
+            @Override
+            public ResultData <List <Map <String, Object>>> findBySubId(Long subId) {
+                return ResultData.fail("获取信标列表失败"+throwable.getMessage());
+            }
         };
     }
 }

+ 20 - 0
zd-model/src/main/java/com/zd/model/constant/BaseConstants.java

@@ -190,6 +190,26 @@ public interface BaseConstants {
     String HOLIDAY_TIME = "holidayTime";
 
     /**
+     * 蓝牙mac配置
+     */
+    String BEACON_MAC = "beaconMac";
+
+    /**
+     * 蓝牙网关信标配置
+     */
+    String BEACON_MATE_INFO = "beaconMateInfo";
+
+    /**
+     * 信标配置
+     */
+    String BEACON_MATE_DET = "beaconMateDet";
+
+    /**
+     * 信标通知
+     */
+    String BEACON_MATE_NOTICE = "beaconMateNotice";
+
+    /**
      * Redis前缀,需统一
      */
     String REDIS_LOCK = "redis_lock:";

+ 3 - 0
zd-model/src/main/java/com/zd/model/constant/MqttConstants.java

@@ -61,6 +61,9 @@ public interface MqttConstants {
     //新疏散通知
     String TOPIC_LAB_NEWEXIT_LINE = "lab/newexit/line";
 
+    //蓝牙网关通知
+    String TOPIC_AIR_BLUETOOTH_GATEWAY = "air/blueTooth/gateway";
+
     //实验室人员变动通知
     String TOPIC_LAB_SUB_USER = "lab/subuser/change";
 

+ 4 - 0
zd-model/src/main/java/com/zd/model/domain/per/PerPrefix.java

@@ -587,6 +587,10 @@ public class PerPrefix {
 
     public static final String LABORATORY_EXJOINSUB = "laboratory:exjoinsub:";
 
+    /**
+     * 气瓶绑定的蓝牙网关
+     */
+    public static final String BLUETOOTH_GATEWAY = "bluetooth:gateway:";
 
     /**
      * 气瓶

+ 150 - 0
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/controller/DbBluetoothGatewayController.java

@@ -0,0 +1,150 @@
+package com.zd.airbottle.controller;
+
+import com.zd.airbottle.domain.DbBluetoothGateway;
+import com.zd.airbottle.service.DbBluetoothGatewayService;
+import com.zd.common.core.annotation.Log;
+import com.zd.common.core.annotation.PreAuthorize;
+import com.zd.common.core.log.BusinessType;
+import com.zd.common.core.redis.RedisService;
+import com.zd.common.core.web.controller.BaseController;
+import com.zd.model.constant.BaseConstants;
+import com.zd.model.domain.ResultData;
+import com.zd.model.domain.per.PerFun;
+import com.zd.model.domain.per.PerPrefix;
+import com.zd.model.page.TableDataInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Controller
+ *
+ * @author cyl
+ * @date 2023/10/16
+ */
+@RestController
+@Api(tags = "【蓝牙网关】")
+@RequestMapping("/bluetooth")
+public class DbBluetoothGatewayController extends BaseController {
+
+    @Autowired
+    private DbBluetoothGatewayService dbBluetoothGatewayService;
+
+    @Autowired
+    private RedisService redisService;
+
+    /**
+     * 查询蓝牙网关列表
+     */
+    @GetMapping("/list")
+    @PreAuthorize(hasPermi = PerPrefix.BLUETOOTH_GATEWAY + PerFun.LIST)
+    @ApiOperation(value = "查询蓝牙网关列表")
+    public TableDataInfo <DbBluetoothGateway> list(DbBluetoothGateway dbBluetoothGateway) {
+        startPage("create_time", "descending");
+        List <DbBluetoothGateway> list = dbBluetoothGatewayService.selectDbBluetoothGatewayList(dbBluetoothGateway);
+        return getDataTable(list);
+    }
+
+
+    /**
+     * 获取蓝牙网关信息
+     */
+    @ApiOperation(value = "获取蓝牙网关信息")
+    @PreAuthorize(hasPermi = PerPrefix.BLUETOOTH_GATEWAY + PerFun.QUERY)
+    @GetMapping(value = "/{id}")
+    public ResultData<DbBluetoothGateway> getInfo(@PathVariable("id") Long id) {
+        return ResultData.success(dbBluetoothGatewayService.selectDbBluetoothGatewayById(id));
+    }
+
+
+    /**
+     * 新增蓝牙网关
+     */
+    @PreAuthorize(hasPermi = PerPrefix.BLUETOOTH_GATEWAY + PerFun.ADD)
+    @ApiOperation(value = "新增蓝牙网关")
+    @Log(title = "蓝牙网关", businessType = BusinessType.INSERT)
+    @PostMapping
+    public ResultData<Boolean> add(@RequestBody DbBluetoothGateway dbBluetoothGateway) {
+        return ResultData.result(dbBluetoothGatewayService.insertDbBluetoothGateway(dbBluetoothGateway));
+    }
+
+    /**
+     * 修改蓝牙网关
+     */
+    @PreAuthorize(hasPermi = PerPrefix.BLUETOOTH_GATEWAY + PerFun.EDIT)
+    @ApiOperation(value = "修改蓝牙网关")
+    @Log(title = "蓝牙网关", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public ResultData<Boolean> edit(@RequestBody DbBluetoothGateway dbBluetoothGateway) {
+        return ResultData.result(dbBluetoothGatewayService.updateDbBluetoothGateway(dbBluetoothGateway));
+    }
+
+    /**
+     * 删除蓝牙网关
+     */
+    @PreAuthorize(hasPermi = PerPrefix.BLUETOOTH_GATEWAY + PerFun.REMOVE)
+    @ApiOperation(value = "删除蓝牙网关")
+    @Log(title = "删除蓝牙网关", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public ResultData<Boolean> remove(@PathVariable Long[] ids) {
+        return ResultData.result(dbBluetoothGatewayService.deleteeDbBluetoothGatewayByIds(ids));
+    }
+
+
+    /**
+     * 修改蓝牙网关在线离线
+     */
+    @ApiOperation(value = "修改蓝牙网关在线离线")
+    @Log(title = "蓝牙网关在线离线", businessType = BusinessType.UPDATE)
+    @PostMapping("/setOnline")
+    public ResultData<Boolean> setOnline(@RequestBody DbBluetoothGateway dbBluetoothGateway) {
+        return ResultData.result(dbBluetoothGatewayService.setOnline(dbBluetoothGateway));
+    }
+
+    /**
+     * 获取蓝牙网关信息
+     */
+    @ApiOperation(value = "获取蓝牙网关信息")
+    @GetMapping(value = "/getSubByMac")
+    public ResultData<DbBluetoothGateway> getSubByMac(String mac) {
+        DbBluetoothGateway dbBluetoothGateway = new DbBluetoothGateway();
+        dbBluetoothGateway.setGatewayMac(mac);
+        List <DbBluetoothGateway> list = dbBluetoothGatewayService.selectDbBluetoothGatewayList(dbBluetoothGateway);
+        if(list.size()>0){
+            return ResultData.success(list.get(0));
+        }
+        return ResultData.fail("查询不到网关");
+    }
+
+    /**
+     * 获取蓝牙网关信息
+     */
+    @ApiOperation(value = "获取蓝牙网关信息")
+    @GetMapping(value = "/getBluetoothBySubId")
+    public ResultData getBluetoothBySubId(Long subId) {
+        DbBluetoothGateway dbBluetoothGateway = new DbBluetoothGateway();
+        dbBluetoothGateway.setSubId(subId);
+        List <DbBluetoothGateway> list = dbBluetoothGatewayService.selectDbBluetoothGatewayList(dbBluetoothGateway);
+        return ResultData.success(list);
+    }
+
+
+
+    /**
+     * 获取蓝牙信标提示语集合
+     */
+    @ApiOperation(value = "获取蓝牙信标提示语集合")
+    @GetMapping(value = "/getBeaconNotice")
+    public ResultData getBeaconNotice(Long subId) {
+        List <Map <String,Object>> beaconNoticeList = redisService.getCacheObject(BaseConstants.BEACON_MATE_NOTICE+"~"+subId);
+        if(beaconNoticeList==null){
+            beaconNoticeList = new ArrayList <>();
+        }
+        return ResultData.success(beaconNoticeList);
+    }
+}

+ 29 - 2
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/controller/DbStockController.java

@@ -28,8 +28,8 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @Description 东北大学库存
@@ -196,6 +196,33 @@ public class DbStockController extends AbstractController {
         return ResultData.success(dbStock);
     }
 
+    /**
+     * 通过subId查询库存分类
+     *
+     * @param subId
+     * @return
+     */
+    @ApiOperation(value = "通过subId查询库存分类", notes = "参数说明:subId 必填")
+    @GetMapping(value = "/findClassifyBySubId")
+    public ResultData findClassifyBySubId(@RequestParam("subId") Long subId) {
+        paramCheck.notNull(subId);
+        LambdaQueryWrapper<DbStock> queryWrapper = new LambdaQueryWrapper();
+        queryWrapper.eq(DbStock::getSubjectId, subId);
+        List<DbStock> list = dbStockService.list(queryWrapper);
+        Map <String,List<DbStock>> dbStockMap = Optional.ofNullable(list).orElseGet(Collections::emptyList).stream()
+                .collect(Collectors.groupingBy(DbStock::getGasName));
+        Map<String,Object> allMap = new HashMap <>();
+        allMap.put("total",list.size());
+        List<Map<String,Object>> classifyList = new ArrayList <>();
+        dbStockMap.forEach((key,value)->{
+            Map<String,Object> classifyMap = new HashMap <>();
+            classifyMap.put("name",key);
+            classifyMap.put("bottleSize",value.size());
+            classifyList.add(classifyMap);
+        });
+        allMap.put("classifyList",classifyList);
+        return ResultData.success(allMap);
+    }
 
     /**
      * 通过subId查询库存列表

+ 51 - 0
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/domain/DbBluetoothGateway.java

@@ -0,0 +1,51 @@
+package com.zd.airbottle.domain;
+
+import com.zd.model.entity.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Controller
+ *
+ * @author cyl
+ * @date 2023/10/16
+ */
+@ApiModel("蓝牙网关")
+@Data
+public class DbBluetoothGateway extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /** 主键id,数据唯一标识 */
+    @ApiModelProperty(value = "${comment}")
+    private Long id;
+
+    /** 网关名称 */
+    @ApiModelProperty(value = "网关名称")
+    private String gatewayName;
+
+    /** 网关mac地址 */
+    @ApiModelProperty(value = "网关mac地址")
+    private String gatewayMac;
+
+    /** 0是离线,1是在线 */
+    @ApiModelProperty(value = "0是离线,1是在线")
+    private Integer gatewayOnline;
+
+    /** 学院id */
+    @ApiModelProperty(value = "学院id")
+    private Long deptId;
+
+    /** 学院名称 */
+    @ApiModelProperty(value = "学院名称")
+    private String deptName;
+
+    /** 实验室id */
+    @ApiModelProperty(value = "实验室id")
+    private Long subId;
+
+    /** 实验室名称 */
+    @ApiModelProperty(value = "实验室名称")
+    private String subName;
+
+}

+ 62 - 0
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/mapper/DbBluetoothGatewayMapper.java

@@ -0,0 +1,62 @@
+package com.zd.airbottle.mapper;
+
+import com.zd.airbottle.domain.DbBluetoothGateway;
+
+import java.util.List;
+
+/**
+ * Controller
+ *
+ * @author cyl
+ * @date 2023/10/16
+ */
+public interface DbBluetoothGatewayMapper {
+
+    /**
+     * 查询蓝牙网关列表
+     *
+     * @param dbBluetoothGateway 蓝牙网关
+     * @return 蓝牙网关集合
+     */
+    List <DbBluetoothGateway> selectDbBluetoothGatewayList(DbBluetoothGateway dbBluetoothGateway);
+
+    /**
+     * 查询蓝牙网关信息
+     *
+     * @param id 蓝牙网关id
+     * @return 蓝牙网关信息
+     */
+    DbBluetoothGateway selectDbBluetoothGatewayById(Long id);
+
+    /**
+     * 新增蓝牙网关信息
+     *
+     * @param dbBluetoothGateway 蓝牙网关
+     * @return 是否成功
+     */
+    int insertDbBluetoothGateway(DbBluetoothGateway dbBluetoothGateway);
+
+    /**
+     * 修改蓝牙网关信息
+     *
+     * @param dbBluetoothGateway 蓝牙网关
+     * @return 是否成功
+     */
+    int updateDbBluetoothGateway(DbBluetoothGateway dbBluetoothGateway);
+
+    /**
+     * 删除蓝牙网关
+     *
+     * @param ids 蓝牙网关
+     * @return 是否成功
+     */
+    int deleteeDbBluetoothGatewayByIds(Long[] ids);
+
+    /**
+     * 修改蓝牙网关在线离线
+     *
+     * @param dbBluetoothGateway 蓝牙网关
+     * @return 是否成功
+     */
+    int setOnline(DbBluetoothGateway dbBluetoothGateway);
+}

+ 63 - 0
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/service/DbBluetoothGatewayService.java

@@ -0,0 +1,63 @@
+package com.zd.airbottle.service;
+
+import com.zd.airbottle.domain.DbBluetoothGateway;
+import java.util.List;
+
+/**
+ * Controller
+ *
+ * @author cyl
+ * @date 2023/10/16
+ */
+public interface DbBluetoothGatewayService {
+    /**
+     * 查询蓝牙网关列表
+     *
+     * @param dbBluetoothGateway 蓝牙网关
+     * @return 蓝牙网关集合
+     */
+    List <DbBluetoothGateway> selectDbBluetoothGatewayList(DbBluetoothGateway dbBluetoothGateway);
+
+    /**
+     * 查询蓝牙网关信息
+     *
+     * @param id 蓝牙网关id
+     * @return 蓝牙网关信息
+     */
+    DbBluetoothGateway selectDbBluetoothGatewayById(Long id);
+
+
+    /**
+     * 新增蓝牙网关信息
+     *
+     * @param dbBluetoothGateway 蓝牙网关
+     * @return 是否成功
+     */
+    int insertDbBluetoothGateway(DbBluetoothGateway dbBluetoothGateway);
+
+    /**
+     * 修改蓝牙网关信息
+     *
+     * @param dbBluetoothGateway 蓝牙网关
+     * @return 是否成功
+     */
+    int updateDbBluetoothGateway(DbBluetoothGateway dbBluetoothGateway);
+
+    /**
+     * 删除蓝牙网关
+     *
+     * @param ids 蓝牙网关
+     * @return 是否成功
+     */
+    int deleteeDbBluetoothGatewayByIds(Long[] ids);
+
+
+    /**
+     * 修改蓝牙网关在线离线
+     *
+     * @param dbBluetoothGateway 蓝牙网关
+     * @return 是否成功
+     */
+    int setOnline(DbBluetoothGateway dbBluetoothGateway);
+
+}

+ 77 - 0
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/service/impl/DbBluetoothGatewayServiceImpl.java

@@ -0,0 +1,77 @@
+package com.zd.airbottle.service.impl;
+
+import com.zd.airbottle.domain.DbBluetoothGateway;
+import com.zd.airbottle.mapper.DbBluetoothGatewayMapper;
+import com.zd.airbottle.service.DbBluetoothGatewayService;
+import com.zd.common.core.exception.ServiceException;
+import com.zd.model.domain.AjaxResult;
+import com.zd.system.api.feign.RemoteDeptService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Controller
+ *
+ * @author cyl
+ * @date 2023/10/16
+ */
+@Service
+public class DbBluetoothGatewayServiceImpl implements DbBluetoothGatewayService {
+
+    @Autowired
+    private DbBluetoothGatewayMapper dbBluetoothGatewayMapper;
+
+    @Autowired
+    private RemoteDeptService remoteDeptService;
+
+    @Override
+    public List <DbBluetoothGateway> selectDbBluetoothGatewayList(DbBluetoothGateway dbBluetoothGateway) {
+        return dbBluetoothGatewayMapper.selectDbBluetoothGatewayList(dbBluetoothGateway);
+    }
+
+    @Override
+    public DbBluetoothGateway selectDbBluetoothGatewayById(Long id) {
+        return dbBluetoothGatewayMapper.selectDbBluetoothGatewayById(id);
+    }
+
+    @Override
+    public int insertDbBluetoothGateway(DbBluetoothGateway dbBluetoothGateway) {
+        AjaxResult result = remoteDeptService.getInfoByDeptId(dbBluetoothGateway.getDeptId());
+        Map <String, String> map = (Map<String, String>) result.get("data");
+        dbBluetoothGateway.setDeptName(map.get("deptName"));
+        int flag=0;
+        try{
+            flag = dbBluetoothGatewayMapper.insertDbBluetoothGateway(dbBluetoothGateway);
+        }catch (Exception e){
+            throw new ServiceException("网关不能重复");
+        }
+        return flag;
+    }
+
+    @Override
+    public int updateDbBluetoothGateway(DbBluetoothGateway dbBluetoothGateway) {
+        AjaxResult result = remoteDeptService.getInfoByDeptId(dbBluetoothGateway.getDeptId());
+        Map <String, String> map = (Map<String, String>) result.get("data");
+        dbBluetoothGateway.setDeptName(map.get("deptName"));
+        int flag=0;
+        try{
+            flag = dbBluetoothGatewayMapper.updateDbBluetoothGateway(dbBluetoothGateway);
+        }catch (Exception e){
+            throw new ServiceException("网关不能重复");
+        }
+        return flag;
+    }
+
+    @Override
+    public int deleteeDbBluetoothGatewayByIds(Long[] ids) {
+        return dbBluetoothGatewayMapper.deleteeDbBluetoothGatewayByIds(ids);
+    }
+
+    @Override
+    public int setOnline(DbBluetoothGateway dbBluetoothGateway) {
+        return dbBluetoothGatewayMapper.setOnline(dbBluetoothGateway);
+    }
+}

+ 125 - 0
zd-modules/zd-airbottle/src/main/resources/mapper/airbottle/DbBluetoothGatewayMapper.xml

@@ -0,0 +1,125 @@
+<?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">
+<mapper namespace="com.zd.airbottle.mapper.DbBluetoothGatewayMapper">
+
+    <resultMap type="com.zd.airbottle.domain.DbBluetoothGateway" id="DbBluetoothGatewayResult">
+        <result property="id" column="id"/>
+        <result property="gatewayName" column="gateway_name"/>
+        <result property="gatewayMac" column="gateway_mac"/>
+        <result property="gatewayOnline" column="gateway_online"/>
+        <result property="deptId" column="dept_id"/>
+        <result property="deptName" column="dept_name"/>
+        <result property="subId" column="sub_id"/>
+        <result property="subName" column="sub_name"/>
+        <result property="userId" column="user_id"/>
+        <result property="createBy" column="create_by"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="remark" column="remark"/>
+    </resultMap>
+
+    <sql id="selectDbBluetoothGatewayVo">
+        select id, gateway_name,gateway_mac, gateway_online, dept_id, dept_name
+        , sub_id, sub_name, user_id, create_by, create_time, update_by, update_time, remark from db_bluetooth_gateway
+    </sql>
+
+    <select id="selectDbBluetoothGatewayList" parameterType="com.zd.airbottle.domain.DbBluetoothGateway" resultMap="DbBluetoothGatewayResult">
+        <include refid="selectDbBluetoothGatewayVo"/>
+        <where>
+            <if test="searchValue != null and searchValue != ''">
+                and sub_name like concat('%', #{searchValue}, '%')
+            </if>
+            <if test="deptId != null and deptId!='' ">
+                and dept_id = #{deptId}
+            </if>
+            <if test="gatewayOnline != null and gatewayOnline!='' ">
+                and gateway_online = #{gatewayOnline}
+            </if>
+            <if test="gatewayMac != null and gatewayMac!='' ">
+                and gateway_mac = #{gatewayMac}
+            </if>
+            <if test="subId != null and subId!='' ">
+                and sub_id = #{subId}
+            </if>
+        </where>
+    </select>
+
+
+    <select id="selectDbBluetoothGatewayById" resultMap="DbBluetoothGatewayResult">
+        <include refid="selectDbBluetoothGatewayVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertDbBluetoothGateway" parameterType="com.zd.airbottle.domain.DbBluetoothGateway" useGeneratedKeys="true" keyProperty="id">
+        insert into db_bluetooth_gateway
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="gatewayName != null">gateway_name,</if>
+            <if test="gatewayMac != null">gateway_mac,</if>
+            <if test="gatewayOnline != null">gateway_online,</if>
+            <if test="deptId != null">dept_id,</if>
+            <if test="deptName != null">dept_name,</if>
+            <if test="subId != null">sub_id,</if>
+            <if test="subName != null">sub_name,</if>
+            <if test="userId != null">user_id,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="remark != null">remark,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="gatewayName != null">#{gatewayName},</if>
+            <if test="gatewayMac != null">#{gatewayMac},</if>
+            <if test="gatewayOnline != null">#{gatewayOnline},</if>
+            <if test="deptId != null">#{deptId},</if>
+            <if test="deptName != null">#{deptName},</if>
+            <if test="subId != null">#{subId},</if>
+            <if test="subName != null">#{subName},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="remark != null">#{remark},</if>
+         </trim>
+    </insert>
+
+    <update id="updateDbBluetoothGateway" parameterType="com.zd.airbottle.domain.DbBluetoothGateway">
+        update db_bluetooth_gateway
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="gatewayName != null">gateway_name = #{gatewayName},</if>
+            <if test="gatewayMac != null">gateway_mac = #{gatewayMac},</if>
+            <if test="gatewayOnline != null">gateway_online = #{gatewayOnline},</if>
+            <if test="deptId != null">dept_id = #{deptId},</if>
+            <if test="deptName != null">dept_name = #{deptName},</if>
+            <if test="subId != null">sub_id = #{subId},</if>
+            <if test="subName != null">sub_name = #{subName},</if>
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteeDbBluetoothGatewayByIds">
+        delete from db_bluetooth_gateway where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+
+    <update id="setOnline" parameterType="com.zd.airbottle.domain.DbBluetoothGateway">
+        update db_bluetooth_gateway
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="gatewayOnline != null">gateway_online = #{gatewayOnline},</if>
+        </trim>
+        where gateway_mac = #{gatewayMac}
+    </update>
+</mapper>

+ 4 - 0
zd-modules/zd-modules-laboratory/pom.xml

@@ -155,6 +155,10 @@
             <version>2.0.8</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>com.zd.airbottle</groupId>
+            <artifactId>zd-airbottle-api</artifactId>
+        </dependency>
     </dependencies>
 
     <build>

+ 4 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/vo/LabBuildFloorLayoutVo.java

@@ -34,6 +34,10 @@ public class LabBuildFloorLayoutVo extends LabBuildFloorLayout {
     @ApiModelProperty(value = "实验室名称")
     private String subName;
 
+    /** 实验室是否有气瓶 */
+    @ApiModelProperty(value = "实验室是否有气瓶")
+    private Boolean subBottle;
+
     /** 布局图数据信息 */
     @ApiModelProperty(value = "布局图数据信息")
     private LabExitLineVertex exitLineVertex;

+ 64 - 4
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/event/RedisExpiredAndWorkListener.java

@@ -3,6 +3,7 @@ package com.zd.laboratory.event;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
 import com.alibaba.fastjson.parser.Feature;
+import com.zd.airbottle.api.feign.RemoteAirBottleService;
 import com.zd.common.core.redis.RedisService;
 import com.zd.laboratory.config.TimeWaitConfigUtils;
 import com.zd.laboratory.domain.LabControl;
@@ -25,10 +26,8 @@ import org.springframework.data.redis.listener.KeyExpirationEventMessageListener
 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
 import org.springframework.stereotype.Component;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 
 /**
@@ -65,6 +64,9 @@ public class RedisExpiredAndWorkListener extends KeyExpirationEventMessageListen
     @Autowired
     private TimeWaitConfigUtils timeWaitConfigUtils;
 
+    @Autowired
+    private RemoteAirBottleService remoteAirBottleService;
+
     private static final Logger log = LoggerFactory.getLogger(RedisExpiredAndWorkListener.class);
 
     public RedisExpiredAndWorkListener(RedisMessageListenerContainer listenerContainer)
@@ -110,6 +112,64 @@ public class RedisExpiredAndWorkListener extends KeyExpirationEventMessageListen
             }
         }
 
+        // 这里获取蓝牙网关mac信息
+        if(expiredKey.indexOf(BaseConstants.BEACON_MAC)!=-1){
+            String[] beaconStr = expiredKey.split(BaseConstants.BEACON_MAC+"~");
+            Map <String,Object> map = new HashMap<>();
+            map.put("gatewayMac",beaconStr[1]);
+            map.put("gatewayOnline",0);
+            log.info("21.=====================================》网关断电或失联mac:"+beaconStr[1]);
+            remoteAirBottleService.setBluetoothGateway(map);
+        }
+
+        // 这里获取蓝牙信标信息
+        if(expiredKey.indexOf(BaseConstants.BEACON_MATE_DET)!=-1){
+            String[] beaconStr = expiredKey.split("~");
+            Map <String,Object> map = new HashMap<>();
+            map.put("beaconTag",beaconStr[1]);
+            map.put("subId",beaconStr[2]);
+            map.put("gasName",beaconStr[3]);
+            log.info("31.=====================================》信标丢失:"+beaconStr[1]+",实验室id:"+beaconStr[2]);
+            // todo 这里需要根据实验室id查询对应的网关,通过网关查询redis,排查是不是有网关掉线了,如果有,就不通知报警,如果没有,发出报警
+            Boolean flag = Boolean.TRUE;
+            ResultData<List<Map<String,Object>>> resultData = remoteAirBottleService.getBluetoothBySubId(Long.parseLong(beaconStr[2]));
+            if(resultData.getCode()==200){
+                List<Map<String,Object>> resultList = resultData.getData();
+                for(Map mapGateway : resultList){
+                    if(redisService.getCacheObject(BaseConstants.BEACON_MAC+"~"+ mapGateway.get("gatewayMac"))==null){
+                        flag = Boolean.FALSE;
+                    }
+                }
+            }
+            log.info("32.=====================================》判别网关是否有断电情况:"+flag);
+            if(flag){
+                List <Map<String,Object>> beaconNoticeList = redisService.getCacheObject(BaseConstants.BEACON_MATE_NOTICE+"~"+beaconStr[2]);
+                if(beaconNoticeList != null && beaconNoticeList.size()>0){
+                    log.info("33.=====================================》通知消息列表大小:"+beaconNoticeList.size());
+                    Boolean noticeFlag = Boolean.TRUE;
+                    for(Map notice:beaconNoticeList){
+                        if(map.get("beaconTag").equals(notice.get("beaconTag"))){
+                            noticeFlag = Boolean.FALSE;
+                        }
+                    }
+                    if(noticeFlag){
+                        beaconNoticeList.add(map);
+                        redisService.setCacheObject(BaseConstants.BEACON_MATE_NOTICE+"~"+ beaconStr[2],beaconNoticeList, 30L, TimeUnit.MINUTES);
+                    }
+                    //下发通知,告诉前端页面,查询redis获取相关信息
+
+                }else{
+                    log.info("34.=====================================》通知消息:");
+                    List<Map <String,Object>> beaconList = new ArrayList <>();
+                    beaconList.add(map);
+                    redisService.setCacheObject(BaseConstants.BEACON_MATE_NOTICE+"~"+ beaconStr[2],beaconList, 30L, TimeUnit.MINUTES);
+                    //下发通知,告诉前端页面,查询redis获取相关信息
+
+                }
+            }
+
+        }
+
     }
 
     public Boolean relayControl(LabHardware labHardwareVO,Symbol.command command){

+ 13 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mqtt/service/impl/SubMessageSendManager.java

@@ -278,6 +278,19 @@ public class SubMessageSendManager {
     }
 
     /**
+     * 蓝牙网关下发通知 稍后用*****
+     *
+     */
+    public void bluetoothGatewayToMac(Map <String,Object> map) {
+        if (map == null) {
+            return;
+        }
+        MessageBody messageBody = new MessageBody();
+        messageBody.setData(map);
+        commonSend.send(MqttConstants.TOPIC_AIR_BLUETOOTH_GATEWAY , messageBody, SendMode.ONCE);
+    }
+
+    /**
      * 结束新疏散下发通知
      *
      */

+ 11 - 9
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/netty/NettyServerHandler.java

@@ -4,31 +4,28 @@ import com.zd.common.core.alert.DingTalkAlert;
 import com.zd.common.core.redis.RedisService;
 import com.zd.common.core.utils.DateUtils;
 import com.zd.common.core.utils.SpringUtils;
-import com.zd.common.core.utils.StringUtils;
 import com.zd.laboratory.constant.RelayConstants;
 import com.zd.laboratory.domain.LabAbnormal;
 import com.zd.laboratory.domain.LabHardware;
-import com.zd.laboratory.domain.LabRelay;
 import com.zd.laboratory.domain.vo.LabHardwareVO;
-import com.zd.laboratory.event.LabRelayNrStatusEvent;
-import com.zd.laboratory.event.LabRelayRegisterEvent;
 import com.zd.laboratory.mapper.LabAbnormalMapper;
 import com.zd.laboratory.mapper.LabHardwareMapper;
-import com.zd.laboratory.mqtt.entiy.EquipmentStatus;
-import com.zd.laboratory.mqtt.entiy.LabRelayStatus;
-import com.zd.laboratory.service.ILabHardwareService;
 import com.zd.laboratory.socket.constant.JXCTPacket;
 import com.zd.laboratory.socket.constant.SocketTypes;
 import com.zd.laboratory.socket.runner.TCPServer;
 import com.zd.laboratory.socket.service.BaseRouter;
+import com.zd.laboratory.socket.service.BeaconMate;
+import com.zd.laboratory.socket.service.impl.BeaconMateImpl;
 import com.zd.laboratory.utils.CRCCHECK;
+import com.zd.laboratory.utils.JsonUtils;
 import com.zd.laboratory.utils.RelayUtils;
-import com.zd.model.enums.HardwareOperate;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandler;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
 
-import java.net.Socket;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.*;
@@ -39,6 +36,9 @@ import java.util.concurrent.*;
 @Slf4j
 public class NettyServerHandler implements ChannelInboundHandler {
     ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
+
+    private  BeaconMate beaconMate = new BeaconMateImpl();
+
     /**
      * 读取客户端发送的消息
      */
@@ -84,6 +84,8 @@ public class NettyServerHandler implements ChannelInboundHandler {
             RelayUtils.relayRefreshStatus(dataStr,relayCode,codeStr);
             //继电器开关
             RelayUtils.relayOpenClose(dataStr,relayCode);
+        }else if(JsonUtils.isJsonString(dataStr)){
+            beaconMate.sendBeaconMate(dataStr);
         }
     }
 

+ 14 - 4
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabExitLineVertexServiceImpl.java

@@ -3,13 +3,11 @@ package com.zd.laboratory.service.impl;
 import cn.hutool.core.date.StopWatch;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
+import com.zd.airbottle.api.feign.RemoteAirBottleService;
 import com.zd.algorithm.api.speaker.entity.ParamVo;
 import com.zd.algorithm.api.speaker.entity.PlayVo;
 import com.zd.algorithm.api.speaker.feign.RemoteSpeakService;
-import com.zd.common.core.utils.DateUtils;
-import com.zd.common.core.utils.SaveUtil;
-import com.zd.common.core.utils.SecurityUtils;
-import com.zd.common.core.utils.StringUtils;
+import com.zd.common.core.utils.*;
 import com.zd.laboratory.config.TimeWaitConfigUtils;
 import com.zd.laboratory.constant.RelayConstants;
 import com.zd.laboratory.domain.*;
@@ -21,6 +19,7 @@ import com.zd.laboratory.service.ILabSparseHardwareService;
 import com.zd.laboratory.socket.command.Symbol;
 import com.zd.laboratory.socket.service.SocketService;
 import com.zd.model.domain.R;
+import com.zd.model.domain.ResultData;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -80,6 +79,9 @@ public class LabExitLineVertexServiceImpl implements ILabExitLineVertexService {
     @Autowired
     private ILabSparseHardwareService labSparseHardwareService;
 
+    @Autowired
+    private RemoteAirBottleService remoteAirBottleService;
+
 
     private static final Logger log = LoggerFactory.getLogger(LabExitLineVertexServiceImpl.class);
 
@@ -757,6 +759,14 @@ public class LabExitLineVertexServiceImpl implements ILabExitLineVertexService {
                         }
                     }
                     a.setSubName(b.getName());
+                    a.setSubBottle(Boolean.FALSE);
+                    //这里查询一下实验室是否有气瓶
+                    ResultData <List <Map<String,Object>>> beaconData = remoteAirBottleService.findBySubId(b.getId());
+                    if(beaconData.getCode()==200){
+                        if(beaconData.getData().size()>0){
+                            a.setSubBottle(Boolean.TRUE);
+                        }
+                    }
                 }));
         //实验室下的在线人员
         List<LabSubjectByUserNumVo> subjectByUserNumVoList = labHardwareStateMapper.querySubsOnlineUser(subIds);

+ 13 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/socket/service/BeaconMate.java

@@ -0,0 +1,13 @@
+package com.zd.laboratory.socket.service;
+
+/**
+ * Controller
+ *
+ * @author cyl
+ * @date 2023/10/12
+ */
+public interface BeaconMate {
+
+    public void sendBeaconMate(String dataStr);
+
+}

+ 128 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/socket/service/impl/BeaconMateImpl.java

@@ -0,0 +1,128 @@
+package com.zd.laboratory.socket.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.zd.airbottle.api.feign.RemoteAirBottleService;
+import com.zd.common.core.redis.RedisService;
+import com.zd.common.core.utils.SpringUtils;
+import com.zd.laboratory.socket.service.BeaconMate;
+import com.zd.model.constant.BaseConstants;
+import com.zd.model.domain.ResultData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Controller
+ *
+ * @author cyl
+ * @date 2023/10/12
+ */
+public class BeaconMateImpl implements BeaconMate {
+
+    private static Logger log = LoggerFactory.getLogger(BeaconMateImpl.class);
+
+    private static RedisService redisService = SpringUtils.getBean(RedisService.class);
+
+    private RemoteAirBottleService remoteAirBottleService = SpringUtils.getBean(RemoteAirBottleService.class);
+
+    public void sendBeaconMate(String dataStr){
+        log.info("1.=====================================》上报蓝牙网关编码:"+dataStr);
+        JSONObject jsonObject=JSONObject.parseObject(dataStr);
+        String mac = jsonObject.getString("mac");
+        if(mac!=null && !"".equals(mac)){
+            //todo 这里用线程去修改网关的具体在线状态
+            Boolean initFlag = Boolean.FALSE;
+            if(redisService.getCacheObject(BaseConstants.BEACON_MAC+"~"+ mac)==null){
+                setOpenBluetoothGateway(mac);
+                //todo 这里每次重启网关,或者第一次开启网关,需要把信标全部重新加载一次
+                initFlag = Boolean.TRUE;
+            }
+            //todo redis存储蓝牙网关mac地址,用于在线离线问题。
+            redisService.setCacheObject(BaseConstants.BEACON_MAC+"~"+ mac,mac, 60L, TimeUnit.SECONDS);
+
+            //todo 根据实验室id获取蓝牙信标列表
+            ResultData<Map<String,Object>> resultData = remoteAirBottleService.getSubByMac(mac);
+            if(resultData.getCode()==200){
+                log.info("2.=====================================》获取实验室id:"+resultData.getData().get("subId"));
+                Long subId = Long.parseLong(resultData.getData().get("subId")+"");
+                List <Map<String,Object>> beaconList = redisService.getCacheObject(BaseConstants.BEACON_MATE_INFO+"~"+subId);
+//                if(beaconList==null || initFlag){
+                    ResultData<List <Map<String,Object>>> beaconData = remoteAirBottleService.findBySubId(subId);
+                    log.info("2.1=====================================》如果信标列表为空,查询信标列表:");
+                    if(beaconData.getCode()==200){
+                        log.info("2.2=====================================》beaconList查询信标列表数据列表大小:"+beaconData.getData().size());
+                        redisService.setCacheObject(BaseConstants.BEACON_MATE_INFO+"~"+ subId,beaconData.getData(), 7L, TimeUnit.DAYS);
+                    }
+//                }
+
+                if(beaconList!=null){
+                    log.info("3.=====================================》上报信标列表:"+jsonObject.getJSONArray("devices"));
+                    JSONArray array = jsonObject.getJSONArray("devices");
+
+                    //todo 这里需要查看信标通知列表,移除通知列表对应的信标气瓶数据
+                    List <Map<String,Object>> beaconNoticeList = redisService.getCacheObject(BaseConstants.BEACON_MATE_NOTICE+"~"+subId);
+                    List <Map<String,Object>> newNoticeList = new ArrayList <>();
+                    newNoticeList.addAll(beaconNoticeList);
+                    //todo 循环检查实验室的信标比对上报的信标,将配对好的信标重新设置默认时间
+                    for(int x=0;x<beaconList.size();x++){
+                        if(array.size()>0){
+                            //todo 这里需要比对redis存储的蓝牙信息列表和上报的列表信息 稍后补全这块
+                            for(int i=0;i<array.size();i++){
+                                String beaconStr = array.getString(i);
+                                //初步过滤只有b5的数据
+                                if(beaconStr.endsWith("b5")){
+                                    //todo 这里需要处理信标字符串
+                                    beaconStr = checkBeacon(beaconStr);
+                                    log.info("4.=====================================》上报的信标处理后返回信标编码:"+beaconStr);
+                                    if(beaconList.get(x).get("beaconTag").equals(beaconStr)){
+                                        log.info("5.=====================================》将匹配的信标保存到对应的redis里面:"+BaseConstants.BEACON_MATE_DET+"~"+ beaconStr+"~"+beaconList.get(x).get("gasName"));
+                                        //todo redis存储蓝牙信标编码和实验室id和mac地址
+                                        redisService.setCacheObject(BaseConstants.BEACON_MATE_DET+"~"+ beaconStr+"~"+subId+"~"+beaconList.get(x).get("gasName"),beaconStr, 120L, TimeUnit.SECONDS);
+
+                                        //todo 循环信标通知,把还回来的气瓶提示移除。
+                                        if(beaconNoticeList != null){
+                                            for(Map notice:beaconNoticeList){
+                                                if(notice.get("beaconTag").equals(beaconStr)){
+                                                    log.info("6.=====================================》移除返回来的信标提示语:"+notice);
+                                                    newNoticeList.remove(notice);
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    //判断通知消息集合有数据,说明信标有变动,需要重新变更加通知
+                    redisService.setCacheObject(BaseConstants.BEACON_MATE_NOTICE+"~"+ subId,newNoticeList, 30L, TimeUnit.MINUTES);
+                    //下发通知,告诉前端页面,查询redis获取相关信息
+
+                }
+            }
+        }
+    }
+
+    //处理信标字符串
+    private String checkBeacon(String beaconStr){
+        StringBuilder appStr = new StringBuilder();
+        beaconStr = beaconStr.substring(beaconStr.length()-12);
+        appStr.append("00"+beaconStr.substring(0,2));
+        appStr.append(Integer.parseInt(beaconStr.substring(2,6),16));
+        appStr.append(Integer.parseInt(beaconStr.substring(6,10),16));
+        return appStr.toString();
+    }
+
+    //蓝牙网关修改在线
+    public void setOpenBluetoothGateway(String mac){
+        Map <String,Object> map = new HashMap<>();
+        map.put("gatewayMac",mac);
+        map.put("gatewayOnline",1);
+        remoteAirBottleService.setBluetoothGateway(map);
+    }
+}

+ 19 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/utils/JsonUtils.java

@@ -0,0 +1,19 @@
+package com.zd.laboratory.utils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Author donggaosheng
+ * @Date 2023-09-22
+ * @description
+ **/
+public class JsonUtils {
+    //判断是否是json
+    public static boolean isJsonString(String jsonString) {
+        String pattern = "\\{.*\\}|\\[.*\\]";
+        Pattern r = Pattern.compile(pattern);
+        Matcher m = r.matcher(jsonString);
+        return m.matches();
+    }
+}