소스 검색

add:
阿里云多数据源订阅

18339543638 1 년 전
부모
커밋
ac5823d6b6
52개의 변경된 파일714개의 추가작업 그리고 1185개의 파일을 삭제
  1. 0 38
      doc/db/insert.sql
  2. 5 54
      nb-admin/pom.xml
  3. 1 0
      nb-admin/src/main/resources/application.yml
  4. 0 2
      nb-admin/src/main/resources/db/migration/V1_init_20230802.sql
  5. 1 5
      nb-admin/src/test/java/com/nb/admin/BusNetpumpTest.java
  6. 1 0
      nb-auth/src/main/java/com/nb/auth/sa/SaTokenConfig.java
  7. 1 1
      nb-common/config-common/src/main/java/com/nb/common/config/mybatisplus/interceptor/DefaultTenantLineInnerInterceptor.java
  8. 2 2
      nb-core/src/main/java/com/nb/core/sms/AliSmsClientConfig.java
  9. 1 1
      nb-core/src/main/java/com/nb/core/sms/SmsHelper.java
  10. 2 2
      nb-oss/src/main/java/com/nb/oss/strategy/AliyunOssUtil.java
  11. 6 0
      nb-oss/src/main/java/com/nb/oss/strategy/MinioUtil.java
  12. 1 1
      nb-oss/src/main/java/com/nb/oss/strategy/impl/AliyunStorageStrategy.java
  13. 0 1
      nb-oss/src/main/java/com/nb/oss/strategy/impl/MinioStorageStrategy.java
  14. 8 2
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/entity/common/BusDeviceRunningEntity.java
  15. 1 2
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/enums/DeviceTypeEnum.java
  16. 5 5
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/utils/DeviceTypeUtils.java
  17. 14 5
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/utils/Items.java
  18. 2 1
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/utils/PumpParams.java
  19. 18 18
      nb-service/app-assistant/src/main/java/com/nb/app/assistant/controller/CaptchaController.java
  20. 5 4
      nb-service/iot-service/pom.xml
  21. 47 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/AliConsumerAutoConfiguration.java
  22. 0 116
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/AliyunConsumerGroupService.java
  23. 0 205
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/AliyunIotSubscribeClient.java
  24. 0 33
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/PlatformLog.java
  25. 0 12
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/PlatformType.java
  26. 25 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/consumer/AbstractAliConsumer.java
  27. 161 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/consumer/AliIotSubscribeClient.java
  28. 218 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/consumer/NBAndFourGConsumerGroupService.java
  29. 3 1
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/handler/DevicePropertyMsgHandler.java
  30. 24 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/pojo/AliIotConfigPojo.java
  31. 27 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/pojo/AliIotConsumerPojo.java
  32. 16 0
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/pojo/AliIotProperties.java
  33. 0 16
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/Constants.java
  34. 0 48
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/DeviceAlarmUtils.java
  35. 0 32
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/DeviceRunStatusUtils.java
  36. 0 25
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/DeviceTypeUtils.java
  37. 0 67
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/PumpParams.java
  38. 0 36
      nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/WarnFlowUtils.java
  39. 0 134
      nb-service/iot-service/src/main/java/com/nb/mq/entity/PcAnalgesicScoreEntity.java
  40. 0 107
      nb-service/iot-service/src/main/java/com/nb/mq/entity/PcPatientEntity.java
  41. 0 173
      nb-service/iot-service/src/main/java/com/nb/mq/entity/PcPumpEntity.java
  42. 12 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/controller/BusDeviceController.java
  43. 3 1
      nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/script/PythonParse.java
  44. 2 1
      nb-service/web-service/src/main/java/com/nb/web/service/bus/listener/DeviceInfoListener.java
  45. 2 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/mapper/BusDeviceMapper.java
  46. 2 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/registry/constant/DeviceKeyConstant.java
  47. 42 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/registry/device/ClusterDeviceOperator.java
  48. 5 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/registry/device/DeviceOperator.java
  49. 4 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusDeviceService.java
  50. 29 22
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusHospitalService.java
  51. 14 12
      nb-service/web-service/src/main/java/com/nb/web/service/bus/utils/CodeUtils.java
  52. 4 0
      nb-service/web-service/src/main/resources/mapper/bus/BusDeviceMapper.xml

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 38
doc/db/insert.sql


+ 5 - 54
nb-admin/pom.xml

@@ -103,6 +103,11 @@
             <artifactId>snakeyaml</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure-processor</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.flywaydb</groupId>
             <artifactId>flyway-core</artifactId>
@@ -110,60 +115,6 @@
     </dependencies>
 
 
-    <!--<build>-->
-        <!--<resources>-->
-            <!--<resource>-->
-                <!--<directory>src/main/resources</directory>-->
-                <!--<includes>-->
-                    <!--&lt;!&ndash; **/* &ndash;&gt;-->
-                    <!--<include>**/*.xml</include>-->
-                    <!--<include>**/*.yml</include>-->
-                <!--</includes>-->
-                <!--<filtering>true</filtering>-->
-            <!--</resource>-->
-        <!--</resources>-->
-        <!--<plugins>-->
-            <!--<plugin>-->
-                <!--<groupId>org.apache.maven.plugins</groupId>-->
-                <!--<artifactId>maven-compiler-plugin</artifactId>-->
-                <!--<version>3.6.2</version>-->
-                <!--<configuration>-->
-                    <!--<source>${maven.compile.source}</source>-->
-                    <!--<target>${maven.compile.target}</target>-->
-                    <!--<encoding>${project.build.sourceEncoding}</encoding>-->
-                <!--</configuration>-->
-            <!--</plugin>-->
-
-            <!--&lt;!&ndash;<plugin>&ndash;&gt;-->
-                <!--&lt;!&ndash;<artifactId>maven-assembly-plugin</artifactId>&ndash;&gt;-->
-                <!--&lt;!&ndash;<configuration>&ndash;&gt;-->
-                    <!--&lt;!&ndash;<archive>&ndash;&gt;-->
-                        <!--&lt;!&ndash;<manifest>&ndash;&gt;-->
-                            <!--&lt;!&ndash;<mainClass>com.nb.admin.AdminApplication</mainClass>&ndash;&gt;-->
-                        <!--&lt;!&ndash;</manifest>&ndash;&gt;-->
-                        <!--&lt;!&ndash;<manifestEntries>&ndash;&gt;-->
-                            <!--&lt;!&ndash;<Class-Path>.</Class-Path>&ndash;&gt;-->
-                        <!--&lt;!&ndash;</manifestEntries>&ndash;&gt;-->
-                    <!--&lt;!&ndash;</archive>&ndash;&gt;-->
-                <!--&lt;!&ndash;</configuration>&ndash;&gt;-->
-                <!--&lt;!&ndash;<executions>&ndash;&gt;-->
-                    <!--&lt;!&ndash;<execution>&ndash;&gt;-->
-                        <!--&lt;!&ndash;<id>make-assembly</id>&ndash;&gt;-->
-                        <!--&lt;!&ndash;<phase>package</phase>&ndash;&gt;-->
-                        <!--&lt;!&ndash;<goals>&ndash;&gt;-->
-                            <!--&lt;!&ndash;<goal>single</goal>&ndash;&gt;-->
-                        <!--&lt;!&ndash;</goals>&ndash;&gt;-->
-                        <!--&lt;!&ndash;<configuration>&ndash;&gt;-->
-                            <!--&lt;!&ndash;<descriptors>&ndash;&gt;-->
-                                <!--&lt;!&ndash;<descriptor>src/main/resources/assembly.xml</descriptor>&ndash;&gt;-->
-                            <!--&lt;!&ndash;</descriptors>&ndash;&gt;-->
-                        <!--&lt;!&ndash;</configuration>&ndash;&gt;-->
-                    <!--&lt;!&ndash;</execution>&ndash;&gt;-->
-                <!--&lt;!&ndash;</executions>&ndash;&gt;-->
-            <!--&lt;!&ndash;</plugin>&ndash;&gt;-->
-        <!--</plugins>-->
-    <!--</build>-->
-
     <build>
         <finalName>${project.name}</finalName>
         <resources>

+ 1 - 0
nb-admin/src/main/resources/application.yml

@@ -100,6 +100,7 @@ captcha:
   width: 140
   height: 38
   #验证码过期时间 5min
+
   expire: 300
 management:
   endpoints:

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 2
nb-admin/src/main/resources/db/migration/V1_init_20230802.sql


+ 1 - 5
nb-admin/src/test/java/com/nb/admin/BusNetpumpTest.java

@@ -2,11 +2,8 @@ package com.nb.admin;
 
 import cn.hutool.core.util.RandomUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.nb.aliyun.service.AliyunConsumerGroupService;
 import com.nb.web.api.entity.BusDeviceEntity;
 import com.nb.web.api.enums.DeviceStatusEnum2;
-import com.nb.web.api.enums.HospitalLogEnum;
-import com.nb.web.api.utils.EnumUtils;
 import com.nb.web.service.bus.service.LocalBusDeviceService;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -118,8 +115,7 @@ public class BusNetpumpTest {
     public void queryRegistry(){
 
     }
-    @Autowired
-    private AliyunConsumerGroupService consumerGroupService;
+
     @Test
     public void alias(){
         BusDeviceEntity device = new BusDeviceEntity();

+ 1 - 0
nb-auth/src/main/java/com/nb/auth/sa/SaTokenConfig.java

@@ -68,6 +68,7 @@ public class SaTokenConfig {
         IGNORE_URL.add("/system/sysConfig/getTime");
         IGNORE_URL.add("/system/sysDept/**");
         IGNORE_URL.add("/assist/phone/**");
+        IGNORE_URL.add("/bus/device/info/hospitalCode");
     }
 
 }

+ 1 - 1
nb-common/config-common/src/main/java/com/nb/common/config/mybatisplus/interceptor/DefaultTenantLineInnerInterceptor.java

@@ -38,7 +38,7 @@ import static org.springframework.web.context.request.RequestAttributes.SCOPE_RE
 @ConditionalOnBean(TenantIdManager.class)
 @Configuration
 public class DefaultTenantLineInnerInterceptor {
-    private final List<String> ignoreUrlTenantId= Arrays.asList("/login","/getUserInfo","/token");
+    private final List<String> ignoreUrlTenantId= Arrays.asList("/login","/getUserInfo","/token","/bus/device/info/hospitalCode");
     private final List<Class<?>> tableClass;
 
     private Set<String> ignoreTableName;

+ 2 - 2
nb-core/src/main/java/com/nb/core/sms/AliSmsClientConfig.java

@@ -12,13 +12,13 @@ import com.aliyun.teaopenapi.models.*;
  * @Description TODO
  * @createTime 2022年10月12日 10:52:00
  */
