Parcourir la source

add 缓存管理

18339543638 il y a 3 ans
Parent
commit
3f9c5e563d
32 fichiers modifiés avec 1426 ajouts et 399 suppressions
  1. 4 0
      coffee-common/pom.xml
  2. 52 0
      coffee-common/src/main/java/com/coffee/common/cache/CacheConfig.java
  3. 83 0
      coffee-common/src/main/java/com/coffee/common/cache/ClusterConfigStorage.java
  4. 31 0
      coffee-common/src/main/java/com/coffee/common/cache/ConfigStorage.java
  5. 34 0
      coffee-common/src/main/java/com/coffee/common/cache/manager/ClusterConfigStorageManager.java
  6. 17 0
      coffee-common/src/main/java/com/coffee/common/cache/manager/ConfigStorageManager.java
  7. 145 0
      coffee-common/src/main/java/com/coffee/common/cache/message/ClusterCache.java
  8. 197 0
      coffee-common/src/main/java/com/coffee/common/cache/message/RedisClusterCache.java
  9. 130 0
      coffee-common/src/main/java/com/coffee/common/cache/value/SimpleValue.java
  10. 38 0
      coffee-common/src/main/java/com/coffee/common/cache/value/Value.java
  11. 55 0
      coffee-common/src/main/java/com/coffee/common/cache/value/Values.java
  12. 6 6
      coffee-framework/src/main/java/com/coffee/framework/config/mybatisplus/MybatisPlusConfig.java
  13. 0 48
      coffee-framework/src/main/java/com/coffee/framework/test/controller/TestController.java
  14. 0 57
      coffee-framework/src/main/java/com/coffee/framework/test/entity/Test.java
  15. 0 17
      coffee-framework/src/main/java/com/coffee/framework/test/mapper/TestMapper.java
  16. 0 33
      coffee-framework/src/main/java/com/coffee/framework/test/service/LocalTestService.java
  17. 1 1
      coffee-system/src/main/java/com/coffee/bus/entity/BusDeviceEntity.java
  18. 1 1
      coffee-system/src/main/java/com/coffee/bus/entity/BusPumpEntity.java
  19. 19 15
      coffee-system/src/main/java/com/coffee/bus/registry/device/ClusterDeviceRegistry.java
  20. 40 52
      coffee-system/src/main/java/com/coffee/bus/registry/device/DeviceOperator.java
  21. 2 2
      coffee-system/src/main/java/com/coffee/bus/registry/device/DeviceRegistry.java
  22. 172 0
      coffee-system/src/main/java/com/coffee/bus/registry/device/RedisDeviceOperator.java
  23. 0 97
      coffee-system/src/main/java/com/coffee/bus/registry/device/bean/DeviceBasicInfo.java
  24. 105 0
      coffee-system/src/main/java/com/coffee/bus/registry/device/bean/DeviceCacheInfo.java
  25. 144 0
      coffee-system/src/main/java/com/coffee/bus/registry/device/bean/DeviceOperator.java
  26. 10 12
      coffee-system/src/main/java/com/coffee/bus/registry/patient/ClusterPatientRegistry.java
  27. 42 38
      coffee-system/src/main/java/com/coffee/bus/registry/patient/PatientOperator.java
  28. 2 2
      coffee-system/src/main/java/com/coffee/bus/registry/patient/PatientRegistry.java
  29. 2 1
      coffee-system/src/main/java/com/coffee/bus/registry/patient/bean/PatientCacheInfo.java
  30. 24 1
      coffee-system/src/main/java/com/coffee/bus/service/LocalBusDeviceService.java
  31. 69 16
      coffee-system/src/main/java/com/coffee/bus/websocket/listener/DeviceInfoListener.java
  32. 1 0
      coffee-system/src/main/java/com/coffee/system/common/dto/SysMenuAddDTO.java

+ 4 - 0
coffee-common/pom.xml

@@ -15,6 +15,10 @@
         <dependency>
             <groupId>org.t-io</groupId>
             <artifactId>tio-websocket-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
          <!--websocket 模块-->
         <!--<dependency>-->

+ 52 - 0
coffee-common/src/main/java/com/coffee/common/cache/CacheConfig.java

@@ -0,0 +1,52 @@
+package com.coffee.common.cache;
+
+import org.redisson.api.RedissonClient;
+import org.redisson.spring.cache.RedissonSpringCacheManager;
+import org.springframework.cache.CacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.cache.RedisCacheWriter;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.stereotype.Component;
+
+import java.time.Duration;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName CacheConfig.java
+ * @Description TODO
+ * @createTime 2022年04月06日 22:31:00
+ */
+@Component
+public class CacheConfig {
+    @Primary
+    @Bean
+    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
+        //缓存配置对象
+        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
+
+        redisCacheConfiguration = redisCacheConfiguration.entryTtl(Duration.ofMinutes(30L)) //设置缓存的默认超时时间:30分钟
+                .disableCachingNullValues()             //如果是空值,不缓存
+                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))         //设置key序列化器
+                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer((valueSerializer())));  //设置value序列化器
+
+        return RedisCacheManager
+                .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
+                .cacheDefaults(redisCacheConfiguration).build();
+    }
+
+    private RedisSerializer<String> keySerializer() {
+        return new StringRedisSerializer();
+    }
+
+    private RedisSerializer<Object> valueSerializer() {
+        return new GenericJackson2JsonRedisSerializer();
+    }
+}

+ 83 - 0
coffee-common/src/main/java/com/coffee/common/cache/ClusterConfigStorage.java

@@ -0,0 +1,83 @@
+package com.coffee.common.cache;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.coffee.common.cache.value.Value;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+import org.springframework.util.CollectionUtils;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ClusterConfigStorage implements ConfigStorage {
+    private final Cache cache;
+
+    public ClusterConfigStorage(CacheManager cacheManager,String name){
+        cache=cacheManager.getCache(name);
+    }
+
+    public Cache getCache(CacheManager cacheManager,String name) {
+        return cache;
+    }
+
+    @Override
+    public Value getConfig(String key) {
+        if (StrUtil.isEmpty(key)) {
+            return null;
+        }
+        return Value.simple(cache.get(key));
+    }
+
+    @Override
+    public Boolean setConfigs(Map<String, Object> values) {
+        if (CollectionUtils.isEmpty(values)) {
+            return true;
+        }
+        values.forEach(cache::put);
+        return true;
+    }
+
+    @Override
+    public Boolean setConfig(String key, Object value) {
+        if (key == null) {
+            return true;
+        }
+        cache.put(key, value);
+        return true;
+    }
+
+    @Override
+    public Value getAndRemove(String key) {
+        Value value = Value.simple(cache.get(key));
+        cache.evictIfPresent(key);
+        return value;
+    }
+
+    @Override
+    public Boolean remove(String key) {
+        cache.evict(key);
+        return true;
+    }
+
+    @Override
+    public Boolean remove(Collection<String> key) {
+        key.forEach(cache::evict);
+        return true;
+    }
+
+    @Override
+    public Boolean clear() {
+        cache.invalidate();
+        return true;
+    }
+
+    @Override
+    public Map<String, Value> getKeys(Collection<String> keys) {
+        Map<String, Value> result = new HashMap<>();
+        keys.parallelStream().forEach(key->{
+            result.put(key,getConfig(key));
+        });
+        return result;
+    }
+}

+ 31 - 0
coffee-common/src/main/java/com/coffee/common/cache/ConfigStorage.java

@@ -0,0 +1,31 @@
+package com.coffee.common.cache;
+
+
+import com.coffee.common.cache.value.Value;
+import com.coffee.common.cache.value.Values;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * 配置存储
+ */
+public interface ConfigStorage {
+
+    Value getConfig(String key);
+
+    Boolean setConfigs(Map<String, Object> values);
+
+    Boolean setConfig(String key, Object value);
+
+    Boolean remove(String key);
+
+    Value getAndRemove(String key);
+
+    Boolean remove(Collection<String> key);
+
+    Boolean clear();
+
+    Map<String,Value> getKeys(Collection<String> keys);
+}

+ 34 - 0
coffee-common/src/main/java/com/coffee/common/cache/manager/ClusterConfigStorageManager.java

@@ -0,0 +1,34 @@
+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.stereotype.Component;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @Author lifang
+ * @Date 16:57 2022/4/6
+ * @Description 集群缓存配置管理器
+ * @Param
+ * @return
+ **/
+
+@Component
+public class ClusterConfigStorageManager implements ConfigStorageManager {
+    private final CacheManager cacheManager;
+
+
+    public ClusterConfigStorageManager(CacheManager cacheManager) {
+        this.cacheManager = cacheManager;
+    }
+
+    private Map<String,ClusterConfigStorage > storageMap=new ConcurrentHashMap<>();
+    @Override
+    public ConfigStorage getStorage(String id) {
+        return  storageMap.computeIfAbsent(id, __ -> new ClusterConfigStorage(cacheManager,id));
+    }
+
+}

+ 17 - 0
coffee-common/src/main/java/com/coffee/common/cache/manager/ConfigStorageManager.java

@@ -0,0 +1,17 @@
+package com.coffee.common.cache.manager;
+
+import com.coffee.common.cache.ConfigStorage;
+
+/** 
+ * @Author lifang
+ * @Date 16:55 2022/4/6
+ * @Description 获取缓存配置
+ * @Param
+ * @return 
+ **/
+
+public interface ConfigStorageManager {
+
+    ConfigStorage getStorage(String id);
+
+}

+ 145 - 0
coffee-common/src/main/java/com/coffee/common/cache/message/ClusterCache.java

