Bläddra i källkod

fix 优化租户逻辑
add 病患设备重复报警

18339543638 3 år sedan
förälder
incheckning
2ced72f124
35 ändrade filer med 435 tillägg och 100 borttagningar
  1. 1 0
      coffee-admin/src/main/java/com/coffee/admin/AdminApplication.java
  2. 1 0
      coffee-admin/src/main/resources/application.yml
  3. 31 0
      coffee-admin/src/test/java/com/coffee/admin/BusPatientTest.java
  4. 3 4
      coffee-common/src/main/java/com/coffee/common/bo/LoginUser.java
  5. 18 17
      coffee-common/src/main/java/com/coffee/common/cache/ClusterConfigStorage.java
  6. 7 5
      coffee-common/src/main/java/com/coffee/common/cache/manager/ClusterConfigStorageManager.java
  7. 13 1
      coffee-framework/src/main/java/com/coffee/framework/config/SwaggerConfig.java
  8. 12 1
      coffee-framework/src/main/java/com/coffee/framework/config/WebAppMvcConfig.java
  9. 19 12
      coffee-framework/src/main/java/com/coffee/framework/config/mybatisplus/MybatisPlusConfig.java
  10. 4 7
      coffee-framework/src/main/java/com/coffee/framework/config/mybatisplus/TenantIdManager.java
  11. 3 0
      coffee-system/src/main/java/com/coffee/bus/controller/BusDeviceRunningController.java
  12. 14 4
      coffee-system/src/main/java/com/coffee/bus/controller/BusPatientController.java
  13. 51 0
      coffee-system/src/main/java/com/coffee/bus/entity/PatientDeviceRepeatDomain.java
  14. 35 0
      coffee-system/src/main/java/com/coffee/bus/handler/TenantIdHandler.java
  15. 10 0
      coffee-system/src/main/java/com/coffee/bus/mapper/BusPatientMapper.java
  16. 3 1
      coffee-system/src/main/java/com/coffee/bus/registry/Operator.java
  17. 39 40
      coffee-system/src/main/java/com/coffee/bus/registry/patient/ClusterPatientOperator.java
  18. 37 5
      coffee-system/src/main/java/com/coffee/bus/service/LocalBusPatientService.java
  19. 67 0
      coffee-system/src/main/java/com/coffee/bus/service/dto/PatientDeviceRepeatResult.java
  20. 25 3
      coffee-system/src/main/java/com/coffee/bus/websocket/listener/DeviceInfoListener.java
  21. 42 0
      coffee-system/src/main/resources/mapper/bus/BusPatientMapper.xml
  22. 0 0
      coffee-system/src/main/resources/mapper/sys/SysAreaMapper.xml
  23. 0 0
      coffee-system/src/main/resources/mapper/sys/SysConfigMapper.xml
  24. 0 0
      coffee-system/src/main/resources/mapper/sys/SysDeptMapper.xml
  25. 0 0
      coffee-system/src/main/resources/mapper/sys/SysDictItemMapper.xml
  26. 0 0
      coffee-system/src/main/resources/mapper/sys/SysDictMapper.xml
  27. 0 0
      coffee-system/src/main/resources/mapper/sys/SysLogMapper.xml
  28. 0 0
      coffee-system/src/main/resources/mapper/sys/SysMenuMapper.xml
  29. 0 0
      coffee-system/src/main/resources/mapper/sys/SysPostMapper.xml
  30. 0 0
      coffee-system/src/main/resources/mapper/sys/SysRoleDeptMapper.xml
  31. 0 0
      coffee-system/src/main/resources/mapper/sys/SysRoleMapper.xml
  32. 0 0
      coffee-system/src/main/resources/mapper/sys/SysRoleMenuMapper.xml
  33. 0 0
      coffee-system/src/main/resources/mapper/sys/SysUserMapper.xml
  34. 0 0
      coffee-system/src/main/resources/mapper/sys/SysUserPostMapper.xml
  35. 0 0
      coffee-system/src/main/resources/mapper/sys/SysUserRoleMapper.xml

+ 1 - 0
coffee-admin/src/main/java/com/coffee/admin/AdminApplication.java

@@ -4,6 +4,7 @@ import com.coffee.common.config.AppConfig;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.web.servlet.ServletComponentScan;
 import org.springframework.context.annotation.Import;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;

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

@@ -66,6 +66,7 @@ mybatis-plus:
   configuration:
     log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
     default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
+  type-aliases-package: com.coffee.bus.entity
 
 # 阿里云对接配置
 aliyun:

+ 31 - 0
coffee-admin/src/test/java/com/coffee/admin/BusPatientTest.java

@@ -0,0 +1,31 @@
+package com.coffee.admin;
+
+import com.coffee.bus.service.LocalBusPatientService;
+import com.coffee.bus.service.dto.PatientDeviceRepeatResult;
+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.List;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName BusPatientTest.java
+ * @Description TODO
+ * @createTime 2022年04月19日 15:08:00
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = AdminApplication.class)
+public class BusPatientTest {
+    @Autowired
+    private LocalBusPatientService patientService;
+
+    @Test
+    public  void test(){
+        List<PatientDeviceRepeatResult> patientDeviceRepeatResults = patientService.repeatDevice("1505808170691784706");
+        System.out.println(patientDeviceRepeatResults);
+    }
+}

