Ver código fonte

add 增加通知机器人
add 药品不可重复添加
fix 修复一些问题

A17404李放 3 anos atrás
pai
commit
3fa8b21dce
27 arquivos alterados com 631 adições e 32 exclusões
  1. 5 1
      nb-admin/src/main/resources/application-dev.yml
  2. 5 1
      nb-admin/src/main/resources/application-prod.yml
  3. 6 2
      nb-admin/src/main/resources/application.yml
  4. 57 0
      nb-admin/src/test/java/com/nb/admin/NotifyTest.java
  5. 38 0
      nb-common/src/main/java/com/nb/common/event/EventConfig.java
  6. 56 0
      nb-common/src/main/java/com/nb/common/notice/NotifyEnums.java
  7. 87 0
      nb-common/src/main/java/com/nb/common/notice/SystemMonitor.java
  8. 45 0
      nb-common/src/main/java/com/nb/common/notice/msg/AbstractMsg.java
  9. 28 0
      nb-common/src/main/java/com/nb/common/notice/msg/DiskMsg.java
  10. 32 0
      nb-common/src/main/java/com/nb/common/notice/msg/ErrorMsg.java
  11. 37 0
      nb-common/src/main/java/com/nb/common/notice/msg/LifeCycleMsg.java
  12. 50 0
      nb-common/src/main/java/com/nb/common/notice/msg/SysResourceMsg.java
  13. 33 0
      nb-common/src/main/java/com/nb/common/notice/wechat/EnterpriseWeChatMsg.java
  14. 15 0
      nb-common/src/main/java/com/nb/common/notice/wechat/EnterpriseWeChatMsgEnums.java
  15. 62 0
      nb-common/src/main/java/com/nb/common/notice/wechat/EnterpriseWeChatNotify.java
  16. 1 0
      nb-framework/src/main/java/com/nb/framework/config/SaTokenConfig.java
  17. 21 6
      nb-framework/src/main/java/com/nb/framework/logback/SystemLoggingAppender.java
  18. 4 1
      nb-system/src/main/java/com/nb/bus/entity/BusClinicEntity.java
  19. 6 2
      nb-system/src/main/java/com/nb/bus/hospital/his/HisScriptSession.java
  20. 2 2
      nb-system/src/main/java/com/nb/bus/service/LocalBusClinicService.java
  21. 18 2
      nb-system/src/main/java/com/nb/bus/service/LocalBusDrugService.java
  22. 6 6
      nb-system/src/main/java/com/nb/bus/service/LocalBusInfusionHistoryService.java
  23. 1 1
      nb-system/src/main/java/com/nb/bus/service/LocalBusPatientService.java
  24. 3 1
      nb-system/src/main/java/com/nb/bus/stats/report/WeightStatsReport.java
  25. 1 1
      nb-system/src/main/java/com/nb/bus/utils/WsPublishUtils.java
  26. 8 6
      nb-system/src/main/resources/mapper/bus/BusPatientMapper.xml
  27. 4 0
      pom.xml

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

@@ -127,4 +127,8 @@ aliyun:
   server-subscription:
     enable: true  # 是否开启阿里云物联网服务端订阅
   product:
-    productKey: a1ALlsBa2ZK
+    productKey: a1ALlsBa2ZK
+
+notify:
+  wechat:
+    url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=c3e093fe-5125-47d5-a171-0f4be2f61a78

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

@@ -129,4 +129,8 @@ aliyun:
   server-subscription:
     enable: false  # 是否开启阿里云物联网服务端订阅
   product:
-    productKey: he1f6YdSWHW
+    productKey: he1f6YdSWHW
+
+notify:
+  wechat:
+    url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=ebeb023b-6f39-4f08-bd5a-67c5f3653107

+ 6 - 2
nb-admin/src/main/resources/application.yml

@@ -80,10 +80,14 @@ mybatis-plus:
     default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
   type-aliases-package: com.nb.bus.entity
 
-
 captcha:
   enable: true
   width: 140
   height: 38
   #验证码过期时间 5min
-  expire: 300
+  expire: 300
+management:
+  endpoints:
+    web:
+      exposure:
+        include: heapdump,metrics

+ 57 - 0
nb-admin/src/test/java/com/nb/admin/NotifyTest.java

