Browse Source

Merge remote-tracking branch 'origin/dev' into dev

15638522405 3 years ago
parent
commit
e71aa8e127
30 changed files with 300 additions and 244 deletions
  1. 1 1
      coffee-admin/Dockerfile
  2. BIN
      coffee-admin/src/main/resources/python/jython-standalone-2.7.1.jar
  3. 6 6
      coffee-admin/src/test/java/com/coffee/admin/BusHospitalLogTest.java
  4. 5 3
      coffee-common/src/main/java/com/coffee/common/cache/value/SimpleValue.java
  5. 22 0
      coffee-common/src/main/java/com/coffee/common/entity/AbstractMsgId.java
  6. 2 2
      coffee-common/src/main/java/com/coffee/common/exception/ExecuteResult.java
  7. 22 0
      coffee-common/src/main/java/com/coffee/common/exception/ScriptException.java
  8. 5 0
      coffee-common/src/main/java/com/coffee/common/result/ResultCode.java
  9. 22 20
      coffee-common/src/main/java/com/coffee/common/util/RedissonUtil.java
  10. 37 118
      coffee-framework/src/main/java/com/coffee/framework/config/RedissonClientAutoConfiguration.java
  11. 9 0
      coffee-framework/src/main/java/com/coffee/framework/web/exception/GlobalExceptionHandler.java
  12. 9 4
      coffee-system/src/main/java/com/coffee/bus/controller/BusConstantController.java
  13. 19 7
      coffee-system/src/main/java/com/coffee/bus/controller/BusHospitalController.java
  14. 1 1
      coffee-system/src/main/java/com/coffee/bus/entity/BusHospitalConfigEntity.java
  15. 27 14
      coffee-system/src/main/java/com/coffee/bus/entity/BusHospitalLogEntity.java
  16. 8 3
      coffee-system/src/main/java/com/coffee/bus/hospital/HospitalManager.java
  17. 7 4
      coffee-system/src/main/java/com/coffee/bus/hospital/HospitalManagerRegister.java
  18. 11 1
      coffee-system/src/main/java/com/coffee/bus/hospital/config/HospitalAutoUndoConfigHandler.java
  19. 13 9
      coffee-system/src/main/java/com/coffee/bus/hospital/config/HospitalFinishMonitorConfigHandler.java
  20. 10 12
      coffee-system/src/main/java/com/coffee/bus/hospital/config/HospitalFunctionAnalConfigHandler.java
  21. 13 12
      coffee-system/src/main/java/com/coffee/bus/hospital/config/HospitalFunctionExtraConfigHandler.java
  22. 1 1
      coffee-system/src/main/java/com/coffee/bus/hospital/config/bean/FunctionOtherConfig.java
  23. 17 4
      coffee-system/src/main/java/com/coffee/bus/hospital/his/HisScriptSession.java
  24. 5 3
      coffee-system/src/main/java/com/coffee/bus/hospital/his/HisScriptSessionManager.java
  25. 1 0
      coffee-system/src/main/java/com/coffee/bus/hospital/script/DefaultParse.java
  26. 17 10
      coffee-system/src/main/java/com/coffee/bus/hospital/script/PythonParse.java
  27. 2 3
      coffee-system/src/main/java/com/coffee/bus/hospital/script/ScriptManager.java
  28. 2 0
      coffee-system/src/main/java/com/coffee/bus/hospital/script/ScriptParse.java
  29. 1 1
      coffee-system/src/main/java/com/coffee/bus/service/LocalBusHospitalConfigService.java
  30. 5 5
      coffee-system/src/main/java/com/coffee/bus/websocket/listener/HisInfoListener.java

+ 1 - 1
coffee-admin/Dockerfile

@@ -1,12 +1,12 @@
 FROM docker.io/java:8
 
 ADD target/coffee-admin.jar /pump.jar
+ADD src/main/resources/python/jython-standalone-2.7.1.jar /jython-standalone-2.7.1.jar
 RUN bash -c "touch /pump.jar"
 ENV TZ 'Asia/Shanghai'
 ENV LANG en_US.UTF-8
 ENV LANGUAGE en_US:en
 ENV LC_ALL en_US.UTF-8
 
-#ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/pump.jar"]
 ENTRYPOINT ["java", "-jar", "/pump.jar"]
 EXPOSE 9090

BIN
coffee-admin/src/main/resources/python/jython-standalone-2.7.1.jar


+ 6 - 6
coffee-admin/src/test/java/com/coffee/admin/BusHospitalLogTest.java