+ 3 - 4
coffee-common/src/main/java/com/coffee/common/bo/LoginUser.java

@@ -74,11 +74,10 @@ public class LoginUser implements Serializable {
      */
     private Set<String> permissions;
 
-    /**
-     * (医院)租户id
-     **/
-    private String tenantId;
 
+    public String getTenantId(){
+        return sysUser.getTenantId();
+    }
     /**
      * 是否为系统级别用户
      *

+ 18 - 17
coffee-common/src/main/java/com/coffee/common/cache/ClusterConfigStorage.java

@@ -1,23 +1,24 @@
 package com.coffee.common.cache;
 
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
 import com.coffee.common.cache.value.Value;
 import org.springframework.cache.Cache;
 import org.springframework.cache.CacheManager;
+import org.springframework.data.redis.core.BoundHashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.util.CollectionUtils;
+
+import java.time.Duration;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 public class ClusterConfigStorage implements ConfigStorage {
-    private final Cache cache;
-
-    public ClusterConfigStorage(CacheManager cacheManager,String name){
-        cache=cacheManager.getCache(name);
-    }
-
-    public Cache getCache() {
-        return cache;
+    private  BoundHashOperations boundHashOperations;
+    public ClusterConfigStorage(RedisTemplate redisTemplate,String name){
+        boundHashOperations = redisTemplate.opsForSet().getOperations().boundHashOps(name);
     }
 
     @Override
@@ -25,7 +26,7 @@ public class ClusterConfigStorage implements ConfigStorage {
         if (StrUtil.isEmpty(key)) {
             return null;
         }
-        return Value.simple(cache.get(key));
+        return Value.simple(boundHashOperations.get(key));
     }
 
     @Override
@@ -33,7 +34,7 @@ public class ClusterConfigStorage implements ConfigStorage {
         if (CollectionUtils.isEmpty(values)) {
             return true;
         }
-        values.forEach(cache::put);
+        boundHashOperations.putAll(values);
         return true;
     }
 
@@ -43,35 +44,35 @@ public class ClusterConfigStorage implements ConfigStorage {
             return true;
         }
         if(value==null){
-            cache.evict(key);
+            boundHashOperations.delete(key);
         }else {
-            cache.put(key, value);
+            boundHashOperations.put(key,value);
         }
         return true;
     }
 
     @Override
     public Value getAndRemove(String key) {
-        Value value = Value.simple(cache.get(key));
-        cache.evict(key);
+        Value value = Value.simple(boundHashOperations.get(key));
+        boundHashOperations.delete(key);
         return value;
     }
 
     @Override
     public Boolean remove(String key) {
-        cache.evict(key);
+        boundHashOperations.delete(key);
         return true;
     }
 
     @Override
     public Boolean remove(Collection<String> key) {
-        key.forEach(cache::evict);
+        boundHashOperations.delete(key);
         return true;
     }
 
     @Override
     public Boolean clear() {
-        cache.invalidate();
+        boundHashOperations.delete(boundHashOperations.keys());
         return true;
     }
 

+ 7 - 5
coffee-common/src/main/java/com/coffee/common/cache/manager/ClusterConfigStorageManager.java

@@ -3,6 +3,7 @@ package com.coffee.common.cache.manager;
 import com.coffee.common.cache.ClusterConfigStorage;
 import com.coffee.common.cache.ConfigStorage;
 import org.springframework.cache.CacheManager;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 
 import java.util.Map;
@@ -18,18 +19,19 @@ import java.util.concurrent.ConcurrentHashMap;
 
 @Component
 public class ClusterConfigStorageManager implements ConfigStorageManager {
-    private final CacheManager cacheManager;
+    private final RedisTemplate redisTemplate;
 
 
-    public ClusterConfigStorageManager(CacheManager cacheManager) {
-        this.cacheManager = cacheManager;
-    }
 
     private Map<String,ClusterConfigStorage > storageMap=new ConcurrentHashMap<>();
 
+    public ClusterConfigStorageManager(RedisTemplate redisTemplate) {
+        this.redisTemplate = redisTemplate;
+    }
+
     @Override
     public ConfigStorage getStorage(String id) {
-        return  storageMap.computeIfAbsent(id, __ -> new ClusterConfigStorage(cacheManager,id));
+        return  storageMap.computeIfAbsent(id, __ -> new ClusterConfigStorage(redisTemplate,id));
     }
 
 }

+ 13 - 1
coffee-framework/src/main/java/com/coffee/framework/config/SwaggerConfig.java

@@ -9,8 +9,10 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.ParameterBuilder;
 import springfox.documentation.builders.PathSelectors;
 import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
 import springfox.documentation.service.*;
 import springfox.documentation.spi.DocumentationType;
 import springfox.documentation.spi.service.contexts.SecurityContext;
@@ -69,6 +71,13 @@ public class SwaggerConfig implements WebMvcConfigurer {
 
     @Bean
     public Docket admin(){
+        ParameterBuilder ticketPar = new ParameterBuilder();
+        List<Parameter> pars = new ArrayList<Parameter>();
+        ticketPar.name("tenantId").description("租户id")
+                .modelRef(new ModelRef("string")).parameterType("query")
+                .required(true).build();
+        pars.add(ticketPar.build());
+
         return new Docket(DocumentationType.SWAGGER_2)
                 .select()
                 .apis(RequestHandlerSelectors.basePackage("com.coffee.admin.controller"))
@@ -76,13 +85,15 @@ public class SwaggerConfig implements WebMvcConfigurer {
                 .build()
                 .groupName("登录模块")
                 .apiInfo(apiInfo())
+                .globalOperationParameters(pars)
                 .securitySchemes(security())
                 .securityContexts(securityContexts())
                 .enable(true);
     }
 
     private List<SecurityScheme> security() {
-        return Arrays.asList(new ApiKey("BASE_TOKEN", "Authorization",   In.HEADER.toValue()));
+        return Arrays.asList(new ApiKey("BASE_TOKEN", "Authorization",   In.HEADER.toValue()),
+                new ApiKey("租户id", "Tenant-Id",   In.HEADER.toValue()));
     }
 
     /**
@@ -109,4 +120,5 @@ public class SwaggerConfig implements WebMvcConfigurer {
         registry.addViewController( "/swagger-ui/")
                 .setViewName("forward:" +  "/swagger-ui/index.html");
     }
+
 }

+ 12 - 1
coffee-framework/src/main/java/com/coffee/framework/config/WebAppMvcConfig.java

@@ -5,10 +5,13 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.module.SimpleModule;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Profile;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
@@ -24,6 +27,8 @@ import java.util.*;
 @Configuration
 //@Profile("dev")
 public class WebAppMvcConfig implements WebMvcConfigurer {
+    @Autowired
+    private HandlerInterceptor interceptors;
     @Override
     public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
         MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
@@ -65,5 +70,11 @@ public class WebAppMvcConfig implements WebMvcConfigurer {
         registry.addResourceHandler("/webjars/**")
                 .addResourceLocations("classpath:/META-INF/resources/webjars/");
     }
- 
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(interceptors);
+    }
+
+
 }

+ 19 - 12
coffee-framework/src/main/java/com/coffee/framework/config/mybatisplus/MybatisPlusConfig.java

@@ -19,6 +19,7 @@ import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerIntercept
 import com.coffee.common.Constants;
 import com.coffee.common.bo.LoginUser;
 import com.coffee.common.entity.TenantGenericEntity;
+import com.coffee.common.util.SecurityUtil;
 import com.coffee.framework.config.mybatisplus.handler.CreateAndUpdateMetaObjectHandler;
 import com.coffee.framework.config.mybatisplus.handler.CustomDataPermissionHandler;
 import net.sf.jsqlparser.expression.Expression;
@@ -34,6 +35,8 @@ import org.springframework.web.context.request.ServletRequestAttributes;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import static org.springframework.web.context.request.RequestAttributes.SCOPE_REQUEST;
+
 /**
  * mybatis-plus配置类
  *
@@ -131,11 +134,6 @@ public class MybatisPlusConfig {
                 return new StringValue(tenantIdManager.getCurrentTenantId());
             }
 
-            @Override
-            public String getTenantIdColumn() {
-                return "tenant_id";
-            }
-
             @Override
             public boolean ignoreTable(String tableName) {
                 ServletRequestAttributes request = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
@@ -147,13 +145,22 @@ public class MybatisPlusConfig {
                 if(url.toString().endsWith("/login")){
                     return true;
                 }
-                return true;
-                //判断当前有用户是否为系统级用户,若是,则忽略逻辑隔离
-//                LoginUser loginUser = (LoginUser) StpUtil.getTokenSession().get(Constants.LOGIN_USER_KEY);
-//                if(1==loginUser.getIsSys()){
-//                    return true;
-//                }
-//                return CollectionUtil.isEmpty(ignoreTableName)||ignoreTableName.contains(tableName);
+                if(CollectionUtil.isNotEmpty(ignoreTableName)&&ignoreTableName.contains(tableName)){
+                    return true;
+                }
+                // 判断当前有用户是否为系统级用户,若是,则忽略逻辑隔离
+                LoginUser loginUser = SecurityUtil.getLoginUser();
+                if(loginUser==null){
+                    //未登录
+                    return false;
+                }
+                if(Boolean.TRUE.equals(loginUser.getIsSys())){
+                    String tenantId = String.valueOf( request.getAttribute("tenantId", SCOPE_REQUEST));
+                    if(StrUtil.isNullOrUndefined(tenantId)){
+                        return true;
+                    }
+                }
+                return false;
             }
 
             @Override

+ 4 - 7
coffee-framework/src/main/java/com/coffee/framework/config/mybatisplus/TenantIdManager.java

@@ -1,13 +1,11 @@
 package com.coffee.framework.config.mybatisplus;
 
-import cn.dev33.satoken.stp.StpUtil;
-import com.coffee.common.Constants;
-import com.coffee.common.bo.LoginUser;
+import cn.hutool.core.util.StrUtil;
 import org.springframework.stereotype.Component;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
-import java.util.Optional;
+import static org.springframework.web.context.request.RequestAttributes.SCOPE_REQUEST;
 
 /**
  * 管理当前用户的租户ID
@@ -28,9 +26,8 @@ public class TenantIdManager {
         if(url.toString().endsWith("/login")){
             return "";
         }
-//        return "";
-        LoginUser loginUser = (LoginUser) StpUtil.getTokenSession().get(Constants.LOGIN_USER_KEY);
-        return Optional.ofNullable(loginUser.getSysUser().getTenantId()).orElse("");
+        String tenantId = String.valueOf( request.getAttribute("tenantId", SCOPE_REQUEST));
+        return StrUtil.isNullOrUndefined(tenantId)?"":tenantId;
     }
 
 }

+ 3 - 0
coffee-system/src/main/java/com/coffee/bus/controller/BusDeviceRunningController.java

@@ -87,6 +87,9 @@ public class BusDeviceRunningController implements BaseQueryController<BusDevice
         return R.success();
     }
 
+
+
+
     /**
      * 权限控制前缀
      * @return

+ 14 - 4
coffee-system/src/main/java/com/coffee/bus/controller/BusPatientController.java

@@ -1,20 +1,25 @@
 package com.coffee.bus.controller;
 
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.mapper.Mapper;
 import com.coffee.bus.entity.BusPatientEntity;
 import com.coffee.bus.service.LocalBusPatientService;
+import com.coffee.bus.service.dto.DeviceShiftConfig;
+import com.coffee.bus.service.dto.PatientDeviceRepeatResult;
+import com.coffee.common.bo.LoginUser;
 import com.coffee.common.crud.BaseService;
 import com.coffee.common.crud.controller.BaseCrudController;
 import com.coffee.common.result.R;
+import com.coffee.common.util.SecurityUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import org.springframework.web.context.request.async.DeferredResult;
 
+import java.util.List;
+
 /**
  * @author lifang
  * @version 1.0.0
@@ -30,6 +35,11 @@ public class BusPatientController extends BaseCrudController<BusPatientEntity, S
     private final LocalBusPatientService patientService;
 
 
+    @GetMapping("/repeat/device")
+    @ApiOperation(value = "获取当前医院绑定设备重复的所有病患信息",notes = "当出现病患统一时间绑定了多个泵时,调用该接口查询出所有设备重复报警数据【无】")
+    public R<List<PatientDeviceRepeatResult>> repeatDevice(@RequestParam(value = "tenantId",required = false)String tenantId){
+        return R.success(patientService.repeatDevice(tenantId));
+    }
     /**
      * 权限控制前缀
      * @return

+ 51 - 0
coffee-system/src/main/java/com/coffee/bus/entity/PatientDeviceRepeatDomain.java

@@ -0,0 +1,51 @@
+package com.coffee.bus.entity;
+
+import com.coffee.bus.enums.DeviceAlarmEnum;
+import com.coffee.bus.enums.DeviceEnum;
+import com.coffee.common.enums.SexEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName PatientDeviceRepeat.java
+ * @Description 病人设备重复绑定
+ * @createTime 2022年04月19日 14:29:00
+ */
+@ApiModel("病人临床设备重复报警详情")
+@Data
+public class PatientDeviceRepeatDomain {
+    @ApiModelProperty("病患名称")
+    private String name;
+    @ApiModelProperty("病患性别")
+    private SexEnum gender;
+    @ApiModelProperty("病号")
+    private String code;
+    @ApiModelProperty("病患年龄")
+    private Integer age;
+    @ApiModelProperty("病区")
+    private String ward;
+    @ApiModelProperty("病床")
+    private String bedNo;
+    @ApiModelProperty("手术名称")
+    private String clinicName;
+    @ApiModelProperty("设备运行Id")
+    private String deviceRunningId;
+    @ApiModelProperty("设备名称")
+    private String deviceId;
+    @ApiModelProperty("设备别名")
+    private String deviceAlias;
+    @ApiModelProperty("设备运行状态")
+    private DeviceEnum deviceRunState;
+    @ApiModelProperty("设备报警信息")
+    private DeviceAlarmEnum deviceAlarm;
+    @ApiModelProperty("输注开始时间")
+    private Date infusionStartTime;
+    @ApiModelProperty("是否为主泵")
+    private Boolean master;
+
+}

+ 35 - 0
coffee-system/src/main/java/com/coffee/bus/handler/TenantIdHandler.java

@@ -0,0 +1,35 @@
+package com.coffee.bus.handler;
+
+import com.coffee.common.bo.LoginUser;
+import com.coffee.common.util.SecurityUtil;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName TenantIdHandler.java
+ * @Description TODO
+ * @createTime 2022年04月19日 14:22:00
+ */
+@Component
+public class TenantIdHandler implements HandlerInterceptor {
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
+        LoginUser loginUser = SecurityUtil.getLoginUser();
+        String header = request.getHeader("Tenant-Id");
+        if(loginUser==null){
+            //未登录且未带 Tenant-Id 请求头
+            return true;
+        }
+        if(!Boolean.TRUE.equals(loginUser.getIsSys())){
+            request.setAttribute("tenantId",loginUser.getTenantId());
+        }else {
+            request.setAttribute("tenantId",header);
+        }
+        return true;
+    }
+}