@@ -0,0 +1,145 @@
+package com.coffee.common.cache.message;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 集群缓存,通常用于集群见共享数据.
+ *
+ * @param <K> Key
+ * @param <V> Value
+ * @author zhouhao
+ * @since 1.0
+ */
+public interface ClusterCache<K, V> {
+
+    /**
+     * 根据Key获取值,值不存在时返回{@link Mono#empty()}
+     *
+     * @param key Key
+     * @return 值
+     */
+    V get(K key);
+
+    /**
+     * 批量获取缓存
+     *
+     * @param key key集合
+     * @return 键值对
+     */
+    List<Map.Entry<K, V>> get(Collection<K> key);
+
+    /**
+     * 设置值
+     *
+     * @param key   key
+     * @param value value
+     * @return 是否成功
+     */
+    void put(K key, V value);
+
+    /**
+     * 设置值,如果值以及存在则忽略.
+     *
+     * @param key   key
+     * @param value value
+     * @return 是否成功
+     */
+    Boolean putIfAbsent(K key, V value);
+
+    /**
+     * 根据key删除缓存
+     *
+     * @param key key
+     * @return 是否删除成功
+     */
+    Long remove(K key);
+
+    /**
+     * 获取值然后删除
+     *
+     * @param key key
+     * @return value
+     */
+    V getAndRemove(K key);
+
+    /**
+     * 批量删除缓存
+     *
+     * @param key key
+     * @return 是否删除成
+     */
+    Long remove(Collection<K> key);
+
+    /**
+     * 判断缓存中是否包含key
+     *
+     * @param key key
+     * @return 是否包含key
+     */
+    Boolean containsKey(K key);
+
+    /**
+     * 获取缓存的所有key
+     *
+     * @return key流
+     */
+    Set<K> keys();
+
+    /**
+     * 获取缓存的所有值
+     *
+     * @return value 流
+     */
+    List<V> values();
+
+    /**
+     * 批量设置值
+     *
+     * @param multi 批量缓存
+     * @return 是否成功
+     */
+    Boolean putAll(Map<? extends K, ? extends V> multi);
+
+    /**
+     * @return 缓存数量
+     */
+    Integer size();
+
+    /**
+     * @return 所有键值对
+     */
+    List<Map.Entry<K, V>> entries();
+
+    /**
+     * 清空缓存
+     *
+     * @return 清空结果
+     */
+    void clear();
+
+    /**
+     * 刷新缓存信息
+     *
+     * @return void
+     * @since 1.1.6
+     */
+    default void refresh(Collection<? extends K> keys) {
+
+    }
+
+    /**
+     * 刷新全部缓存信息
+     *
+     * @return void
+     * @since 1.1.6
+     */
+    default void refresh() {
+
+    }
+}

+ 197 - 0
coffee-common/src/main/java/com/coffee/common/cache/message/RedisClusterCache.java