-@Configuration
+//@Configuration
 public class AliSmsClientConfig {
     @Value("${aliyun.accessKey}")
     private String accessKeyId;
     @Value("${aliyun.accessSecret}")
     private String accessKeySecret;
-    @Bean
+//    @Bean
     public Client creatClient() throws Exception {
         com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                 // 您的 AccessKey ID

+ 1 - 1
nb-core/src/main/java/com/nb/core/sms/SmsHelper.java

@@ -17,7 +17,7 @@ import java.util.Map;
  * @Description TODO
  * @createTime 2022年10月13日 09:28:00
  */
-@Configuration
+//@Configuration
 @AllArgsConstructor
 public class SmsHelper {
 

+ 2 - 2
nb-oss/src/main/java/com/nb/oss/strategy/AliyunOssUtil.java

@@ -29,9 +29,9 @@ import java.io.InputStream;
  *
  * @author Kevin
  */
-@Component
+//@Component
 @Slf4j
-@EnableConfigurationProperties(AliyunOssProperties.class)
+//@EnableConfigurationProperties(AliyunOssProperties.class)
 public class AliyunOssUtil {
     @Autowired
     private AliyunOssProperties ossProperties;

+ 6 - 0
nb-oss/src/main/java/com/nb/oss/strategy/MinioUtil.java

@@ -25,6 +25,9 @@ public class MinioUtil {
     @Resource
     MinioClient minioClient;
 
+    private static final String BUCKET_PARAM="--bucketName--";
+    private static final String PUBLIC_POLICY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\",\"s3:GetBucketLocation\"],\"Resource\":[\"arn:aws:s3:::"+BUCKET_PARAM+"\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\"],\"Resource\":[\"arn:aws:s3:::"+BUCKET_PARAM+"/*\"]}]}";
+
     @Bean
     private MinioClient minioClient() {
         MinioClient minioClient = MinioClient.builder()
@@ -39,6 +42,9 @@ public class MinioUtil {
             boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioConfig.getBucketName()).build());
             if (!exists) {
                 minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioConfig.getBucketName()).build());
+                minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(minioConfig.getBucketName())
+                        .config(PUBLIC_POLICY.replaceAll(BUCKET_PARAM,(minioConfig.getBucketName())))
+                        .build());
             }
             PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                     .bucket(minioConfig.getBucketName())

+ 1 - 1
nb-oss/src/main/java/com/nb/oss/strategy/impl/AliyunStorageStrategy.java

@@ -21,7 +21,7 @@ import java.io.IOException;
  *
  * @author Kevin
  */
-@Service
+//@Service
 @Slf4j
 public class AliyunStorageStrategy extends AbstractFileStorage {
     @Autowired

+ 0 - 1
nb-oss/src/main/java/com/nb/oss/strategy/impl/MinioStorageStrategy.java

@@ -31,7 +31,6 @@ public class MinioStorageStrategy extends AbstractFileStorage {
 
     @Resource
     MinioConfig minioConfig;
-
     @Override
     public String getStrategyName() {
         return FileStorageStrategyEnum.MINIO.name();

+ 8 - 2
nb-service-api/web-service-api/src/main/java/com/nb/web/api/entity/common/BusDeviceRunningEntity.java

@@ -151,6 +151,12 @@ public class BusDeviceRunningEntity extends CommonDeviceParam<String,String> {
     @TableField(exist = false)
     @JsonIgnoreProperties
     private boolean flowRestricted;
+
+    /**
+     * 4G 传输时会带上医院编码
+     */
+    private String hospitalCode;
+
     /**
      * @author 龙三郎
      * 根据阿里云传回数据的items,设置输注的属性
@@ -177,7 +183,7 @@ public class BusDeviceRunningEntity extends CommonDeviceParam<String,String> {
 
         this.setSelfControlLockTime(items.getBigDecimal(PumpParams.lockTime));
 
-        this.setTest(StrUtil.equals("2",items.getString(PumpParams.dataType)));
+        this.setTest(StrUtil.equals("2",items.getStringReturnDefault(PumpParams.dataType,"1")));
 
         this.setContinueDose(items.getBigDecimal(PumpParams.flow));
         this.setType( DeviceTypeUtils.getDeviceType(items.getInteger(PumpParams.pumpType)));
@@ -229,7 +235,7 @@ public class BusDeviceRunningEntity extends CommonDeviceParam<String,String> {
             this.setWarnFlow(WarnFlowUtils.getAlarm(items.getInteger(PumpParams.warnFlow)));
         }
 
-
+        this.setHospitalCode(items.getString(PumpParams.userId));
     }
 
 

+ 1 - 2
nb-service-api/web-service-api/src/main/java/com/nb/web/api/enums/DeviceTypeEnum.java

@@ -20,8 +20,7 @@ public enum DeviceTypeEnum implements IEnum<Integer> {
     continuous(1,"持续型"),
     intelligent(2,"智能型"),
     pulse(3,"脉冲型"),
-    other(4,"其他"),
-    chemotherapy(5,"化疗泵"),;
+    chemistry(4,"化疗泵");
 
     @Getter
     @ApiModelProperty("设备编码")

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

@@ -10,16 +10,16 @@ import com.nb.web.api.enums.DeviceTypeEnum;
  */
 public class DeviceTypeUtils {
     public static DeviceTypeEnum getDeviceType(Integer i){
-        if (i == 0){
-            return DeviceTypeEnum.no;
-        }else if (i == 1){
+        if (i == 1){
             return DeviceTypeEnum.continuous;
         }else if (i == 2){
             return DeviceTypeEnum.pulse;
         }else if (i == 3){
             return DeviceTypeEnum.intelligent;
-        }else {
-            return DeviceTypeEnum.other;
+        } else if (i == 4){
+            return DeviceTypeEnum.chemistry;
+        } else {
+            return DeviceTypeEnum.no;
         }
     }
 }

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

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

+ 2 - 1
nb-service-api/web-service-api/src/main/java/com/nb/web/api/utils/PumpParams.java

@@ -59,8 +59,9 @@ public enum PumpParams {
 
     dataType("dataType","数据类型,1、业务数据 2、测试数据"),
 
-    CRC("CRC","CRC");
+    CRC("CRC","CRC"),
 
+    userId("userId","医院编码");
 
 
     @Getter

+ 18 - 18
nb-service/app-assistant/src/main/java/com/nb/app/assistant/controller/CaptchaController.java

@@ -36,26 +36,26 @@ public class CaptchaController {
 
     private final ResetPswUtil resetPswUtil;
 
-    private final SmsHelper smsHelper;
+//    private final SmsHelper smsHelper;
 
     private final LocalAssistantUserService assistantUserService;
-    @PostMapping("/create")
-    @ApiOperation("获取短信验证码")
-    public R<String> capture(@RequestBody @Validated CaptureVo vo){
-       CaptchaEnum type = vo.getType();
-       if(CaptchaEnum.FORGET_PSW.equals(type)){
-           //判断手机号账户是否存在
-           AssistantUserEntity user = assistantUserService.getOne(new QueryWrapper<AssistantUserEntity>()
-                   .lambda()
-                   .eq(AssistantUserEntity::getPhone, vo.getPhone()));
-           if(user==null){
-               throw new CustomException("该手机号尚未注册");
-           }
-       }
-        String code = captchaUtil.getCode(vo.getType(), vo.getPhone());
-        smsHelper.sendVerifyCode(vo.getPhone(),code);
-        return R.success(code);
-    }
+//    @PostMapping("/create")
+//    @ApiOperation("获取短信验证码")
+//    public R<String> capture(@RequestBody @Validated CaptureVo vo){
+//       CaptchaEnum type = vo.getType();
+//       if(CaptchaEnum.FORGET_PSW.equals(type)){
+//           //判断手机号账户是否存在
+//           AssistantUserEntity user = assistantUserService.getOne(new QueryWrapper<AssistantUserEntity>()
+//                   .lambda()
+//                   .eq(AssistantUserEntity::getPhone, vo.getPhone()));
+//           if(user==null){
+//               throw new CustomException("该手机号尚未注册");
+//           }
+//       }
+//        String code = captchaUtil.getCode(vo.getType(), vo.getPhone());
+//        smsHelper.sendVerifyCode(vo.getPhone(),code);
+//        return R.success(code);
+//    }
 
     @PostMapping("/reset/validate")
     @ApiOperation(value = "重置验证码校验",notes = "校验验证码并获取校验token,过期时间24h")

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

@@ -28,9 +28,10 @@
             <version>1.0</version>
         </dependency>
 
-        <!--<dependency>-->
-            <!--<groupId>org.springframework.boot</groupId>-->
-            <!--<artifactId>spring-boot-starter-amqp</artifactId>-->
-        <!--</dependency>-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
     </dependencies>
 </project>

+ 47 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/AliConsumerAutoConfiguration.java

@@ -0,0 +1,47 @@
+package com.nb.aliyun.service;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.nb.aliyun.service.consumer.AbstractAliConsumer;
+import com.nb.aliyun.service.consumer.AliIotSubscribeClient;
+import com.nb.aliyun.service.consumer.NBAndFourGConsumerGroupService;
+import com.nb.aliyun.service.pojo.AliIotConsumerPojo;
+import com.nb.aliyun.service.pojo.AliIotProperties;
+import jodd.util.ClassUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+/**
+ * @ClassName : AliConsumerAutoConfiguration
+ * @Description :
+ * @Author : LF
+ * @Date: 2024年02月18日
+ */
+@Configuration
+@EnableConfigurationProperties(AliIotProperties.class)
+public class AliConsumerAutoConfiguration {
+    @Autowired
+    private  AliIotProperties iotProperties;
+
+    @PostConstruct
+    public void init() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
+        if(ObjectUtil.isNotNull(iotProperties)){
+            List<AliIotConsumerPojo> consumers = iotProperties.getConsumers();
+            if(CollectionUtil.isNotEmpty(consumers)){
+                for (AliIotConsumerPojo consumer : consumers) {
+                    if(!Boolean.TRUE.equals(consumer.getEnable())){
+                        continue;
+                    }
+                    AliIotSubscribeClient client = new AliIotSubscribeClient(consumer.getName(), consumer.getConfig());
+                    AbstractAliConsumer consumerGroup = ClassUtil.newInstance(consumer.getConsumer(), client, consumer);
+                    consumerGroup.doSubscribe();
+                }
+            }
+        }
+    }
+}

+ 0 - 116
nb-service/iot-service/src/main/java/com/nb/aliyun/service/AliyunConsumerGroupService.java

@@ -1,116 +0,0 @@
-package com.nb.aliyun.service;
-
-import cn.hutool.json.JSONObject;
-import cn.hutool.json.JSONUtil;
-import com.nb.aliyun.service.bean.AliIotMessagePojo;
-import com.nb.aliyun.service.process.DeviceMsgHandler;
-import com.nb.web.api.entity.BusDeviceEntity;
-import com.nb.web.api.feign.IDeviceClient;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.CommandLineRunner;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.stereotype.Service;
-import javax.jms.Message;
-import javax.jms.MessageListener;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicInteger;
-/**
- * @Author 龙三郎
- * @Date 2022-4-06 16:22:13
- * @Version 1.0
- * @Description 阿里云物联网平台服务端订阅
- */
-//@Service
-@Slf4j
-@ConditionalOnProperty(name = "aliyun.server-subscription.enable",havingValue = "true",matchIfMissing = false)
-public class AliyunConsumerGroupService implements CommandLineRunner {
-
-    private final AliyunIotSubscribeClient client;
-
-    private final DeviceMsgHandler deviceMsgHandler;
-
-    private final IDeviceClient deviceService;
-
-    public AliyunConsumerGroupService(AliyunIotSubscribeClient client, DeviceMsgHandler deviceMsgHandler,IDeviceClient deviceService) {
-        this.client = client;
-        this.deviceMsgHandler = deviceMsgHandler;
-        this.deviceService=deviceService;
-    }
-
-    /**
-     * 描述:业务处理异步线程池,线程池参数可以根据您的业务特点调整,或者您也可以用其他异步方式处理接收到的消息。
-     */
-    private final static ExecutorService executorService = new ThreadPoolExecutor(
-            Runtime.getRuntime().availableProcessors(),
-            Runtime.getRuntime().availableProcessors() * 2, 60, TimeUnit.SECONDS,
-            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;
-        final AtomicInteger threadNumber = new AtomicInteger(1);
-        final String namePrefix;
-
-        AliYunThreadFactory() {
-            SecurityManager s = System.getSecurityManager();
-            group = (s != null)? s.getThreadGroup() :
-                    Thread.currentThread().getThreadGroup();
-            namePrefix = "ali-iot-" +
-                    poolNumber.getAndIncrement();
-        }
-        @Override
-        public Thread newThread(Runnable r) {
-            Thread t = new Thread(group, r,
-                    namePrefix + threadNumber.getAndIncrement(),
-                    0);
-            if (t.isDaemon()){
-                t.setDaemon(false);
-            }
-            if (t.getPriority() != Thread.NORM_PRIORITY){
-                t.setPriority(Thread.NORM_PRIORITY);
-            }
-            return t;
-        }
-    }
-
-    private MessageListener messageListener = (message) -> {
-        try {
-            //1.收到消息之后一定要ACK。
-            // 推荐做法:创建Session选择Session.AUTO_ACKNOWLEDGE,这里会自动ACK。
-            // 其他做法:创建Session选择Session.CLIENT_ACKNOWLEDGE,这里一定要调message.acknowledge()来ACK。
-            // message.acknowledge();
-            //2.建议异步处理收到的消息,确保onMessage函数里没有耗时逻辑。
-            // 如果业务处理耗时过程过长阻塞住线程,可能会影响SDK收到消息后的正常回调。
-            executorService.submit(()-> processMessage(message));
-        } catch (Exception e) {
-            log.error("submit task occurs exception ", e);
-        }
-    };
-
-    private void processMessage(Message message) {
-        try {
-            // 获取主题,消息id和内容
-            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());
-            String deviceName = content.getStr(AliIotConstant.DEVICE_NAME);
-            BusDeviceEntity device = deviceService.getByDeviceId(deviceName);
-            AliIotMessagePojo msg = AliIotMessagePojo.of(topic, messageId, content,device);
-            deviceMsgHandler.handleMessage(msg,true);
-        } catch (Exception e) {
-            log.error("阿里云数据【{}】处理失败 ", JSONUtil.toJsonStr(message), e);
-        }
-    }
-}

+ 0 - 205
nb-service/iot-service/src/main/java/com/nb/aliyun/service/AliyunIotSubscribeClient.java

@@ -1,205 +0,0 @@
-package com.nb.aliyun.service;
-
-import com.baomidou.mybatisplus.core.toolkit.IdWorker;
-import com.nb.aliyun.api.bean.PlatformAccount;
-import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.qpid.jms.JmsConnection;
-import org.apache.qpid.jms.JmsConnectionListener;
-import org.apache.qpid.jms.message.JmsInboundMessageDispatch;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.scheduling.annotation.Async;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import javax.jms.*;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.List;
-
-/**
- * @Author 龙三郎
- * @Date 2021-06-17 10:53:30
- * @Version 1.0
- * @Description XXX
- */
-@Configuration
-@EnableConfigurationProperties(PlatformAccount.class)
-@Slf4j
-public class AliyunIotSubscribeClient {
-
-    private final PlatformAccount platformAccount;
-
-    public AliyunIotSubscribeClient(PlatformAccount platformAccount) {
-        this.platformAccount = platformAccount;
-        this.accessKey = platformAccount.getAccessKey();
-        this.accessSecret = platformAccount.getAccessSecret();
-        this.regionId = platformAccount.getRegionId();
-        this.consumerGroupId = platformAccount.getConsumerGroupId();
-        this.aliyunUid = platformAccount.getAliyunUid();
-        this.iotInstanceId = platformAccount.getIotInstanceId();
-
-        this.host = aliyunUid+".iot-amqp."+ regionId +".aliyuncs.com";
-        // 设置客户端id
-        setClientIdAndHost();
-    }
-
-    // 设置客户端id
-    private void setClientIdAndHost(){
-        // 获取ip地址
-        InetAddress addr = null;
-        try {
-            addr = InetAddress.getLocalHost();
-        } catch (UnknownHostException e) {
-            e.printStackTrace();
-        }
-        this.clientId = IdWorker.getIdStr();
-    }
-
-    private String accessKey;
-    private String accessSecret;
-    private String consumerGroupId;
-    private String aliyunUid;
-    private String regionId;
-
-    //iotInstanceId:企业版实例请填写实例ID,公共实例请填空字符串""。
-    private String iotInstanceId;
-
-    //控制台服务端订阅中消费组状态页客户端ID一栏将显示clientId参数。
-    //建议使用机器UUID、MAC地址、IP等唯一标识等作为clientId。便于您区分识别不同的客户端。
-    private String clientId;
-
-    //${YourHost}为接入域名,请参见AMQP客户端接入说明文档。
-    private String host;
-
-    // 指定单个进程启动的连接数
-    // 单个连接消费速率有限,请参考使用限制,最大64个连接
-    // 连接数和消费速率及rebalance相关,建议每500QPS增加一个连接
-    private static int connectionCount = 1;
-
-    @Getter
-    private List<Connection> connections = null;
-
-    @Async
-    public void start(MessageListener messageListener) throws Exception {
-        // 先关闭一下
-        close();
-        connections = new ArrayList<>();
-        //参数说明,请参见AMQP客户端接入说明文档。
-        for (int i = 0; i < connectionCount; i++) {
-            long timeStamp = System.currentTimeMillis();
-            //签名方法:支持hmacmd5、hmacsha1和hmacsha256。
-            String signMethod = "hmacsha1";
-
-            //userName组装方法,请参见AMQP客户端接入说明文档。
-            String userName = clientId + "-" + i + "|authMode=aksign"
-                    + ",signMethod=" + signMethod
-                    + ",timestamp=" + timeStamp
-                    + ",authId=" + accessKey
-                    + ",iotInstanceId=" + iotInstanceId
-                    + ",consumerGroupId=" + consumerGroupId
-                    + "|";
-            //计算签名,password组装方法,请参见AMQP客户端接入说明文档。
-            String signContent = "authId=" + accessKey + "&timestamp=" + timeStamp;
-            String password = doSign(signContent, accessSecret, signMethod);
-            String connectionUrl = "failover:(amqps://" + host + ":5671?amqp.idleTimeout=80000)"
-                    + "?failover.reconnectDelay=30";
-
-            Hashtable<String, String> hashtable = new Hashtable<>();
-            hashtable.put("connectionfactory.SBCF", connectionUrl);
-            hashtable.put("queue.QUEUE", "default");
-            hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
-            Context context = new InitialContext(hashtable);
-            ConnectionFactory cf = (ConnectionFactory)context.lookup("SBCF");
-            Destination queue = (Destination)context.lookup("QUEUE");
-            // 创建连接。
-            Connection connection = cf.createConnection(userName, password);
-            connections.add(connection);
-
-            ((JmsConnection)connection).addConnectionListener(myJmsConnectionListener);
-            // 创建会话。
-            // Session.CLIENT_ACKNOWLEDGE: 收到消息后,需要手动调用message.acknowledge()。
-            // Session.AUTO_ACKNOWLEDGE: SDK自动ACK(推荐)。
-            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
-            connection.start();
-            // 创建Receiver连接。
-            MessageConsumer consumer = session.createConsumer(queue);
-            consumer.setMessageListener(messageListener);
-        }
-    }
-
-    public void close() throws Exception {
-        if (connections == null){
-            return;
-        }
-        connections.forEach(c-> {
-            try {
-                c.close();
-            } catch (JMSException e) {
-                log.error("连接关闭失败", e);
-            }
-        });
-    }
-
-
-    private static JmsConnectionListener myJmsConnectionListener = new JmsConnectionListener() {
-        /**
-         * 连接成功建立。
-         */
-        @Override
-        public void onConnectionEstablished(URI remoteURI) {
-            log.info("连接成功, remoteUri:{}", remoteURI);
-        }
-        /**
-         * 尝试过最大重试次数之后,最终连接失败。
-         */
-        @Override
-        public void onConnectionFailure(Throwable error) {
-            log.error("连接失败, {}", error.getMessage());
-        }
-        /**
-         * 连接中断。
-         */
-        @Override
-        public void onConnectionInterrupted(URI remoteURI) {
-            log.info("连接中断, remoteUri:{}", remoteURI);
-        }
-        /**
-         * 连接中断后又自动重连上。
-         */
-        @Override
-        public void onConnectionRestored(URI remoteURI) {
-            log.info("自动重连, remoteUri:{}", remoteURI);
-        }
-        @Override
-        public void onInboundMessage(JmsInboundMessageDispatch envelope) {}
-        @Override
-        public void onSessionClosed(Session session, Throwable cause) {}
-        @Override
-        public void onConsumerClosed(MessageConsumer consumer, Throwable cause) {}
-        @Override
-        public void onProducerClosed(MessageProducer producer, Throwable cause) {}
-    };
-
-    /**
-     * 计算签名,password组装方法,请参见AMQP客户端接入说明文档。
-     */
-    private static String doSign(String toSignString, String secret, String signMethod) throws Exception {
-        SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), signMethod);
-        Mac mac = Mac.getInstance(signMethod);
-        mac.init(signingKey);
-        byte[] rawHmac = mac.doFinal(toSignString.getBytes());
-        return Base64.encodeBase64String(rawHmac);
-    }
-
-
-
-}

+ 0 - 33
nb-service/iot-service/src/main/java/com/nb/aliyun/service/PlatformLog.java

@@ -1,33 +0,0 @@
-package com.nb.aliyun.service;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * @Author XX
- * @Date 2022-01-10 11:43:57
- * @Version 1.0
- * @Description XXX
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class PlatformLog {
-    @TableId(value = "id",type = IdType.AUTO)
-    private Long id;
-    private String code;
-    private String platformCode;
-    private String platformProductCode;
-    private String deviceCode;
-    private String platformData;
-    private String resultData;
-    private String errorLog;
-    private String isError;
-    private Long addTime;
-    private Long updateTime;
-    private String description;
-    private String isDelete;
-}

+ 0 - 12
nb-service/iot-service/src/main/java/com/nb/aliyun/service/PlatformType.java

@@ -1,12 +0,0 @@
-package com.nb.aliyun.service;
-
-/**
- * @Author XX
- * @Date 2022-02-12 08:08:15
- * @Version 1.0
- * @Description XXX
- */
-public class PlatformType {
-    public static final String ALIYUN = "10";
-    public static final String TUOREN = "30";
-}

+ 25 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/consumer/AbstractAliConsumer.java

@@ -0,0 +1,25 @@
+package com.nb.aliyun.service.consumer;
+
+import com.nb.aliyun.service.pojo.AliIotConsumerPojo;
+import lombok.Getter;
+
+/**
+ * @ClassName : AbstractAliyunConsumer
+ * @Description : 阿里云消费组接口
+ * @Author : LF
+ * @Date: 2024年02月18日
+ */
+
+public abstract class AbstractAliConsumer {
+    @Getter
+    private final AliIotConsumerPojo consumer;
+    @Getter
+    private final AliIotSubscribeClient client;
+
+    public AbstractAliConsumer(AliIotSubscribeClient client,AliIotConsumerPojo consumer) {
+        this.consumer = consumer;
+        this.client=client;
+    }
+
+    public  abstract void doSubscribe();
+}

+ 161 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/consumer/AliIotSubscribeClient.java

@@ -0,0 +1,161 @@
+package com.nb.aliyun.service.consumer;
+
+import cn.hutool.core.lang.UUID;
+import cn.hutool.core.net.NetUtil;
+import cn.hutool.core.util.RuntimeUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.nb.aliyun.api.bean.PlatformAccount;
+import com.nb.aliyun.service.pojo.AliIotConfigPojo;
+import lombok.Data;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.qpid.jms.JmsConnection;
+import org.apache.qpid.jms.JmsConnectionListener;
+import org.apache.qpid.jms.message.JmsInboundMessageDispatch;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.Async;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.jms.*;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * @Author 龙三郎
+ * @Date 2021-06-17 10:53:30
+ * @Version 1.0
+ * @Description XXX
+ *
+ *
+ *
+ * @Author 李放
+ * @Date 2024-02-18 10:53:30
+ * @Version 1.0
+ * @Description 更新 改为多个阿里云订阅配置
+ */
+@Slf4j
+@Data
+public class AliIotSubscribeClient {
+
+    private final AliIotConfigPojo config;
+    private final String subScribeName;
+    public AliIotSubscribeClient(String subScribeName,AliIotConfigPojo config) {
+        this.config=config;
+        this.subScribeName=subScribeName;
+    }
+
+    @Getter
+    private Connection connection = null;
+
+    @Async
+    public void start(MessageListener messageListener) throws Exception {
+        String host=config.getAliyunUid()+".iot-amqp."+ config.getRegionId() +".aliyuncs.com";
+        String macAddress= NetUtil.getMacAddress(InetAddress.getLocalHost());
+        if(StrUtil.isBlank(macAddress)){
+            macAddress= UUID.fastUUID().toString();
+        }
+        //参数说明,请参见AMQP客户端接入说明文档。
+        long timeStamp = System.currentTimeMillis();
+        //签名方法:支持hmacmd5、hmacsha1和hmacsha256。
+        String signMethod = "hmacsha1";
+
+        //userName组装方法,请参见AMQP客户端接入说明文档。
+        String userName = macAddress + "-1|authMode=aksign"
+                + ",signMethod=" + signMethod
+                + ",timestamp=" + timeStamp
+                + ",authId=" + config.getAccessKey()
+                + ",iotInstanceId=" + config.getIotInstanceId()
+                + ",consumerGroupId=" + config.getConsumerGroupId()
+                + "|";
+        //计算签名,password组装方法,请参见AMQP客户端接入说明文档。
+        String signContent = "authId=" + config.getAccessKey() + "&timestamp=" + timeStamp;
+        String password = doSign(signContent, config.getAccessSecret(), signMethod);
+        String connectionUrl = "failover:(amqps://" + host + ":5671?amqp.idleTimeout=80000)"
+                + "?failover.reconnectDelay=30";
+
+        Hashtable<String, String> hashtable = new Hashtable<>();
+        hashtable.put("connectionfactory.SBCF", connectionUrl);
+        hashtable.put("queue.QUEUE", "default");
+        hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
+        Context context = new InitialContext(hashtable);
+        ConnectionFactory cf = (ConnectionFactory)context.lookup("SBCF");
+        Destination queue = (Destination)context.lookup("QUEUE");
+        // 创建连接。
+        connection = cf.createConnection(userName, password);
+
+        ((JmsConnection)connection).addConnectionListener(myJmsConnectionListener);
+        // 创建会话。
+        // Session.CLIENT_ACKNOWLEDGE: 收到消息后,需要手动调用message.acknowledge()。
+        // Session.AUTO_ACKNOWLEDGE: SDK自动ACK(推荐)。
+        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+        connection.start();
+        // 创建Receiver连接。
+        MessageConsumer consumer = session.createConsumer(queue);
+        consumer.setMessageListener(messageListener);
+    }
+
+
+    private JmsConnectionListener myJmsConnectionListener = new JmsConnectionListener() {
+        /**
+         * 连接成功建立。
+         */
+        @Override
+        public void onConnectionEstablished(URI remoteURI) {
+            log.info("{},连接成功, remoteUri:{}",subScribeName, remoteURI);
+        }
+        /**
+         * 尝试过最大重试次数之后,最终连接失败。
+         */
+        @Override
+        public void onConnectionFailure(Throwable error) {
+            log.error("{},连接失败, {}", subScribeName,error.getMessage());
+        }
+        /**
+         * 连接中断。
+         */
+        @Override
+        public void onConnectionInterrupted(URI remoteURI) {
+            log.info("{},连接中断, remoteUri:{}",subScribeName, remoteURI);
+        }
+        /**
+         * 连接中断后又自动重连上。
+         */
+        @Override
+        public void onConnectionRestored(URI remoteURI) {
+            log.info("{},自动重连, remoteUri:{}",subScribeName, remoteURI);
+        }
+        @Override
+        public void onInboundMessage(JmsInboundMessageDispatch envelope) {}
+        @Override
+        public void onSessionClosed(Session session, Throwable cause) {}
+        @Override
+        public void onConsumerClosed(MessageConsumer consumer, Throwable cause) {}
+        @Override
+        public void onProducerClosed(MessageProducer producer, Throwable cause) {}
+    };
+
+    /**
+     * 计算签名,password组装方法,请参见AMQP客户端接入说明文档。
+     */
+    private static String doSign(String toSignString, String secret, String signMethod) throws Exception {
+        SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), signMethod);
+        Mac mac = Mac.getInstance(signMethod);
+        mac.init(signingKey);
+        byte[] rawHmac = mac.doFinal(toSignString.getBytes());
+        return Base64.encodeBase64String(rawHmac);
+    }
+
+
+
+}

+ 218 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/consumer/NBAndFourGConsumerGroupService.java

@@ -0,0 +1,218 @@
+package com.nb.aliyun.service.consumer;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.extra.spring.SpringUtil;
+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.aliyun.service.pojo.AliIotConsumerPojo;
+import com.nb.web.api.bean.AliIotConfig;
+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 lombok.extern.slf4j.Slf4j;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 4G和Nb型网络泵消费者处理组
+ *
+ *
+ * @Author 龙三郎
+ * @Date 2022-4-06 16:22:13
+ * @Version 1.0
+ * @Description 阿里云物联网平台服务端订阅
+ *
+ *
+ * @Author 李放
+ * @Date 2024-02-18 16:22:13
+ * @Version 2.0
+ * @Description 改为多连接配置订阅
+ */
+@Slf4j
+public class NBAndFourGConsumerGroupService extends AbstractAliConsumer {
+    private static final String DEVICENAME = "deviceName";
+    private static final String TOPIC = "topic";
+    private static final String MESSAGEID = "messageId";
+    private static final String STATUS = "status";
+
+
+
+    private IDeviceClient deviceService;
+
+    private IIotMsgHandler iotMsgHandler;
+
+
+    private IHospitalLogClient hospitalLogService;
+
+    public NBAndFourGConsumerGroupService(AliIotSubscribeClient client,AliIotConsumerPojo consumer) {
+        super(client,consumer);
+        this.deviceService= SpringUtil.getBean(IDeviceClient.class);
+        this.iotMsgHandler= SpringUtil.getBean(IIotMsgHandler.class);
+        this.hospitalLogService= SpringUtil.getBean(IHospitalLogClient.class);
+    }
+
+
+    @Override
+    public void doSubscribe(){
+        try {
+            this.getClient().start(messageListener);
+            log.info("{},阿里云物联网订阅成功。",this.getConsumer().getName());
+        } catch (Exception e) {
+            log.error("{},阿里云物联网订阅失败,e:{}",this.getConsumer().getName(),e);
+        }
+    }
+
+
+
+    /**
+     * 描述:业务处理异步线程池,线程池参数可以根据您的业务特点调整,或者您也可以用其他异步方式处理接收到的消息。
+     */
+    private final static ExecutorService executorService = new ThreadPoolExecutor(
+            Runtime.getRuntime().availableProcessors(),
+            Runtime.getRuntime().availableProcessors() * 2, 60, TimeUnit.SECONDS,
+            new LinkedBlockingQueue(50000),
+            new AliYunThreadFactory());
+
+
+    static class AliYunThreadFactory implements ThreadFactory {
+        static final AtomicInteger poolNumber = new AtomicInteger(1);
+        final ThreadGroup group;
+        final AtomicInteger threadNumber = new AtomicInteger(1);
+        final String namePrefix;
+
+        AliYunThreadFactory() {
+            SecurityManager s = System.getSecurityManager();
+            group = (s != null)? s.getThreadGroup() :
+                    Thread.currentThread().getThreadGroup();
+            namePrefix = "ali-iot-" +
+                    poolNumber.getAndIncrement();
+        }
+        @Override
+        public Thread newThread(Runnable r) {
+            Thread t = new Thread(group, r,
+                    namePrefix + threadNumber.getAndIncrement(),
+                    0);
+            if (t.isDaemon()){
+                t.setDaemon(false);
+            }
+            if (t.getPriority() != Thread.NORM_PRIORITY){
+                t.setPriority(Thread.NORM_PRIORITY);
+            }
+            return t;
+        }
+    }
+
+    private MessageListener messageListener = (message) -> {
+        try {
+            //1.收到消息之后一定要ACK。
+            // 推荐做法:创建Session选择Session.AUTO_ACKNOWLEDGE,这里会自动ACK。
+            // 其他做法:创建Session选择Session.CLIENT_ACKNOWLEDGE,这里一定要调message.acknowledge()来ACK。
+            // message.acknowledge();
+            //2.建议异步处理收到的消息,确保onMessage函数里没有耗时逻辑。
+            // 如果业务处理耗时过程过长阻塞住线程,可能会影响SDK收到消息后的正常回调。
+            executorService.submit(()-> processMessage(message));
+        } catch (Exception e) {
+            log.error("{},submit task occurs exception ", this.getConsumer().getName(),e);
+        }
+    };
+
+    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("{},阿里云物联网发送的数据:{}",this.getConsumer().getName(),JSON.toJSONString(content));
+            // 设备名称
+            deviceName = content.getString(DEVICENAME);
+            hospitalLog.setIdentityCode(deviceName);
+            hospitalLog.setInput(content.toJSONString());
+            // 根据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"));
+                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);
+        } 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);
+        }
+    }
+
+
+}