+ 10 - 0
coffee-system/src/main/java/com/coffee/bus/mapper/BusPatientMapper.java

@@ -2,8 +2,11 @@ package com.coffee.bus.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.coffee.bus.entity.BusPatientEntity;
+import com.coffee.bus.entity.PatientDeviceRepeatDomain;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
+import java.util.*;
 /**
  * @author lifang
  * @version 1.0.0
@@ -13,4 +16,11 @@ import org.apache.ibatis.annotations.Mapper;
  */
 @Mapper
 public interface BusPatientMapper extends BaseMapper<BusPatientEntity> {
+
+    /**
+     * 查询给定医院下所有同时挂载多个泵的病患信息
+     * @param tenantId 医院id
+     * @return
+     */
+    List<PatientDeviceRepeatDomain> repeatDevice(@Param("tenantId") String tenantId);
 }

+ 3 - 1
coffee-system/src/main/java/com/coffee/bus/registry/Operator.java

@@ -22,6 +22,7 @@ public interface Operator<T> {
      * 获取所有缓存数据
      * @return
      */
+    @Deprecated
     T get();
 
     void set(T all);
@@ -60,6 +61,7 @@ public interface Operator<T> {
         if(value==null||value.get()==null){
             return value;
         }
-        return Value.simple(value.as(SimpleValueWrapper.class).get());
+//        return Value.simple(value.as(SimpleValueWrapper.class).get());
+        return value;
     }
 }

