瀏覽代碼

feat(本地化部署):
新增本地化部署云端分发数据功能

18339543638 2 年之前
父節點
當前提交
8dae1f49e0
共有 22 個文件被更改,包括 455 次插入234 次删除
  1. 2 0
      nb-admin/src/main/java/com/nb/admin/AdminApplication.java
  2. 0 47
      nb-admin/src/test/java/com/nb/admin/SpringBootApplicationTests.java
  3. 4 0
      nb-service-api/web-service-api/pom.xml
  4. 26 0
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/HospitalProperties.java
  5. 2 0
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/IHospitalClient.java
  6. 5 0
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/result/HospitalResult.java
  7. 5 5
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/utils/Items.java
  8. 5 0
      nb-service/iot-service/pom.xml
  9. 18 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/AliIotConstant.java
  10. 58 155
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/AliyunConsumerGroupService.java
  11. 0 18
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/bean/AliIotConfig.java
  12. 23 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/bean/AliIotMessagePojo.java
  13. 83 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/handler/AbstractAliIotMsgHandler.java
  14. 61 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/handler/DeviceLifeCycleMsgHandler.java
  15. 51 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/handler/DevicePropertyMsgHandler.java
  16. 56 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/handler/DeviceStatusMsgHandler.java
  17. 25 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/mq/RabbitMqChannelConfig.java
  18. 18 5
      nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/HospitalManager.java
  19. 2 2
      nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/his/strategy/onlynew/DefaultHisNewStrategyHandler.java
  20. 7 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusHospitalService.java
  21. 2 2
      nb-service/web-service/src/main/java/com/nb/web/service/log/config/LogEventListenerConfig.java
  22. 2 0
      pom.xml

+ 2 - 0
nb-admin/src/main/java/com/nb/admin/AdminApplication.java

@@ -9,6 +9,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.boot.web.servlet.ServletComponentScan;
+import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Import;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;
@@ -34,6 +35,7 @@ exclude = {RedisAutoConfiguration.class,RedissonAutoConfiguration.class})
 @EnableTioWebSocketServer
 @EnableScheduling
 @EnableAsync
+@EnableCaching
 @MapperScan({"com.nb.**.mapper"})
 @EnableConfigurationProperties({RequestCheckProperties.class, DruidProperties.class})
 @ServletComponentScan(basePackages = "com.nb.common.config")

+ 0 - 47
nb-admin/src/test/java/com/nb/admin/SpringBootApplicationTests.java

@@ -1,47 +0,0 @@
-package com.nb.admin;
-
-import cn.hutool.json.JSONUtil;
-import com.nb.web.service.bus.hospital.HospitalManagerRegister;
-import com.nb.web.service.bus.hospital.config.HospitalDeviceAutoUndoConfigHandler;
-import com.nb.web.service.bus.hospital.config.handler.DeputyDeviceAutoUndoHandler;
-import com.nb.core.Value;
-import com.nb.common.queue.delay.message.DelayMessage;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.util.Date;
-
-/**
- * @author lifang
- * @version 1.0.0
- * @ClassName SpringBootApplicationTests.java
- * @Description TODO
- * @createTime 2022年03月17日 13:50:00
- */
-@RunWith(SpringRunner.class)
-@SpringBootTest(classes = AdminApplication.class)
-public class SpringBootApplicationTests {
-
-    @Autowired
-    DeputyDeviceAutoUndoHandler deputyDeviceAutoUndoHandler;
-
-    @Autowired
-    HospitalManagerRegister hospitalManagerRegister;
-    @Test
-    public void autoUndo(){
-        String json="{\"key\":1551842476831064066,\"body\":{\"nativeValue\":{\"uploadTime\":1658823052919,\"deviceId\":\"43165411383902B1\",\"infusionId\":\"1551842476755566594\",\"tenantId\":\"1544525896866643970\",\"patientCode\":\"1000000000000\",\"timestamp\":1658823052972}},\"handlerId\":\"no_signal\",\"properties\":{\"expire\":30,\"timeUnit\":\"MINUTES\"}}";
-        DelayMessage delayMessage = JSONUtil.parseObj(json).toBean(DelayMessage.class);
-        String body="{\"uploadTime\":1658823052919,\"deviceId\":\"43165411383902B1\",\"infusionId\":\"1551842476755566594\",\"tenantId\":\"1544525896866643970\",\"patientCode\":\"1000000000000\",\"timestamp\":1658823052972}";
-        HospitalDeviceAutoUndoConfigHandler.UndoEntity undoEntity = JSONUtil.parseObj(body).toBean(HospitalDeviceAutoUndoConfigHandler.UndoEntity.class);
-        delayMessage.setBody(Value.simple(undoEntity));
-        deputyDeviceAutoUndoHandler.handle(delayMessage);
-    }
-
-    @Test
-    public void undo(){
-        hospitalManagerRegister.get("1544525896866643970").getAutoUndoConfigHandler().judgeNoSignalAutoUndo("43165411383902B1","1544870134758293505","1544525896866643970","1551842476755566594",new Date(1658823052919L));
-    }
-}