+ 3 - 1
nb-service/iot-service/src/main/java/com/nb/aliyun/service/handler/DevicePropertyMsgHandler.java

@@ -41,7 +41,9 @@ public class DevicePropertyMsgHandler extends AbstractAliIotMsgHandler{
     protected void doHandle(String messageId, JSONObject content) {
         // 设备属性集合
         String deviceName = getDeviceName(content);
-        Items items = new Items(content.getJSONObject("items"));
+        com.alibaba.fastjson.JSONObject obj = new com.alibaba.fastjson.JSONObject();
+        obj.putAll(content.getJSONObject("items"));
+        Items items = new Items(obj);
         log.info("上传设备属性:【{}】", JSONUtil.toJsonStr(items));
         BusDeviceRunningEntity deviceRunning = new BusDeviceRunningEntity();
         deviceRunning.updateFieldsByItems(deviceName,items);

+ 24 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/pojo/AliIotConfigPojo.java

@@ -0,0 +1,24 @@
+package com.nb.aliyun.service.pojo;
+
+import lombok.Data;
+
+/**
+ * @ClassName : AliIotConfigPojo
+ * @Description :
+ * @Author : LF
+ * @Date: 2024年02月18日
+ */
+@Data
+public class AliIotConfigPojo {
+    private String accessKey;
+    private String accessSecret;
+    private String consumerGroupId;
+    private String aliyunUid;
+    private String regionId;
+    /**
+     *   iotInstanceId:企业版实例请填写实例ID,公共实例请填空字符串""。
+     */
+    private String iotInstanceId;
+
+    private String productKey;
+}

+ 27 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/pojo/AliIotConsumerPojo.java

@@ -0,0 +1,27 @@
+package com.nb.aliyun.service.pojo;
+
+
+import com.nb.aliyun.service.consumer.AbstractAliConsumer;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @ClassName : AliIotConsumerPojo
+ * @Description :
+ * @Author : LF
+ * @Date: 2024年02月18日
+ */
+@Data
+public class AliIotConsumerPojo {
+    @ApiModelProperty("是否启用")
+    private Boolean enable;
+
+    @ApiModelProperty("阿里云iot配置")
+    private AliIotConfigPojo config;
+
+    @ApiModelProperty("消息消费者处理器")
+    private Class<AbstractAliConsumer> consumer;
+
+    @ApiModelProperty("消费者名称")
+    private String name;
+}

+ 16 - 0
nb-service/iot-service/src/main/java/com/nb/aliyun/service/pojo/AliIotProperties.java

@@ -0,0 +1,16 @@
+package com.nb.aliyun.service.pojo;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import java.util.*;
+/**
+ * @ClassName : AliIotProperties
+ * @Description :
+ * @Author : LF
+ * @Date: 2024年02月18日
+ */
+@Data
+@ConfigurationProperties(prefix = "iot")
+public class AliIotProperties {
+    List<AliIotConsumerPojo> consumers;
+}

+ 0 - 16
nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/Constants.java

@@ -1,16 +0,0 @@
-package com.nb.aliyun.service.utils;
-
-/**
- * @Author 龙三郎
- * @Date 2022-04-26 13:44:36
- * @Version 1.0
- * @Description XXX
- */
-public class Constants {
-    // 默认医院
-    public static final String DefaultHospital = "1";
-    // 默认创建人
-    public static final String DefaultCreateBy = "1";
-    // 默认更新人
-    public static final String DefaultUpdateBy = "1";
-}

+ 0 - 48
nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/DeviceAlarmUtils.java

@@ -1,48 +0,0 @@
-package com.nb.aliyun.service.utils;
-
-import com.nb.web.api.enums.DeviceAlarmEnum;
-
-/**
- * @Author 龙三郎
- * @Date 2022-04-29 11:04:04
- * @Version 1.0
- * @Description 根据阿里云发送的报警标识,获取报警枚举对象。阿里云发送的报警是0-9的整数。
- */
-public class DeviceAlarmUtils {
-    public static DeviceAlarmEnum getAlarm(Integer i){
-        if (i == 0){
-            // 无报警
-            return DeviceAlarmEnum.None;
-        }else if (i == 1){
-            // 气泡无液报警
-            return DeviceAlarmEnum.Bubble;
-        }else if (i == 2){
-            // 堵塞
-            return DeviceAlarmEnum.Jam;
-        }else if (i == 3){
-            // 输入总量
-            return DeviceAlarmEnum.InfusionMax;
-        }else if (i == 4){
-            // 极限量
-            return DeviceAlarmEnum.Limit;
-        }else if (i == 5){
-            // 电量耗尽
-            return DeviceAlarmEnum.LowBattery;
-        }else if (i == 6){
-            // 输液结束
-            return DeviceAlarmEnum.Finished;
-//        }else if (i == 7){
-            // 电机失控
-//            return DeviceAlarmEnum.OutOfControl;
-        }else if (i == 8){
-            // 机械故障
-            return DeviceAlarmEnum.Machine;
-        }else if (i == 9){
-            // 未装药盒
-            return DeviceAlarmEnum.NotBox;
-        }else {
-
-            return DeviceAlarmEnum.Finished;
-        }
-    }
-}

+ 0 - 32
nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/DeviceRunStatusUtils.java

@@ -1,32 +0,0 @@
-package com.nb.aliyun.service.utils;
-
-import com.nb.web.api.enums.DeviceStatusEnum;
-
-/**
- * @Author 龙三郎
- * @Date 2022-04-29 11:36:03
- * @Version 1.0
- * @Description 根据阿里云发送的运行标识,获取运行枚举对象。阿里云发送的运行是0-4的整数。
- */
-public class DeviceRunStatusUtils {
-    public static DeviceStatusEnum getRunStatus(Integer i){
-        if (i == 0){
-            // 关机
-            return DeviceStatusEnum.Shutdown;
-        }else if (i == 1){
-            // 运行
-            return DeviceStatusEnum.StartUp;
-        }else if (i == 2){
-            // 运行
-            return DeviceStatusEnum.Running;
-        }else if (i == 3){
-            // 暂停
-            return DeviceStatusEnum.Pause;
-        }else if (i == 4){
-            // 待机
-            return DeviceStatusEnum.Waiting;
-        }else {
-            return DeviceStatusEnum.Shutdown;
-        }
-    }
-}

+ 0 - 25
nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/DeviceTypeUtils.java

@@ -1,25 +0,0 @@
-package com.nb.aliyun.service.utils;
-
-import com.nb.web.api.enums.DeviceTypeEnum;
-
-/**
- * @Author 龙三郎
- * @Date 2022-04-29 11:52:36
- * @Version 1.0
- * @Description XXX
- */
-public class DeviceTypeUtils {
-    public static DeviceTypeEnum getDeviceType(Integer i){
-        if (i == 0){
-            return DeviceTypeEnum.no;
-        }else if (i == 1){
-            return DeviceTypeEnum.continuous;
-        }else if (i == 2){
-            return DeviceTypeEnum.pulse;
-        }else if (i == 3){
-            return DeviceTypeEnum.intelligent;
-        }else {
-            return DeviceTypeEnum.other;
-        }
-    }
-}

+ 0 - 67
nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/PumpParams.java

@@ -1,67 +0,0 @@
-package com.nb.aliyun.service.utils;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * @Author 龙三郎
- * @Date 2022-04-26 10:37:47
- * @Version 1.0
- * @Description 设备上传的数据参数
- */
-@AllArgsConstructor
-public enum PumpParams {
-    protocolHeader("protocolHeader","协议头"),
-    dataLength("dataLength","数据长度"),
-    pumpType("pumpType","泵类型"),
-    classification("classification","分类标识"),
-    dataNumber("dataNumber","数据编号"),
-    patientCodeLength("patientCodeLength","住院号长度"),
-    patientCode("patientCode","住院号"),
-    ward("ward","病区"),
-    bedNo("bedNo","床号"),
-    totalDose("totalDose","总量"),
-    maxDose("maxDose","极限量"),
-    singleDosis("singleDose","追加量"),
-    lockTime("lockTime","锁时时间"),
-    flow("flow","持续量"),
-    finishedDose("finishedDose","已输入量"),
-    firstDosis("firstDose","首次量"),
-    pcaValid("pcaValid","PCA有效次数"),
-    pcaInvalid("pcaInvalid","PCA无效次数"),
-    electricQuantity("electricQuantity","电池电量"),
-    runStatus("runStatus","运行状态"),
-    alarmStatus("alarmStatus","报警"),
-    warnWillFinished("warnWillFinished","输液将结束预报"),
-    warnAnalgesicPoor("warnAnalgesicPoor","镇痛不足预报"),
-    warnLowBattery("warnLowBattery","电量偏低预报"),
-
-    // 脉冲泵属性
-    pulseLockTime("pulseLockTime","脉冲量锁时"),
-    firstLockTime("firstLockTime","首次锁时"),
-    pulseDose("pulseDose","脉冲量"),
-
-    // 智能泵属性
-    resetParams("resetParams","重设参数标志"),
-    warnFlow("warnFlow","加减档预报"),
-    flowDownTime("flowDownTime","减档时间"),
-    flowUpTime("flowUpTime","加档时间"),
-    flowUpPcaValid("flowUpPcaValid","触发加档pca有效次数"),
-    flowAdjuseRate("flowAdjuseRate","加减档百分比"),
-    minFlow("minFlow","减档下限"),
-    maxFlow("maxFlow","加档上限"),
-
-
-
-
-
-    CRC("CRC","CRC");
-
-
-
-    @Getter
-    private String param;
-    @Getter
-    private String info;
-
-}

+ 0 - 36
nb-service/iot-service/src/main/java/com/nb/aliyun/service/utils/WarnFlowUtils.java

@@ -1,36 +0,0 @@
-package com.nb.aliyun.service.utils;
-
-import com.nb.web.api.enums.FlowStatusEnum;
-
-/**
- * @Author 龙三郎
- * @Date 2022-04-29 11:04:04
- * @Version 1.0
- * @Description 根据阿里云发送的加减档预报。阿里云发送的报警是0-5的整数。
- */
-public class WarnFlowUtils {
-    public static FlowStatusEnum getAlarm(Integer i){
-        if (i == 0){
-            // 正常
-            return FlowStatusEnum.None;
-        }else if (i == 1){
-            // 加档受限
-            return FlowStatusEnum.Limited;
-        }else if (i == 2){
-            // 流速已达上限
-            return FlowStatusEnum.MaxFlow;
-        }else if (i == 3){
-            // 加档
-            return FlowStatusEnum.Up;
-        }else if (i == 4){
-            // 减档
-            return FlowStatusEnum.Down;
-        }else if (i == 5){
-            // 低输注状态
-            return FlowStatusEnum.Lowest;
-        }else {
-
-            return FlowStatusEnum.None;
-        }
-    }
-}

+ 0 - 134
nb-service/iot-service/src/main/java/com/nb/mq/entity/PcAnalgesicScoreEntity.java

@@ -1,134 +0,0 @@
-package com.nb.mq.entity;
-
-
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import java.time.LocalDateTime;
-import java.io.Serializable;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
-
-/**
- *
- * 
- * </p>
- *
- * @author fanfan
- * @since 2020-07-03
- */
-@Data
-@EqualsAndHashCode(callSuper = false)
-@Accessors(chain = true)
-@TableName("bus_analgesic_score")
-@ApiModel(value="BusAnalgesicScoreEntity对象", description="")
-public class PcAnalgesicScoreEntity implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @ApiModelProperty(value = "主键",hidden = true)
-    @TableId(value = "id", type = IdType.AUTO)
-    private Long id;
-
-    @ApiModelProperty(value = "病人ID")
-    public String patientId;
-
-    @ApiModelProperty(value = "泵号")
-    private String pumpCode;
-
-    @ApiModelProperty(value = "医院编码")
-    private String hospitalCode;
-
-    @ApiModelProperty(value = "住院号")
-    private String patientCode;
-
-    @ApiModelProperty(value = "疼痛评分静止")
-    private Integer statics;
-
-    @ApiModelProperty(value = "疼痛评分活动")
-    private Integer activity;
-
-    @ApiModelProperty(value = "镇静评分")
-    private Integer calm;
-
-    @ApiModelProperty(value = "左上肢")
-    private Integer leftArm;
-
-    @ApiModelProperty(value = "左下肢")
-    private Integer leftLeg;
-
-    @ApiModelProperty(value = "右上肢")
-    private Integer rightArm;
-
-    @ApiModelProperty(value = "右下肢")
-    private Integer rightLeg;
-
-    @ApiModelProperty(value = "恶心呕吐")
-    private Integer nauseaVomit;
-
-    @ApiModelProperty(value = "瘙痒")
-    private Integer itch;
-
-    @ApiModelProperty(value = "眩晕")
-    private Integer vertigo;
-
-    @ApiModelProperty(value = "咽喉疼痛")
-    private Integer soreThroat;
-
-    @ApiModelProperty(value = "尿潴留")
-    private Integer uroschesis;
-
-    @ApiModelProperty(value = "呼吸抑制")
-    private Integer breathDepression;
-
-    @ApiModelProperty(value = "声音嘶哑")
-    private Integer hoarseness;
-
-    @ApiModelProperty(value = "认知障碍")
-    private Integer cognitionObstacle;
-
-    @ApiModelProperty(value = "其他")
-    private String other;
-
-    @ApiModelProperty(value = "满意度")
-    private Integer satisfaction;
-
-    @ApiModelProperty(value = "创建时间",hidden = true)
-    private LocalDateTime gmtCreate;
-
-    @ApiModelProperty(value = "更新时间",hidden = true)
-    private LocalDateTime gmtModified;
-
-    @ApiModelProperty(value = "评价时间",hidden = true)
-    private LocalDateTime followDate;
-
-    @ApiModelProperty(value = "评价人")
-    private String creator;
-
-    @ApiModelProperty(value = "产品编码")
-    private String productCode;
-
-    @ApiModelProperty(value = "评价传输ID",hidden = true)
-    @TableField(exist = false)
-    private String analgesicScoreId;
-
-    @ApiModelProperty(value = "收缩压")
-    private String  SBP;
-
-
-    @ApiModelProperty(value = "舒张压")
-    private String  DBP;
-
-    @ApiModelProperty(value = "心率")
-    private String HR;
-
-    @ApiModelProperty(value = "呼吸频率")
-    private String RR;
-
-    @ApiModelProperty(value = "血氧饱和度")
-    private String SpO2;
-}

+ 0 - 107
nb-service/iot-service/src/main/java/com/nb/mq/entity/PcPatientEntity.java

@@ -1,107 +0,0 @@
-package com.nb.mq.entity;
-import java.time.LocalDateTime;
-import java.io.Serializable;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-/**
- * <p>
- * 
- * </p>
- *
- * @author fanfan
- * @since 2020-07-03
- */
-@Data
-public class PcPatientEntity implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @ApiModelProperty(value = "主键/病人id")
-    private String patientId;
-
-    @ApiModelProperty(value = "医院Id")
-    private String hospitalCode;
-
-    @ApiModelProperty(value = "产品编号")
-    private String productCode;
-
-    @ApiModelProperty(value = "住院号")
-    private String patientCode;
-
-    @ApiModelProperty(value = "泵号")
-    private String pumpCode;
-
-    @ApiModelProperty(value = "姓名")
-    private String name;
-
-    @ApiModelProperty(value = "性别")
-    private String sex;
-
-    @ApiModelProperty(value = "体重")
-    private String weight;
-
-    @ApiModelProperty(value = "身高")
-    private String height;
-
-    @ApiModelProperty(value = "年龄")
-    private Integer age;
-
-    @ApiModelProperty(value = "病区")
-    private String wardCode;
-
-    @ApiModelProperty(value = "床号")
-    private String bedCode;
-
-    @ApiModelProperty(value = "手术名称")
-    private String operationName;
-
-    @ApiModelProperty(value = "手术医生")
-    private String operationDoctor;
-
-    @ApiModelProperty(value = "ASA")
-    private String asa;
-
-    @ApiModelProperty(value = "镇痛方式")
-    private String easyMode;
-
-    @ApiModelProperty(value = "麻醉医生")
-    private String anesthesiaDoctor1;
-
-    @ApiModelProperty(value = "麻醉医生2")
-    private String anesthesiaDoctor2;
-
-    @ApiModelProperty(value = "麻醉方式")
-    private String anesthesiaMode;
-
-    @ApiModelProperty(value = "配置人员")
-    private String configPerson;
-
-    @ApiModelProperty(value = "配方")
-    private String formula;
-
-    @ApiModelProperty(value = "撤泵人")
-    private String undoPerson;
-
-    @ApiModelProperty(value = "销毁人")
-    private String destoryPerson;
-
-    @ApiModelProperty(value = "见证人")
-    private String witnessPerson;
-
-    @ApiModelProperty(value = "撤泵时间")
-    private LocalDateTime undoTime;
-
-    @ApiModelProperty(value = "盐值")
-    private String salt;
-
-    @ApiModelProperty(value = "剩余量处置")
-    private String remain;
-
-    @ApiModelProperty(value = "备注")
-    private String remark;
-
-    @ApiModelProperty(value = "是否删除")
-    private Boolean isDelete;
-
-    private String bmi;
-}