+ 39 - 40
coffee-system/src/main/java/com/coffee/bus/registry/patient/ClusterPatientOperator.java

@@ -6,7 +6,6 @@ import com.coffee.bus.registry.constant.PatientKeyConstant;
 import com.coffee.bus.registry.patient.bean.DeviceTimeSmallInfo;
 import com.coffee.bus.registry.patient.bean.PatientCacheInfo;
 import com.coffee.common.cache.ConfigStorage;
-import com.coffee.common.cache.value.Value;
 import com.coffee.common.enums.SexEnum;
 import lombok.AllArgsConstructor;
 
@@ -30,45 +29,45 @@ public class ClusterPatientOperator implements PatientOperator<PatientCacheInfo>
 
     @Override
     public PatientCacheInfo get() {
-        Map<String, Value> result = configStorage.getKeys(getAllKeys());
-        PatientCacheInfo cacheInfo = PatientCacheInfo.builder().build();
-        Value code =parseValue(result.get("code")) ;
-        if(code!=null&&code.get()!=null){
-            cacheInfo.setCode(code.asString());
-        }
-        Value gender =parseValue(result.get("gender"));
-        if(gender!=null&&gender.get()!=null){
-            cacheInfo.setGender(gender.as(SexEnum.class));
-        }
-        Value name =parseValue( result.get("name"));
-        if(name!=null&&name.get()!=null){
-            cacheInfo.setName(name.asString());
-        }
-        Value tenantId =parseValue(result.get("tenantId")) ;
-        if(tenantId!=null&&tenantId.get()!=null){
-            cacheInfo.setTenantId(tenantId.asString());
-        }
-        Value clinicId =parseValue(result.get("clinicId")) ;
-        if(clinicId!=null&&clinicId.get()!=null){
-            cacheInfo.setClinicId(clinicId.asString());
-        }
-        Value startTime = parseValue(result.get("startTime"));
-        if(startTime!=null&&startTime.get()!=null){
-            cacheInfo.setStartTime(startTime.asDate());
-        }
-        Value finished = parseValue(result.get("finished"));
-        if(finished!=null&&finished.get()!=null){
-            cacheInfo.setIsFinished(finished.asBoolean());
-        }
-        Value bindDeviceId =parseValue( result.get("bindDeviceId"));
-        if(bindDeviceId!=null&&bindDeviceId.get()!=null){
-            cacheInfo.setBindDeviceId(bindDeviceId.asString());
-        }
-        Value devices = parseValue(result.get("devices"));
-        if(devices!=null&&devices.get()!=null){
-            cacheInfo.setDevices(code.as(HashSet.class));
-        }
-        return cacheInfo;
+//        Map<String, Value> result = configStorage.getKeys(getAllKeys());
+//        PatientCacheInfo cacheInfo = PatientCacheInfo.builder().build();
+//        Value code =parseValue(result.get("code")) ;
+//        if(code!=null&&code.get()!=null){
+//            cacheInfo.setCode(code.asString());
+//        }
+//        Value gender =parseValue(result.get("gender"));
+//        if(gender!=null&&gender.get()!=null){
+//            cacheInfo.setGender(gender.as(SexEnum.class));
+//        }
+//        Value name =parseValue( result.get("name"));
+//        if(name!=null&&name.get()!=null){
+//            cacheInfo.setName(name.asString());
+//        }
+//        Value tenantId =parseValue(result.get("tenantId")) ;
+//        if(tenantId!=null&&tenantId.get()!=null){
+//            cacheInfo.setTenantId(tenantId.asString());
+//        }
+//        Value clinicId =parseValue(result.get("clinicId")) ;
+//        if(clinicId!=null&&clinicId.get()!=null){
+//            cacheInfo.setClinicId(clinicId.asString());
+//        }
+//        Value startTime = parseValue(result.get("startTime"));
+//        if(startTime!=null&&startTime.get()!=null){
+//            cacheInfo.setStartTime(startTime.asDate());
+//        }
+//        Value finished = parseValue(result.get("finished"));
+//        if(finished!=null&&finished.get()!=null){
+//            cacheInfo.setIsFinished(finished.asBoolean());
+//        }
+//        Value bindDeviceId =parseValue( result.get("bindDeviceId"));
+//        if(bindDeviceId!=null&&bindDeviceId.get()!=null){
+//            cacheInfo.setBindDeviceId(bindDeviceId.asString());
+//        }
+//        Value devices = parseValue(result.get("devices"));
+//        if(devices!=null&&devices.get()!=null){
+//            cacheInfo.setDevices(code.as(HashSet.class));
+//        }
+        return null;
     }
 
     @Override