@@ -33,12 +33,12 @@ public class BusHospitalLogTest {
     private BusHospitalLogController logController;
     @Test
     public void save(){
-        BusHospitalLogEntity logEntity = new BusHospitalLogEntity();
-        logEntity.setIp("192.168.100.32");
-        logEntity.setReceiveTime(new Date());
-        logEntity.setResult("success");
-        logEntity.setType(HospitalLogEnum.HEART);
-        logService.save(logEntity);
+//        BusHospitalLogEntity logEntity = new BusHospitalLogEntity();
+//        logEntity.setIp("192.168.100.32");
+//        logEntity.setReceiveTime(new Date());
+//        logEntity.setResult("success");
+//        logEntity.setType(HospitalLogEnum.HEART);
+//        logService.save(logEntity);
     }
 
     @Test

+ 5 - 3
coffee-common/src/main/java/com/coffee/common/cache/value/SimpleValue.java

@@ -3,7 +3,9 @@ package com.coffee.common.cache.value;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.EnumUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.annotation.IEnum;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.yaml.snakeyaml.util.EnumUtils;
@@ -49,7 +51,7 @@ public class SimpleValue implements Value {
         }
         if (targetClass == Date.class) {
             if (source instanceof String) {
-               return (T) DateUtil.parse(String.valueOf(source));
+                return (T) DateUtil.parse(String.valueOf(source));
             }
             if (source instanceof Number) {
                 return (T) new Date(((Number) source).longValue());
@@ -114,7 +116,7 @@ public class SimpleValue implements Value {
                 T[] enumConstants = targetClass.getEnumConstants();
                 for (T enumConstant : enumConstants) {
                     if (String.valueOf(source).equals(( (Enum)enumConstant).ordinal())
-                    ||String.valueOf(source).equals(( (Enum)enumConstant).name())) {
+                            ||String.valueOf(source).equals(( (Enum)enumConstant).name())) {
                         return enumConstant;
                     }
                 }
@@ -137,7 +139,7 @@ public class SimpleValue implements Value {
             List<?> val = convert(source, List.class, new Class[]{componentType});
             return (T) val.toArray((Object[]) Array.newInstance(componentType, val.size()));
         }
-            return null;
+        return JSONUtil.toBean(JSONUtil.parseObj(source),targetClass);
     }
 
     private Collection<?> newCollection(Class<?> targetClass) {

+ 22 - 0
coffee-common/src/main/java/com/coffee/common/entity/AbstractMsgId.java

@@ -0,0 +1,22 @@
+package com.coffee.common.entity;
+
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName AbstractMsgId.java
+ * @Description TODO
+ * @createTime 2022年05月23日 23:10:00
+ */
+@Data
+public abstract class AbstractMsgId implements Serializable {
+    private String id;
+
+    public AbstractMsgId() {
+        this.id= IdWorker.getIdStr();
+    }
+}

+ 2 - 2
coffee-system/src/main/java/com/coffee/bus/hospital/script/ExecuteResult.java → coffee-common/src/main/java/com/coffee/common/exception/ExecuteResult.java

@@ -1,4 +1,4 @@
-package com.coffee.bus.hospital.script;
+package com.coffee.common.exception;
 
 import cn.hutool.json.JSON;
 import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -14,7 +14,7 @@ import java.util.function.Supplier;
 public class ExecuteResult {
     @ApiModelProperty("脚本是否执行成功")
     private boolean success;
-    @ApiModelProperty("脚本输入参数成功")
+    @ApiModelProperty("脚本输入参数")
     private String input;
     @ApiModelProperty("脚本输出")
     private JSON result;

+ 22 - 0
coffee-common/src/main/java/com/coffee/common/exception/ScriptException.java

@@ -0,0 +1,22 @@
+package com.coffee.common.exception;
+
+import lombok.Data;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName ScriptException.java
+ * @Description TODO
+ * @createTime 2022年05月24日 11:51:00
+ */
+@Data
+public class ScriptException  extends RuntimeException  {
+    private ExecuteResult executeResult;
+
+    public ScriptException(String message) {
+        super(message);
+        this.executeResult=new ExecuteResult();
+        executeResult.setSuccess(false);
+        executeResult.setMessage(message);
+    }
+}

+ 5 - 0
coffee-common/src/main/java/com/coffee/common/result/ResultCode.java

@@ -19,6 +19,11 @@ public enum ResultCode implements IResultCode {
      */
     SUCCESS(HttpServletResponse.SC_OK, "操作成功"),
 
+    /**
+     * 操作成功
+     */
+    SCRIPT_ERROR(HttpServletResponse.SC_OK,"解析脚本错误"),
+
     /**
      * 业务异常
      */

+ 22 - 20
coffee-common/src/main/java/com/coffee/common/util/RedissonUtil.java

@@ -1,9 +1,12 @@
 package com.coffee.common.util;
 
 
+import cn.hutool.json.JSONUtil;
+import com.coffee.common.entity.AbstractMsgId;
 import io.netty.channel.DefaultEventLoop;
 import io.netty.channel.EventLoopGroup;
 import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.*;
 import org.redisson.client.codec.Codec;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -16,22 +19,24 @@ import java.util.function.Consumer;
 /**
  * @author lifang
  * @version 1.0.0
- * @ClassName RedissonUtil.java
+ * @ClassName RedssionUtil.java
  * @Description TODO
  * @createTime 2022年05月17日 16:16:00
  */
 @Component
+@Slf4j
 public class RedissonUtil {
 
     @Autowired
     @Getter
     private RedissonClient redissonClient;
 
-    private static Map<String,RDelayedQueue<Object>> delayedQueueMap=new ConcurrentHashMap<>();
+    private static Map<String,RDelayedQueue<AbstractMsgId>> delayedQueueMap=new ConcurrentHashMap<>();
 
-    private static Map<String,RBlockingDeque<Object>> blockingDequeMap=new ConcurrentHashMap<>();
+    private static Map<String,RBlockingQueue<AbstractMsgId>> blockingDequeMap=new ConcurrentHashMap<>();
 
     private static Map<String,RLock> lockMap=new ConcurrentHashMap<>();
+
     private EventLoopGroup eventLoopGroup=new DefaultEventLoop();
 
     public RPatternTopic getPatternTopic(String pattern){
@@ -46,30 +51,27 @@ public class RedissonUtil {
         return redissonClient.getTopic(pattern,codec);
     }
 
-    public RDelayedQueue getDelayedQueue(String name, Consumer<Object> consumer){
+    public void offerQueue(RDelayedQueue<AbstractMsgId> delayedQueue,AbstractMsgId msg,long delay, TimeUnit timeUnit){
+        delayedQueue.offerAsync(msg,delay,timeUnit);
+    }
+
+    public void clearQueue(RQueue<AbstractMsgId> queue){
+        queue.deleteAsync();
+    }
+
+    public RDelayedQueue<AbstractMsgId> getDelayedQueue(String name, Consumer<AbstractMsgId> consumer){
         name="queue:"+name;
         synchronized (name){
             if(!blockingDequeMap.containsKey(name)){
                 String lockName="lock:"+name;
-                RBlockingDeque<Object> value = redissonClient.getBlockingDeque(name);
-                delayedQueueMap.putIfAbsent(name,redissonClient.getDelayedQueue(value));
+                RBlockingQueue<AbstractMsgId> destinationQueue   = redissonClient.getBlockingQueue(name);
+                delayedQueueMap.putIfAbsent(name,redissonClient.getDelayedQueue(destinationQueue));
                 lockMap.putIfAbsent(lockName,redissonClient.getLock(lockName));
-                value.subscribeOnElements(i->{
+                blockingDequeMap.put(name,destinationQueue);
+                destinationQueue.subscribeOnElements(i->{
                     //开启新的线程消费,唯一线程消费,不可阻塞该异步线程
                     eventLoopGroup.submit(() -> {
-                        RLock lock = lockMap.get(lockName);
-                        try {
-                            if (lock.tryLock(-1,20,TimeUnit.SECONDS)) {
-                                try {
-                                    consumer.accept(i);
-                                    value.popAsync();
-                                }finally {
-                                    lock.unlockAsync();
-                                }
-                            }
-                        } catch (InterruptedException e) {
-                            e.printStackTrace();
-                        }
+                        consumer.accept(i);
                     });
                 });
             }

+ 37 - 118
coffee-framework/src/main/java/com/coffee/framework/config/RedissonClientAutoConfiguration.java

@@ -7,10 +7,7 @@ package com.coffee.framework.config;
 
 import org.redisson.Redisson;
 import org.redisson.api.RedissonClient;
-import org.redisson.config.ClusterServersConfig;
-import org.redisson.config.Config;
-import org.redisson.config.SentinelServersConfig;
-import org.redisson.config.SingleServerConfig;
+import org.redisson.config.*;
 import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
 import org.redisson.spring.starter.RedissonProperties;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -24,21 +21,16 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
 import org.springframework.core.io.Resource;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.core.RedisOperations;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.util.ReflectionUtils;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
+import java.time.Duration;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 @Configuration
 @ConditionalOnClass({Redisson.class, RedisOperations.class})
@@ -51,8 +43,7 @@ public class RedissonClientAutoConfiguration {
         required = false
     )
     private List<RedissonAutoConfigurationCustomizer> redissonAutoConfigurationCustomizers;
-    @Autowired
-    private RedissonProperties redissonProperties;
+
     @Autowired
     private RedisProperties redisProperties;
     @Autowired
@@ -65,110 +56,38 @@ public class RedissonClientAutoConfiguration {
         destroyMethod = "shutdown"
     )
     @ConditionalOnMissingBean({RedissonClient.class})
-    public RedissonClient redisson() throws IOException {
-        Config config = null;
-        Method clusterMethod = ReflectionUtils.findMethod(RedisProperties.class, "getCluster");
-        Method timeoutMethod = ReflectionUtils.findMethod(RedisProperties.class, "getTimeout");
-        Object timeoutValue = ReflectionUtils.invokeMethod(timeoutMethod, this.redisProperties);
-        int timeout;
-        Method nodesMethod;
-        if (null == timeoutValue) {
-            timeout = 10000;
-        } else if (!(timeoutValue instanceof Integer)) {
-            nodesMethod = ReflectionUtils.findMethod(timeoutValue.getClass(), "toMillis");
-            timeout = ((Long) ReflectionUtils.invokeMethod(nodesMethod, timeoutValue)).intValue();
-        } else {
-            timeout = (Integer)timeoutValue;
-        }
-
-        if (this.redissonProperties.getConfig() != null) {
-            try {
-                config = Config.fromYAML(this.redissonProperties.getConfig());
-            } catch (IOException var13) {
-                try {
-                    config = Config.fromJSON(this.redissonProperties.getConfig());
-                } catch (IOException var12) {
-                    throw new IllegalArgumentException("Can't parse config", var12);
-                }
-            }
-        } else if (this.redissonProperties.getFile() != null) {
-            try {
-                InputStream is = this.getConfigStream();
-                config = Config.fromYAML(is);
-            } catch (IOException var11) {
-                try {
-                    InputStream is = this.getConfigStream();
-                    config = Config.fromJSON(is);
-                } catch (IOException var10) {
-                    throw new IllegalArgumentException("Can't parse config", var10);
-                }
-            }
-        } else if (this.redisProperties.getSentinel() != null) {
-            nodesMethod = ReflectionUtils.findMethod(Sentinel.class, "getNodes");
-            Object nodesValue = ReflectionUtils.invokeMethod(nodesMethod, this.redisProperties.getSentinel());
-            String[] nodes;
-            if (nodesValue instanceof String) {
-                nodes = this.convert(Arrays.asList(((String)nodesValue).split(",")));
-            } else {
-                nodes = this.convert((List)nodesValue);
-            }
-
-            config = new Config();
-            ((SentinelServersConfig)config.useSentinelServers().setMasterName(this.redisProperties.getSentinel().getMaster()).addSentinelAddress(nodes).setDatabase(this.redisProperties.getDatabase()).setConnectTimeout(timeout)).setPassword(this.redisProperties.getPassword());
-        } else {
-            Method method;
-            if (clusterMethod != null && ReflectionUtils.invokeMethod(clusterMethod, this.redisProperties) != null) {
-                Object clusterObject = ReflectionUtils.invokeMethod(clusterMethod, this.redisProperties);
-                method = ReflectionUtils.findMethod(clusterObject.getClass(), "getNodes");
-                List<String> nodesObject = (List) ReflectionUtils.invokeMethod(method, clusterObject);
-                String[] nodes = this.convert(nodesObject);
-                config = new Config();
-                ((ClusterServersConfig)config.useClusterServers().addNodeAddress(nodes).setConnectTimeout(timeout)).setPassword(this.redisProperties.getPassword());
-            } else {
-                config = new Config();
-                String prefix = "redis://";
-                method = ReflectionUtils.findMethod(RedisProperties.class, "isSsl");
-                if (method != null && (Boolean) ReflectionUtils.invokeMethod(method, this.redisProperties)) {
-                    prefix = "rediss://";
-                }
-
-                ((SingleServerConfig)config.useSingleServer().setAddress(prefix + this.redisProperties.getHost() + ":" + this.redisProperties.getPort()).setConnectTimeout(timeout)).setDatabase(this.redisProperties.getDatabase()).setPassword(this.redisProperties.getPassword());
-            }
-        }
-
-        if (this.redissonAutoConfigurationCustomizers != null) {
-            Iterator var19 = this.redissonAutoConfigurationCustomizers.iterator();
-
-            while(var19.hasNext()) {
-                RedissonAutoConfigurationCustomizer customizer = (RedissonAutoConfigurationCustomizer)var19.next();
-                customizer.customize(config);
-            }
-        }
-
+    public RedissonClient redisson() {
+        Config config = new Config();
+        SingleServerConfig singleServerConfig= config.useSingleServer();
+        singleServerConfig.setDatabase(redisProperties.getDatabase());
+        singleServerConfig.setPassword(redisProperties.getPassword());
+        singleServerConfig.setAddress("redis://"+redisProperties.getHost()+":"+redisProperties.getPort());
+        singleServerConfig.setPingConnectionInterval(0);
+        //  如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒。默认10000
+        singleServerConfig.setIdleConnectionTimeout(30000);
+        //建立连接时的等待超时。时间单位是毫秒。默认10000
+        singleServerConfig.setConnectTimeout(Long.valueOf(Optional.ofNullable(redisProperties.getConnectTimeout()).orElse(Duration.ofSeconds(3)).toMillis()).intValue());
+        //等待节点回复命令的时间。该时间从命令发送成功时开始计时。默认3000
+        singleServerConfig.setTimeout(Long.valueOf(Optional.ofNullable(redisProperties.getTimeout()).orElse(Duration.ofSeconds(3)).toMillis()).intValue());
+        //命令失败重试次数,如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误,如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。
+        singleServerConfig.setRetryAttempts(3);
+        //在一条命令发送失败以后,等待重试发送的时间间隔。时间单位是毫秒。默认1500
+        singleServerConfig.setRetryInterval(1500);
+        //每个连接的最大订阅数量。默认5
+        singleServerConfig.setSubscriptionsPerConnection(5000);
+        //在Redis节点里显示的客户端名称。默认null
+        singleServerConfig.setClientName("nb");
+        //用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能,长期保持一定数量的发布订阅连接是必须的。默认1
+        singleServerConfig.setSubscriptionConnectionMinimumIdleSize(1);
+        //多从节点的环境里,每个从服务节点里用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。默认50
+        singleServerConfig.setSubscriptionConnectionPoolSize(500);
+        //是否保持连接
+        singleServerConfig.setKeepAlive(false);
+        //这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。默认当前处理核数量 * 2
+        config.setThreads(Runtime.getRuntime().availableProcessors()*2);
+        // 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。
+        config.setThreads(Runtime.getRuntime().availableProcessors()*2);
+        config.setTransportMode(TransportMode.NIO);
         return Redisson.create(config);
     }
-
-    private String[] convert(List<String> nodesObject) {
-        List<String> nodes = new ArrayList(nodesObject.size());
-        Iterator var3 = nodesObject.iterator();
-
-        while(true) {
-            while(var3.hasNext()) {
-                String node = (String)var3.next();
-                if (!node.startsWith("redis://") && !node.startsWith("rediss://")) {
-                    nodes.add("redis://" + node);
-                } else {
-                    nodes.add(node);
-                }
-            }
-
-            return (String[])nodes.toArray(new String[nodes.size()]);
-        }
-    }
-
-    private InputStream getConfigStream() throws IOException {
-        Resource resource = this.ctx.getResource(this.redissonProperties.getFile());
-        InputStream is = resource.getInputStream();
-        return is;
-    }
 }

+ 9 - 0
coffee-framework/src/main/java/com/coffee/framework/web/exception/GlobalExceptionHandler.java

@@ -5,6 +5,7 @@ import cn.dev33.satoken.exception.NotPermissionException;
 import cn.dev33.satoken.exception.NotRoleException;
 import com.coffee.common.exception.CustomException;
 import com.coffee.common.exception.DemoModeException;
+import com.coffee.common.exception.ScriptException;
 import com.coffee.common.result.R;
 import com.coffee.common.result.ResultCode;
 import lombok.extern.slf4j.Slf4j;
@@ -36,6 +37,14 @@ public class GlobalExceptionHandler {
         return R.result(e.getCode(), e.getMessage());
     }
 
+    /**
+     * 业务异常
+     */
+    @ExceptionHandler(ScriptException.class)
+    public R businessException(ScriptException e) {
+        return R.success(e.getExecuteResult());
+    }
+
     @ExceptionHandler(NotLoginException.class)
     public R handleNotLoginException(NotLoginException e) {
         log.error(e.getMessage(), e);

+ 9 - 4
coffee-system/src/main/java/com/coffee/bus/controller/BusConstantController.java

@@ -1,5 +1,6 @@
 package com.coffee.bus.controller;
 
+import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
@@ -44,11 +45,12 @@ public class BusConstantController {
     }
 
     @PostMapping("/{type}/page")
+    @SaCheckPermission("bus:constant:query")
     @ApiImplicitParams({
             @ApiImplicitParam(name = "type",value = "常量类型",required = true,allowableValues = "mix,doctor,alarm",allowMultiple = true,dataTypeClass = ConstantEnum.class),
             @ApiImplicitParam(name = "query",value = "查询参数",required = true)
     })
-    @ApiOperation(value = "使用POST方式分页动态查询")
+    @ApiOperation(value = "使用POST方式分页动态查询",notes = "权限【bus:constant:query】")
     public R<IPage<?>> queryPager(@PathVariable("type") ConstantEnum type,@RequestBody QueryParamEntity<?> query) {
         AbstractConstantService constantService = constantHashMap.get(type);
         if(constantService==null){
@@ -58,11 +60,12 @@ public class BusConstantController {
     }
 
     @PostMapping("/{type}/remove")
+    @SaCheckPermission("bus:constant:delete")
     @ApiImplicitParams({
             @ApiImplicitParam(name = "id",value = "主键id",required = true),
             @ApiImplicitParam(name = "type",value = "常量类型",required = true,allowableValues = "mix,doctor,alarm",allowMultiple = true,dataTypeClass = ConstantEnum.class)
     })
-    @ApiOperation(value = "根据ID删除")
+    @ApiOperation(value = "根据ID删除",notes = "权限【bus:constant:delete】")
     public R delete(@PathVariable("type") ConstantEnum type,@RequestParam("id") Serializable id) {
         if(StrUtil.isNullOrUndefined(String.valueOf(id))){
             return R.success();
@@ -77,7 +80,8 @@ public class BusConstantController {
     }
 
     @PostMapping("/save/{type}")
-    @ApiOperation(value = "新增数据")
+    @SaCheckPermission("bus:constant:add")
+    @ApiOperation(value = "新增数据",notes = "权限【bus:constant:add】")
     @ApiImplicitParams({
             @ApiImplicitParam(name = "type",value = "常量类型",required = true,allowableValues = "doctor,alarm,mix",allowMultiple = true,dataTypeClass = ConstantEnum.class)
     })
@@ -90,7 +94,8 @@ public class BusConstantController {
     }
 
     @PostMapping("/update/{type}")
-    @ApiOperation(value = "更新数据")
+    @SaCheckPermission("bus:constant:edit")
+    @ApiOperation(value = "更新数据",notes = "权限【bus:constant:edit】")
     @ApiImplicitParams({
             @ApiImplicitParam(name = "type",value = "常量类型",required = true,allowableValues = "doctor,alarm,mix",allowMultiple = true,dataTypeClass = ConstantEnum.class)
     })

+ 19 - 7
coffee-system/src/main/java/com/coffee/bus/controller/BusHospitalController.java

@@ -5,6 +5,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.annotation.SaMode;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.mapper.Mapper;
 import com.coffee.bus.bean.Script;
@@ -22,6 +23,7 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.AllArgsConstructor;
+import org.simpleframework.xml.Attribute;
 import org.springframework.web.bind.annotation.*;
 
 /**
@@ -55,7 +57,8 @@ public class BusHospitalController extends BaseCrudController<BusHospitalEntity,
     }
 
     @PostMapping("/{id}/script")
-    @ApiOperation(value = "保存医院信息解析脚本")
+    @SaCheckPermission("bus:hospital:script:save")
+    @ApiOperation(value = "保存医院信息解析脚本",notes = "保存医院信息解析脚本,权限【bus:hospital:script:save】")
     public R script(@PathVariable("id") String id,@RequestBody Script script){
         BusHospitalEntity busHospitalEntity = new BusHospitalEntity();
         busHospitalEntity.setId(id);
@@ -68,15 +71,15 @@ public class BusHospitalController extends BaseCrudController<BusHospitalEntity,
     }
 
     @PostMapping("/debug")
-    @SaCheckPermission("bus:hospital:script")
-    @ApiOperation(value = "执行解析脚本",notes = "医院必选,根据入参执行解析脚本,权限【bus:hospital:script】")
+    @SaCheckPermission("bus:hospital:script:query")
+    @ApiOperation(value = "执行解析脚本",notes = "医院必选,根据入参执行解析脚本,权限【bus:hospital:script:query】")
     public R debug(@RequestBody ExecScript execScript){
         return R.success( scriptManager.debug(execScript.getContent(),execScript.getInput()));
     }
 
     @PostMapping("/draft/script")
-    @SaCheckPermission("bus:hospital:script")
-    @ApiOperation(value = "保存脚本草稿脚本",notes = "医院必选,保存脚本草稿脚本,权限【bus:hospital:script】")
+    @SaCheckPermission("bus:hospital:script:edit")
+    @ApiOperation(value = "保存脚本草稿脚本",notes = "医院必选,保存脚本草稿脚本,权限【bus:hospital:script:edit】")
     public R draftScript(@RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId, @RequestBody Script script){
         scriptManager.check(script.getContent(),script.getType());
         hospitalService.update(new UpdateWrapper<BusHospitalEntity>().lambda().eq(BusHospitalEntity::getId,tenantId)
@@ -85,8 +88,8 @@ public class BusHospitalController extends BaseCrudController<BusHospitalEntity,
     }
 
     @PostMapping("/publish/script")
-    @SaCheckPermission("bus:hospital:script")
-    @ApiOperation(value = "发布脚本",notes = "医院必选,发布脚本,发布后即用该脚本解析his数据,权限【bus:hospital:script】")
+    @SaCheckPermission("bus:hospital:script:pub")
+    @ApiOperation(value = "发布脚本",notes = "医院必选,发布脚本,发布后即用该脚本解析his数据,权限【bus:hospital:script:pub】")
     public R publishScript(@RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId){
         BusHospitalEntity hospital = hospitalService.getById(tenantId);
         if (ObjectUtil.isNull(hospital.getScript())||StrUtil.isEmpty(hospital.getScript().getContent())) {
@@ -120,4 +123,13 @@ public class BusHospitalController extends BaseCrudController<BusHospitalEntity,
     public R<Boolean> validate(@RequestBody String name){
         return R.success(this.hospitalService.validateName(name));
     }
+
+
+    @PostMapping("/look/script")
+    @SaCheckPermission("bus:hospital:script:query")
+    @ApiOperation(value = "查看医院脚本信息",notes = "His对接策略编辑,权限【bus:hospital:script:query】")
+    public R<BusHospitalEntity> lookScript(@RequestAttribute("tenantId") String id){
+        return R.success(this.hospitalService.getOne(new QueryWrapper<BusHospitalEntity>().lambda().select(BusHospitalEntity::getId,BusHospitalEntity::getScript,BusHospitalEntity::getStrategy,BusHospitalEntity::getDraftScript)
+                .eq(BusHospitalEntity::getId,id)));
+    }
 }

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

@@ -23,7 +23,7 @@ import java.util.Map;
 public class BusHospitalConfigEntity extends TenantGenericEntity<String,String>  {
 
 
-    @ApiModelProperty(value = "配置类型",example = "eval:评价配置,extra:其他设置,undo:撤泵配置",allowableValues = "eval:评价配置,extra:其他设置,undo:撤泵配置")
+    @ApiModelProperty(value = "配置类型",example = "eval:评价配置,other:其他设置,undo:撤泵配置",allowableValues = "eval:评价配置,other:其他设置,undo:撤泵配置")
     private ConfigEnum type;
 
     @TableField(typeHandler = FastjsonTypeHandler.class,javaType = true)

+ 27 - 14
coffee-system/src/main/java/com/coffee/bus/entity/BusHospitalLogEntity.java

@@ -1,11 +1,15 @@
 package com.coffee.bus.entity;
 
+import cn.hutool.json.JSON;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
 import com.coffee.bus.enums.HospitalLogEnum;
 import com.coffee.common.config.mybatis.DateToBigIntHandler;
 import com.coffee.common.entity.TenantGenericEntity;
+import com.coffee.common.exception.ExecuteResult;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -28,21 +32,30 @@ import java.util.Date;
 @ApiModel(value="医院数据传输日志", description="医院数据传输日志")
 public class BusHospitalLogEntity extends TenantGenericEntity<String,String> {
 
-    @ApiModelProperty(value = "医院数据接收时间")
-    private Date receiveTime;
+    @ApiModelProperty("脚本是否执行成功")
+    private boolean success;
 
-    @ApiModelProperty(value = "医院数据类型,0、心跳 1、病人信息")
-    private HospitalLogEnum  type;
+    @ApiModelProperty("输入参数")
+    private String input;
 
     @ApiModelProperty(value = "医院数据处理结果")
-    @Length(max = 255,message = "医院数据处理结果长度不得超过255个字节")
-    private String result;
-
-    @ApiModelProperty(value = "医院数据来源ip地址")
-    @Length(max = 255,message = "医院数据来源ip地址长度不得超过255个字节")
-    private String ip;
-
-    @ApiModelProperty(value = "元数据")
-    @Length(max = 1024,message = "元数据长度不得超过255个字节")
-    private String meta;
+    @TableField(typeHandler = FastjsonTypeHandler.class)
+    private JSON result;
+
+    @ApiModelProperty("错误消息")
+    private String message;
+
+    @ApiModelProperty("本消息处理运行时间")
+    private long useTime;
+
+    public static BusHospitalLogEntity of(ExecuteResult source,String tenantId){
+        BusHospitalLogEntity result = new BusHospitalLogEntity();
+        result.setTenantId(tenantId);
+        result.setInput(source.getInput());
+        result.setMessage(source.getMessage());
+        result.setResult(source.getResult());
+        result.setSuccess(source.isSuccess());
+        result.setUseTime(source.getUseTime());
+        return result;
+    }
 }

+ 8 - 3
coffee-system/src/main/java/com/coffee/bus/hospital/HospitalManager.java

@@ -60,6 +60,7 @@ public class HospitalManager {
 
     private LocalBusDeviceAlarmService alarmService;
 
+    private LocalBusHospitalLogService hospitalLogService;
     public HospitalManager(String hospitalId,
                            LocalBusHospitalService hospitalService,
                            LocalBusHospitalConfigService hospitalConfigService,
@@ -71,7 +72,9 @@ public class HospitalManager {
                            WsPublishUtils wsPublishUtils,
                            ScriptManager scriptManager,
                            ConfigStorageManager configStorageManager,
-                           RedissonUtil redissonUtil) {
+                           RedissonUtil redissonUtil,
+                           LocalBusDeviceAlarmService alarmService,
+                           LocalBusHospitalLogService hospitalLogService) {
         this.hospitalId = hospitalId;
         this.hospitalService = hospitalService;
         this.hospitalConfigService = hospitalConfigService;
@@ -79,6 +82,8 @@ public class HospitalManager {
         this.scriptManager = scriptManager;
         this.hospitalId = hospitalId;
         this.storage=configStorageManager.getStorage(hospitalId);
+        this.alarmService=alarmService;
+        this.hospitalLogService=hospitalLogService;
         this.autoUndoConfigHandler=new HospitalAutoUndoConfigHandler(storage,hospitalId,redissonUtil,deviceRunningService,infusionHistoryService,deviceRegistry,wsPublishUtils,patientRegistry);
         this.finishMonitorConfigHandler=new HospitalFinishMonitorConfigHandler(storage,hospitalId,redissonUtil,deviceRunningService,infusionHistoryService,deviceRegistry,wsPublishUtils,patientRegistry);
         this.analConfigHandler=new HospitalFunctionAnalConfigHandler(storage,hospitalId,redissonUtil,deviceRunningService,infusionHistoryService,deviceRegistry,wsPublishUtils,patientRegistry,alarmService);
@@ -87,7 +92,7 @@ public class HospitalManager {
     }
 
     private void init(ConfigStorageManager configStorageManager){
-        this.scriptSession=new HisScriptSession(hospitalId,scriptManager,configStorageManager,clinicService,hospitalService);
+        this.scriptSession=new HisScriptSession(hospitalId,scriptManager,configStorageManager,clinicService,hospitalService,hospitalLogService);
         refreshInfo();
         refreshConfig();
         refreshScript();
@@ -137,7 +142,7 @@ public class HospitalManager {
                     FunctionAnalConfig anal = otherConfig.getAnal();
                     analConfigHandler.setConfig(anal);
                     //其他
-                    FunctionExtraConfig extraConfig = otherConfig.getExtra();
+                    FunctionExtraConfig extraConfig = otherConfig.getOther();
                     extraConfigHandler.setConfig(extraConfig);
                     break;
                 default:break;

+ 7 - 4
coffee-system/src/main/java/com/coffee/bus/hospital/HospitalManagerRegister.java

@@ -34,8 +34,9 @@ public class HospitalManagerRegister {
     private ScriptManager scriptManager;
     private ConfigStorageManager configStorageManager;
     private RedissonUtil redissonUtil;
-
-    public HospitalManagerRegister( LocalBusHospitalService hospitalService, LocalBusHospitalConfigService hospitalConfigService, LocalBusClinicService clinicService, LocalBusDeviceRunningService deviceRunningService, LocalBusInfusionHistoryService infusionHistoryService, PatientRegistry patientRegistry, DeviceRegistry deviceRegistry, WsPublishUtils wsPublishUtils, ScriptManager scriptManager, ConfigStorageManager configStorageManager, RedissonUtil redissonUtil) {
+    private LocalBusDeviceAlarmService alarmService;
+    private LocalBusHospitalLogService hospitalLogService;
+    public HospitalManagerRegister( LocalBusHospitalService hospitalService, LocalBusHospitalConfigService hospitalConfigService, LocalBusClinicService clinicService, LocalBusDeviceRunningService deviceRunningService, LocalBusInfusionHistoryService infusionHistoryService, PatientRegistry patientRegistry, DeviceRegistry deviceRegistry, WsPublishUtils wsPublishUtils, ScriptManager scriptManager, ConfigStorageManager configStorageManager,LocalBusDeviceAlarmService alarmService,LocalBusHospitalLogService hospitalLogService, RedissonUtil redissonUtil) {
         this.hospitalService = hospitalService;
         this.hospitalConfigService = hospitalConfigService;
         this.clinicService = clinicService;
@@ -47,17 +48,19 @@ public class HospitalManagerRegister {
         this.scriptManager = scriptManager;
         this.configStorageManager = configStorageManager;
         this.redissonUtil = redissonUtil;
+        this.alarmService=alarmService;
+        this.hospitalLogService=hospitalLogService;
     }
 
     public void register(String hospitalId){
         managerMap.computeIfAbsent(hospitalId,k->
-                new HospitalManager(k,hospitalService,hospitalConfigService,clinicService,deviceRunningService,infusionHistoryService,patientRegistry,deviceRegistry,wsPublishUtils,scriptManager,configStorageManager,redissonUtil)
+                new HospitalManager(k,hospitalService,hospitalConfigService,clinicService,deviceRunningService,infusionHistoryService,patientRegistry,deviceRegistry,wsPublishUtils,scriptManager,configStorageManager,redissonUtil,alarmService,hospitalLogService)
         );
     };
 
     public HospitalManager get(String hospitalId){
         return  managerMap.computeIfAbsent(hospitalId,k->
-                new HospitalManager(k,hospitalService,hospitalConfigService,clinicService,deviceRunningService,infusionHistoryService,patientRegistry,deviceRegistry,wsPublishUtils,scriptManager,configStorageManager,redissonUtil)
+                new HospitalManager(k,hospitalService,hospitalConfigService,clinicService,deviceRunningService,infusionHistoryService,patientRegistry,deviceRegistry,wsPublishUtils,scriptManager,configStorageManager,redissonUtil,alarmService,hospitalLogService)
         );
     }
 

+ 11 - 1
coffee-system/src/main/java/com/coffee/bus/hospital/config/HospitalAutoUndoConfigHandler.java

@@ -14,6 +14,7 @@ import com.coffee.bus.service.dto.ManualUndoConfig;
 import com.coffee.bus.service.dto.UndoDeviceConfig;
 import com.coffee.bus.utils.WsPublishUtils;
 import com.coffee.common.cache.ConfigStorage;
+import com.coffee.common.entity.AbstractMsgId;
 import com.coffee.common.util.RedissonUtil;
 import lombok.Builder;
 import lombok.Data;
@@ -57,6 +58,15 @@ public class HospitalAutoUndoConfigHandler extends  AbstractHospitalConfigHandle
         judgeShutdown(source,config);
     }
 
+    /**
+     * 描述: 不在服务区处理
+     * @author lifang
+     * @date 2022/5/23 23:24
+     * @param device
+     * @param patientCode
+     * @param tenantId
+     * @return void
+     */
     public void judgeNoSignal(String device,String patientCode,String tenantId){
         FunctionFinishMonitorConfig config = this.getConfig().as(FunctionFinishMonitorConfig.class);
         if(config==null||!Boolean.TRUE.equals(config.isEnable())|| Objects.isNull(config.getNoSignalInterval())){
@@ -142,7 +152,7 @@ public class HospitalAutoUndoConfigHandler extends  AbstractHospitalConfigHandle
 
     @Data
     @Builder
-    static class UndoEntity{
+    static class UndoEntity extends AbstractMsgId {
         private String deviceId;
         private String patientCode;
         private UndoDeviceConfig config;

+ 13 - 9
coffee-system/src/main/java/com/coffee/bus/hospital/config/HospitalFinishMonitorConfigHandler.java

@@ -16,12 +16,13 @@ import com.coffee.bus.service.dto.ManualUndoConfig;
 import com.coffee.bus.service.dto.UndoDeviceConfig;
 import com.coffee.bus.utils.WsPublishUtils;
 import com.coffee.common.cache.ConfigStorage;
+import com.coffee.common.entity.AbstractMsgId;
 import com.coffee.common.util.RedissonUtil;
 import lombok.Builder;
 import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RDelayedQueue;
 
-import java.io.Serializable;
 import java.util.Date;
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
@@ -34,6 +35,7 @@ import java.util.stream.Collectors;
  * @Description 自动结束管理处理
  * @createTime 2022年05月19日 16:22:00
  */
+@Slf4j
 public class HospitalFinishMonitorConfigHandler extends AbstractHospitalConfigHandler<FunctionFinishMonitorConfig, BusDeviceRunningEntity>{
 
 
@@ -55,6 +57,7 @@ public class HospitalFinishMonitorConfigHandler extends AbstractHospitalConfigHa
     public void handler(BusDeviceRunningEntity source) {
         FunctionFinishMonitorConfig config = this.getConfig().as(FunctionFinishMonitorConfig.class);
         if(config==null||!Boolean.TRUE.equals(config.isEnable())||Objects.isNull(config.getShutDownInterval())){
+            log.warn("id:{},配置名称:{},不存在",hospitalId,getId());
             return;
         }
         judgeShutdown(source,config);
@@ -66,7 +69,7 @@ public class HospitalFinishMonitorConfigHandler extends AbstractHospitalConfigHa
         if(config==null||!Boolean.TRUE.equals(config.isEnable())|| Objects.isNull(config.getNoSignalInterval())){
             return;
         }
-        RDelayedQueue noSignalFinishDelay = redissonUtil.getDelayedQueue(getId() +"-noSignalFinish"+ "-" + tenantId + "-" +device, e -> {
+        RDelayedQueue<AbstractMsgId> noSignalFinishDelay = redissonUtil.getDelayedQueue(getId() +"-noSignalFinish"+ "-" + tenantId + "-" +device, e -> {
             if(e instanceof FinishMonitorEntity){
                 this.handleFinishMonitor((FinishMonitorEntity) e);
             }
@@ -82,7 +85,8 @@ public class HospitalFinishMonitorConfigHandler extends AbstractHospitalConfigHa
                 .tenantId(tenantId)
                 .timestamp(new Date())
                 .build();
-        noSignalFinishDelay.offer(finishMonitor,finishMonitor.getTimeout(),finishMonitor.getUnit());
+
+        redissonUtil.offerQueue(noSignalFinishDelay,finishMonitor,finishMonitor.getTimeout(),finishMonitor.getUnit());
     }
 
     /**
@@ -94,7 +98,7 @@ public class HospitalFinishMonitorConfigHandler extends AbstractHospitalConfigHa
      * @return void
      */
     private void judgeShutdown(BusDeviceRunningEntity source,FunctionFinishMonitorConfig config){
-        RDelayedQueue shutdownFinishDelay = redissonUtil.getDelayedQueue(getId() +"-ShutdownFinish"+ "-" + source.getTenantId() + "-" + source.getDeviceId(), e -> {
+        RDelayedQueue<AbstractMsgId> shutdownFinishDelay = redissonUtil.getDelayedQueue(getId() +"-ShutdownFinish"+ "-" + source.getTenantId() + "-" + source.getDeviceId(), e -> {
             if(e instanceof FinishMonitorEntity){
                 this.handleFinishMonitor((FinishMonitorEntity) e);
             }
@@ -102,7 +106,7 @@ public class HospitalFinishMonitorConfigHandler extends AbstractHospitalConfigHa
         UndoDeviceConfig undoDeviceConfig = new UndoDeviceConfig();
         undoDeviceConfig.setUndoBy(config.getUndoBy());
         //清空延迟队列消息
-        shutdownFinishDelay.clear();
+        redissonUtil.clearQueue(shutdownFinishDelay);
         if(DeviceStatusEnum.Shutdown.equals(source.getType())){
             FinishMonitorEntity finishMonitor = FinishMonitorEntity.builder()
                     .deviceId(source.getDeviceId())
@@ -113,16 +117,16 @@ public class HospitalFinishMonitorConfigHandler extends AbstractHospitalConfigHa
                     .tenantId(source.getTenantId())
                     .timestamp(new Date())
                     .build();
-            shutdownFinishDelay.offer(finishMonitor,config.getShutDownInterval(),finishMonitor.getUnit());
+            redissonUtil.offerQueue(shutdownFinishDelay,finishMonitor,config.getShutDownInterval(),finishMonitor.getUnit());
         }
 
         //不在服务区延迟队列清空
-        RDelayedQueue noSignalFinishDelay = redissonUtil.getDelayedQueue(getId() +"-noSignalFinish"+ "-" + source.getTenantId() + "-" +source.getDeviceId(), e -> {
+        RDelayedQueue<AbstractMsgId> noSignalFinishDelay = redissonUtil.getDelayedQueue(getId() +"-noSignalFinish"+ "-" + source.getTenantId() + "-" +source.getDeviceId(), e -> {
             if(e instanceof FinishMonitorEntity){
                 this.handleFinishMonitor((FinishMonitorEntity) e);
             }
         });
-        noSignalFinishDelay.clear();
+        redissonUtil.clearQueue(noSignalFinishDelay);
     }
 
     /**
@@ -157,7 +161,7 @@ public class HospitalFinishMonitorConfigHandler extends AbstractHospitalConfigHa
 
     @Data
     @Builder
-    static class FinishMonitorEntity implements Serializable {
+    static class FinishMonitorEntity extends AbstractMsgId {
         private String deviceId;
         private String patientCode;
         private UndoDeviceConfig config;

+ 10 - 12
coffee-system/src/main/java/com/coffee/bus/hospital/config/HospitalFunctionAnalConfigHandler.java

@@ -15,14 +15,13 @@ import com.coffee.bus.service.LocalBusDeviceRunningService;
 import com.coffee.bus.service.LocalBusInfusionHistoryService;
 import com.coffee.bus.utils.WsPublishUtils;
 import com.coffee.common.cache.ConfigStorage;
+import com.coffee.common.entity.AbstractMsgId;
 import com.coffee.common.util.RedissonUtil;
 import lombok.Builder;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RDelayedQueue;
-import org.redisson.api.RedissonClient;
 
-import java.io.Serializable;
 import java.util.Date;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
@@ -60,7 +59,7 @@ public class HospitalFunctionAnalConfigHandler extends AbstractHospitalConfigHan
     public void handler(BusDeviceRunningEntity source) {
         FunctionAnalConfig config = this.getConfig().as(FunctionAnalConfig.class);
         if(config==null){
-            log.warn("id:{},配置名称:{},不存在",getId(),hospitalId);
+            log.warn("id:{},配置名称:{},不存在",hospitalId,getId());
             return;
         }
         handlerAnal(source,config);
@@ -76,7 +75,7 @@ public class HospitalFunctionAnalConfigHandler extends AbstractHospitalConfigHan
      * @return void
      */
     private void handlerAnal(BusDeviceRunningEntity source,FunctionAnalConfig analConfig){
-        RDelayedQueue delayedQueue = redissonUtil.getDelayedQueue(getId() + "-" + source.getTenantId() + "-" + source.getDeviceId(), e -> {
+        RDelayedQueue<AbstractMsgId>  delayedQueue = redissonUtil.getDelayedQueue(getId() + "-" + source.getTenantId() + "-" + source.getDeviceId(), e -> {
             if(e instanceof AnalEntity){
                 this.judgeAnalPoor((AnalEntity) e);
             }
@@ -85,7 +84,7 @@ public class HospitalFunctionAnalConfigHandler extends AbstractHospitalConfigHan
         if(source.isNewInfusion()){
             //镇痛不足设置为false
             source.setWarnAnalgesicPoor(false);
-            delayedQueue.clear();
+            redissonUtil.clearQueue(delayedQueue);
         }
         Integer insufficientTime = analConfig.getInsufficientTime();
         Integer insufficientCount = analConfig.getInsufficientCount();
@@ -108,8 +107,7 @@ public class HospitalFunctionAnalConfigHandler extends AbstractHospitalConfigHan
                 .timestamp(new Date())
                 .infusionId(source.getInfusionId())
                 .build();
-
-        delayedQueue.offer(anal,anal.getTimeout(),anal.getUnit());
+        redissonUtil.offerQueue(delayedQueue,anal,anal.getTimeout(),anal.getUnit());
     }
 
 
@@ -122,7 +120,7 @@ public class HospitalFunctionAnalConfigHandler extends AbstractHospitalConfigHan
      */
     private void judgeAnalPoor(AnalEntity anal){
         //镇痛消失延迟队列
-        RDelayedQueue noneAnalDelayedQueue = redissonUtil.getDelayedQueue("none-" + getId()+"-" + anal.getTenantId()+"-" + anal.getDeviceId(), e -> {
+        RDelayedQueue<AbstractMsgId> noneAnalDelayedQueue = redissonUtil.getDelayedQueue("none-" + getId()+"-" + anal.getTenantId()+"-" + anal.getDeviceId(), e -> {
             if(e instanceof NoneAnalEntity){
                 handleNoneAnal((NoneAnalEntity) e);
             }
@@ -159,7 +157,7 @@ public class HospitalFunctionAnalConfigHandler extends AbstractHospitalConfigHan
                 BusDeviceAlarmEntity alarm = BusDeviceAlarmEntity.insufficient(anal.getDeviceId(),anal.getInfusionId(),anal.getHistoryId(),anal.getTenantId(),uploadTime);
                 alarmService.save(alarm);
             }
-            noneAnalDelayedQueue.clear();
+            redissonUtil.clearQueue(noneAnalDelayedQueue);
         }else {
             //没有触发阈值,发入镇痛消失处理
             FunctionAnalConfig config = this.getConfig().as(FunctionAnalConfig.class);
@@ -172,7 +170,7 @@ public class HospitalFunctionAnalConfigHandler extends AbstractHospitalConfigHan
                     .historyId(anal.getHistoryId())
                     .timestamp(new Date())
                     .build();
-            noneAnalDelayedQueue.offer(noneAnal,noneAnal.getTimeout(),noneAnal.getUnit());
+            redissonUtil.offerQueue(noneAnalDelayedQueue,noneAnal,noneAnal.getTimeout(),noneAnal.getUnit());
         }
     }
 
@@ -203,7 +201,7 @@ public class HospitalFunctionAnalConfigHandler extends AbstractHospitalConfigHan
     }
     @Data
     @Builder
-    static class AnalEntity implements Serializable {
+    static class AnalEntity extends AbstractMsgId {
         private String deviceId;
         private Integer pcaValidCount;
         private Integer pcaInvalidCount;
@@ -219,7 +217,7 @@ public class HospitalFunctionAnalConfigHandler extends AbstractHospitalConfigHan
 
     @Data
     @Builder
-    static class NoneAnalEntity implements Serializable {
+    static class NoneAnalEntity extends AbstractMsgId   {
         private String deviceId;
         private Integer timeout;
         private TimeUnit unit;

+ 13 - 12
coffee-system/src/main/java/com/coffee/bus/hospital/config/HospitalFunctionExtraConfigHandler.java

@@ -3,7 +3,6 @@ package com.coffee.bus.hospital.config;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.coffee.bus.entity.BusDeviceAlarmEntity;
-import com.coffee.bus.enums.ConfigEnum;
 import com.coffee.bus.hospital.config.bean.FunctionExtraConfig;
 import com.coffee.bus.entity.BusDeviceRunningEntity;
 import com.coffee.bus.entity.BusInfusionHistoryEntity;
@@ -17,13 +16,13 @@ import com.coffee.bus.service.LocalBusDeviceRunningService;
 import com.coffee.bus.service.LocalBusInfusionHistoryService;
 import com.coffee.bus.utils.WsPublishUtils;
 import com.coffee.common.cache.ConfigStorage;
+import com.coffee.common.entity.AbstractMsgId;
 import com.coffee.common.util.RedissonUtil;
 import lombok.Builder;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RDelayedQueue;
 
-import java.io.Serializable;
 import java.math.BigDecimal;
 import java.util.Date;
 import java.util.concurrent.TimeUnit;
@@ -65,7 +64,7 @@ public class HospitalFunctionExtraConfigHandler  extends  AbstractHospitalConfig
     public void handler(BusDeviceRunningEntity source) {
         FunctionExtraConfig config = this.getConfig().as(FunctionExtraConfig.class);
         if(config==null){
-            log.warn("id:{},配置名称:{},不存在",getId(),hospitalId);
+            log.warn("id:{},配置名称:{},不存在",hospitalId,getId());
             return;
         }
         if (config.getNoSignal()!=null&&config.getNoSignal()>0) {
@@ -85,14 +84,16 @@ public class HospitalFunctionExtraConfigHandler  extends  AbstractHospitalConfig
      * @return void
      */
     private void judgeNoSignal(BusDeviceRunningEntity source,int interval){
-        RDelayedQueue delayedQueue = redissonUtil.getDelayedQueue(getId() +"-signal"+ "-" + source.getTenantId() + "-" + source.getDeviceId(), e -> {
+        if(DeviceStatusEnum.Shutdown.equals(source.getRunState())){
+            return;
+        }
+        RDelayedQueue<AbstractMsgId> delayedQueue = redissonUtil.getDelayedQueue(getId() +"-signal"+ "-" + source.getTenantId() + "-" + source.getDeviceId(), e -> {
             if(e instanceof  NoSignalEntity){
                 this.handleNoSignal((NoSignalEntity) e);
             }
         });
         //清空延迟队列消息
-        delayedQueue.clear();
-
+        redissonUtil.clearQueue(delayedQueue);
         NoSignalEntity noSignal = NoSignalEntity.builder()
                 .deviceId(source.getDeviceId())
                 .patientCode(source.getPatientCode())
@@ -104,7 +105,7 @@ public class HospitalFunctionExtraConfigHandler  extends  AbstractHospitalConfig
                 .unit(TimeUnit.MINUTES)
                 .build();
         //将该次消息视为最后一次消息放入队列中
-        delayedQueue.offer(noSignal,noSignal.getTimeout(),noSignal.getUnit());
+        redissonUtil.offerQueue(delayedQueue,noSignal,noSignal.getTimeout(),noSignal.getUnit());
     }
 
     /**
@@ -153,7 +154,7 @@ public class HospitalFunctionExtraConfigHandler  extends  AbstractHospitalConfig
      * @return void
      */
     private void judgeLowInfusion(BusDeviceRunningEntity source,int interval){
-        RDelayedQueue delayedQueue = redissonUtil.getDelayedQueue(getId() +"-lowFusion"+ "-" + source.getTenantId() + "-" + source.getDeviceId(), e -> {
+        RDelayedQueue<AbstractMsgId> delayedQueue = redissonUtil.getDelayedQueue(getId() +"-lowFusion"+ "-" + source.getTenantId() + "-" + source.getDeviceId(), e -> {
             if(e instanceof  LowInfusionEntity){
                 handleLowInfusion((LowInfusionEntity)e);
             }
@@ -171,7 +172,7 @@ public class HospitalFunctionExtraConfigHandler  extends  AbstractHospitalConfig
                         .infusionId(source.getInfusionId())
                         .timestamp(new Date())
                         .build();
-                delayedQueue.offer(lowInfusionEntity,lowInfusionEntity.getTimeout(),lowInfusionEntity.getUnit());
+                redissonUtil.offerQueue(delayedQueue,lowInfusionEntity,lowInfusionEntity.getTimeout(),lowInfusionEntity.getUnit());
             }
 
 
@@ -179,7 +180,7 @@ public class HospitalFunctionExtraConfigHandler  extends  AbstractHospitalConfig
         }else {
             //输注量未超过阈值,取消低输注状态
             source.setWarnLowBattery(false);
-            delayedQueue.clear();
+            redissonUtil.clearQueue(delayedQueue);
         }
     }
 
@@ -217,7 +218,7 @@ public class HospitalFunctionExtraConfigHandler  extends  AbstractHospitalConfig
 
     @Data
     @Builder
-    static class NoSignalEntity implements Serializable {
+    static class NoSignalEntity extends AbstractMsgId {
         private String deviceId;
         private String patientCode;
         private Integer timeout;
@@ -230,7 +231,7 @@ public class HospitalFunctionExtraConfigHandler  extends  AbstractHospitalConfig
 
     @Data
     @Builder
-    static class LowInfusionEntity implements Serializable {
+    static class LowInfusionEntity extends AbstractMsgId   {
         private String deviceId;
         private Integer timeout;
         private TimeUnit unit;

+ 1 - 1
coffee-system/src/main/java/com/coffee/bus/hospital/config/bean/FunctionOtherConfig.java

@@ -17,7 +17,7 @@ import java.io.Serializable;
 @ApiModel("其他配置")
 public class FunctionOtherConfig implements Serializable {
     @ApiModelProperty("其他配置")
-    private FunctionExtraConfig extra;
+    private FunctionExtraConfig other;
     @ApiModelProperty("镇痛不足配置")
     private FunctionAnalConfig anal;
 }

+ 17 - 4
coffee-system/src/main/java/com/coffee/bus/hospital/his/HisScriptSession.java

@@ -14,9 +14,11 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.coffee.bus.entity.BusClinicEntity;
 import com.coffee.bus.entity.BusHospitalEntity;
+import com.coffee.bus.entity.BusHospitalLogEntity;
 import com.coffee.bus.listener.event.bean.HisEvent;
 import com.coffee.bus.hospital.script.DefaultParse;
-import com.coffee.bus.hospital.script.ExecuteResult;
+import com.coffee.bus.service.LocalBusHospitalLogService;
+import com.coffee.common.exception.ExecuteResult;
 import com.coffee.bus.hospital.script.ScriptManager;
 import com.coffee.bus.hospital.script.ScriptParse;
 import com.coffee.bus.service.LocalBusClinicService;
@@ -38,7 +40,6 @@ import org.tio.core.Tio;
 import org.tio.core.utils.TioUtils;
 import org.tio.websocket.common.WsResponse;
 
-import java.math.BigDecimal;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
@@ -61,13 +62,15 @@ public class HisScriptSession {
     private LocalBusClinicService clinicService;
     private ConfigStorage clusterConfigStorage;
     private LocalBusHospitalService hospitalService;
+    private LocalBusHospitalLogService hospitalLogService;
     private Map<String,HisRequest> hisRequestMap=new ConcurrentHashMap<>();
 
-    public HisScriptSession(String hospitalId, ScriptManager scriptManager, ConfigStorageManager configStorageManager, LocalBusClinicService clinicService, LocalBusHospitalService hospitalService) {
+    public HisScriptSession(String hospitalId, ScriptManager scriptManager, ConfigStorageManager configStorageManager, LocalBusClinicService clinicService, LocalBusHospitalService hospitalService, LocalBusHospitalLogService hospitalLogService) {
         this.hospitalId = hospitalId;
         this.scriptManager = scriptManager;
         this.clinicService = clinicService;
         this.hospitalService=hospitalService;
+        this.hospitalLogService=hospitalLogService;
         init(configStorageManager,hospitalId);
     }
 
@@ -115,6 +118,7 @@ public class HisScriptSession {
                 .messageId(messageId)
                 .patientCode(patientCode)
                 .sync(true)
+                .tenantId(this.hospitalId)
                 .timeout(timeout)
                 .timeUnit(unit)
                 .result(Arrays.asList(result))
@@ -152,6 +156,7 @@ public class HisScriptSession {
                 .messageId(messageId)
                 .patientCode(patientCode)
                 .sync(true)
+                .tenantId(this.hospitalId)
                 .timeout(timeout)
                 .timeUnit(unit)
                 .result(Arrays.asList(result))
@@ -197,6 +202,14 @@ public class HisScriptSession {
         }catch (Exception e){
             log.error("数据解析后转化为json失败,{},",text,e.getMessage());
             return null;
+        }finally {
+            BusHospitalLogEntity hospitalLog = BusHospitalLogEntity.of(exec, this.getHospitalId());
+            try {
+                hospitalLogService.save(hospitalLog);
+            }catch (Exception e){
+                log.error("医院日志存储异常,数据:【{}】",JSONUtil.toJsonStr(hospitalLog),e);
+            }
+
         }
         //数据解析完成后发布
         JSONArray jsonArray = JSONUtil.parseArray(result);
@@ -325,7 +338,7 @@ public class HisScriptSession {
                 List<DeferredResult<R<BusClinicEntity>>> results = hisRequest.getResult();
                 if(CollectionUtil.isNotEmpty(results)){
                     results.parallelStream().forEach(result->{
-                        if (requestTimestamp.getTime()+timeUnit.toMillis(timeout)>responseTimestamp.getTime()) {
+                        if (requestTimestamp.getTime()+timeUnit.toMillis(timeout)<responseTimestamp.getTime()) {
                             log.warn("请求[{}]已超时,请求时间[{}],响应时间[{}],是否为同步请求[{}]",messageId,requestTimestamp,responseTimestamp,sync);
                             if(sync){
                                 result.setErrorResult("响应超时");

+ 5 - 3
coffee-system/src/main/java/com/coffee/bus/hospital/his/HisScriptSessionManager.java

@@ -2,6 +2,7 @@ package com.coffee.bus.hospital.his;
 
 import com.coffee.bus.hospital.script.ScriptManager;
 import com.coffee.bus.service.LocalBusClinicService;
+import com.coffee.bus.service.LocalBusHospitalLogService;
 import com.coffee.bus.service.LocalBusHospitalService;
 import com.coffee.common.cache.manager.ClusterConfigStorageManager;
 import org.redisson.api.RedissonClient;
@@ -25,12 +26,13 @@ public class HisScriptSessionManager {
     private ScriptManager scriptManager;
     private LocalBusHospitalService hospitalService;
     private ClusterConfigStorageManager configStorageManager;
-
+    private LocalBusHospitalLogService hospitalLogService;
     @Autowired
-    public HisScriptSessionManager( LocalBusClinicService clinicService, ScriptManager scriptManager, LocalBusHospitalService hospitalService, ClusterConfigStorageManager configStorageManager) {
+    public HisScriptSessionManager( LocalBusClinicService clinicService, ScriptManager scriptManager, LocalBusHospitalService hospitalService, LocalBusHospitalLogService hospitalLogService, ClusterConfigStorageManager configStorageManager) {
         this.clinicService = clinicService;
         this.scriptManager = scriptManager;
         this.hospitalService = hospitalService;
+        this.hospitalLogService=hospitalLogService;
         this.configStorageManager = configStorageManager;
     }
 
@@ -53,7 +55,7 @@ public class HisScriptSessionManager {
      * @return HisScriptSession
      */
     public HisScriptSession register(String hospitalId){
-        return new HisScriptSession(hospitalId, scriptManager,configStorageManager, clinicService,hospitalService);
+        return new HisScriptSession(hospitalId, scriptManager,configStorageManager, clinicService,hospitalService,hospitalLogService);
     }
 
     /**

+ 1 - 0
coffee-system/src/main/java/com/coffee/bus/hospital/script/DefaultParse.java

@@ -1,6 +1,7 @@
 package com.coffee.bus.hospital.script;
 
 import cn.hutool.json.JSONUtil;
+import com.coffee.common.exception.ExecuteResult;
 
 /**
  * @author lifang

+ 17 - 10
coffee-system/src/main/java/com/coffee/bus/hospital/script/PythonParse.java

@@ -3,7 +3,8 @@ package com.coffee.bus.hospital.script;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSON;
 import cn.hutool.json.JSONUtil;
-import com.coffee.common.exception.CustomException;
+import com.coffee.common.exception.ExecuteResult;
+import com.coffee.common.exception.ScriptException;
 import lombok.extern.slf4j.Slf4j;
 import org.python.core.*;
 import org.python.util.PythonInterpreter;
@@ -25,14 +26,20 @@ public class PythonParse implements ScriptParse {
     private PyFunction pyFunction;
 
     public PythonParse() {
-//        Properties p = new Properties();
-//        p.setProperty("python.console.encoding", "UTF-8");
-//        PySystemState systemState = Py.getSystemState();
-////        PyString xml = new PyString("\\python-modules");
+        Properties props = new Properties();
+        props.setProperty("python.console.encoding", "UTF-8");
+        props.put("python.home", "\\jython-standalone-2.7.1.jar");
+        props.put("python.console.encoding", "UTF-8");
+        props.put("python.security.respectJavaAccessibility", "false");
+        props.put("python.import.site", "false");
+        Properties preprops = System.getProperties();
+        PythonInterpreter.initialize(preprops, props, new String[0]);
+        PySystemState systemState = Py.getSystemState();
+//        PyString standalone = new PyString("\\python-modules\\Lib");
 //        PyString xml = new PyString("E:\\software\\coffee-boot\\coffee-admin\\src\\main\\resources\\python");
-//        systemState.path.append(xml);
-//        PythonInterpreter.initialize(System.getProperties(), p, new String[] {});
-//        interpreter = new PythonInterpreter();
+//        systemState.path.append(standalone);
+        PythonInterpreter.initialize(System.getProperties(), props, new String[] {});
+        interpreter = new PythonInterpreter();
 
     }
 
@@ -55,11 +62,11 @@ public class PythonParse implements ScriptParse {
         try {
             interpreter.exec(Py.newStringUTF8(script));
         }catch (Exception e){
-            throw new CustomException("脚本错误,请检查后重试,"+e.toString());
+            throw new ScriptException("脚本错误,请检查后重试,"+e.toString());
         }
         pyFunction = interpreter.get(functionName(), PyFunction.class);
         if(pyFunction==null){
-            throw new CustomException("脚本不包含方法【{"+functionName()+"}】");
+            throw new ScriptException("脚本不包含方法【{"+functionName()+"}】");
         }
     }
 

+ 2 - 3
coffee-system/src/main/java/com/coffee/bus/hospital/script/ScriptManager.java

@@ -1,9 +1,8 @@
 package com.coffee.bus.hospital.script;
 
 import cn.hutool.core.collection.CollectionUtil;
-import com.coffee.bus.service.LocalBusHospitalService;
+import com.coffee.common.exception.ExecuteResult;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.CommandLineRunner;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.PostConstruct;
@@ -60,7 +59,7 @@ public class ScriptManager {
         hospital.put(hospitalId,scriptParse);
     }
 
-    public ExecuteResult debug(String script,String input){
+    public ExecuteResult debug(String script, String input){
         pythonParse.reset(script);
         return pythonParse.exec(input);
     }

+ 2 - 0
coffee-system/src/main/java/com/coffee/bus/hospital/script/ScriptParse.java

@@ -1,5 +1,7 @@
 package com.coffee.bus.hospital.script;
 
+import com.coffee.common.exception.ExecuteResult;
+
 /**
  * @author lifang
  * @version 1.0.0

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

@@ -132,7 +132,7 @@ public class LocalBusHospitalConfigService extends BaseService<BusHospitalConfig
         anal.setValid(true);
 
         FunctionOtherConfig result = new FunctionOtherConfig();
-        result.setExtra(extraConfig);
+        result.setOther(extraConfig);
         result.setAnal(anal);
         return JSONUtil.parseObj(result);
     }

+ 5 - 5
coffee-system/src/main/java/com/coffee/bus/websocket/listener/HisInfoListener.java

@@ -48,7 +48,7 @@ public class HisInfoListener {
         if(CollectionUtil.isEmpty(sources)){
             return;
         }
-//        try {
+        try {
             BusHospitalEntity hospital = hospitalService.getById(hospitalId);
             HisStrategyManager<? extends HisStrategyHandler> hisStrategyManager = managerRegister.get(hospital.getStrategy());
 
@@ -65,10 +65,10 @@ public class HisInfoListener {
                     //找到第一个匹配的处理器进行处理
                     .findFirst()
                     .ifPresent(handler-> handler.handle(sources,target));
-//        } catch (Exception e){
-//            log.error("解析his数据时出错,解析后数据:{},错误原因,{}",JSONUtil.toJsonStr(infoEvent),e.getLocalizedMessage());
-//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-//        }
+        } catch (Exception e){
+            log.error("解析his数据时出错,解析后数据:{},错误原因,{}",JSONUtil.toJsonStr(infoEvent),e.getLocalizedMessage());
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+        }
 
     }
 }