+ 0 - 173
nb-service/iot-service/src/main/java/com/nb/mq/entity/PcPumpEntity.java

@@ -1,173 +0,0 @@
-package com.nb.mq.entity;
-import java.math.BigDecimal;
-
-import java.time.LocalDateTime;
-import java.io.Serializable;
-import java.util.Date;
-import com.fasterxml.jackson.annotation.JsonSetter;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
-/**
- * <p>
- * 
- * </p>
- *
- * @author fanfan
- * @since 2020-07-03
- */
-@Data
-@EqualsAndHashCode(callSuper = false)
-@Accessors(chain = true)
-public class PcPumpEntity implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @ApiModelProperty(value = "主键")
-    private Long id;
-
-    @ApiModelProperty(value = "注液泵编码")
-    private String PumpCode;
-
-    @ApiModelProperty(value = "产品编码")
-    private String SysProduct_ID;
-
-    @ApiModelProperty(value = "医院编码")
-    private String SysHospital_ID;
-
-    @ApiModelProperty(value = "住院号")
-    private String PatientCode;
-
-    @ApiModelProperty(value = "剩余量")
-    private BigDecimal BalanceQuantity;
-
-    @ApiModelProperty(value = "持续量(智能泵当前流速)(脉冲泵KVO)")
-    private BigDecimal ContinueQuantity;
-
-    @ApiModelProperty(value = "自控量")
-    private BigDecimal SelfQuantity;
-
-    @ApiModelProperty(value = "锁定时间")
-    private Integer LockTime;
-
-    @ApiModelProperty(value = "已输入量")
-    private BigDecimal InputQuantity;
-
-    @ApiModelProperty(value = "有效次数")
-    private Integer TrueNum;
-
-    @ApiModelProperty(value = "无效次数")
-    private Integer FalseNum;
-
-    @ApiModelProperty(value = "极限量")
-    private BigDecimal MaxQuantity;
-
-    @ApiModelProperty(value = "首次量")
-    private Integer FirstQuantity;
-
-    @ApiModelProperty(value = "追加量")
-    private BigDecimal SingleQuantity;
-
-    @ApiModelProperty(value = "总量")
-    private Integer AllQuantity;
-
-    @ApiModelProperty(value = "总按次数")
-    private Integer AllCount;
-
-    @ApiModelProperty(value = "脉冲量")
-    private BigDecimal PulseQuantity;
-
-    @ApiModelProperty(value = "脉冲锁时")
-    private Integer PulseLockTime;
-
-    @ApiModelProperty(value = "首次量锁时")
-    private Integer FirstLockTime;
-
-    @ApiModelProperty(value = "上限")
-    private BigDecimal UpperLimit;
-
-    @ApiModelProperty(value = "下限")
-    private BigDecimal LowerLimit;
-
-    @ApiModelProperty(value = "自调比例")
-    private Integer CustomScate;
-
-    @ApiModelProperty(value = "加档有效次数")
-    private Integer AddTrueFrequency;
-
-    @ApiModelProperty(value = "镇痛泵运行状态")
-    private Integer RunState;
-
-    @ApiModelProperty(value = "镇痛泵状态BUF")
-    private Integer BUFState1;
-
-    @ApiModelProperty(value = "镇痛泵状态BUF")
-    private Integer BUFState2;
-
-    @ApiModelProperty(value = "镇痛泵状态BUF")
-    private Integer BUFState3;
-
-    @ApiModelProperty(value = "镇痛泵状态BUF")
-    @JsonSetter(value = "BUFState4")
-    private Integer BUFState4;
-
-    @ApiModelProperty(value = "镇痛泵状态BUF")
-    private Integer BUFState5;
-
-    @ApiModelProperty(value = "镇痛泵状态BUF")
-    private Integer BUFState6;
-
-    @ApiModelProperty(value = "镇痛泵状态BUF")
-    private Integer BUFState7;
-
-    @ApiModelProperty(value = "镇痛泵状态BUF")
-    private Integer BUFState8;
-
-    @ApiModelProperty(value = "镇痛泵状态BUF")
-    private Integer BUFState9;
-
-    @ApiModelProperty(value = "镇痛评分")
-    private Integer Score;
-
-    @ApiModelProperty(value = "加档周期")
-    private BigDecimal FilingCycle;
-
-    @ApiModelProperty(value = "减档周期")
-    private BigDecimal ReductionPeriod;
-
-    @ApiModelProperty(value = "呼叫标记")
-    private Integer CallFlag;
-
-    @ApiModelProperty(value = "开始时间")
-    private Date StartTime;
-
-    @ApiModelProperty(value = "是否可见")
-    private Boolean Visible;
-
-    @ApiModelProperty(value = "状态标记")
-    private Integer StateFlag;
-
-    @ApiModelProperty(value = "是否在服务区")
-    private Integer NoSignal;
-
-    @ApiModelProperty(value = "显示状态")
-    private String ViewState;
-
-    @ApiModelProperty(value = "备注")
-    private String Remark;
-
-    @ApiModelProperty(value = "最后上传时间")
-    private LocalDateTime LastUploadTime;
-
-    @ApiModelProperty(value = "创建时间",hidden = true)
-    private LocalDateTime gmtCreate;
-
-    @ApiModelProperty(value = "更新时间",hidden = true)
-    private LocalDateTime gmtModified;
-
-    @ApiModelProperty(value = "是否是家用")
-    private Boolean isFamily;
-
-
-}