+ 37 - 5
coffee-system/src/main/java/com/coffee/bus/service/LocalBusPatientService.java

@@ -1,18 +1,16 @@
 package com.coffee.bus.service;
 
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
-import com.coffee.bus.entity.BusDeviceRunningEntity;
 import com.coffee.bus.entity.BusPatientEntity;
+import com.coffee.bus.entity.PatientDeviceRepeatDomain;
 import com.coffee.bus.mapper.BusPatientMapper;
+import com.coffee.bus.service.dto.PatientDeviceRepeatResult;
 import com.coffee.common.crud.BaseService;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Date;
+import java.util.*;
 
 /**
  * @author lifang
@@ -51,4 +49,38 @@ public class LocalBusPatientService extends BaseService<BusPatientMapper, BusPat
     public void syncGetPatientInfoFromHis(String hospitalId,String patientCode){
 
     }
+
+    /**
+     * 获取给定医院下所有的挂载多个设备的病人信息
+     * @param tenantId 医院id
+     */
+    public List<PatientDeviceRepeatResult> repeatDevice(String tenantId) {
+        List<PatientDeviceRepeatDomain> patientDeviceRepeats = this.baseMapper.repeatDevice(tenantId);
+        Map<String, PatientDeviceRepeatResult> resultMap = new HashMap<>();
+        patientDeviceRepeats.forEach(deviceRepeat->{
+            PatientDeviceRepeatResult repeatResult = resultMap.computeIfAbsent(deviceRepeat.getCode(),k->
+                    PatientDeviceRepeatResult.of(
+                            deviceRepeat.getName(),
+                            deviceRepeat.getGender(),
+                            deviceRepeat.getCode(),
+                            deviceRepeat.getAge(),
+                            deviceRepeat.getWard(),
+                            deviceRepeat.getBedNo(),
+                            deviceRepeat.getClinicName(),
+                            new ArrayList<>())
+            );
+            List<PatientDeviceRepeatResult.DeviceRunningSmallInfo> deviceRunningSmallInfos = Optional.ofNullable(repeatResult.getDevices()).orElse(new ArrayList<>());
+            deviceRunningSmallInfos.add(PatientDeviceRepeatResult.DeviceRunningSmallInfo.of(
+                    deviceRepeat.getDeviceRunningId(),
+                    deviceRepeat.getDeviceId(),
+                    deviceRepeat.getDeviceAlias(),
+                    deviceRepeat.getDeviceRunState(),
+                    deviceRepeat.getDeviceAlarm(),
+                    deviceRepeat.getInfusionStartTime(),
+                    deviceRepeat.getMaster()
+            ));
+            repeatResult.setDevices(deviceRunningSmallInfos);
+        });
+        return new ArrayList<>(resultMap.values());
+    }
 }