@@ -0,0 +1,57 @@
+package com.nb.admin;
+
+import cn.hutool.json.JSONUtil;
+import com.nb.common.notice.msg.DiskMsg;
+import com.nb.common.notice.msg.LifeCycleMsg;
+import com.nb.common.notice.wechat.EnterpriseWeChatNotify;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.redis.RedisHealthIndicator;
+import org.springframework.boot.actuate.system.DiskSpaceHealthIndicator;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.jws.Oneway;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.OperatingSystemMXBean;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName NotifyTest.java
+ * @Description TODO
+ * @createTime 2022年07月19日 16:13:00
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = AdminApplication.class)
+public class NotifyTest {
+    @Autowired(required = false)
+    EnterpriseWeChatNotify notify;
+
+    @Autowired
+    DiskSpaceHealthIndicator spaceHealthIndicator;
+
+    @Autowired
+    @Test
+    public void test(){
+        notify.send(LifeCycleMsg.of(true,"测试服务器"));
+        while (true){
+
+        }
+    }
+    @Test
+    public void disk(){
+        Map<String, Object> details = spaceHealthIndicator.getHealth(true).getDetails();
+        DiskMsg diskMsg = JSONUtil.parseObj(details).toBean(DiskMsg.class);
+        System.out.println(diskMsg);
+        System.out.println(JSONUtil.toJsonPrettyStr(details));
+    }
+    @Test
+    public void cpu(){
+
+    }
+}

+ 38 - 0
nb-common/src/main/java/com/nb/common/event/EventConfig.java

@@ -0,0 +1,38 @@
+package com.nb.common.event;
+
+import com.nb.common.notice.msg.LifeCycleMsg;
+import com.nb.common.notice.wechat.EnterpriseWeChatNotify;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName EventConfig.java
+ * @Description TODO
+ * @createTime 2022年07月19日 17:09:00
+ */
+@Configuration
+@ConditionalOnBean(EnterpriseWeChatNotify.class)
+public class EventConfig implements CommandLineRunner, DisposableBean {
+    @Autowired
+    private EnterpriseWeChatNotify notify;
+
+    @Value("${spring.application.name}")
+    private String applicationName;
+
+
+    @Override
+    public void destroy() throws Exception {
+        notify.send(LifeCycleMsg.of(true,applicationName));
+    }
+
+    @Override
+    public void run(String... args) throws Exception {
+        notify.send(LifeCycleMsg.of(false,applicationName));
+    }
+}

+ 56 - 0
nb-common/src/main/java/com/nb/common/notice/NotifyEnums.java

@@ -0,0 +1,56 @@
+package com.nb.common.notice;
+
+import cn.hutool.core.date.DateUtil;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName NotifyEnums.java
+ * @Description 通知类型
+ * @createTime 2022年07月19日 15:24:00
+ */
+@AllArgsConstructor
+@Getter
+public enum  NotifyEnums {
+    ERROR("系统运行错误日志通知"){
+        @Override
+        public String getMarkDownTitle() {
+            return String.format("%s\n" +
+                    "<font color=\"warning\">**%s**</font>,请相关同事注意。\n", DateUtil.now(),ERROR.text);
+        }
+    },
+    LIFECYCLE("服务器生命周期"){
+        @Override
+        public String getMarkDownTitle() {
+            return String.format("%s\n" +
+                    "<font color=\"info\">**%s**</font>,请相关同事注意。\n", DateUtil.now(),LIFECYCLE.text);
+        }
+    },
+    RESOURCE("服务器资源监控"){
+        @Override
+        public  String getMarkDownTitle() {
+            return String.format("%s\n" +
+                    "<font color=\"info\">**%s**</font>,请相关同事注意。\n", DateUtil.now(),RESOURCE.text);
+        }
+    },
+    INTERFACE("接口流量监控"){
+        @Override
+        public String getMarkDownTitle() {
+            return String.format("%s\n" +
+                    "<font color=\"info\">**%s**</font>,请相关同事注意。\n", DateUtil.now(),INTERFACE.text);
+        }
+    }
+    ;
+    private String text;
+
+    /**
+     * 描述: 获取相关通知的markDown标题
+     * @author lifang
+     * @date 2022/7/19 15:52
+     * @param
+     * @return String
+     */
+    public abstract String getMarkDownTitle();
+}

+ 87 - 0
nb-common/src/main/java/com/nb/common/notice/SystemMonitor.java