@@ -0,0 +1,197 @@
+package com.coffee.common.cache.message;
+
+import org.springframework.data.redis.core.Cursor;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ScanOptions;
+import org.springframework.util.CollectionUtils;
+import reactor.core.publisher.Mono;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 使用redis中的 hash 结构保存缓存结果
+ * @param <K>
+ * @param <V>
+ */
+public class RedisClusterCache<K, V> implements ClusterCache<K, V> {
+
+    private HashOperations<Object, K, V> hash;
+
+    private RedisTemplate<Object, Object> redisTemplate;
+
+    private String redisKey;
+
+    public RedisClusterCache(String redisKey, RedisTemplate<Object, Object> redisTemplate) {
+        this(redisKey, redisTemplate.opsForHash());
+        this.redisTemplate = redisTemplate;
+    }
+
+    private RedisClusterCache(String redisKey, HashOperations<Object, K, V> hash) {
+        this.hash = hash;
+        this.redisKey = redisKey;
+    }
+
+    @Override
+    public V get(K key) {
+        return hash.get(redisKey, key);
+    }
+
+    @Override
+    public List<Map.Entry<K, V>> get(Collection<K> key) {
+        List<V> list = hash.multiGet(redisKey, key);
+        Object[] keyArr = key.toArray();
+        List<Map.Entry<K, V>> entries = new ArrayList<>(keyArr.length);
+        for (int i = 0; i < list.size(); i++) {
+            entries.add(new RedisSimpleEntry((K) keyArr[i], list.get(i)));
+        }
+        return entries;
+    }
+
+    @Override
+    public void put(K key, V value) {
+        hash.put(redisKey, key, value);
+    }
+
+    @Override
+    public Boolean putIfAbsent(K key, V value) {
+        return hash.putIfAbsent(redisKey, key, value);
+    }
+
+    @Override
+    public V getAndRemove(K key) {
+        // TODO: 2020/8/24 使用script实现?
+        V result = hash.get(redisKey, key);
+        remove(key);
+        return result;
+    }
+
+    @Override
+    public Long remove(K key) {
+        return hash.delete(redisKey, key);
+    }
+
+    @Override
+    public Long remove(Collection<K> key) {
+        return hash.delete(redisKey, key.toArray());
+    }
+
+    @Override
+    public Boolean containsKey(K key) {
+        return hash.hasKey(redisKey, key);
+    }
+
+
+    @Override
+    public Set<K> keys() {
+
+        return hash.keys(redisKey);
+    }
+
+    @Override
+    public List<V> values() {
+
+        return hash.values(redisKey);
+    }
+
+    @Override
+    public Boolean putAll(Map<? extends K, ? extends V> multi) {
+        if (CollectionUtils.isEmpty(multi)) {
+            return true;
+        }
+        List<K> remove = multi.entrySet()
+                .stream()
+                .filter(e -> e.getValue() == null)
+                .map(Map.Entry::getKey)
+                .collect(Collectors.toList());
+        if (remove.size() > 0) {
+            Map<K, V> newTarget = new HashMap<>(multi);
+            remove.forEach(newTarget::remove);
+            //todo value值为空暂时放置不管
+//             hash.delete(redisKey, remove.toArray());
+        }
+        hash.putAll(redisKey, multi);
+        return true;
+    }
+
+    @Override
+    public Integer size() {
+        return hash.size(redisKey).intValue();
+    }
+
+    @Override
+    public List<Map.Entry<K, V>> entries() {
+        List<Map.Entry<K, V>> result = new ArrayList<>();
+        //单机redis,集群redis请另行操作
+        Cursor<Map.Entry<K, V>> cursor = hash.scan(redisKey, ScanOptions.scanOptions().count(1000).build());
+        while (cursor.hasNext()){
+            result.add(cursor.next());
+        }
+        return result;
+    }
+
+    @Override
+    public void clear() {
+        hash
+                .delete(redisKey);
+    }
+
+    class RedisSimpleEntry implements Map.Entry<K, V> {
+        K key;
+        V value;
+
+        RedisSimpleEntry(K key, V value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        @Override
+        public K getKey() {
+            return key;
+        }
+
+        @Override
+        public V getValue() {
+            return value;
+        }
+
+        @Override
+        public V setValue(V value) {
+            V old = getValue();
+            if (value == null) {
+                remove(getKey());
+            } else {
+                put(getKey(), this.value = value);
+            }
+            return old;
+        }
+    }
+
+    class RedisHashEntry implements Map.Entry<K, V> {
+        Map.Entry<K, V> entry;
+        V value;
+
+        RedisHashEntry(Map.Entry<K, V> entry) {
+            this.entry = entry;
+            this.value = entry.getValue();
+        }
+
+        @Override
+        public K getKey() {
+            return entry.getKey();
+        }
+
+        @Override
+        public V getValue() {
+            return value;
+        }
+
+        @Override
+        public V setValue(V value) {
+            V old = getValue();
+            put(getKey(), this.value = value);
+            return old;
+        }
+    }
+}

+ 130 - 0
coffee-common/src/main/java/com/coffee/common/cache/value/SimpleValue.java

@@ -0,0 +1,130 @@
+package com.coffee.common.cache.value;
+
+import cn.hutool.core.date.DateUtil;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import java.lang.reflect.Array;
+import java.util.*;
+
+@AllArgsConstructor(staticName = "of")
+@Slf4j
+public class SimpleValue implements Value {
+
+    private Object nativeValue;
+
+    @Override
+    public Object get() {
+        return nativeValue;
+    }
+
+    @Override
+    public <T> T as(Class<T> type) {
+        if (nativeValue == null) {
+            return null;
+        }
+        if(type.isInstance(nativeValue)){
+            return (T)nativeValue;
+        }
+        return convert(nativeValue, type, new Class[0]);
+    }
+
+    public <T> T convert(Object source, Class<T> targetClass, Class[] genericType) {
+        if (source == null) {
+            return null;
+        }
+        if (targetClass == String.class) {
+            if (source instanceof Date) {
+                return (T) DateUtil.format(((Date) source), "yyyy-MM-dd HH:mm:ss");
+            }
+            return (T) String.valueOf(source);
+        }
+        if (targetClass == Object.class) {
+            return (T) source;
+        }
+        if (targetClass == Date.class) {
+            if (source instanceof String) {
+               return (T) DateUtil.parse(String.valueOf(source),"yyyy-MM-dd HH:mm:ss");
+            }
+            if (source instanceof Number) {
+                return (T) new Date(((Number) source).longValue());
+            }
+            if (source instanceof Date) {
+                return (T) source;
+            }
+        }
+        if (Collection.class.isAssignableFrom(targetClass)) {
+            Collection collection = newCollection(targetClass);
+            Collection sourceCollection;
+            if (source instanceof Collection) {
+                sourceCollection = (Collection) source;
+            } else if (source instanceof Object[]) {
+                sourceCollection = Arrays.asList((Object[]) source);
+            } else {
+                if (source instanceof String) {
+                    String stringValue = ((String) source);
+                    sourceCollection = Arrays.asList(stringValue.split("[,]"));
+                } else {
+                    sourceCollection = Arrays.asList(source);
+                }
+            }
+            //转换泛型
+            if (genericType != null && genericType.length > 0 && genericType[0] != Object.class) {
+                for (Object sourceObj : sourceCollection) {
+                    collection.add(convert(sourceObj, genericType[0], null));
+                }
+            } else {
+                collection.addAll(sourceCollection);
+            }
+            return (T) collection;
+        }
+
+        if (targetClass.isEnum()) {
+            if (Enum.class.isAssignableFrom(targetClass)) {
+                String strVal = String.valueOf(source);
+                T[] enumConstants = targetClass.getEnumConstants();
+                for (T enumConstant : enumConstants) {
+                    if (( (Enum)enumConstant).ordinal()==Integer.valueOf(String.valueOf(source))) {
+                        return enumConstant;
+                    }
+                }
+                return null;
+            }
+            String strSource=String.valueOf(source);
+            for (T t : targetClass.getEnumConstants()) {
+                if (((Enum) t).name().equalsIgnoreCase(strSource)
+                        || Objects.equals(String.valueOf(((Enum<?>) t).ordinal()),strSource)) {
+                    return t;
+                }
+            }
+
+            log.warn("无法将:{}转为枚举:{}", source, targetClass);
+            return null;
+        }
+        //转换为数组
+        if (targetClass.isArray()) {
+            Class<?> componentType = targetClass.getComponentType();
+            List<?> val = convert(source, List.class, new Class[]{componentType});
+            return (T) val.toArray((Object[]) Array.newInstance(componentType, val.size()));
+        }
+            return null;
+    }
+
+    private Collection<?> newCollection(Class<?> targetClass) {
+
+        if (targetClass == List.class) {
+            return new ArrayList<>();
+        } else if (targetClass == Set.class) {
+            return new HashSet<>();
+        } else if (targetClass == Queue.class) {
+            return new LinkedList<>();
+        } else {
+            try {
+                return (Collection<?>) targetClass.newInstance();
+            } catch (Exception e) {
+                throw new UnsupportedOperationException("不支持的类型:" + targetClass, e);
+            }
+        }
+    }
+
+
+}

+ 38 - 0
coffee-common/src/main/java/com/coffee/common/cache/value/Value.java

@@ -0,0 +1,38 @@
+package com.coffee.common.cache.value;
+
+import java.util.Date;
+
+public interface Value {
+    default String asString() {
+        return String.valueOf(get());
+    }
+
+    default int asInt() {
+        return as(Integer.class);
+    }
+
+    default long asLong() {
+        return as(Long.class);
+    }
+
+    default boolean asBoolean() {
+        return Boolean.TRUE.equals(get())
+                || "true".equals(get());
+    }
+
+    default Number asNumber() {
+        return as(Number.class);
+    }
+
+    default Date asDate() {
+        return as(Date.class);
+    }
+
+    Object get();
+
+    <T> T as(Class<T> type);
+
+    static Value simple(Object value) {
+        return SimpleValue.of(value);
+    }
+}

+ 55 - 0
coffee-common/src/main/java/com/coffee/common/cache/value/Values.java

@@ -0,0 +1,55 @@
+package com.coffee.common.cache.value;
+
+import org.jetlinks.core.config.ConfigKey;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Supplier;
+
+public interface Values {
+
+    Map<String, Object> getAllValues();
+
+    Optional<Value> getValue(String key);
+
+    Values merge(Values source);
+
+    int size();
+
+    Set<String> getNonExistentKeys(Collection<String> keys);
+
+    default boolean isEmpty() {
+        return size() == 0;
+    }
+
+    default boolean isNoEmpty() {
+        return size() > 0;
+    }
+
+    default <T> Optional<T> getValue(ConfigKey<T> key) {
+        return getValue(key.getKey())
+                .map(val -> (val.as(key.getType())));
+    }
+
+    default String getString(String key, Supplier<String> defaultValue) {
+        return getValue(key).map(Value::asString).orElseGet(defaultValue);
+    }
+
+    default String getString(String key, String defaultValue) {
+        return getString(key, () -> defaultValue);
+    }
+
+    default Number getNumber(String key, Supplier<Number> defaultValue) {
+        return getValue(key).map(Value::asNumber).orElseGet(defaultValue);
+    }
+
+    default Number getNumber(String key, Number defaultValue) {
+        return getNumber(key, () -> defaultValue);
+    }
+
+    static Values of(Map<String, ?> values) {
+        return SimpleValues.of((Map) values);
+    }
+}

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

@@ -145,13 +145,13 @@ public class MybatisPlusConfig {
                 if(url.toString().endsWith("/login")){
                     return true;
                 }
-//                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);
+//                LoginUser loginUser = (LoginUser) StpUtil.getTokenSession().get(Constants.LOGIN_USER_KEY);
+//                if(1==loginUser.getIsSys()){
+//                    return true;
+//                }
+//                return CollectionUtil.isEmpty(ignoreTableName)||ignoreTableName.contains(tableName);
             }
 
             @Override

+ 0 - 48
coffee-framework/src/main/java/com/coffee/framework/test/controller/TestController.java

@@ -1,48 +0,0 @@
-package com.coffee.framework.test.controller;
-
-import com.baomidou.mybatisplus.core.mapper.Mapper;
-import com.coffee.common.crud.BaseService;
-import com.coffee.common.crud.controller.BaseCrudController;
-import com.coffee.framework.test.entity.Test;
-import com.coffee.framework.test.service.LocalTestService;
-import io.swagger.annotations.Api;
-import lombok.AllArgsConstructor;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * @author lifang
- * @version 1.0.0
- * @ClassName CurlController.java
- * @Description TODO
- * @createTime 2022年03月12日 17:12:00
- */
-@RestController
-@RequestMapping("/system/curl")
-@Api("curl接口测试")
-@AllArgsConstructor
-public class TestController extends BaseCrudController<Test,String> {
-
-    private final LocalTestService service;
-
-
-    /**
-     * @Author lifang
-     * @Date 14:34 2022/3/14
-     * @Description 权限标签前缀
-     * @Param []
-     * @return java.lang.String
-     **/
-    @Override
-    public String getPermissionPrefix() {
-        return "test";
-    }
-
-    @Override
-    public BaseService<? extends Mapper<Test>, Test, String> getService() {
-        return service;
-    }
-
-
-
-}

+ 0 - 57
coffee-framework/src/main/java/com/coffee/framework/test/entity/Test.java

@@ -1,57 +0,0 @@
-package com.coffee.framework.test.entity;
-
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.coffee.common.entity.Entity;
-import com.coffee.common.entity.GenericEntity;
-import com.coffee.common.entity.RecordCreationEntity;
-import com.coffee.common.entity.RecordModifierEntity;
-import lombok.Data;
-
-import java.util.Date;
-
-/**
- * @author lifang
- * @version 1.0.0
- * @ClassName Test.java
- * @Description TODO
- * @createTime 2022年03月14日 10:31:00
- */
-@TableName("test")
-@Data
-public class Test extends GenericEntity<String> implements RecordCreationEntity, RecordModifierEntity {
-
-    @Override
-    public String getId() {
-        return super.getId();
-    }
-
-    @TableField("name")
-    private String name;
-
-
-    @TableField("nick_name")
-    private String nickName;
-
-    /**
-     * 创建人
-     */
-    private String createBy;
-
-    /**
-     * 创建时间
-     */
-    private Date createTime;
-
-    /**
-     * 更新人
-     */
-    private String updateBy;
-
-    /**
-     * 更新时间
-     */
-    private Date updateTime;
-
-
-}

+ 0 - 17
coffee-framework/src/main/java/com/coffee/framework/test/mapper/TestMapper.java

@@ -1,17 +0,0 @@
-package com.coffee.framework.test.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.coffee.framework.test.entity.Test;
-import org.apache.ibatis.annotations.Mapper;
-
-/**
- * @author lifang
- * @version 1.0.0
- * @ClassName TestMapper.java
- * @Description TODO
- * @createTime 2022年03月14日 10:39:00
- */
-@Mapper
-public interface TestMapper  extends BaseMapper<Test> {
-
-}

+ 0 - 33
coffee-framework/src/main/java/com/coffee/framework/test/service/LocalTestService.java

@@ -1,33 +0,0 @@
-package com.coffee.framework.test.service;
-
-
-import com.coffee.common.crud.BaseService;
-import com.coffee.framework.test.entity.Test;
-import com.coffee.framework.test.mapper.TestMapper;
-import org.springframework.stereotype.Service;
-
-/**
- * @author lifang
- * @version 1.0.0
- * @ClassName LocalTestService.java
- * @Description TODO
- * @createTime 2022年03月14日 10:38:00
- */
-@Service
-public class LocalTestService extends BaseService<TestMapper, Test,String> {
-
-    @Override
-    public void validateBeforeSave(Test entity) {
-
-    }
-
-    @Override
-    public void validateBeforeUpdate(Test entity) {
-
-    }
-
-    @Override
-    public void validateBeforeDelete(String id) {
-
-    }
-}

+ 1 - 1
coffee-system/src/main/java/com/coffee/bus/entity/BusDeviceEntity.java

@@ -31,7 +31,7 @@ import java.util.Set;
 @EqualsAndHashCode(callSuper = true)
 @Data
 @TableName(value = "bus_device",autoResultMap = true)
-@ApiModel(value="设备注册管理", description="设备注册管理实体类")
+@ApiModel(value="设备经销商管理", description="设备与医院关系管理")
 @ToString
 public class BusDeviceEntity extends TenantGenericEntity<String,String> {
 

+ 1 - 1
coffee-system/src/main/java/com/coffee/bus/entity/BusPumpEntity.java

@@ -32,7 +32,7 @@ import java.util.Date;
 @EqualsAndHashCode(callSuper = false)
 @Accessors(chain = true)
 @TableName(value = "bus_pump",autoResultMap = true)
-@ApiModel(value="网络泵", description="")
+@ApiModel(value="设备运行状态", description="")
 public class BusPumpEntity extends TenantGenericEntity<String,String> {
 
     @ApiModelProperty(value = "网络泵id")

+ 19 - 15
coffee-system/src/main/java/com/coffee/bus/registry/device/ClusterDeviceRegistry.java

@@ -6,9 +6,11 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.coffee.bus.entity.BusDeviceEntity;
 import com.coffee.bus.entity.BusPumpEntity;
 import com.coffee.bus.registry.RegistryConstant;
-import com.coffee.bus.registry.device.bean.DeviceBasicInfo;
+import com.coffee.bus.registry.device.bean.DeviceCacheInfo;
 import com.coffee.bus.service.LocalBusDeviceService;
 import com.coffee.bus.service.LocalBusPumpService;
+import com.coffee.common.cache.ClusterConfigStorage;
+import com.coffee.common.cache.manager.ClusterConfigStorageManager;
 import com.coffee.common.redis.RedisUtils;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
@@ -19,7 +21,7 @@ import java.util.Map;
  * @author lifang
  * @version 1.0.0
  * @ClassName ClusterDeviceRegistry.java
- * @Description TODO
+ * @Description 集群设备注册
  * @createTime 2022年04月01日 17:10:00
  */
 @AllArgsConstructor
@@ -28,37 +30,40 @@ public class ClusterDeviceRegistry implements DeviceRegistry {
     private final RedisUtils redisUtils;
     private final LocalBusPumpService pumpService;
     private final LocalBusDeviceService deviceRegisteredService;
+    private final ClusterConfigStorageManager configStorageManager;
+
     @Override
     public DeviceOperator getDevice(String deviceId) {
         if(StrUtil.isEmpty(deviceId)){
-            return DeviceOperator.of(new DeviceBasicInfo(),redisUtils);
+            return DeviceOperator.of(new DeviceCacheInfo(),redisUtils);
         }
         String key=getId()+deviceId;
+
         Map<Object, Object> result = redisUtils.hmget(key);
         if(result==null||result.size()==0){
             //从数据库中获取数据
             BusPumpEntity pump = pumpService.getOne(new QueryWrapper<BusPumpEntity>().lambda().eq(BusPumpEntity::getDeviceId, deviceId));
-            BusDeviceEntity registeredDevice = deviceRegisteredService.getOne(new QueryWrapper<BusDeviceEntity>().lambda()
+            BusDeviceEntity device = deviceRegisteredService.getOne(new QueryWrapper<BusDeviceEntity>().lambda()
                     .eq(BusDeviceEntity::getDeviceId, deviceId));
-            if(registeredDevice==null){
-                return DeviceOperator.of(new DeviceBasicInfo(),redisUtils);
+            if(device==null){
+                return DeviceOperator.of(new DeviceCacheInfo(),redisUtils);
             }
             if(pump==null){
                 pump=new BusPumpEntity();
-                pump.setAlias(registeredDevice.getAlias());
-                pump.setTenantId(registeredDevice.getTenantId());
-                pump.setDeviceId(registeredDevice.getDeviceId());
+                pump.setAlias(device.getAlias());
+                pump.setTenantId(device.getTenantId());
+                pump.setDeviceId(device.getDeviceId());
             }
-            DeviceOperator operator = DeviceOperator.of(DeviceBasicInfo.of(key,pump, registeredDevice), redisUtils);
+            DeviceOperator operator = DeviceOperator.of(DeviceCacheInfo.of(pump, device), redisUtils);
             //数据同步到缓存中
             operator.sync();
             return operator;
         }
-        return DeviceOperator.of(JSONUtil.toBean(JSONUtil.toJsonStr(result),DeviceBasicInfo.class),redisUtils);
+        return DeviceOperator.of(JSONUtil.toBean(JSONUtil.toJsonStr(result), DeviceCacheInfo.class),redisUtils);
     }
 
     @Override
-    public void register(DeviceBasicInfo basicInfo) {
+    public void register(DeviceCacheInfo basicInfo) {
         if(StrUtil.isNotEmpty(basicInfo.getDeviceId())){
             DeviceOperator.of(basicInfo, redisUtils).sync();
         }
@@ -66,9 +71,8 @@ public class ClusterDeviceRegistry implements DeviceRegistry {
 
     @Override
     public void unRegister(String deviceId) {
-        String key=getId()+deviceId;
-        DeviceBasicInfo deviceBasicInfo = DeviceBasicInfo.of(key,deviceId);
-        DeviceOperator.of(deviceBasicInfo, redisUtils).clear();
+        DeviceCacheInfo deviceCacheInfo = DeviceCacheInfo.of(deviceId);
+        DeviceOperator.of(deviceCacheInfo, redisUtils).clear();
     }
 
 

+ 40 - 52
coffee-system/src/main/java/com/coffee/bus/registry/device/DeviceOperator.java

@@ -1,9 +1,7 @@
 package com.coffee.bus.registry.device;
 
 import cn.hutool.core.util.StrUtil;
-import com.coffee.bus.registry.RegistryConstant;
-import com.coffee.bus.registry.device.bean.DeviceBasicInfo;
-import com.coffee.common.enums.SexEnum;
+import com.coffee.bus.registry.device.bean.DeviceCacheInfo;
 import com.coffee.common.redis.RedisUtils;
 import lombok.AllArgsConstructor;
 
@@ -20,7 +18,7 @@ import java.util.Map;
  */
 @AllArgsConstructor
 public class DeviceOperator {
-    private transient final DeviceBasicInfo deviceBasicInfo;
+    private transient final DeviceCacheInfo deviceCacheInfo;
 
     private transient final RedisUtils redisUtils;
 
@@ -29,15 +27,15 @@ public class DeviceOperator {
      */
     private final boolean validate;
 
-    public static DeviceOperator of(DeviceBasicInfo deviceBasicInfo,RedisUtils redisUtils){
-        return new DeviceOperator(deviceBasicInfo,redisUtils,!StrUtil.isNullOrUndefined(deviceBasicInfo.getDeviceId()));
+    public static DeviceOperator of(DeviceCacheInfo deviceCacheInfo, RedisUtils redisUtils){
+        return new DeviceOperator(deviceCacheInfo,redisUtils,!StrUtil.isNullOrUndefined(deviceCacheInfo.getDeviceId()));
     }
     /**
      * 清除缓存
      */
     public DeviceOperator clear(){
         if(!validate)return this;
-        redisUtils.del(deviceBasicInfo.getKey());
+        redisUtils.del(deviceCacheInfo.getKey());
         return this;
     }
     /**
@@ -46,64 +44,61 @@ public class DeviceOperator {
      */
     public DeviceOperator sync(){
         if(!validate)return this;
-        redisUtils.hmset(deviceBasicInfo.getKey(),getMap());
+        redisUtils.hmset(deviceCacheInfo.getKey(),getMap());
         return this;
     }
 
     public DeviceOperator updateAlias(String alias){
         if(!validate)return this;
-        deviceBasicInfo.setAlias(alias);
-        redisUtils.hset(deviceBasicInfo.getKey(),"alias",alias);
+        deviceCacheInfo.setAlias(alias);
+        redisUtils.hset(deviceCacheInfo.getKey(),"alias",alias);
         return this;
     }
 
     public DeviceOperator updateEnable(Integer enable){
         if(!validate)return this;
-        deviceBasicInfo.setEnable(enable);
-        redisUtils.hset(deviceBasicInfo.getKey(),"enable",enable);
+        deviceCacheInfo.setEnable(enable);
+        redisUtils.hset(deviceCacheInfo.getKey(),"enable",enable);
         return this;
     }
 
     public DeviceOperator updateTenantId(String tenantId){
         if(!validate)return this;
-        deviceBasicInfo.setTenantId(tenantId);
-        redisUtils.hset(deviceBasicInfo.getKey(),"tenantId",tenantId);
+        deviceCacheInfo.setTenantId(tenantId);
+        redisUtils.hset(deviceCacheInfo.getKey(),"tenantId",tenantId);
         return this;
     }
 
 
     public DeviceOperator updateRunId(String runId){
         if(!validate)return this;
-        deviceBasicInfo.setId(runId);
-        redisUtils.hset(deviceBasicInfo.getKey(),"id",runId);
+        deviceCacheInfo.setId(runId);
+        redisUtils.hset(deviceCacheInfo.getKey(),"id",runId);
         return this;
     }
 
     public DeviceOperator updateStartTime(Date startTime){
         if(!validate)return this;
-        deviceBasicInfo.setStartTime(startTime);
-        redisUtils.hset(deviceBasicInfo.getKey(),"startTime",startTime);
+        deviceCacheInfo.setStartTime(startTime);
+        redisUtils.hset(deviceCacheInfo.getKey(),"startTime",startTime);
         return this;
     }
 
 
-    public DeviceOperator updateRegisterTime(Date registerTime){
-        if(!validate)return this;
-        deviceBasicInfo.setRegisterTime(registerTime);
-        redisUtils.hset(deviceBasicInfo.getKey(),"registerTime",registerTime);
-        return this;
-    }
-
     public String getDeviceId(){
-        return deviceBasicInfo.getDeviceId();
+        return deviceCacheInfo.getDeviceId();
     }
 
     public String getAlias(){
-        return deviceBasicInfo.getAlias();
+        return deviceCacheInfo.getAlias();
     }
 
     public String getTenantId(){
-        return deviceBasicInfo.getTenantId();
+        return deviceCacheInfo.getTenantId();
+    }
+
+    public String getPatientCode(){
+        return deviceCacheInfo.getPatientCode();
     }
 
     /**
@@ -111,15 +106,11 @@ public class DeviceOperator {
      * @return
      */
     public String getRunId(){
-        return deviceBasicInfo.getId();
+        return deviceCacheInfo.getId();
     }
 
     public Date getStartTime(){
-        return deviceBasicInfo.getStartTime();
-    }
-
-    public Date getRegisterTime(){
-        return deviceBasicInfo.getRegisterTime();
+        return deviceCacheInfo.getStartTime();
     }
 
     /**
@@ -127,7 +118,7 @@ public class DeviceOperator {
      * @return
      */
     public boolean isExist(){
-        return deviceBasicInfo!=null&& !StrUtil.isEmpty(deviceBasicInfo.getDeviceId()) ;
+        return deviceCacheInfo !=null&& !StrUtil.isEmpty(deviceCacheInfo.getDeviceId()) ;
     }
 
 
@@ -136,7 +127,7 @@ public class DeviceOperator {
      * @return
      */
     public boolean canUse(){
-        return isExist()&&deviceBasicInfo.getEnable()!=null&&deviceBasicInfo.getEnable()==1 ;
+        return isExist()&& deviceCacheInfo.getEnable()!=null&& deviceCacheInfo.getEnable()==1 ;
     }
 
     /**
@@ -144,31 +135,28 @@ public class DeviceOperator {
      * @return
      */
     public boolean isFirst(){
-        return StrUtil.isEmpty(deviceBasicInfo.getId());
+        return StrUtil.isEmpty(deviceCacheInfo.getId());
     }
 
     public Map<String,Object> getMap(){
         Map<String, Object> result = new HashMap<>();
-        if(null!=deviceBasicInfo.getId()){
-            result.put("id",deviceBasicInfo.getId());
-        }
-        if(null!=deviceBasicInfo.getDeviceId()){
-            result.put("deviceId",deviceBasicInfo.getDeviceId());
+        if(null!= deviceCacheInfo.getId()){
+            result.put("id", deviceCacheInfo.getId());
         }
-        if(StrUtil.isNotEmpty(deviceBasicInfo.getAlias())){
-            result.put("alias",deviceBasicInfo.getAlias());
+        if(null!= deviceCacheInfo.getDeviceId()){
+            result.put("deviceId", deviceCacheInfo.getDeviceId());
         }
-        if(null!=deviceBasicInfo.getEnable()){
-            result.put("enable",deviceBasicInfo.getEnable());
+        if(StrUtil.isNotEmpty(deviceCacheInfo.getAlias())){
+            result.put("alias", deviceCacheInfo.getAlias());
         }
-        if(StrUtil.isNotEmpty(deviceBasicInfo.getTenantId())){
-            result.put("tenantId",deviceBasicInfo.getTenantId());
+        if(null!= deviceCacheInfo.getEnable()){
+            result.put("enable", deviceCacheInfo.getEnable());
         }
-        if(null!=deviceBasicInfo.getStartTime()){
-            result.put("startTime",deviceBasicInfo.getStartTime());
+        if(StrUtil.isNotEmpty(deviceCacheInfo.getTenantId())){
+            result.put("tenantId", deviceCacheInfo.getTenantId());
         }
-        if(null!=deviceBasicInfo.getRegisterTime()){
-            result.put("registerTime",deviceBasicInfo.getRegisterTime());
+        if(null!= deviceCacheInfo.getStartTime()){
+            result.put("startTime", deviceCacheInfo.getStartTime());
         }
 
         return result;

+ 2 - 2
coffee-system/src/main/java/com/coffee/bus/registry/device/DeviceRegistry.java

@@ -1,7 +1,7 @@
 package com.coffee.bus.registry.device;
 
 import com.coffee.bus.registry.Registry;
-import com.coffee.bus.registry.device.bean.DeviceBasicInfo;
+import com.coffee.bus.registry.device.bean.DeviceCacheInfo;
 
 /**
  * @author lifang
@@ -22,7 +22,7 @@ public interface DeviceRegistry extends Registry {
      * 注册设备信息
      * @param basicInfo
      */
-    void register(DeviceBasicInfo basicInfo);
+    void register(DeviceCacheInfo basicInfo);
 
     /**
      * 取消注册设备信息

+ 172 - 0
coffee-system/src/main/java/com/coffee/bus/registry/device/RedisDeviceOperator.java

@@ -0,0 +1,172 @@
+package com.coffee.bus.registry.device;
+
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.coffee.bus.enums.NetPumpStatusEnum;
+import com.coffee.bus.registry.device.bean.DeviceCacheInfo;
+import com.coffee.bus.registry.device.bean.DeviceOperator;
+import com.coffee.common.redis.RedisUtils;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName RedisDeviceOperator.java
+ * @Description TODO
+ * @createTime 2022年04月06日 15:27:00
+ */
+public class RedisDeviceOperator implements DeviceOperator<DeviceCacheInfo> {
+    private transient RedisUtils redisUtils;
+    private DeviceCacheInfo cacheInfo;
+    @Override
+    public void clear() {
+        if(cacheInfo!=null){
+            redisUtils.del(cacheInfo.getKey());
+        }
+
+    }
+
+    @Override
+    public void sync() {
+        if(cacheInfo!=null){
+            redisUtils.hmset(cacheInfo.getKey(),getMap());
+        }
+
+    }
+
+    @Override
+    public void setAll(DeviceCacheInfo all) {
+
+        this.cacheInfo=all;
+    }
+
+    @Override
+    public DeviceCacheInfo getAll() {
+        return cacheInfo;
+    }
+
+    @Override
+    public void setDeviceId(String deviceId) {
+
+    }
+
+    @Override
+    public String getDeviceId() {
+        return null;
+    }
+
+    @Override
+    public void setAlias(String alias) {
+
+    }
+
+    @Override
+    public String getAlias() {
+        return null;
+    }
+
+    @Override
+    public void setEnable(String enable) {
+
+    }
+
+    @Override
+    public boolean getEnable() {
+        return false;
+    }
+
+    @Override
+    public void setTenantId(String tenantId) {
+
+    }
+
+    @Override
+    public String getTenantId() {
+        return null;
+    }
+
+    @Override
+    public void setUsingId(String usingId) {
+
+    }
+
+    @Override
+    public String getUsingId() {
+        return null;
+    }
+
+    @Override
+    public void setStartTime(Date startTime) {
+
+    }
+
+    @Override
+    public Date getStartTime() {
+        return null;
+    }
+
+    @Override
+    public void setPatientCode(String patientCode) {
+
+    }
+
+    @Override
+    public String getPatientCode() {
+        return null;
+    }
+
+    @Override
+    public NetPumpStatusEnum getStatus() {
+        return null;
+    }
+
+    @Override
+    public void setStatus(NetPumpStatusEnum status) {
+
+    }
+
+    @Override
+    public void setMaster(boolean master) {
+
+    }
+
+    @Override
+    public boolean getMaster() {
+        return false;
+    }
+
+    private Map<String,Object> getMap(){
+        Map<String, Object> result = new HashMap<>();
+        if(null!= cacheInfo.getDeviceId()){
+            result.put("deviceId", cacheInfo.getDeviceId());
+        }
+        if(StrUtil.isNotEmpty(cacheInfo.getAlias())){
+            result.put("alias", cacheInfo.getAlias());
+        }
+        if(null!= cacheInfo.getEnable()){
+            result.put("enable", cacheInfo.getEnable());
+        }
+        if(StrUtil.isNotEmpty(cacheInfo.getTenantId())){
+            result.put("tenantId", cacheInfo.getTenantId());
+        }
+        if(StrUtil.isNotEmpty(cacheInfo.getPatientCode())){
+            result.put("patientCode", cacheInfo.getPatientCode());
+        }
+        if(null!= cacheInfo.getId()){
+            result.put("usingId", cacheInfo.getId());
+        }
+        if(null!= cacheInfo.getStartTime()){
+            result.put("startTime", cacheInfo.getStartTime());
+        }
+        if(null!= cacheInfo.getStatus()){
+            result.put("status", cacheInfo.getStatus());
+        }
+        if(null!= cacheInfo.getMaster()){
+            result.put("master", cacheInfo.getMaster());
+        }
+        return result;
+    }
+}

+ 0 - 97
coffee-system/src/main/java/com/coffee/bus/registry/device/bean/DeviceBasicInfo.java

@@ -1,97 +0,0 @@
-package com.coffee.bus.registry.device.bean;
-
-import com.coffee.bus.entity.BusDeviceEntity;
-import com.coffee.bus.entity.BusPumpEntity;
-import com.coffee.bus.registry.CacheInfo;
-import com.coffee.bus.registry.RegistryConstant;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.Date;
-
-/**
- * @author lifang
- * @version 1.0.0
- * @ClassName DeviceInfo.java
- * @Description 注册设备基本信息
- * @createTime 2022年04月01日 17:06:00
- */
-@Data
-@NoArgsConstructor
-public class DeviceBasicInfo implements CacheInfo {
-    private String key;
-    /*****经销商泵管理状态********/
-    /**
-     * 设备id
-     */
-    private String deviceId;
-    /**
-     * 设备别名
-     */
-    private String alias;
-
-    /**
-     * 是否启用
-     */
-    private Integer enable;
-
-    /**
-     * 设备所属医院
-     */
-    private String tenantId;
-    /*****经销商泵管理状态********/
-
-    /*****泵正在运行状态********/
-
-    /**
-     * 对应泵设备正在运行id
-     * @see com.coffee.bus.entity.BusPumpEntity
-     */
-    private String id;
-
-    private Date startTime;
-
-    private Date registerTime;
-
-    @Override
-    public String getKey() {
-        if(key==null){
-            return RegistryConstant.Device+deviceId;
-        }
-        return key;
-    }
-
-    /*****泵正在运行状态********/
-
-    public DeviceBasicInfo(String key,String deviceId, String alias, Integer enable, String tenantId) {
-        this.deviceId = deviceId;
-        this.alias = alias;
-        this.enable = enable;
-        this.tenantId = tenantId;
-        this.key=key;
-    }
-
-    public DeviceBasicInfo(String key,String deviceId, String alias, Integer enable, String tenantId, String id, Date startTime, Date registerTime) {
-        this.key=key;
-        this.deviceId = deviceId;
-        this.alias = alias;
-        this.enable = enable;
-        this.tenantId = tenantId;
-        this.id = id;
-        this.startTime = startTime;
-        this.registerTime = registerTime;
-    }
-
-    public static DeviceBasicInfo of(String key, String deviceId, String alias, Integer enable, String tenantId) {
-        return new DeviceBasicInfo(key,deviceId,alias,enable,tenantId);
-    }
-
-    public static DeviceBasicInfo of(String key,String deviceId) {
-        return new DeviceBasicInfo(key,deviceId,null,null,null);
-    }
-
-    public static DeviceBasicInfo of(String key,BusPumpEntity pump, BusDeviceEntity deviceRegistered) {
-        return new DeviceBasicInfo(key,pump.getDeviceId(), pump.getAlias(),deviceRegistered.getEnable(),pump.getTenantId(),pump.getId(),pump.getStartTime(),pump.getRegisterTime());
-    }
-
-}

+ 105 - 0
coffee-system/src/main/java/com/coffee/bus/registry/device/bean/DeviceCacheInfo.java

@@ -0,0 +1,105 @@
+package com.coffee.bus.registry.device.bean;
+
+import com.coffee.bus.entity.BusDeviceEntity;
+import com.coffee.bus.entity.BusPumpEntity;
+import com.coffee.bus.enums.NetPumpStatusEnum;
+import com.coffee.bus.registry.CacheInfo;
+import com.coffee.bus.registry.RegistryConstant;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+//import com.coffee.common.cache.*;
+import java.util.Date;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DeviceInfo.java
+ * @Description 注册设备基本信息
+ * @createTime 2022年04月01日 17:06:00
+ */
+@Data
+@NoArgsConstructor
+public class DeviceCacheInfo implements CacheInfo {
+    @Override
+    public String getKey() {
+        return RegistryConstant.Device+deviceId;
+    }
+    /**********经销商泵管理信息**********/
+    /**
+     * 设备id
+     */
+    private String deviceId;
+    /**
+     * 设备别名
+     */
+    private String alias;
+
+    /**
+     * 是否启用
+     */
+    private Integer enable;
+
+    /**
+     * 设备所属医院
+     */
+    private String tenantId;
+    /**********经销商泵管理状态**********/
+
+    /**********泵正在运行状态**********/
+
+    /**
+     * 运行泵主键id
+     * @see com.coffee.bus.entity.BusPumpEntity
+     */
+    private String id;
+
+    private Date startTime;
+
+    private NetPumpStatusEnum status;
+
+    /**********泵正在运行状态**********/
+
+    /**********泵正在运行状态**********/
+
+    private String patientCode;
+
+    /**
+     * 当前泵是否为主泵
+     */
+    private Integer master;
+    /**********泵正在运行状态**********/
+
+
+
+
+    public DeviceCacheInfo(String deviceId, String alias, Integer enable, String tenantId) {
+        this.deviceId = deviceId;
+        this.alias = alias;
+        this.enable = enable;
+        this.tenantId = tenantId;
+    }
+
+    public DeviceCacheInfo( String deviceId, String alias, Integer enable, String tenantId, String id, Date startTime) {
+        this.deviceId = deviceId;
+        this.alias = alias;
+        this.enable = enable;
+        this.tenantId = tenantId;
+        this.id = id;
+        this.startTime = startTime;
+    }
+
+    public static DeviceCacheInfo of(String deviceId, String alias, Integer enable, String tenantId) {
+        return new DeviceCacheInfo(deviceId,alias,enable,tenantId);
+    }
+
+    public static DeviceCacheInfo of(String deviceId) {
+        return new DeviceCacheInfo(deviceId,null,null,null);
+    }
+
+    public static DeviceCacheInfo of( BusPumpEntity deviceUsing, BusDeviceEntity device) {
+
+        return new DeviceCacheInfo(deviceUsing.getDeviceId(), deviceUsing.getAlias(),device.getEnable(),deviceUsing.getTenantId(),deviceUsing.getId(),deviceUsing.getStartTime());
+    }
+
+
+}

+ 144 - 0
coffee-system/src/main/java/com/coffee/bus/registry/device/bean/DeviceOperator.java

@@ -0,0 +1,144 @@
+package com.coffee.bus.registry.device.bean;
+
+import com.coffee.bus.enums.NetPumpStatusEnum;
+import java.util.Date;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DeviceOperator.java
+ * @Description 设备操作符
+ * @createTime 2022年04月06日 15:16:00
+ */
+public interface DeviceOperator<T> {
+    /**
+     * 清除操作缓存
+     */
+    void clear();
+
+    /**
+     * 同步缓存数据
+     */
+    void sync();
+
+    /**
+     * 设置缓存数据
+     * @param all
+     */
+    void setAll(T all);
+
+    /**
+     * 获取所有缓存数据
+     * @return
+     */
+    T getAll();
+
+    /**
+     * 设置设备号
+     * @param deviceId
+     */
+    void setDeviceId(String deviceId);
+
+    /**
+     * 获取设备号
+     * @return
+     */
+    String getDeviceId();
+
+    /**
+     * 设置别名
+     * @param alias
+     */
+    void setAlias(String alias);
+
+    /**
+     * 获取设备别名
+     * @return
+     */
+    String getAlias();
+
+    /**
+     * 设置设备是否启用
+     * @param enable
+     */
+    void setEnable(String enable);
+
+    /**
+     * 获取设备是否启用
+     * @return
+     */
+    boolean getEnable();
+
+    /**
+     * 设置医院id
+     * @param tenantId
+     */
+    void setTenantId(String tenantId);
+
+    /**
+     * 获取医院id
+     * @return
+     */
+    String getTenantId();
+
+    /**
+     * 设置设备运行id
+     * @see com.coffee.bus.entity.BusPumpEntity
+     * @param usingId
+     */
+    void setUsingId(String usingId);
+
+    /**
+     * 获取设备运行id
+     * @return
+     */
+    String getUsingId();
+
+    /**
+     * 设置设备开机时间
+     * @param startTime
+     */
+    void setStartTime(Date startTime);
+
+    /**
+     * 获取设备开机时间
+     * @return
+     */
+    Date getStartTime();
+
+    /**
+     * 设置设备当前绑定泵号
+     * @param patientCode
+     */
+    void setPatientCode(String patientCode);
+
+    /**
+     * 获取设备当前绑定泵号
+     * @return
+     */
+    String getPatientCode();
+
+    /**
+     * 获取设备当前状态
+     * @return
+     */
+    NetPumpStatusEnum getStatus();
+
+    /**
+     * 设置设备当前状态
+     * @param status
+     */
+    void setStatus(NetPumpStatusEnum status);
+
+    /**
+     * 设置设备当前是否为主泵
+     * @param master
+     */
+    void setMaster(boolean master);
+
+    /**
+     * 获取设备当前是否为主泵
+     * @return
+     */
+    boolean getMaster();
+}

+ 10 - 12
coffee-system/src/main/java/com/coffee/bus/registry/patient/ClusterPatientRegistry.java

@@ -5,9 +5,7 @@ import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.coffee.bus.entity.BusPatientEntity;
 import com.coffee.bus.registry.RegistryConstant;
-import com.coffee.bus.registry.device.DeviceOperator;
-import com.coffee.bus.registry.device.bean.DeviceBasicInfo;
-import com.coffee.bus.registry.patient.bean.PatientCurrentInfo;
+import com.coffee.bus.registry.patient.bean.PatientCacheInfo;
 import com.coffee.bus.service.LocalBusPatientService;
 import com.coffee.common.redis.RedisUtils;
 import lombok.AllArgsConstructor;
@@ -35,11 +33,11 @@ public class ClusterPatientRegistry implements PatientRegistry {
     @Transactional(rollbackFor = Exception.class)
     public PatientOperator getPatient(String hospitalId, String patientCode) {
         if(StrUtil.isEmpty(hospitalId)||StrUtil.isEmpty(patientCode)){
-            return PatientOperator.of(new PatientCurrentInfo(),redisUtils,null);
+            return PatientOperator.of(new PatientCacheInfo(),redisUtils,null);
         }
         String key=getId()+hospitalId+":"+patientCode;
         Map<Object, Object> result = redisUtils.hmget(key);
-        PatientCurrentInfo currentInfo = new PatientCurrentInfo();
+        PatientCacheInfo currentInfo = new PatientCacheInfo();
         currentInfo.setKey(key);
         if(result==null||result.size()==0){
             //将新数据存入数据库
@@ -72,11 +70,11 @@ public class ClusterPatientRegistry implements PatientRegistry {
             return patientOperator;
 
         }
-        return PatientOperator.of(JSONUtil.toBean(JSONUtil.toJsonStr(result), PatientCurrentInfo.class),redisUtils,patientCurrentInfo->{
+        return PatientOperator.of(JSONUtil.toBean(JSONUtil.toJsonStr(result), PatientCacheInfo.class),redisUtils, patientCacheInfo ->{
             //从数据库中刷新数据 todo
             BusPatientEntity patient = patientService.getOne(
-                    new QueryWrapper<BusPatientEntity>().lambda().eq(BusPatientEntity::getCode, patientCurrentInfo.getPatientCode())
-                            .eq(BusPatientEntity::getTenantId, patientCurrentInfo.getTenantId()));
+                    new QueryWrapper<BusPatientEntity>().lambda().eq(BusPatientEntity::getCode, patientCacheInfo.getPatientCode())
+                            .eq(BusPatientEntity::getTenantId, patientCacheInfo.getTenantId()));
             if(patient==null){
                 //存储新的病人数据
                 patient = new BusPatientEntity();
@@ -87,16 +85,16 @@ public class ClusterPatientRegistry implements PatientRegistry {
             }else if(StrUtil.isNotEmpty(patient.getName())){
                 //同步数据 todo
             }else {
-                patientCurrentInfo.setPatientGender(patient.getGender());
-                patientCurrentInfo.setPatientName(patient.getName());
+                patientCacheInfo.setPatientGender(patient.getGender());
+                patientCacheInfo.setPatientName(patient.getName());
                 //同步临床数据 todo
             }
-            return patientCurrentInfo;
+            return patientCacheInfo;
         });
     }
 
     @Override
-    public void register(PatientCurrentInfo basicInfo) {
+    public void register(PatientCacheInfo basicInfo) {
 
     }
 

+ 42 - 38
coffee-system/src/main/java/com/coffee/bus/registry/patient/PatientOperator.java

@@ -1,7 +1,7 @@
 package com.coffee.bus.registry.patient;
 
 import cn.hutool.core.util.StrUtil;
-import com.coffee.bus.registry.patient.bean.PatientCurrentInfo;
+import com.coffee.bus.registry.patient.bean.PatientCacheInfo;
 import com.coffee.common.enums.SexEnum;
 import com.coffee.common.redis.RedisUtils;
 import lombok.AllArgsConstructor;
@@ -21,17 +21,17 @@ import java.util.function.Function;
  */
 @AllArgsConstructor(staticName = "of")
 public class PatientOperator {
-    private transient final PatientCurrentInfo patientCurrentInfo;
+    private transient final PatientCacheInfo patientCacheInfo;
 
     private transient final RedisUtils redisUtils;
 
-    private transient final Function<PatientCurrentInfo,PatientCurrentInfo> syncCurrentInfo;
+    private transient final Function<PatientCacheInfo, PatientCacheInfo> syncCurrentInfo;
 
     /**
      * 清除缓存
      */
     public PatientOperator clear(){
-        redisUtils.del(patientCurrentInfo.getKey());
+        redisUtils.del(patientCacheInfo.getKey());
         return this;
     }
     /**
@@ -39,7 +39,7 @@ public class PatientOperator {
      * @param
      */
     public PatientOperator syncCache(){
-        redisUtils.hmset(patientCurrentInfo.getKey(),getMap());
+        redisUtils.hmset(patientCacheInfo.getKey(),getMap());
         return this;
     }
 
@@ -47,7 +47,7 @@ public class PatientOperator {
      * 是否存在病人
      */
     public boolean existPatient(){
-        return patientCurrentInfo!=null&& StrUtil.isNotEmpty(patientCurrentInfo.getPatientCode());
+        return patientCacheInfo !=null&& StrUtil.isNotEmpty(patientCacheInfo.getPatientCode());
     }
 
     /**
@@ -55,7 +55,7 @@ public class PatientOperator {
      * @return
      */
     public boolean existClinic(){
-        return patientCurrentInfo!=null&&StrUtil.isNotEmpty(patientCurrentInfo.getClinicId());
+        return patientCacheInfo !=null&&StrUtil.isNotEmpty(patientCacheInfo.getClinicId());
     }
 
     /**
@@ -75,89 +75,93 @@ public class PatientOperator {
      * @return
      */
     public String getPatientName(boolean isNullRefresh){
-        String patientName = patientCurrentInfo.getPatientName();
+        String patientName = patientCacheInfo.getPatientName();
         if(StrUtil.isEmpty(patientName)&&isNullRefresh){
             freshInfo();
         }
-        return patientCurrentInfo.getPatientName();
+        return patientCacheInfo.getPatientName();
     }
 
     public String getTenantId(){
-        return patientCurrentInfo.getTenantId();
+        return patientCacheInfo.getTenantId();
     }
 
     public String getClinicId(boolean isNullRefresh){
-        String clinicId = patientCurrentInfo.getClinicId();
+        String clinicId = patientCacheInfo.getClinicId();
         if(StrUtil.isEmpty(clinicId)&&isNullRefresh){
             freshInfo();
         }
-        return patientCurrentInfo.getClinicId();
+        return patientCacheInfo.getClinicId();
     }
 
     public Date getClinicStartTime(boolean isNullRefresh){
-        Date clinicStartTime = patientCurrentInfo.getClinicStartTime();
+        Date clinicStartTime = patientCacheInfo.getClinicStartTime();
         if(null!=clinicStartTime&&isNullRefresh){
             freshInfo();
         }
-        return patientCurrentInfo.getClinicStartTime();
+        return patientCacheInfo.getClinicStartTime();
     }
 
     public Boolean getIsFinished(boolean isNullRefresh){
-        Boolean isFinished = patientCurrentInfo.getIsFinished();
+        Boolean isFinished = patientCacheInfo.getIsFinished();
         if(null!=isFinished&&isNullRefresh){
             freshInfo();
         }
-        return patientCurrentInfo.getIsFinished();
+        return patientCacheInfo.getIsFinished();
     }
 
     public String getDeviceId(){
-        return patientCurrentInfo.getCurrentDeviceId();
+        return patientCacheInfo.getCurrentDeviceId();
     }
 
     public SexEnum getPatientGender(boolean isNullRefresh){
-        SexEnum patientGender = patientCurrentInfo.getPatientGender();
+        SexEnum patientGender = patientCacheInfo.getPatientGender();
         if(patientGender==null&&isNullRefresh){
             freshInfo();
         }
-        return patientCurrentInfo.getPatientGender();
+        return patientCacheInfo.getPatientGender();
     }
 
     private void freshInfo(){
         if(syncCurrentInfo!=null
-                && StrUtil.isNotEmpty(patientCurrentInfo.getPatientCode())
-                &&StrUtil.isNotEmpty(patientCurrentInfo.getTenantId())){
-            syncCurrentInfo.apply(patientCurrentInfo);
+                && StrUtil.isNotEmpty(patientCacheInfo.getPatientCode())
+                &&StrUtil.isNotEmpty(patientCacheInfo.getTenantId())){
+            syncCurrentInfo.apply(patientCacheInfo);
 
         }
     }
 
+    public void updateDeviceId(String deviceId) {
+        redisUtils.hset(patientCacheInfo.getKey(),"currentDeviceId",deviceId);
+    }
 
     public Map<String,Object> getMap(){
         Map<String, Object> result = new HashMap<>();
-        if(StrUtil.isNotEmpty(patientCurrentInfo.getPatientCode())){
-            result.put("patientCode",patientCurrentInfo.getPatientCode());
+        if(StrUtil.isNotEmpty(patientCacheInfo.getPatientCode())){
+            result.put("patientCode", patientCacheInfo.getPatientCode());
         }
-        if(null!=patientCurrentInfo.getPatientGender()){
-            result.put("patientGender",patientCurrentInfo.getPatientGender());
+        if(null!= patientCacheInfo.getPatientGender()){
+            result.put("patientGender", patientCacheInfo.getPatientGender());
         }
-        if(StrUtil.isNotEmpty(patientCurrentInfo.getPatientName())){
-            result.put("patientName",patientCurrentInfo.getPatientName());
+        if(StrUtil.isNotEmpty(patientCacheInfo.getPatientName())){
+            result.put("patientName", patientCacheInfo.getPatientName());
         }
-        if(StrUtil.isNotEmpty(patientCurrentInfo.getTenantId())){
-            result.put("tenantId",patientCurrentInfo.getTenantId());
+        if(StrUtil.isNotEmpty(patientCacheInfo.getTenantId())){
+            result.put("tenantId", patientCacheInfo.getTenantId());
         }
-        if(StrUtil.isNotEmpty(patientCurrentInfo.getClinicId())){
-            result.put("clinicId",patientCurrentInfo.getClinicId());
+        if(StrUtil.isNotEmpty(patientCacheInfo.getClinicId())){
+            result.put("clinicId", patientCacheInfo.getClinicId());
         }
-        if(null!=patientCurrentInfo.getClinicStartTime()){
-            result.put("clinicStartTime",patientCurrentInfo.getClinicStartTime());
-        }if(null!=patientCurrentInfo.getIsFinished()){
-            result.put("isFinished",patientCurrentInfo.getIsFinished());
+        if(null!= patientCacheInfo.getClinicStartTime()){
+            result.put("clinicStartTime", patientCacheInfo.getClinicStartTime());
+        }if(null!= patientCacheInfo.getIsFinished()){
+            result.put("isFinished", patientCacheInfo.getIsFinished());
         }
-        if(StrUtil.isNotEmpty(patientCurrentInfo.getCurrentDeviceId())){
-            result.put("currentDeviceId",patientCurrentInfo.getCurrentDeviceId());
+        if(StrUtil.isNotEmpty(patientCacheInfo.getCurrentDeviceId())){
+            result.put("currentDeviceId", patientCacheInfo.getCurrentDeviceId());
         }
         return result;
     }
 
+
 }

+ 2 - 2
coffee-system/src/main/java/com/coffee/bus/registry/patient/PatientRegistry.java

@@ -1,7 +1,7 @@
 package com.coffee.bus.registry.patient;
 
 import com.coffee.bus.registry.Registry;
-import com.coffee.bus.registry.patient.bean.PatientCurrentInfo;
+import com.coffee.bus.registry.patient.bean.PatientCacheInfo;
 
 /**
  * @author lifang
@@ -23,5 +23,5 @@ public interface PatientRegistry extends Registry {
      * 注册病人信息
      * @param basicInfo
      */
-    void register(PatientCurrentInfo basicInfo);
+    void register(PatientCacheInfo basicInfo);
 }

+ 2 - 1
coffee-system/src/main/java/com/coffee/bus/registry/patient/bean/PatientCurrentInfo.java → coffee-system/src/main/java/com/coffee/bus/registry/patient/bean/PatientCacheInfo.java

@@ -14,8 +14,9 @@ import java.util.Date;
  * @createTime 2022年04月02日 16:19:00
  */
 @Data
-public class PatientCurrentInfo implements CacheInfo {
+public class PatientCacheInfo implements CacheInfo {
     private String key;
+
     /******病人信息***********/
     private String patientCode;
     private SexEnum patientGender;

+ 24 - 1
coffee-system/src/main/java/com/coffee/bus/service/LocalBusDeviceService.java

@@ -1,5 +1,7 @@
 package com.coffee.bus.service;
 
+import cn.hutool.core.util.StrUtil;
+import com.coffee.bus.registry.device.DeviceOperator;
 import com.coffee.bus.registry.device.DeviceRegistry;
 import com.coffee.bus.entity.BusDeviceEntity;
 import com.coffee.bus.mapper.BusDeviceMapper;
@@ -35,8 +37,29 @@ public class LocalBusDeviceService extends BaseService<BusDeviceMapper, BusDevic
 
     @Override
     public void validateBeforeDelete(String id) {
+
+    }
+
+    @Override
+    public void postSave(BusDeviceEntity entity) {
+
+    }
+
+    @Override
+    public void postUpdate(BusDeviceEntity entity) {
+        DeviceOperator deviceOperator = deviceRegistry
+                .getDevice(entity.getDeviceId());
+        if(StrUtil.isNotEmpty(entity.getAlias())){
+            deviceOperator.updateAlias(entity.getAlias());
+        }
+        if(entity.getEnable()!=null){
+            deviceOperator.updateEnable(entity.getEnable());
+        }
+    }
+
+    @Override
+    public void postDelete(String id) {
         BusDeviceEntity registeredEntity = this.getById(id);
         deviceRegistry.unRegister(registeredEntity.getDeviceId());
     }
-
 }

+ 69 - 16
coffee-system/src/main/java/com/coffee/bus/websocket/listener/DeviceInfoListener.java

@@ -1,9 +1,12 @@
 package com.coffee.bus.websocket.listener;
 
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.thread.ThreadUtil;
 import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.coffee.bus.registry.device.DeviceOperator;
 import com.coffee.bus.registry.device.DeviceRegistry;
@@ -11,7 +14,6 @@ import com.coffee.bus.entity.BusPumpEntity;
 import com.coffee.bus.enums.NetPumpStatusEnum;
 import com.coffee.bus.listener.event.bean.DeviceAlarmEvent;
 import com.coffee.bus.listener.event.bean.DeviceInfoEvent;
-import com.coffee.bus.registry.device.bean.DeviceBasicInfo;
 import com.coffee.bus.registry.patient.PatientOperator;
 import com.coffee.bus.registry.patient.PatientRegistry;
 import com.coffee.bus.service.LocalBusPumpService;
@@ -19,7 +21,6 @@ import com.coffee.bus.service.LocalBusPatientService;
 import com.coffee.common.config.websocket.WebSocketConstant;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.event.EventListener;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.scheduling.annotation.Async;
@@ -29,8 +30,10 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
+import java.util.function.Supplier;
 
 /**
  * @author lifang
@@ -46,7 +49,7 @@ public class DeviceInfoListener {
 
     private final RedisTemplate redisTemplate;
 
-    private final LocalBusPumpService deviceRunInfoService;
+    private final LocalBusPumpService deviceUsingService;
 
     private final LocalBusPatientService patientService;
 
@@ -64,10 +67,12 @@ public class DeviceInfoListener {
     @Async
     @Transactional(rollbackFor = Exception.class)
     public void deviceInfoDetail(DeviceInfoEvent infoEvent){
+        /****************处理泵数据****************/
         BusPumpEntity device = infoEvent.getContent();
         //1、判断该设备是否已和医院绑定并开启使用
         String deviceId = device.getDeviceId();
         DeviceOperator deviceOperator = deviceRegistry.getDevice(deviceId);
+        PatientOperator patientOperator =null;
         if (!deviceOperator.canUse()) {
             log.warn("设备[{}]暂不可用,数据已丢弃",deviceId);
             return ;
@@ -77,25 +82,74 @@ public class DeviceInfoListener {
         //首次运行需要与病人、医院进行绑定
         if(deviceOperator.isFirst()){
             initDevice(device,deviceOperator);
-            PatientOperator patientOperator = patientRegistry.getPatient(device.getTenantId(), device.getPatientCode());
+            patientOperator = patientRegistry.getPatient(device.getTenantId(), device.getPatientCode());
             initPatient(device,patientOperator);
             //二次确认
             deviceOperator = deviceRegistry.getDevice(deviceId);
             if(device.getId().equals(deviceOperator.getRunId())){
-                deviceRunInfoService.save(device);
+                deviceUsingService.save(device);
             }
-
         }
         else {
             device.setId(deviceOperator.getRunId());
-            deviceRunInfoService.updateById(device);
+            deviceUsingService.updateById(device);
+        }
+        /****************处理泵数据****************/
+
+        /****************处理泵与患者关系****************/
+        if(patientOperator==null){
+            patientOperator = patientRegistry.getPatient(device.getTenantId(), device.getPatientCode());
+        }
+        //泵绑定重复判定
+        if(StrUtil.isNotEmpty(patientOperator.getDeviceId())&&deviceId.equals(patientOperator.getDeviceId())){
+            //泵号发生改变,判断泵的开始时间,将开始时间稍后的泵设置为主泵再与设备绑定
+            DeviceOperator currentBindDevice = deviceRegistry.getDevice(patientOperator.getDeviceId());
+            if (currentBindDevice.getStartTime().before(device.getStartTime())) {
+                //设置当前上传信息的泵为主泵,将旧泵设置为副泵吗,并更新病人绑定泵的信息
+                deviceUsingService.update(new UpdateWrapper<BusPumpEntity>().lambda().eq(BusPumpEntity::getDeviceId,deviceId).set(BusPumpEntity::getMaster,1));
+                deviceUsingService.update(new UpdateWrapper<BusPumpEntity>().lambda().eq(BusPumpEntity::getDeviceId,patientOperator.getDeviceId()).set(BusPumpEntity::getMaster,0));
+                //todo 缓存更新放在最后
+                patientOperator.updateDeviceId(deviceId);
+            }
+        }else {
+            patientOperator.updateDeviceId(deviceId);
         }
 
-        //病号是否进行换泵操作
-//        if (patientService.isChangedDevice(device.getTenantId(),device.getPatientCode(),device.getDeviceId(),device.getStartTime())) {
-//            patientService.changePump(device.getTenantId(),device.getPatientCode(),device.getDeviceId());
-//        }
-        //发送设备报警
+        //当泵所绑定的病号发生变化时,进行无泵判定
+        if(device.getPatientCode().equals(deviceOperator.getPatientCode())){
+            //临床无泵绑定时,查看是否存在副泵,若存在将开始时间稍后的泵设置为副泵,若不存在,则报无泵异常
+            List<BusPumpEntity> usingDevices = deviceUsingService.list(new QueryWrapper<BusPumpEntity>().lambda()
+                    .eq(BusPumpEntity::getTenantId, device.getTenantId())
+                    .eq(BusPumpEntity::getPatientCode, device.getPatientCode()));
+            if(CollectionUtil.isEmpty(usingDevices)){
+                //todo 发起无泵报警
+
+            }else {
+                //将开始时间最大的泵设置为主泵
+                BusPumpEntity master = usingDevices.stream().max(new Comparator<BusPumpEntity>() {
+                    @Override
+                    public int compare(BusPumpEntity o1, BusPumpEntity o2) {
+                        return o1.getStartTime().before(o2.getStartTime()) ? 1 : 0;
+                    }
+                })
+                        .orElseGet(new Supplier<BusPumpEntity>() {
+                            @Override
+                            public BusPumpEntity get() {
+                                //todo 发起无泵报警
+                                return null;
+                            }
+                        });
+
+                if(master!=null){
+                    master.setMaster(1);
+                    deviceUsingService.updateById(master);
+                }
+
+            }
+        }
+
+        /****************处理泵与患者关系****************/
+
         if(!deviceOperator.isFirst()){
             //非首次注册,则推送设备消息
             String topic = WebSocketConstant.getDeviceInfoDetailTopic(null, device.getId(), device.getTenantId());
@@ -131,7 +185,7 @@ public class DeviceInfoListener {
             //存储报警信息 todo
             String topic = WebSocketConstant.getDeviceStateCount(null, runState.name(), pump.getTenantId());
             //获取报警设备数量
-            List<BusPumpEntity> alarmList = deviceRunInfoService.list(new QueryWrapper<BusPumpEntity>()
+            List<BusPumpEntity> alarmList = deviceUsingService.list(new QueryWrapper<BusPumpEntity>()
                     .lambda()
                     .select(BusPumpEntity::getId)
                     .eq(BusPumpEntity::getRunState, runState));
@@ -160,15 +214,14 @@ public class DeviceInfoListener {
         //设备绑定医院
         pump.setTenantId(deviceOperator.getTenantId());
 
-        //缓存存储泵的开始时间和注册时间
-        deviceOperator.updateRegisterTime(now);
+        //缓存存储泵的开始时间和注册时间 todo 缓存更新放在最后进行
         deviceOperator.updateStartTime(now);
         deviceOperator.updateRunId(pump.getId());
     }
 
     @Scheduled(cron = "0/50 * * * * ?")
     public void send(){
-//        List<BusPumpEntity> list = deviceRunInfoService.list();
+//        List<BusPumpEntity> list = deviceUsingService.list();
 //        list.forEach(pump->{
 
         ThreadUtil.concurrencyTest(5,()->  {

+ 1 - 0
coffee-system/src/main/java/com/coffee/system/common/dto/SysMenuAddDTO.java

@@ -112,4 +112,5 @@ public class SysMenuAddDTO implements Serializable {
     @NotBlank(message = "状态不能为空")
     private String status;
 
+    private String tenantId;
 }