+ 67 - 0
coffee-system/src/main/java/com/coffee/bus/service/dto/PatientDeviceRepeatResult.java

@@ -0,0 +1,67 @@
+package com.coffee.bus.service.dto;
+
+import com.coffee.bus.enums.DeviceAlarmEnum;
+import com.coffee.bus.enums.DeviceEnum;
+import com.coffee.common.enums.SexEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.*;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName PatientDeviceRepeatResult.java
+ * @Description 病人设备重复返回数据
+ * @createTime 2022年04月19日 14:53:00
+ */
+@Data
+@ApiModel("病人重复设备返回数据")
+@AllArgsConstructor(staticName = "of")
+public class PatientDeviceRepeatResult {
+    @ApiModelProperty("病患名称")
+    private String name;
+
+    @ApiModelProperty("病患性别")
+    private SexEnum gender;
+
+    @ApiModelProperty("病号")
+    private String code;
+
+    @ApiModelProperty("病患年龄")
+    private Integer age;
+
+    @ApiModelProperty("病区")
+    private String ward;
+
+    @ApiModelProperty("病床")
+    private String bedNo;
+
+    @ApiModelProperty("手术名称")
+    private String clinicName;
+
+    @ApiModelProperty("设备集合")
+    private List<DeviceRunningSmallInfo> devices;
+
+    @ApiModel("设备运行小数据集合")
+    @Data
+    @AllArgsConstructor(staticName = "of")
+    public static class DeviceRunningSmallInfo{
+        @ApiModelProperty("设备运行Id")
+        private String deviceRunningId;
+        @ApiModelProperty("设备名称")
+        private String deviceId;
+        @ApiModelProperty("设备别名")
+        private String deviceAlias;
+        @ApiModelProperty("设备运行状态")
+        private DeviceEnum deviceRunState;
+        @ApiModelProperty("设备报警信息")
+        private DeviceAlarmEnum deviceAlarm;
+        @ApiModelProperty("输注开始时间")
+        private Date infusionStartTime;
+        @ApiModelProperty("是否为主泵")
+        private Boolean master;
+    }
+}