+ 12 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/controller/BusDeviceController.java

@@ -1,12 +1,15 @@
 package com.nb.web.service.bus.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.annotation.SaIgnore;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.text.CharSequenceUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.core.mapper.Mapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nb.web.api.feign.query.AlarmQuery;
 import com.nb.web.service.bus.controller.vo.DeviceBindVo;
 import com.nb.web.api.entity.BusDeviceEntity;
 import com.nb.web.api.enums.DeviceAlarmEnum;
@@ -21,6 +24,7 @@ import com.nb.core.result.R;
 import io.swagger.annotations.*;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -183,4 +187,12 @@ public class BusDeviceController implements
             return R.fail("同步失败");
         }
     }
+
+
+    @PostMapping("/hospitalCode")
+    @SaIgnore
+    @ApiOperation(value = "根据设备id查询设备所在的医院编码")
+    public R<String> hospitalCode(@RequestBody String deviceId){
+        return R.success(deviceService.hospitalCode(deviceId));
+    }
 }

+ 3 - 1
nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/script/PythonParse.java

@@ -1,5 +1,7 @@
 package com.nb.web.service.bus.hospital.script;
 
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.file.PathUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.nb.core.exception.ExecuteResult;
@@ -28,7 +30,7 @@ public class PythonParse implements ScriptParse {
     public PythonParse() {
         Properties props = new Properties();
         props.setProperty("python.console.encoding", "UTF-8");
-        props.put("python.home", "jython-standalone-2.7.1.jar");
+        props.put("python.home","jython-standalone-2.7.1.jar");
         props.put("python.console.encoding", "UTF-8");
         props.put("python.security.respectJavaAccessibility", "false");
         props.put("python.import.site", "false");

+ 2 - 1
nb-service/web-service/src/main/java/com/nb/web/service/bus/listener/DeviceInfoListener.java

@@ -93,15 +93,16 @@ public class DeviceInfoListener implements IIotMsgHandler {
     public BusDeviceRunningEntity sync(BusDeviceRunningEntity device, String deviceId) {
         //保证统一设备数据顺序处理,若数据发送过快,为防止冲突,请在此加锁处理
         synchronized (deviceId){
-            log.info("接收到设备消息:{}",JSONUtil.toJsonStr(device));
             String classification = device.getClassification();
             if(StrUtil.isBlank(classification)){
                 log.error("消息【{}】,设备号:【{}】分包标识号为空,无法更新开始时间",device.getMsgId(),device.getDeviceId());
                 throw new RuntimeException("设备数据中分包标识不能为空");
             }
+            log.info("上传设备属性:【{}】",JSONUtil.toJsonStr(device));
             long startTime = System.currentTimeMillis();
             DeviceOperator deviceOperator = deviceRegistry.getOperator(deviceId);
             //对设备数据的一些参数进行初始化设置
+            deviceOperator.refreshHospitalCode(device.getHospitalCode());
             init(device);
 
             //缓存操作

+ 2 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/mapper/BusDeviceMapper.java

@@ -42,4 +42,6 @@ public interface BusDeviceMapper extends BaseMapper<BusDeviceEntity> {
     DeviceResult view(@Param("id") String id);
 
     List<BusDeviceEntity> ignoreLogicAll(@Param("ids") Set<String> pollDeviceIds);
+
+    String hospitalCode(@Param("deviceId") String deviceId);
 }

+ 2 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/registry/constant/DeviceKeyConstant.java

@@ -43,4 +43,6 @@ public class DeviceKeyConstant {
      * 当设备切换医院时,将设备的缓存输注标识更换
      */
     public static final String DEFAULT_CLASSIFY="-1";
+
+    public static final String HOSPITAL_CODE="hospital_code";
 }

+ 42 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/registry/device/ClusterDeviceOperator.java

@@ -2,20 +2,26 @@ package com.nb.web.service.bus.registry.device;
 
 
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.nb.web.api.entity.BusDeviceEntity;
 import com.nb.web.api.entity.BusInfusionHistoryEntity;
+import com.nb.web.service.bus.entity.BusHospitalEntity;
 import com.nb.web.service.bus.entity.BusInfusionModifyEntity;
 import com.nb.web.api.enums.DeviceTypeEnum;
 import com.nb.web.api.enums.FlowStatusEnum;
 import com.nb.web.service.bus.registry.constant.DeviceKeyConstant;
 import com.nb.web.service.bus.service.LocalBusDeviceService;
+import com.nb.web.service.bus.service.LocalBusHospitalService;
 import com.nb.web.service.bus.service.LocalBusInfusionHistoryService;
 import com.nb.core.Value;
 import com.nb.common.config.utils.RedissonUtil;
+import org.apache.batik.svggen.font.table.Device;
 import org.redisson.api.RMapCache;
 
 import java.math.BigDecimal;
+import java.util.Arrays;
 import java.util.Date;
 
 /**
@@ -31,6 +37,7 @@ public class ClusterDeviceOperator implements DeviceOperator {
     private final RMapCache<String, Value> mapCache;
     private final LocalBusDeviceService deviceService;
     private final LocalBusInfusionHistoryService infusionHistoryService;
+    private final LocalBusHospitalService hospitalService;
 
     public ClusterDeviceOperator(String deviceId) {
         String key="device:"+deviceId;
@@ -38,6 +45,7 @@ public class ClusterDeviceOperator implements DeviceOperator {
         infusionHistoryService=SpringUtil.getBean(LocalBusInfusionHistoryService.class);
         this.deviceId=deviceId;
         mapCache = SpringUtil.getBean(RedissonUtil.class).getRedissonClient().getMapCache(key);
+        this.hospitalService=SpringUtil.getBean(LocalBusHospitalService.class);
     }
 
     @Override
@@ -99,6 +107,37 @@ public class ClusterDeviceOperator implements DeviceOperator {
         return value.asString();
     }
 
+    @Override
+    public void refreshHospitalCode(String hospitalCode) {
+        if(StrUtil.isBlank(hospitalCode)){
+            return;
+        }
+        Value value = getValue(DeviceKeyConstant.HOSPITAL_CODE);
+        boolean change=false;
+        //医院编码发生了改变
+        if(value==null ||!StrUtil.equals(hospitalCode,value.asString()) ){
+            change=true;
+            put(DeviceKeyConstant.HOSPITAL_CODE,wrapperValue(hospitalCode));
+        }
+
+        if(change){
+            BusHospitalEntity hospital = getHospital(hospitalCode);
+            if(hospital==null){
+                return;
+            }
+            BusDeviceEntity device = getDevice();
+            if(device==null||StrUtil.isBlank(device.getId())){
+                device=new BusDeviceEntity();
+                String deviceId = getDeviceId();
+                device.setDeviceId(deviceId);
+                device.setTenantId(hospital.getId());
+                deviceService.saveDevice(device);
+            }else {
+                deviceService.shift(Arrays.asList(this.getDeviceId()),hospital.getId(),device.getTenantId());
+            }
+        }
+    }
+
     @Override
     public void setInfusionTenantId(String tenantId) {
         put(DeviceKeyConstant.INFUSION_TENANT_ID,wrapperValue(tenantId) );
@@ -367,4 +406,7 @@ public class ClusterDeviceOperator implements DeviceOperator {
         return infusionHistoryService.lastInfusion(deviceId);
     }
 
+    private BusHospitalEntity getHospital(String hospitalCode){
+        return hospitalService.getOne(new LambdaQueryWrapper<BusHospitalEntity>().eq(BusHospitalEntity::getCode,hospitalCode));
+    }
 }

+ 5 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/registry/device/DeviceOperator.java

@@ -63,6 +63,11 @@ public interface DeviceOperator extends Operator {
      */
     String getTenantId();
 
+    /**
+     * 根据医院编码刷新医院id
+     * @param hospitalCode
+     */
+    void refreshHospitalCode(String hospitalCode);
 
 
     /**

+ 4 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusDeviceService.java

@@ -97,6 +97,10 @@ public class LocalBusDeviceService extends BaseService<BusDeviceMapper, BusDevic
 
     }
 
+    public String hospitalCode(String deviceId){
+        return baseMapper.hospitalCode(deviceId);
+    }
+
     @Override
     public void postUpdate(BusDeviceEntity entity) {
         DeviceOperator deviceOperator = deviceRegistry

+ 29 - 22
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusHospitalService.java

@@ -4,12 +4,12 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.nb.auth.utils.SecurityUtil;
-import com.nb.web.api.HospitalProperties;
 import com.nb.web.api.bean.GeoPoint;
 import com.nb.web.api.entity.BusHospitalConfigEntity;
 import com.nb.web.api.feign.IHospitalClient;
@@ -33,7 +33,6 @@ 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;
@@ -55,9 +54,6 @@ import java.util.stream.Collectors;
  */
 @Service
 public class LocalBusHospitalService extends BaseService<BusHospitalMapper, BusHospitalEntity,String> implements CommandLineRunner, GetNameInterface<String,String>, HospitalCodeCheck, IHospitalClient {
-    @Autowired
-    private HospitalProperties hospitalProperties;
-
     @Autowired
     @Lazy
     private ConfigStorageManager configStorageManager;
@@ -98,9 +94,22 @@ public class LocalBusHospitalService extends BaseService<BusHospitalMapper, BusH
             entity.setStrategy(HisStrategyEnum.NONE);
         }
         entity.setScriptOnline(false);
-        if(StrUtil.isBlank(entity.getCode())){
-            entity.setCode(CodeUtils.genInviteCode(id));
+
+        String code="";
+        for (int i = 0; i < 10; i++) {
+            String tmpCode = CodeUtils.genInviteCode(id);
+            BusHospitalEntity hospital = baseMapper.selectOne(new LambdaQueryWrapper<BusHospitalEntity>().eq(BusHospitalEntity::getCode, tmpCode).last("limit 1"));
+            if(ObjectUtil.isNull(hospital)){
+                code=tmpCode;
+            }
+            if(StrUtil.isNotBlank(code)){
+                break;
+            }
+        }
+        if(StrUtil.isBlank(code)){
+            throw new CustomException("医院编码已用尽,请联系管理员");
         }
+        entity.setCode(code);
         entity.setId(String.valueOf(id));
     }
 
@@ -226,20 +235,19 @@ public class LocalBusHospitalService extends BaseService<BusHospitalMapper, BusH
 
 
     private void saveDefaultHospital(){
-//        BusHospitalEntity hospital = new BusHospitalEntity();
-//        hospital.setId("1");
-//        hospital.setName(StrUtil.isNotBlank(hospitalProperties.getName())?hospitalProperties.getName():"驼人医疗器械有限公司");
-//        hospital.setCode(hospitalProperties.getCode());
-//        hospital.setRemark("系统级医院,不可删除、修改");
-//        GeoPoint geoPoint = new GeoPoint();
-//        geoPoint.setLon("35.135106");
-//        geoPoint.setLat("114.658855");
-//        hospital.setCoordinate(geoPoint);
-//        try {
-//            this.save(hospital);
-//        }catch (Exception e){
-//
-//        }
+        BusHospitalEntity hospital = new BusHospitalEntity();
+        hospital.setId("1");
+        hospital.setName("驼人医疗器械有限公司");
+        hospital.setRemark("系统级医院,不可删除、修改");
+        GeoPoint geoPoint = new GeoPoint();
+        geoPoint.setLon("35.135106");
+        geoPoint.setLat("114.658855");
+        hospital.setCoordinate(geoPoint);
+        try {
+            this.save(hospital);
+        }catch (Exception e){
+
+        }
     }
 
 
@@ -297,7 +305,6 @@ public class LocalBusHospitalService extends BaseService<BusHospitalMapper, BusH
     }
 
     @Override
-    @Cacheable(value = "tenantId",key = "#tenantId")
     public HospitalResult findById(String tenantId) {
         return BeanUtil.copyProperties(getById(tenantId),HospitalResult.class);
     }

+ 14 - 12
nb-service/web-service/src/main/java/com/nb/web/service/bus/utils/CodeUtils.java

@@ -1,6 +1,8 @@
 package com.nb.web.service.bus.utils;
 
 
+import cn.hutool.core.util.RandomUtil;
+
 import java.util.*;
 /**
  * @author lifang
@@ -56,17 +58,17 @@ public class CodeUtils {
 
 
     public static String genInviteCode(long id) {
-        int key = (int) (id % 36);
-        char[] cs = new char[4];
-        cs[0] = INDEX.charAt(key);
-        String select = baseList.get(key);
-        id=id/36;
-        long code = 1_0000_0000 + id * 13;
-        for (int i = 1; i < cs.length; i++) {
-            cs[i] = select.charAt((int) (code % 36));
-            code = code / 36;
-        }
-        return new String(cs);
+//        int key = (int) (id % 36);
+//        char[] cs = new char[4];
+//        cs[0] = INDEX.charAt(key);
+//        String select = baseList.get(key);
+//        id=id/36;
+//        long code = 1_0000_0000 + id * 13;
+//        for (int i = 1; i < cs.length; i++) {
+//            cs[i] = select.charAt((int) (code % 36));
+//            code = code / 36;
+//        }
+//        return new String(cs);
+        return String.valueOf(RandomUtil.randomInt(1000, 9999));
     }
-
 }

+ 4 - 0
nb-service/web-service/src/main/resources/mapper/bus/BusDeviceMapper.xml

@@ -125,4 +125,8 @@
             </if>
         </where>
     </select>
+
+    <select id="hospitalCode" resultType="java.lang.String">
+        select  bh.code from  bus_device as bd join bus_hospital as bh on bd.tenant_id = bh.tenant_id  where bd.device_id = #{deviceId}
+    </select>
 </mapper>

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.