+ 4 - 0
nb-service-api/web-service-api/pom.xml

@@ -38,5 +38,9 @@
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 26 - 0
nb-service-api/web-service-api/src/main/java/com/nb/web/api/HospitalProperties.java

@@ -0,0 +1,26 @@
+package com.nb.web.api;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @ClassName : HospitalProperties
+ * @Description : 默认医院信息
+ * @Author : LF
+ * @Date: 2023年07月31日
+ */
+@Data
+@Configuration
+@ConfigurationProperties("hospital")
+public class HospitalProperties {
+    /**
+     * 医院名称
+     */
+    private String name;
+
+    /**
+     * 医院编码(本地部署时,必输)
+     */
+    private String code;
+}

+ 2 - 0
nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/IHospitalClient.java

@@ -18,4 +18,6 @@ public interface IHospitalClient {
      * @return List<HospitalResult>
      */
     List<HospitalResult> selectAll();
+
+    HospitalResult findById(String tenantId);
 }

+ 5 - 0
nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/result/HospitalResult.java

@@ -1,6 +1,7 @@
 package com.nb.web.api.feign.result;
 
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -28,6 +29,10 @@ public class HospitalResult implements Serializable {
     @Length(max = 255,message = "区域编码名称长度不得超过255个字节")
     private String areaCode;
 
+    @ApiModelProperty("医院唯一编码,自动生成")
+    @JsonIgnoreProperties(allowGetters = true)
+    private String code;
+
     /**
      * 医院地址
      */

+ 5 - 5
nb-service-api/web-service-api/src/main/java/com/nb/web/api/utils/Items.java

@@ -1,8 +1,8 @@
 package com.nb.web.api.utils;
 
-import com.alibaba.fastjson.JSONObject;
-import lombok.AllArgsConstructor;
 
+import cn.hutool.json.JSONObject;
+import lombok.AllArgsConstructor;
 import java.math.BigDecimal;
 import java.util.Date;
 import java.util.Optional;
@@ -21,11 +21,11 @@ public class Items {
     private JSONObject items;
 
     public String getString(PumpParams param){
-        return items.getJSONObject(param.getParam()).getString(VALUE);
+        return items.getJSONObject(param.getParam()).getStr(VALUE);
     }
 
     public Integer getInteger(PumpParams param){
-        return Optional.ofNullable(items.getJSONObject(param.getParam())).orElse(new JSONObject()).getInteger(VALUE);
+        return Optional.ofNullable(items.getJSONObject(param.getParam())).orElse(new JSONObject()).getInt(VALUE);
     }
 
     public Date getDate(){
@@ -38,7 +38,7 @@ public class Items {
     }
 
     public Boolean getBoolean(PumpParams param){
-        return Optional.ofNullable(items.getJSONObject(param.getParam())).orElse(new JSONObject()).getBoolean(VALUE);
+        return Optional.ofNullable(items.getJSONObject(param.getParam())).orElse(new JSONObject()).getBool(VALUE);
     }
 
 }

+ 5 - 0
nb-service/iot-service/pom.xml

@@ -27,5 +27,10 @@
             <artifactId>web-service-api</artifactId>
             <version>1.0</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-amqp</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 18 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/AliIotConstant.java

@@ -0,0 +1,18 @@
+package com.nb.aliyun.service;
+
+/**
+ * @ClassName : AliIotConstant
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年07月31日
+ */
+
+public interface AliIotConstant {
+    String TOPIC = "topic";
+    String MESSAGE_ID = "messageId";
+    String DEVICE_NAME = "deviceName";
+    String STATUS = "status";
+
+    //分发器
+    String Exchange="AliIot";
+}

+ 58 - 155
nb-service/iot-service/src/main/java/com/nb/aliyun/service/AliyunConsumerGroupService.java

@@ -1,35 +1,28 @@
 package com.nb.aliyun.service;
 
-import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.toolkit.IdWorker;
-import com.nb.web.api.bean.AliIotConfig;
+import com.nb.aliyun.service.bean.AliIotMessagePojo;
+import com.nb.aliyun.service.handler.AbstractAliIotMsgHandler;
+import com.nb.web.api.HospitalProperties;
 import com.nb.web.api.entity.BusDeviceEntity;
-import com.nb.web.api.entity.BusHospitalLogEntity;
-import com.nb.web.api.entity.common.BusDeviceRunningEntity;
-import com.nb.web.api.enums.HospitalLogEnum;
-import com.nb.web.api.feign.IHospitalLogClient;
-import com.nb.web.api.feign.IIotMsgHandler;
-import com.nb.web.api.utils.EnumUtils;
-import com.nb.core.utils.ExceptionUtil;
 import com.nb.web.api.feign.IDeviceClient;
-import com.nb.web.api.utils.Items;
-import io.netty.util.concurrent.SingleThreadEventExecutor;
+import com.nb.web.api.feign.IHospitalClient;
+import com.nb.web.api.feign.result.HospitalResult;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
 import javax.jms.Message;
 import javax.jms.MessageListener;
-import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.AtomicInteger;
-
+import java.util.*;
 /**
  * @Author 龙三郎
  * @Date 2022-4-06 16:22:13
@@ -38,65 +31,24 @@ import java.util.concurrent.atomic.AtomicInteger;
  */
 @Service
 @Slf4j
-public class AliyunConsumerGroupService {
-    private static final String IOTID = "iotId";
-    private static final String PRODUCTKEY = "productKey";
-    private static final String DEVICENAME = "deviceName";
-    private static final String TOPIC = "topic";
-    private static final String MESSAGEID = "messageId";
-    private static final String ITEMS = "items";
-    private static final String VALUE = "value";
-    private static final String STATUS = "status";
-    private static final String CONTENT = "payload";
+@ConditionalOnProperty(name = "aliyun.server-subscription.enable",havingValue = "true",matchIfMissing = false)
+public class AliyunConsumerGroupService implements CommandLineRunner {
 
     @Autowired
     @Lazy
     private AliyunIotSubscribeClient client;
-    @Autowired
-    @Lazy
-    private IDeviceClient deviceService;
 
     @Autowired
-    private IIotMsgHandler iotMsgHandler;
-
-    /**
-     * 阿里云订阅延迟启动,给ws重连时间
-     */
-    @Value("${tio.websocket.server.heartbeat-timeout:0}")
-    private Long delayTime;
+    private List<AbstractAliIotMsgHandler> handlers;
 
     @Autowired
-    @Lazy
-    private IHospitalLogClient hospitalLogService;
-
-    @Value("${aliyun.server-subscription.enable:false}")
-    private boolean isEnable;
-
-    // 开启服务端订阅
-    @PostConstruct
-    public void subscribe(){
-        if (!isEnable){
-            log.info("订阅禁止");
-            return;
-        }
-        log.info("允许开启订阅");
-        try {
-            client.start(messageListener);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        log.info("阿里云物联网订阅成功。。。。。。。。。。。");
-//        // 开启订阅
-//        Executors.newSingleThreadScheduledExecutor()
-//                .schedule(()->{
-//
-//                        },
-//                        Optional.ofNullable(delayTime).orElse(0L)*2,TimeUnit.SECONDS ) ;
-
-    }
-
+    private RabbitTemplate rabbitTemplate;
 
+    @Autowired
+    private IDeviceClient deviceService;
 
+    @Autowired
+    private IHospitalClient hospitalClient;
     /**
      * 描述:业务处理异步线程池,线程池参数可以根据您的业务特点调整,或者您也可以用其他异步方式处理接收到的消息。
      */
@@ -106,6 +58,16 @@ public class AliyunConsumerGroupService {
             new LinkedBlockingQueue(50000),
             new AliYunThreadFactory());
 
+    @Override
+    public void run(String... args) throws Exception {
+        try {
+            client.start(messageListener);
+            log.info("阿里云物联网订阅成功。");
+        } catch (Exception e) {
+            log.error("[阿里云物联网订阅失败],",e);
+        }
+    }
+
     static class AliYunThreadFactory implements ThreadFactory {
         static final AtomicInteger poolNumber = new AtomicInteger(1);
         final ThreadGroup group;
@@ -148,99 +110,40 @@ public class AliyunConsumerGroupService {
         }
     };
 
+    public void doProcessMessage(AliIotMessagePojo msg,String tenantId){
+        for (AbstractAliIotMsgHandler handler : handlers) {
+            handler.handle(msg,tenantId);
+        }
+    }
+
     private void processMessage(Message message) {
-        BusHospitalLogEntity hospitalLog = new BusHospitalLogEntity();
-        long startTime = System.currentTimeMillis();
-        String deviceName=null;
         try {
             // 获取主题,消息id和内容
-            String topic = message.getStringProperty(TOPIC);
-            String messageId = message.getStringProperty(MESSAGEID);
-            hospitalLog.setMsgId(messageId);
-            JSONObject content = JSON.parseObject(new String(message.getBody(byte[].class)));
-            log.info("阿里云物联网发送的数据:"+JSON.toJSONString(content));
-            // 设备名称
-            deviceName = content.getString(DEVICENAME);
-            hospitalLog.setIdentityCode(deviceName);
-            hospitalLog.setInput(content.toJSONString());
-            // 创建设备对象
-            Date now = new Date();
-            // 根据topic判断数据类型,设备上下线状态
-            if (topic.matches("^/as/mqtt/status/[\\w\\/]*")){
-                BusDeviceEntity device = new BusDeviceEntity();
-                device.setDeviceId(deviceName);
-                String status = content.getString(STATUS);
-                device.setStatus(EnumUtils.getDeviceStatusEnum2(status));
-                if ("online".equalsIgnoreCase(status)){
-                    log.info(deviceName+"设备【{}】上线",deviceName);
-                }else if ("offline".equalsIgnoreCase(status)){
-                    log.info(deviceName+"设备【{}】下线",deviceName);
-                }else {
-                    log.info(deviceName+"设备【{}】未激活",deviceName);
-                }
-                hospitalLog.setType(HospitalLogEnum.ALI_STATUS);
-                // 更新设备状态
-                deviceService.updateDevice(device);
-            }else if (topic.matches("[\\w\\/]*event/property/post$")){//设备属性上报
-                // 设备属性集合
-                Items items = new Items(content.getJSONObject("items"));
-                log.info("上传设备属性:【{}】",JSONUtil.toJsonStr(items));
-                BusDeviceRunningEntity deviceRunning = new BusDeviceRunningEntity();
-                deviceRunning.updateFieldsByItems(deviceName,items);
-                deviceRunning.setMsgId(messageId);
-                hospitalLog.setType(HospitalLogEnum.ALI_DATA_UPLOAD);
-                BusDeviceRunningEntity result = iotMsgHandler.sync(deviceRunning, deviceName);
-                hospitalLog.setTenantId(result.getTenantId());
-                hospitalLog.setResult(JSONUtil.toJsonStr(result));
-            }else if(topic.matches("[\\w\\/]+thing/lifecycle$")){// 设备生命周期
-                // 获取生命周期类型
-                String action = content.getString("action");
-                if ("create".equals(action)){
-                    // 创建设备
-                    BusDeviceEntity device = new BusDeviceEntity();
-                    device.setDeviceId(deviceName);
-
-                    // 配置信息
-                    AliIotConfig config = new AliIotConfig();
-                    config.setDeviceName(deviceName);
-                    config.setDeviceSecret(content.getString("deviceSecret"));
-                    config.setIotId(content.getString("iotId"));
-                    config.setProductKey(content.getString("productKey"));
-                    hospitalLog.setType(HospitalLogEnum.ALI_LIFECYCLE);
-                    // 设置配置信息
-                    device.setConfig(config);
-                    deviceService.saveDevice(device);
-                }else if ("delete".equals(action)){
-                    // 删除设备
-                    hospitalLog.setType(HospitalLogEnum.ALI_DEL);
-                    deviceService.removeByDeviceId(deviceName);
-                }
-            }else {
-                log.warn("阿里云数据【{}】,未知的topic:【{}】",content.toJSONString(),topic);
-            }
-            hospitalLog.setSuccess(true);
+            String topic = message.getStringProperty(AliIotConstant.TOPIC);
+            String messageId = message.getStringProperty(AliIotConstant.MESSAGE_ID);
+            JSONObject content = JSONUtil.parseObj(new String(message.getBody(byte[].class)));
+            log.info("阿里云物联网发送的数据:"+content.toString());
+            AliIotMessagePojo msg = AliIotMessagePojo.of(topic, messageId, content);
+            String deviceName = content.getStr(AliIotConstant.DEVICE_NAME);
+            BusDeviceEntity device = deviceService.getByDeviceId(deviceName);
+
+            //分发数据
+            distributeIotMsg(msg, ObjectUtil.isNull(device)?null:device.getTenantId());
+            doProcessMessage(msg,ObjectUtil.isNull(device)?null:device.getTenantId());
         } catch (Exception e) {
-            hospitalLog.setSuccess(false);
-            hospitalLog.setMessage(ExceptionUtil.getExceptionMsg(e));
             log.error("阿里云数据【{}】数据处理失败 ", JSONUtil.toJsonStr(message), e);
-        }finally {
-            if(CharSequenceUtil.isNotBlank(deviceName)&&CharSequenceUtil.isEmpty(hospitalLog.getTenantId())){
-                BusDeviceEntity device = deviceService.getByDeviceId(deviceName);
-                hospitalLog.setTenantId(device.getTenantId());
-            }
-            long entTime = System.currentTimeMillis();
-            hospitalLog.setUseTime(entTime-startTime);
-            hospitalLog.setId(IdWorker.getIdStr());
-            if(CharSequenceUtil.isEmpty(hospitalLog.getTenantId())){
-                log.warn("日志【{}】医院为空,进行自动填充",JSONUtil.toJsonStr(hospitalLog));
-            }
-            hospitalLogService.save(hospitalLog);
         }
-
     }
 
-
-
-
-
+    /**
+     * 向本地服务器分发数据
+     * @param msg
+     */
+    private void distributeIotMsg(AliIotMessagePojo msg,String tenantId){
+        if(StrUtil.isNullOrUndefined(tenantId)){
+            return;
+        }
+        HospitalResult hospital = hospitalClient.findById(tenantId);
+        rabbitTemplate.convertAndSend(AliIotConstant.Exchange,hospital.getCode(),msg);
+    }
 }

+ 0 - 18
nb-service/iot-service/src/main/java/com/nb/aliyun/service/bean/AliIotConfig.java

@@ -1,18 +0,0 @@
-package com.nb.aliyun.service.bean;
-
-import lombok.Data;
-
-/**
- * @author lifang
- * @version 1.0.0
- * @ClassName AliIotConfig.java
- * @Description 阿里云物联网注册设备返回配置结果
- * @createTime 2022年04月01日 15:43:00
- */
-@Data
-public class AliIotConfig {
-    private String deviceName;
-    private String deviceSecret;
-    private String productKey;
-    private String iotId;
-}

+ 23 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/bean/AliIotMessagePojo.java

@@ -0,0 +1,23 @@
+package com.nb.aliyun.service.bean;
+
+import cn.hutool.json.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @ClassName : AliIotMessagePojo
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年07月31日
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor(staticName = "of")
+public class AliIotMessagePojo implements Serializable {
+    private String topic;
+    private String messageId;
+    private JSONObject content;
+}

+ 83 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/handler/AbstractAliIotMsgHandler.java

@@ -0,0 +1,83 @@
+package com.nb.aliyun.service.handler;
+
+import cn.hutool.json.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.nb.aliyun.service.AliIotConstant;
+import com.nb.aliyun.service.bean.AliIotMessagePojo;
+import com.nb.core.utils.ExceptionUtil;
+import com.nb.web.api.entity.BusHospitalLogEntity;
+import com.nb.web.api.enums.HospitalLogEnum;
+import com.nb.web.api.feign.IDeviceClient;
+import com.nb.web.api.feign.IHospitalLogClient;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @Interface : AliIotMsgHandler
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年07月31日
+ */
+@Slf4j
+public abstract class AbstractAliIotMsgHandler {
+    protected final IDeviceClient deviceService;
+    protected final IHospitalLogClient hospitalLogService;
+
+    public AbstractAliIotMsgHandler(IDeviceClient deviceService, IHospitalLogClient hospitalLogService) {
+        this.deviceService = deviceService;
+        this.hospitalLogService = hospitalLogService;
+    }
+
+
+    public void handle(AliIotMessagePojo source,String tenantId){
+        String topic = source.getTopic();
+        if(!matchTopic(topic)){
+            return;
+        }
+        JSONObject content = source.getContent();
+        String deviceName =getDeviceName(content);
+        //日志记录
+        BusHospitalLogEntity hospitalLog = new BusHospitalLogEntity();
+        hospitalLog.setIdentityCode(deviceName);
+        hospitalLog.setInput(content.toString());
+        hospitalLog.setType(msgType());
+        hospitalLog.setTenantId(tenantId);
+        long startTime = System.currentTimeMillis();
+        try {
+            //阿里云信息处理
+            doHandle(source.getMessageId(),content);
+            hospitalLog.setSuccess(true);
+        }catch (Exception e){
+            hospitalLog.setSuccess(false);
+            hospitalLog.setMessage(ExceptionUtil.getExceptionMsg(e));
+            log.error("阿里云数据【{}】数据处理失败 ", content.toStringPretty(), e);}
+        long entTime = System.currentTimeMillis();
+        hospitalLog.setUseTime(entTime-startTime);
+        hospitalLog.setId(IdWorker.getIdStr());
+        hospitalLogService.save(hospitalLog);
+    }
+
+    protected  String getDeviceName(JSONObject content){
+        return content.getStr(AliIotConstant.DEVICE_NAME);
+    }
+
+    /**
+     * 查看主题是否匹配
+     * @param topic
+     * @return
+     */
+    protected abstract boolean matchTopic(String topic);
+
+
+    /**
+     * 获取当前消息类型
+     * @return
+     */
+    protected abstract HospitalLogEnum msgType();
+
+    /**
+     * 处理消息的地方
+     * @param messageId
+     * @param content
+     */
+    protected abstract void doHandle(String messageId, JSONObject content);
+}

+ 61 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/handler/DeviceLifeCycleMsgHandler.java

@@ -0,0 +1,61 @@
+package com.nb.aliyun.service.handler;
+
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import com.nb.web.api.bean.AliIotConfig;
+import com.nb.web.api.entity.BusDeviceEntity;
+import com.nb.web.api.enums.HospitalLogEnum;
+import com.nb.web.api.feign.IDeviceClient;
+import com.nb.web.api.feign.IHospitalLogClient;
+import com.nb.web.api.utils.EnumUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * @ClassName : DeviceLifeCycleMsgHandler
+ * @Description : 阿里云设备生命周期变化
+ * @Author : LF
+ * @Date: 2023年07月31日
+ */
+@Component
+@Slf4j
+public class DeviceLifeCycleMsgHandler extends AbstractAliIotMsgHandler{
+    public DeviceLifeCycleMsgHandler(IDeviceClient deviceService, IHospitalLogClient hospitalLogService) {
+        super(deviceService, hospitalLogService);
+    }
+
+    @Override
+    protected boolean matchTopic(String topic) {
+        return ReUtil.isMatch("[\\w\\/]+thing/lifecycle$", topic);
+    }
+
+    @Override
+    protected HospitalLogEnum msgType() {
+        return HospitalLogEnum.ALI_LIFECYCLE;
+    }
+
+    @Override
+    protected void doHandle(String messageId, JSONObject content) {
+        // 获取生命周期类型
+        String deviceName = getDeviceName(content);
+        String action = content.getStr("action");
+        if (StrUtil.equalsIgnoreCase("create",action)){
+            // 创建设备
+            BusDeviceEntity device = new BusDeviceEntity();
+            device.setDeviceId(deviceName);
+            // 配置信息
+            AliIotConfig config = new AliIotConfig();
+            config.setDeviceName(deviceName);
+            config.setDeviceSecret(content.getStr("deviceSecret"));
+            config.setIotId(content.getStr("iotId"));
+            config.setProductKey(content.getStr("productKey"));
+            // 设置配置信息
+            device.setConfig(config);
+            deviceService.saveDevice(device);
+        }else if (StrUtil.equalsIgnoreCase("delete",action)){
+            // 删除设备
+            deviceService.removeByDeviceId(deviceName);
+        }
+    }
+}

+ 51 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/handler/DevicePropertyMsgHandler.java

@@ -0,0 +1,51 @@
+package com.nb.aliyun.service.handler;
+
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.nb.web.api.entity.common.BusDeviceRunningEntity;
+import com.nb.web.api.enums.HospitalLogEnum;
+import com.nb.web.api.feign.IDeviceClient;
+import com.nb.web.api.feign.IHospitalLogClient;
+import com.nb.web.api.feign.IIotMsgHandler;
+import com.nb.web.api.utils.Items;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * @ClassName : DevicePropertyMsgHandler
+ * @Description : 设备属性信息上传
+ * @Author : LF
+ * @Date: 2023年07月31日
+ */
+@Component
+@Slf4j
+public class DevicePropertyMsgHandler extends AbstractAliIotMsgHandler{
+    private final IIotMsgHandler iotMsgHandler;
+    public DevicePropertyMsgHandler(IDeviceClient deviceService, IHospitalLogClient hospitalLogService, IIotMsgHandler iotMsgHandler) {
+        super(deviceService, hospitalLogService);
+        this.iotMsgHandler=iotMsgHandler;
+    }
+
+    @Override
+    protected boolean matchTopic(String topic) {
+        return ReUtil.isMatch("[\\w\\/]*event/property/post$", topic);
+    }
+
+    @Override
+    protected HospitalLogEnum msgType() {
+        return HospitalLogEnum.ALI_DATA_UPLOAD;
+    }
+
+    @Override
+    protected void doHandle(String messageId, JSONObject content) {
+        // 设备属性集合
+        String deviceName = getDeviceName(content);
+        Items items = new Items(content.getJSONObject("items"));
+        log.info("上传设备属性:【{}】", JSONUtil.toJsonStr(items));
+        BusDeviceRunningEntity deviceRunning = new BusDeviceRunningEntity();
+        deviceRunning.updateFieldsByItems(deviceName,items);
+        deviceRunning.setMsgId(messageId);
+        iotMsgHandler.sync(deviceRunning, deviceName);
+    }
+}

+ 56 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/handler/DeviceStatusMsgHandler.java

@@ -0,0 +1,56 @@
+package com.nb.aliyun.service.handler;
+
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import com.nb.aliyun.service.AliIotConstant;
+import com.nb.web.api.entity.BusDeviceEntity;
+import com.nb.web.api.enums.HospitalLogEnum;
+import com.nb.web.api.feign.IDeviceClient;
+import com.nb.web.api.feign.IHospitalLogClient;
+import com.nb.web.api.utils.EnumUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * @ClassName : DeviceStatusMsgHandler
+ * @Description : 阿里云设备上下线状态变化
+ * @Author : LF
+ * @Date: 2023年07月31日
+ */
+@Component
+@Slf4j
+public class DeviceStatusMsgHandler extends AbstractAliIotMsgHandler{
+
+    public DeviceStatusMsgHandler(IDeviceClient deviceService, IHospitalLogClient hospitalLogService) {
+        super(deviceService, hospitalLogService);
+    }
+
+    @Override
+    protected boolean matchTopic(String topic) {
+        return ReUtil.isMatch("^/as/mqtt/status/[\\w\\/]*", topic);
+    }
+
+    @Override
+    protected HospitalLogEnum msgType() {
+        return HospitalLogEnum.ALI_STATUS;
+    }
+
+    @Override
+    protected void doHandle(String messageId, JSONObject content) {
+        BusDeviceEntity device = new BusDeviceEntity();
+        String deviceName =getDeviceName(content);
+        device.setDeviceId(deviceName);
+        String status = content.getStr(AliIotConstant.STATUS);
+        device.setStatus(EnumUtils.getDeviceStatusEnum2(status));
+        if (StrUtil.equalsIgnoreCase( "online",status)){
+            log.info(deviceName+"设备【{}】上线",deviceName);
+        }else if (StrUtil.equalsIgnoreCase("offline",status)){
+            log.info(deviceName+"设备【{}】下线",deviceName);
+        }else {
+            log.info(deviceName+"设备【{}】未激活",deviceName);
+        }
+        // 更新设备状态
+        deviceService.updateDevice(device);
+    }
+}

+ 25 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/mq/RabbitMqChannelConfig.java

@@ -0,0 +1,25 @@
+package com.nb.aliyun.service.mq;
+
+import lombok.AllArgsConstructor;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * @ClassName : RabbitMqChannelConfig
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年07月31日
+ */
+@Component
+@ConditionalOnBean(RabbitTemplate.class)
+@AllArgsConstructor
+public class RabbitMqChannelConfig {
+    private final RabbitTemplate rabbitTemplate;
+    @PostConstruct
+    public void init(){
+
+    }
+}

+ 18 - 5
nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/HospitalManager.java

@@ -2,8 +2,10 @@ package com.nb.web.service.bus.hospital;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.cron.CronUtil;
@@ -107,6 +109,9 @@ public class HospitalManager {
                         PatientMonitorQuery query = new PatientMonitorQuery();
                         query.setTenantId(this.getHospitalId());
                         List<PatientMonitorResult> patientMonitorResults = patientService.selectAll(query);
+                        if(CollectionUtil.isEmpty(patientMonitorResults)){
+                            return;
+                        }
                         Date now = new Date();
                         patientMonitorResults
                                 .stream()
@@ -249,17 +254,25 @@ public class HospitalManager {
      * @return void
      */
     public void refreshUpdateConfig(HisUpdateEntity updateConfig){
-        if(updateConfig==null
-                ||!Boolean.TRUE.equals(updateConfig.getEnable())
-                ||null==updateConfig.getInterval()
-                ||updateConfig.getInterval()<0){
+        if(ObjectUtil.isNull(updateConfig)||ObjectUtil.isNull(updateConfig.getInterval())){
+            return;
+        }
+        if(!Boolean.TRUE.equals(updateConfig.getEnable())||updateConfig.getInterval()<0){
             if(hisSchedule !=null&&!hisSchedule.isCancelled()){
                 //如果有定时任务正在运行,则关闭
                 hisSchedule.cancel(true);
             }
             return;
         }
-        hisSchedule = singleHisExecutor.scheduleAtFixedRate(this::scheduleHis, 0, updateConfig.getInterval(),TimeUnit.MINUTES);
+        //参数未改变
+        if(ObjectUtil.equals(this.getUpdateConfig().getInterval(),updateConfig.getInterval())){
+            return;
+        }else {
+            //取消上次循环
+            hisSchedule.cancel(true);
+            hisSchedule = singleHisExecutor.scheduleAtFixedRate(this::scheduleHis, 0, updateConfig.getInterval(),TimeUnit.MINUTES);
+        }
+        this.updateConfig=updateConfig;
     }
 
     /**

+ 2 - 2
nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/his/strategy/onlynew/DefaultHisNewStrategyHandler.java

@@ -31,7 +31,7 @@ public class DefaultHisNewStrategyHandler implements HisNewStrategyHandler {
 
     @Override
     public String getDescription() {
-        return "拉取his只获取最新的一病人数据,对其进行处理";
+        return "拉取his只获取最新的一病人数据,对其进行处理";
     }
 
     @Override
@@ -40,7 +40,7 @@ public class DefaultHisNewStrategyHandler implements HisNewStrategyHandler {
         if(CollectionUtil.isEmpty(source)){
             return;
         }
-        log.info("拉取his只获取最新的一病人数据,对其进行处理,拉取手术信息{},数据库数据{}", JSONUtil.toJsonStr(source),JSONUtil.toJsonStr(target));
+        log.info("拉取his只获取最新的一病人数据,对其进行处理,拉取手术信息{},数据库数据{}", JSONUtil.toJsonStr(source),JSONUtil.toJsonStr(target));
         //是否插入新的数据
         boolean insert=true;
         //是否为设置为当前的临床数据

+ 7 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusHospitalService.java

@@ -32,6 +32,7 @@ import com.nb.web.service.system.entity.SysRole;
 import com.nb.web.service.system.service.impl.SysRoleServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.CommandLineRunner;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.jdbc.BadSqlGrammarException;
 import org.springframework.stereotype.Service;
@@ -287,4 +288,10 @@ public class LocalBusHospitalService extends BaseService<BusHospitalMapper, BusH
     public List<HospitalResult> selectAll() {
         return BeanUtil.copyToList(list(),HospitalResult.class);
     }
+
+    @Override
+    @Cacheable(value = "tenantId",key = "#tenantId")
+    public HospitalResult findById(String tenantId) {
+        return BeanUtil.copyProperties(getById(tenantId),HospitalResult.class);
+    }
 }

+ 2 - 2
nb-service/web-service/src/main/java/com/nb/web/service/log/config/LogEventListenerConfig.java

@@ -26,8 +26,8 @@ import org.springframework.stereotype.Component;
  * @Description TODO
  * @createTime 2022年08月02日 11:42:00
  */
-@Component
-@Order(1)
+//@Component
+//@Order(1)
 public class LogEventListenerConfig {
     private ISysLogService sysLogService;
     private LocalSysRunningLogService sysRunningLogService;

+ 2 - 0
pom.xml

@@ -379,6 +379,8 @@
                 <artifactId>pinyin4j</artifactId>
                 <version>${pinyin.verison}</version>
             </dependency>
+
+
         </dependencies>
     </dependencyManagement>