+ 25 - 3
coffee-system/src/main/java/com/coffee/bus/websocket/listener/DeviceInfoListener.java

@@ -15,6 +15,7 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.coffee.bus.entity.*;
 import com.coffee.bus.enums.DeviceAlarmEnum;
 import com.coffee.bus.enums.DeviceEnum;
+import com.coffee.bus.enums.PatientAlarmEnum;
 import com.coffee.bus.listener.event.bean.HisEvent;
 import com.coffee.bus.registry.device.DeviceRegistry;
 import com.coffee.bus.listener.event.bean.DeviceInfoEvent;
@@ -71,6 +72,8 @@ public class DeviceInfoListener {
     public static final Sign sign = SignUtil.sign(SignAlgorithm.MD5withRSA);
 
     private final LocalBusDeviceHistoryService historyService;
+
+    private final LocalBusPatientService patientService;
     /**
      * 监听上传的数据信息,
      * 若设备详情发生变化,则及时通知相应的ws通道
@@ -209,8 +212,12 @@ public class DeviceInfoListener {
         if(!StrUtil.isNullOrUndefined(bindDeviceId)&&!deviceId.equals(bindDeviceId)){
             handleConflictCurrentPatient(device,suppliers);
         }else if(StrUtil.isNullOrUndefined(bindDeviceId)){
-            //之前的病号为无泵状态,无泵 -》 有泵 做处理  修改缓存信息
+            //当前的病号之前为无泵状态,无泵 -》 有泵 做处理  修改缓存信息
             log.error("病号:【{}】临床发生由无泵转为有泵",device.getPatientCode());
+            patientService.update(new UpdateWrapper<BusPatientEntity>().lambda().eq(BusPatientEntity::getCode,device.getPatientCode())
+                    .eq(BusPatientEntity::getTenantId,device.getTenantId())
+                    .set(BusPatientEntity::getAlarm, null)
+            );
         }
         //更新泵所绑定当前病人缓存信息
         suppliers.add(()->{
@@ -239,8 +246,11 @@ public class DeviceInfoListener {
         if(CollectionUtils.isNotEmpty(allDevice)){
             Set<DeviceTimeSmallInfo> remainPatientBindDevices = allDevice.stream().filter(bindDevice -> !bindDevice.getDeviceId().equals(deviceId)).collect(Collectors.toSet());
             if(CollectionUtil.isEmpty(remainPatientBindDevices)){
-
                 log.error("病号:【{}】临床发生无泵报警",patientCode);
+                patientService.update(new UpdateWrapper<BusPatientEntity>().lambda().eq(BusPatientEntity::getCode,patientCode)
+                        .eq(BusPatientEntity::getTenantId,hospitalId)
+                        .set(BusPatientEntity::getAlarm, PatientAlarmEnum.DEVICE_NONE)
+                );
                 suppliers.add(()->{
                     //todo 发起无泵报警,处理原先泵的无泵信息
                     patientOperator.setBindDeviceId(null);
@@ -265,6 +275,13 @@ public class DeviceInfoListener {
                         return null;
                     });
                 }
+                if(remainPatientBindDevices.size()==1){
+                    //泵重复—>正常
+                    patientService.update(new UpdateWrapper<BusPatientEntity>().lambda().eq(BusPatientEntity::getCode,patientCode)
+                            .eq(BusPatientEntity::getTenantId,hospitalId)
+                            .set(BusPatientEntity::getAlarm, null)
+                    );
+                }
             }
         }else {
             suppliers.add(()->{
@@ -283,7 +300,7 @@ public class DeviceInfoListener {
         PatientOperator<PatientCacheInfo> patientOperator = patientRegistry.getOperator(device.getTenantId(), device.getPatientCode());
         String bindDeviceId = patientOperator.getBindDeviceId();
         if(!StrUtil.isNullOrUndefined(bindDeviceId)&&!deviceId.equals(bindDeviceId)){
-            //泵号发生改变,获取病号绑定的泵信息,判断绑定的泵开始时间,将开始时间稍后的泵设置为主泵
+            //泵号发生改变,获取病号绑定的泵信息,判断绑定的泵开始时间,将开始时间稍后的泵设置为主泵 todo 发生病人绑定多个泵冲突
             DeviceOperator<DeviceCacheInfo> patientCurrentBindDevice = deviceRegistry.getOperator(bindDeviceId);
             Date startTime = patientCurrentBindDevice.getStartTime();
             if (startTime==null||startTime.before(device.getStartTime())) {
@@ -294,6 +311,11 @@ public class DeviceInfoListener {
             }else {
                 device.setMaster(false);
             }
+            log.error("病号:{}发生了泵重复",device.getPatientCode());
+            patientService.update(new UpdateWrapper<BusPatientEntity>().lambda()
+                    .eq(BusPatientEntity::getCode,device.getPatientCode())
+                    .eq(BusPatientEntity::getTenantId,device.getTenantId())
+                    .set(BusPatientEntity::getAlarm,PatientAlarmEnum.DEVICE_REPEAT));
         }
     }
 

+ 42 - 0
coffee-system/src/main/resources/mapper/bus/BusPatientMapper.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.coffee.bus.mapper.BusPatientMapper">
+
+    <resultMap id="repeatDeviceResult" type="com.coffee.bus.entity.PatientDeviceRepeatDomain">
+        <result column="name" property="name"/>
+        <result column="gender" property="gender"/>
+        <result column="code" property="code"/>
+        <result column="age" property="age"/>
+        <result column="ward" property="ward"/>
+        <result column="bed_no" property="bedNo"/>
+        <result column="clinic_name" property="clinicName"/>
+        <result column="device_running_id" property="deviceRunningId"/>
+        <result column="device_id" property="deviceId"/>
+        <result column="device_alias" property="deviceAlias"/>
+        <result column="device_run_state" property="deviceRunState" typeHandler="com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler"/>
+        <result column="device_alarm" property="deviceAlarm" typeHandler="com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler"/>
+        <result column="infusion_start_time" property="infusionStartTime"/>
+        <result column="master" property="master"/>
+    </resultMap>
+
+    <select id="repeatDevice" resultMap="repeatDeviceResult">
+         SELECT
+ p.name,
+ p.gender,
+ p.code,
+ c.patient_age as age,
+ c.ward,
+ c.bed_no,
+ c.`name` as clinic_name,
+ d.id as device_running_id,
+ d.device_id as device_id,
+ d.alias as device_alias,
+ d.run_state as device_run_state,
+ d.alarm as device_alarm,
+ d.start_time as infusion_start_time,
+ d.master
+FROM (SELECT `name`,gender,CODE,tenant_id FROM bus_patient WHERE bus_patient.`alarm`=1) AS p
+left join (SELECT * from bus_device_running where monitor_type=1 ) as d on p.CODE=d.patient_code and p.tenant_id=d.tenant_id
+left join  (SELECT * FROM bus_clinic WHERE finished=0 ) AS c ON  c.`patient_code`=p.code AND c.`tenant_id`=p.tenant_id;
+    </select>
+</mapper>

+ 0 - 0
coffee-system/src/main/resources/mapper/SysAreaMapper.xml → coffee-system/src/main/resources/mapper/sys/SysAreaMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysConfigMapper.xml → coffee-system/src/main/resources/mapper/sys/SysConfigMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysDeptMapper.xml → coffee-system/src/main/resources/mapper/sys/SysDeptMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysDictItemMapper.xml → coffee-system/src/main/resources/mapper/sys/SysDictItemMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysDictMapper.xml → coffee-system/src/main/resources/mapper/sys/SysDictMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysLogMapper.xml → coffee-system/src/main/resources/mapper/sys/SysLogMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysMenuMapper.xml → coffee-system/src/main/resources/mapper/sys/SysMenuMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysPostMapper.xml → coffee-system/src/main/resources/mapper/sys/SysPostMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysRoleDeptMapper.xml → coffee-system/src/main/resources/mapper/sys/SysRoleDeptMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysRoleMapper.xml → coffee-system/src/main/resources/mapper/sys/SysRoleMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysRoleMenuMapper.xml → coffee-system/src/main/resources/mapper/sys/SysRoleMenuMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysUserMapper.xml → coffee-system/src/main/resources/mapper/sys/SysUserMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysUserPostMapper.xml → coffee-system/src/main/resources/mapper/sys/SysUserPostMapper.xml


+ 0 - 0
coffee-system/src/main/resources/mapper/SysUserRoleMapper.xml → coffee-system/src/main/resources/mapper/sys/SysUserRoleMapper.xml