@@ -0,0 +1,87 @@
+package com.nb.common.notice;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.SneakyThrows;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.function.Function;
+
+@AllArgsConstructor
+@Getter
+public enum SystemMonitor {
+    systemCpuUsage("系统CPU使用率"),
+    systemCpuLoad("系统平均负载"),
+    jvmCpuUsage("JVM进程CPU使用率"),
+    freeSystemMemory("系统空闲内存"),
+    totalSystemMemory("系统总内存"),
+    openFileCount("已打开文件数"),
+    maxOpenFileCount("最大打开文件数"),
+    ;
+
+    private String text;
+
+    public double getValue() {
+        return getValue(name());
+    }
+    static OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean();
+
+    private static Map<String, Callable<Double>> items = new HashMap<>();
+
+        private static final List<String> OPERATING_SYSTEM_BEAN_CLASS_NAMES = Arrays.asList(
+            "com.sun.management.OperatingSystemMXBean", // HotSpot
+            "com.ibm.lang.management.OperatingSystemMXBean" // J9
+        );
+
+    private static Callable<Double> zero = () -> 0D;
+
+    private static Class<?> mxBeanClass;
+
+    private static void register(String item, String methodName, Function<Double, Double> mapping) {
+        try {
+            Method method = mxBeanClass.getMethod(methodName);
+            items.put(item, () -> mapping.apply(((Number) method.invoke(osMxBean)).doubleValue()));
+        } catch (Exception e) {
+
+        }
+    }
+
+    static {
+        for (String s : OPERATING_SYSTEM_BEAN_CLASS_NAMES) {
+            try {
+                mxBeanClass = Class.forName(s);
+            } catch (Exception ignore) {
+            }
+        }
+        try {
+            if (mxBeanClass != null) {
+                register(systemCpuUsage.name(), "getSystemCpuLoad", usage -> usage * 100D);
+                register(systemCpuLoad.name(), "getSystemLoadAverage", Function.identity());
+                register(jvmCpuUsage.name(), "getProcessCpuLoad", usage -> usage * 100D);
+                register(freeSystemMemory.name(), "getFreePhysicalMemorySize", val -> val / 1024 / 1024);
+                register(totalSystemMemory.name(), "getTotalPhysicalMemorySize", val -> val / 1024 / 1024);
+                register("virtualMemory", "getCommittedVirtualMemorySize", val -> val / 1024 / 1024);
+                register(openFileCount.name(), "getOpenFileDescriptorCount", Function.identity());
+                register(maxOpenFileCount.name(), "getMaxFileDescriptorCount", Function.identity());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    @SneakyThrows
+    public static double getValue(String id) {
+        double val = items.getOrDefault(id, zero).call();
+
+        return Double.isNaN(val) ? 0 : val;
+    }
+
+}

+ 45 - 0
nb-common/src/main/java/com/nb/common/notice/msg/AbstractMsg.java

@@ -0,0 +1,45 @@
+package com.nb.common.notice.msg;
+
+import cn.hutool.json.JSONUtil;
+import com.nb.common.notice.NotifyEnums;
+import com.nb.common.notice.wechat.EnterpriseWeChatMsgEnums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName AbstractMsg.java
+ * @Description 发送消息内容
+ * @createTime 2022年07月19日 15:57:00
+ */
+public abstract class AbstractMsg {
+
+    public String getSendMarkDownMsg(){
+        Map<String, Object> result = new HashMap<>();
+        result.put("msgtype", EnterpriseWeChatMsgEnums.markdown.name());
+        Map<String, String> content = new HashMap<>();
+        content.put("content",getSendMarkDownMsgContent());
+        result.put("markdown",content);
+        return JSONUtil.toJsonPrettyStr(result);
+    };
+    /**
+     * 描述: 获取发送的markDown消息
+     * @author lifang
+     * @date 2022/7/19 15:58
+     * @param
+     * @return String
+     */
+    abstract String getSendMarkDownMsgContent();
+
+
+   /**
+    * 描述: 通知消息类型
+    * @author lifang
+    * @date 2022/7/19 15:59
+    * @param
+    * @return NotifyEnums
+    */
+   abstract NotifyEnums getType();
+}

+ 28 - 0
nb-common/src/main/java/com/nb/common/notice/msg/DiskMsg.java

@@ -0,0 +1,28 @@
+package com.nb.common.notice.msg;
+
+import lombok.Data;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DiskMsg.java
+ * @Description 磁盘信息
+ * @createTime 2022年07月20日 10:37:00
+ */
+@Data
+public class DiskMsg  {
+    private long total;
+    private long free;
+    private long threshold;
+
+    /**
+     * 描述: 判断磁盘容量是否已达阈值,即 可用磁盘大小是否小于20%
+     * @author lifang
+     * @date 2022/7/20 14:16
+     * @param
+     * @return boolean
+     */
+    public boolean judgeWarn(){
+        return Long.valueOf(free).doubleValue()/Long.valueOf(total).doubleValue()<0.2;
+    }
+}

+ 32 - 0
nb-common/src/main/java/com/nb/common/notice/msg/ErrorMsg.java

@@ -0,0 +1,32 @@
+package com.nb.common.notice.msg;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import com.nb.common.notice.NotifyEnums;
+import lombok.AllArgsConstructor;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName ErrorMsg.java
+ * @Description TODO
+ * @createTime 2022年07月19日 15:56:00
+ */
+@AllArgsConstructor(staticName = "of")
+public class ErrorMsg extends AbstractMsg{
+    private String content;
+
+
+    @Override
+    String getSendMarkDownMsgContent() {
+        if(CharSequenceUtil.length(content)>4000){
+            content=content.substring(0,4000);
+        }
+        return  getType().getMarkDownTitle()+"\n"+String.format("> ### **错误信息**: \n" +
+                "`%s`",content);
+    }
+
+    @Override
+    NotifyEnums getType() {
+        return NotifyEnums.ERROR;
+    }
+}

+ 37 - 0
nb-common/src/main/java/com/nb/common/notice/msg/LifeCycleMsg.java

@@ -0,0 +1,37 @@
+package com.nb.common.notice.msg;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import com.nb.common.notice.NotifyEnums;
+import lombok.AllArgsConstructor;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName LifeCycleMsg.java
+ * @Description 服务器生命周期
+ * @createTime 2022年07月19日 16:06:00
+ */
+@AllArgsConstructor(staticName = "of")
+public class LifeCycleMsg extends AbstractMsg{
+    /**
+     * 服务器下线
+     */
+    private boolean offline;
+
+    /**
+     * 节点名称
+     */
+    private String name;
+    @Override
+    String getSendMarkDownMsgContent() {
+        if(CharSequenceUtil.length(name)>4000){
+            name=name.substring(0,4000);
+        }
+        return  getType().getMarkDownTitle()+"\n"+String.format("> 服务器节点: <font color=\"comment\">**{  %s }**</font>\t已\t<font color=\"comment\">**%s**</font>",name,offline?"下线":"上线");
+    }
+
+    @Override
+    NotifyEnums getType() {
+        return NotifyEnums.LIFECYCLE;
+    }
+}

+ 50 - 0
nb-common/src/main/java/com/nb/common/notice/msg/SysResourceMsg.java

@@ -0,0 +1,50 @@
+package com.nb.common.notice.msg;
+
+import com.nb.common.notice.NotifyEnums;
+import com.nb.common.notice.SystemMonitor;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName SysResourceMsg.java
+ * @Description 系统资源信息
+ * @createTime 2022年07月20日 14:52:00
+ */
+@Data
+@AllArgsConstructor(staticName = "of")
+public class SysResourceMsg extends AbstractMsg{
+    private SystemMonitor systemCpuUsage;
+    private SystemMonitor systemCpuLoad;
+    private SystemMonitor jvmCpuUsage;
+    private SystemMonitor freeSystemMemory;
+    private SystemMonitor totalSystemMemory;
+    private DiskMsg diskMsg;
+
+    @Override
+    String getSendMarkDownMsgContent() {
+        double freeSystemMemoryValue = freeSystemMemory.getValue();
+        double totalSystemMemoryValue = totalSystemMemory.getValue();
+        //内存大小小于20%时报警
+        boolean memoryDifficiency =freeSystemMemoryValue/totalSystemMemoryValue<20;
+        boolean warn = diskMsg.judgeWarn();
+        double cpuUsageValue = systemCpuUsage.getValue();
+        double jvmCpuUsageValue = jvmCpuUsage.getValue();
+
+
+        return getType().getMarkDownTitle() +
+                "\n>系统CPU使用率:  <font color=\""+(Double.compare(cpuUsageValue,70D)>1?"warning":"info")+"\">"+Double.valueOf(cpuUsageValue).intValue()+"%</font>" +
+                "\n>系统平均负载:  <font color=\"info\">"+systemCpuLoad.getValue()+"</font>\n" +
+                "\n>VM进程CPU使用率:  <font color=\""+(Double.compare(cpuUsageValue,70D)>1?"warning":"info")+"\">"+Double.valueOf(jvmCpuUsageValue).intValue()+"%</font>"+
+                "\n>系统总内存:  <font color=\"info\">"+Double.valueOf(totalSystemMemoryValue).intValue()+"M</font>\n" +
+                "\n>系统空闲内存:  <font color=\""+(memoryDifficiency?"info":"warning")+"\">"+Double.valueOf(freeSystemMemoryValue).intValue()+"M</font>" +
+                "\n>磁盘总大小:   <font color=\"info\">"+Double.valueOf(diskMsg.getTotal()/1024/1024).intValue()+"M</font>" +
+                "\n>磁盘剩余大小:  <font color=\""+(warn?"warning":"info")+"\">"+Double.valueOf(diskMsg.getFree()/1024/1024).intValue()+"M</font>";
+    }
+
+    @Override
+    NotifyEnums getType() {
+        return NotifyEnums.RESOURCE;
+    }
+}

+ 33 - 0
nb-common/src/main/java/com/nb/common/notice/wechat/EnterpriseWeChatMsg.java

@@ -0,0 +1,33 @@
+package com.nb.common.notice.wechat;
+
+import lombok.Data;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName EnterpriseWeChatMsg.java
+ * @Description TODO
+ * @createTime 2022年07月19日 15:34:00
+ */
+@Data
+public class EnterpriseWeChatMsg {
+    /**
+     * 消息类型,必填
+     */
+    private String msgType;
+
+    /**
+     * 消息内容,必填
+     */
+    private String content;
+
+    /**
+     * userid的列表,提醒群中的指定成员(@某个成员),@all表示提醒所有人,如果开发者获取不到userid,可以使用mentioned_mobile_list,非必填
+     */
+    private String mentioned_list;
+
+    /**
+     * 手机号列表,提醒手机号对应的群成员(@某个成员),@all表示提醒所有人,非必填
+     */
+    private String mentioned_mobile_list;
+}

+ 15 - 0
nb-common/src/main/java/com/nb/common/notice/wechat/EnterpriseWeChatMsgEnums.java

@@ -0,0 +1,15 @@
+package com.nb.common.notice.wechat;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName EnterpriseWeChatMsgEnums.java
+ * @Description TODO
+ * @createTime 2022年07月19日 15:35:00
+ */
+public enum  EnterpriseWeChatMsgEnums {
+    text,
+    markdown,
+    image,
+    news;
+}

+ 62 - 0
nb-common/src/main/java/com/nb/common/notice/wechat/EnterpriseWeChatNotify.java

@@ -0,0 +1,62 @@
+package com.nb.common.notice.wechat;
+
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+import com.nb.common.notice.SystemMonitor;
+import com.nb.common.notice.msg.AbstractMsg;
+import com.nb.common.notice.msg.DiskMsg;
+import com.nb.common.notice.msg.SysResourceMsg;
+import io.netty.channel.DefaultEventLoop;
+import io.netty.channel.EventLoopGroup;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.system.DiskSpaceHealthIndicator;
+import org.springframework.context.annotation.Profile;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.concurrent.*;
+
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName EnterpriseWeChatNotify.java
+ * @Description 企业微信通知
+ * @createTime 2022年07月19日 15:21:00
+ */
+@Component
+@Profile("prod")
+public class EnterpriseWeChatNotify {
+    @Autowired
+    private DiskSpaceHealthIndicator spaceHealthIndicator;
+    private EventLoopGroup eventExecutors=new DefaultEventLoop();
+    /**
+     * 企业微信钩子地址
+     */
+    @Value("${notify.wechat.url}")
+    private String webHookUrl;
+
+    @Async
+    public void send( AbstractMsg msg){
+        HttpUtil.post(webHookUrl, msg.getSendMarkDownMsg());
+    }
+
+    @PostConstruct
+    public void resourceNotify(){
+        Health health = spaceHealthIndicator.getHealth(true);
+        DiskMsg diskMsg = JSONUtil.parseObj(health.getDetails()).toBean(DiskMsg.class);
+        eventExecutors.scheduleAtFixedRate(() -> {
+            this.send( SysResourceMsg.of(SystemMonitor.systemCpuUsage,
+                    SystemMonitor.systemCpuLoad,
+                    SystemMonitor.jvmCpuUsage,
+                    SystemMonitor.freeSystemMemory,
+                    SystemMonitor.totalSystemMemory,
+                    diskMsg));
+        }, 0, 30,TimeUnit.MINUTES);
+
+
+    }
+}

+ 1 - 0
nb-framework/src/main/java/com/nb/framework/config/SaTokenConfig.java

@@ -32,6 +32,7 @@ public class SaTokenConfig {
     private static final List<String> IGNORE_URL = Lists.newArrayList();
 
     static {
+        IGNORE_URL.add("/actuator/**");
         IGNORE_URL.add("/bus/version/page");
         IGNORE_URL.add("/druid/**");
         IGNORE_URL.add("/favicon.ico");

+ 21 - 6
nb-framework/src/main/java/com/nb/framework/logback/SystemLoggingAppender.java

@@ -1,5 +1,6 @@
 package com.nb.framework.logback;
 
+import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.classic.spi.IThrowableProxy;
 import ch.qos.logback.classic.spi.StackTraceElementProxy;
@@ -7,6 +8,8 @@ import ch.qos.logback.classic.spi.ThrowableProxyUtil;
 import ch.qos.logback.core.CoreConstants;
 import ch.qos.logback.core.UnsynchronizedAppenderBase;
 import cn.hutool.extra.spring.SpringUtil;
+import com.nb.common.notice.msg.ErrorMsg;
+import com.nb.common.notice.wechat.EnterpriseWeChatNotify;
 import com.nb.system.entity.SysRunningLog;
 import com.nb.system.mapper.SysRunningLogMapper;
 import lombok.extern.slf4j.Slf4j;
@@ -17,14 +20,11 @@ import java.util.*;
 public class SystemLoggingAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
 
     private SysRunningLogMapper logMapper=null;
+
+    private EnterpriseWeChatNotify notify=null;
     @Override
     protected void append(ILoggingEvent event) {
-        if(logMapper==null){
-            logMapper= SpringUtil.getBean(SysRunningLogMapper.class);
-        }
-        if(logMapper==null){
-            return;
-        }
+        init();
         StackTraceElement element = event.getCallerData()[0];
         IThrowableProxy proxies = event.getThrowableProxy();
         String message = event.getFormattedMessage();
@@ -65,6 +65,21 @@ public class SystemLoggingAppender extends UnsynchronizedAppenderBase<ILoggingEv
                 .message(message)
                 .threadId(String.valueOf(Thread.currentThread().getId()))
                 .build();
+        if (Level.ERROR.equals(event.getLevel())) {
+            if(notify!=null){
+                notify.send( ErrorMsg.of(message));
+            }
+        }
+
         logMapper.insert(info);
     }
+
+    private void init(){
+        if(logMapper==null){
+            logMapper= SpringUtil.getBean(SysRunningLogMapper.class);
+        }
+        if(notify==null){
+            notify= SpringUtil.getBean(EnterpriseWeChatNotify.class);
+        }
+    }
 }

+ 4 - 1
nb-system/src/main/java/com/nb/bus/entity/BusClinicEntity.java

@@ -93,7 +93,6 @@ public class BusClinicEntity extends TenantGenericEntity<String,String> {
     @ApiModelProperty(value = "麻醉医生")
     @Length(max = 255,message = "麻醉医生不得超过255个字节",groups = {Insert.class,Update.class})
     @TableField(updateStrategy = FieldStrategy.IGNORED)
-
     private String anaDoctor;
 
     @ApiModelProperty(value = "麻醉方式")
@@ -101,6 +100,10 @@ public class BusClinicEntity extends TenantGenericEntity<String,String> {
     @Length(max = 255,message = "麻醉方式不得超过255个字节",groups = {Insert.class,Update.class})
     private String anaType;
 
+    @ApiModelProperty(value = "备注")
+    @Length(max = 255,message = "备注不得超过255个字节",groups = {Insert.class,Update.class})
+    private String remark;
+
     @ApiModelProperty(value = "镇痛方式")
     @TableField(updateStrategy = FieldStrategy.IGNORED)
     @Length(max = 255,message = "镇痛方式不得超过255个字节",groups = {Insert.class,Update.class})

+ 6 - 2
nb-system/src/main/java/com/nb/bus/hospital/his/HisScriptSession.java

@@ -256,8 +256,12 @@ public class HisScriptSession {
                     BusClinicEntity::getStartTime));
             publish.forEach(source->{
                 source.setTenantId(hospitalId);
-                //存在病号为输注监控、不存在病号为无泵监控
-                source.setMonitorType(patient!=null);
+                if(patient!=null){
+                    source.setPatientId(patient.getId());
+                    source.setMonitorType(true);
+                }else {
+                    source.setMonitorType(false);
+                }
             });
 
             if(patient!=null){

+ 2 - 2
nb-system/src/main/java/com/nb/bus/service/LocalBusClinicService.java

@@ -119,7 +119,7 @@ public class LocalBusClinicService extends BaseService<BusClinicMapper, BusClini
         this.updateById(source);
         //手术开始时间发生变化,重新计算输注数据
         if(source.getStartTime()!=null&&source.getStartTime()!=target.getStartTime()){
-            infusionHistoryService.adjustInfusionByClinic(source.getId(),source.getPatientCode(),source.getTenantId(),source.getStartTime());
+            infusionHistoryService.adjustInfusionByClinic(source.getId(),source.getPatientId(),source.getTenantId(),source.getStartTime());
         }
     }
 
@@ -138,7 +138,7 @@ public class LocalBusClinicService extends BaseService<BusClinicMapper, BusClini
         Assert.hasText(source.getPatientCode(),"LocalBusClinicService.insertFromHis方法调用时,source参数patientCode不能为空");
         Assert.hasText(source.getSurgeryName(),"LocalBusClinicService.insertFromHis方法调用时,source参数surgeName不能为空");
         this.save(source);
-        infusionHistoryService.adjustInfusionByClinic(source.getId(),source.getPatientCode(),source.getTenantId(),source.getStartTime());
+        infusionHistoryService.adjustInfusionByClinic(source.getId(),source.getPatientId(),source.getTenantId(),source.getStartTime());
     }
 
 

+ 18 - 2
nb-system/src/main/java/com/nb/bus/service/LocalBusDrugService.java

@@ -1,8 +1,11 @@
 package com.nb.bus.service;
 
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.nb.bus.entity.BusDrugEntity;
 import com.nb.bus.mapper.BusDrugMapper;
 import com.nb.common.crud.BaseService;
+import com.nb.common.exception.CustomException;
 import org.springframework.stereotype.Service;
 
 /**
@@ -17,12 +20,25 @@ public class LocalBusDrugService extends BaseService<BusDrugMapper, BusDrugEntit
 
     @Override
     public void validateBeforeSave(BusDrugEntity entity) {
-
+        BusDrugEntity drug = this.getOne(new QueryWrapper<BusDrugEntity>().lambda()
+                .eq(BusDrugEntity::getName, entity.getName())
+                .eq(StrUtil.isNotBlank(entity.getType()), BusDrugEntity::getType, entity.getType())
+                .last("limit 1"));
+        if(drug!=null){
+            throw new CustomException("药品已存在,请勿重复添加");
+        }
     }
 
     @Override
     public void validateBeforeUpdate(BusDrugEntity entity) {
-
+        BusDrugEntity drug = this.getOne(new QueryWrapper<BusDrugEntity>().lambda()
+                .eq(BusDrugEntity::getName, entity.getName())
+                .ne(BusDrugEntity::getId,entity.getId())
+                .eq(StrUtil.isNotBlank(entity.getType()), BusDrugEntity::getType, entity.getType())
+                .last("limit 1"));
+        if(drug!=null){
+            throw new CustomException("药品已存在,请勿重复添加");
+        }
     }
 
     @Override

+ 6 - 6
nb-system/src/main/java/com/nb/bus/service/LocalBusInfusionHistoryService.java

@@ -166,15 +166,15 @@ public class LocalBusInfusionHistoryService extends BaseService<BusInfusionHisto
      * @author lifang
      * @date 2022/5/12 9:28
      * @param clinicId 手术id
-     * @param patientCode 病号
+     * @param patientId 病人id
      * @param tenantId 医院id
      * @param startTime 开始时间
      * @return void
      */
     @Transactional(rollbackFor = Exception.class)
-    public void adjustInfusionByClinic(String clinicId, String patientCode, String tenantId, Date startTime){
+    public void adjustInfusionByClinic(String clinicId, String patientId, String tenantId, Date startTime){
         Assert.hasText(clinicId,"手术id不可为空");
-        Assert.hasText(patientCode,"住院号不可为空");
+        Assert.hasText(patientId,"住院号Id不可为空");
         Assert.hasText(tenantId,"医院id不可为空");
         Assert.notNull(startTime,"手术开始时间不可为空");
 
@@ -182,7 +182,7 @@ public class LocalBusInfusionHistoryService extends BaseService<BusInfusionHisto
         List<BusInfusionHistoryEntity> infusionHistories = this.list(new QueryWrapper<BusInfusionHistoryEntity>()
                 .lambda()
                 .eq(BusInfusionHistoryEntity::getTenantId, tenantId)
-                .eq(BusInfusionHistoryEntity::getPatientCode, patientCode)
+                .eq(BusInfusionHistoryEntity::getPatientId, patientId)
                 .ge(BusInfusionHistoryEntity::getStartTime, startTime)
                 .le(BusInfusionHistoryEntity::getClinicStartTime, startTime));
         if(CollectionUtil.isNotEmpty(infusionHistories)){
@@ -305,7 +305,7 @@ public class LocalBusInfusionHistoryService extends BaseService<BusInfusionHisto
     public BusInfusionHistoryEntity deviceOccupation(BusInfusionHistoryEntity lastInfusion) {
         List<BusInfusionHistoryEntity> infusionHistories = this.list(new QueryWrapper<BusInfusionHistoryEntity>().lambda()
                 .eq(BusInfusionHistoryEntity::getFinished, false)
-                .eq(BusInfusionHistoryEntity::getPatientCode, lastInfusion.getPatientCode())
+                .eq(BusInfusionHistoryEntity::getPatientId, lastInfusion.getPatientId())
                 .eq(BusInfusionHistoryEntity::getTenantId, lastInfusion.getTenantId()));
         int size = CollectionUtil.size(infusionHistories);
         if(size>0){
@@ -314,7 +314,7 @@ public class LocalBusInfusionHistoryService extends BaseService<BusInfusionHisto
         }
 
         patientService.update(new UpdateWrapper<BusPatientEntity>().lambda()
-                .eq(BusPatientEntity::getCode,lastInfusion.getPatientCode())
+                .eq(BusPatientEntity::getId,lastInfusion.getPatientId())
                 .eq(BusPatientEntity::getTenantId,lastInfusion.getTenantId())
                 .set(BusPatientEntity::getInfusionId,lastInfusion.getId())
                 .set(size==0,BusPatientEntity::getAlarm, PatientAlarmEnum.DEVICE_NONE)

+ 1 - 1
nb-system/src/main/java/com/nb/bus/service/LocalBusPatientService.java

@@ -263,7 +263,7 @@ public class LocalBusPatientService extends BaseService<BusPatientMapper, BusPat
      * @return
      * @author lifang
      */
-    public PatientMonitorResult lookMonitorByPatientCode(String patientId, String tenantId) {
+    public PatientMonitorResult lookMonitorByPatientId(String patientId, String tenantId) {
         try {
             return this.baseMapper.findByPatientId(tenantId, patientId);
         } catch (Exception e) {

+ 3 - 1
nb-system/src/main/java/com/nb/bus/stats/report/WeightStatsReport.java

@@ -105,7 +105,9 @@ public class WeightStatsReport implements CommonStats<CombineResult> {
                 BigDecimal count = BigDecimal.valueOf(Double.valueOf(weight));
                 ageMap.merge(WeightRangeEnum.judgeWeight(count),1,(t1, t2)->t1+t2);
             }catch (Exception e){
-                log.error("手术【{}】,体重格式错误【{}】",combineResult.getClinicId(),combineResult.getWeight());
+                if(log.isDebugEnabled()){
+                    log.debug("手术【{}】,体重格式错误【{}】",combineResult.getClinicId(),combineResult.getWeight());
+                }
             }
         }
         ageMap.forEach((weightRangeEnum,count)->{

+ 1 - 1
nb-system/src/main/java/com/nb/bus/utils/WsPublishUtils.java

@@ -48,7 +48,7 @@ public class WsPublishUtils implements Serializable{
     public void publishPatientMonitor(String patientId,String tenantId){
         Assert.hasText(tenantId,"医院id不能为空");
         log.info("推送病号数据【{}】", JSONUtil.toJsonStr(patientId));
-        PatientMonitorResult message = patientService.lookMonitorByPatientCode(patientId, tenantId);
+        PatientMonitorResult message = patientService.lookMonitorByPatientId(patientId, tenantId);
         if (log.isDebugEnabled()) {
             log.debug("推送病号当前状态,【{}】",JSONUtil.toJsonStr(message));
         }

+ 8 - 6
nb-system/src/main/resources/mapper/bus/BusPatientMapper.xml

@@ -344,12 +344,13 @@
     <select id="findByPatientId" resultMap="monitorResult">
         select
         p.id as patient_id,
-        p.alarm as patient_alarm,
         p.`code` as patient_code,
-        i.device_id as device_id,
+        p.alarm as patient_alarm,
         i.id as infusion_id,
+        i.device_id as device_id,
         i.clinic_id as clinic_id,
         i.classification as classification,
+        i.data_number as data_number,
         i.total_dose as total_dose,
         i.first_dose as first_dose,
         i.remain_dose as remain_dose,
@@ -357,6 +358,7 @@
         i.append_dose as append_dose,
         i.append_lock_time as append_lock_time,
         i.max_dose as max_dose,
+        i.finished as infusion_finished,
         i.electric_quantity as electric_quantity,
         i.warn_flow as warn_flow,
         i.self_control_count as self_control_count,
@@ -383,11 +385,9 @@
         i.remark as remark,
         i.type as device_type,
         d.alias as device_alias,
-        c.ward as ward,
-        c.bed_no as bed_no,
-        c.finished as finished,
+        c.patient_gender as patient_gender,
         c.`patient_name` as patient_name,
-        c.patient_gender as gender,
+        c.finished as finished,
         c.monitor_start_time as monitor_start_time,
         c.end_time as monitor_end_time,
         c.ana_doctor as ana_doctor,
@@ -396,6 +396,8 @@
         c.anal_type as anal_type,
         c.surgery_doctor as surgery_doctor,
         c.surgery_name as surgery_name,
+        c.ward as ward,
+        c.bed_no as bed_no,
         c.eval_time as eval_time
         from
         (select * from bus_patient

+ 4 - 0
pom.xml

@@ -62,6 +62,10 @@
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
     </dependencies>
 
     <!-- 依赖管理 -->