ソースを参照

add
优化定时任务

# Conflicts:
# nb-admin/src/main/resources/application-dev.yml
# nb-admin/src/main/resources/logback-spring.xml
# nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusClinicService.java
# nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusPatientService.java
# nb-service/web-service/src/main/java/com/nb/web/service/quartz/job/service/impl/SysJobServiceImpl.java
# nb-service/web-service/src/main/java/com/nb/web/service/quartz/util/AbstractQuartzJob.java

lifang 1 ヶ月 前
コミット
2f37c844e5
19 ファイル変更683 行追加162 行削除
  1. 2 0
      nb-admin/src/main/java/com/nb/admin/StartUpRunner.java
  2. 8 7
      nb-admin/src/main/resources/application-dev.yml
  3. 31 0
      nb-admin/src/main/resources/application-prod.yml
  4. 40 4
      nb-admin/src/main/resources/application-test.yml
  5. 2 2
      nb-admin/src/main/resources/application.yml
  6. 28 16
      nb-admin/src/main/resources/logback-spring.xml
  7. 70 0
      nb-core/src/main/java/com/nb/core/utils/CronExpressionUtil.java
  8. 70 0
      nb-core/src/main/java/com/nb/core/utils/DateCompareUtil.java
  9. 6 9
      nb-service/web-service/pom.xml
  10. 74 81
      nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/HospitalManager.java
  11. 2 5
      nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/HospitalManagerRegister.java
  12. 10 2
      nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/his/strategy/onlynew/DefaultHisNewStrategyHandler.java
  13. 2 1
      nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/his/strategy/part/DefaultHisPartStrategyHandler.java
  14. 7 26
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusClinicService.java
  15. 2 1
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusPatientService.java
  16. 109 0
      nb-service/web-service/src/main/java/com/nb/web/service/quartz/job/service/impl/SysJobServiceImpl.java
  17. 105 0
      nb-service/web-service/src/main/java/com/nb/web/service/quartz/task/HospitalHisDataPullTask.java
  18. 107 0
      nb-service/web-service/src/main/java/com/nb/web/service/quartz/util/AbstractQuartzJob.java
  19. 8 8
      nb-service/web-service/src/main/resources/mapper/bus/BusPatientMapper.xml

+ 2 - 0
nb-admin/src/main/java/com/nb/admin/StartUpRunner.java

@@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.boot.web.context.WebServerInitializedEvent;
 import org.springframework.context.ApplicationListener;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
@@ -26,6 +27,7 @@ public class StartUpRunner implements CommandLineRunner , ApplicationListener<We
     ISysConfigService sysConfigService;
 
     @Override
+    @Async
     public void run(String... args) {
         log.info("============  web is running ,start load data============");
         sysDictService.loadAllDictCache();

+ 8 - 7
nb-admin/src/main/resources/application-dev.yml

@@ -7,7 +7,7 @@ app:
   # 获取ip地址开关
   addressEnabled: true
   # 上传类型,minio;aliyun
-  uploadType: minio
+  uploadType: aliyun
   # 上传目录
   uploadDir: D:/${app.name}-files
   # 缓存前缀
@@ -18,7 +18,7 @@ minio:
   uploadPort: 7001
   uploadSecure: false
   downEndpoint: 192.168.100.32
-  downPort: 7001
+  downPort: 7002
   downSecure: false
   accessKey: nbnetpump
   secretKey: tuoren123
@@ -30,14 +30,14 @@ spring:
   datasource:
     type: com.alibaba.druid.pool.DruidDataSource
     driverClassName: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://192.168.100.32:3306/nbnetpump?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true
+    url: jdbc:mysql://192.168.100.32:3306/nbnetpump?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true
     username: root
     password: 123456
     druid:
       # 初始连接数
-      initialSize: 5
+      initialSize: 16
       # 最小连接池数量
-      minIdle: 10
+      minIdle: 20
       # 最大连接池数量
       maxActive: 20
       # 配置获取连接等待超时的时间
@@ -82,9 +82,9 @@ spring:
   redis:
     # 地址
     host: 192.168.100.32
-    # 端口,默认为6379
+      # 端口,默认为6379
     port: 9736
-    # 数据库索引
+      # 数据库索引
     database: 6
     # 密码
     password: 6E6985E1F7CB40F24A\.
@@ -117,6 +117,7 @@ request:
     # 请求不可重复接收时间 10分钟
     repeat-interval: 600
 
+
 # 阿里云对接配置
 #aliyun:
 #  accessKey: "LTAI4FhB19MgQuviGxwA3aod"

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

@@ -92,6 +92,37 @@ spring:
             multi-statement-allow: true
       #合并多个DruidDataSource的监控数据
       use-global-data-source-stat: true
+  quartz:
+    job-store-type: jdbc
+    jdbc:
+      initialize-schema: never
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: NbScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+            tablePrefix: QRTZ_
+            isClustered: true
+            clusterCheckinInterval: 10000
+            useProperties: false
+            dataSource: myDS
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10
+            threadPriority: 5
+            threadsInheritContextClassLoaderOfInitializingThread: true
+          dataSource:
+            myDS:
+              provider: hikaricp
+              driver: com.mysql.cj.jdbc.Driver
+              URL: jdbc:mysql://47.101.214.91:7001/nbnetpump?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true
+              user: root
+              password: Tuoren123.
+              validationQuery: SELECT 1
   # redis 配置
   redis:
     # 地址

+ 40 - 4
nb-admin/src/main/resources/application-test.yml

@@ -57,6 +57,11 @@ spring:
       testWhileIdle: true
       testOnBorrow: false
       testOnReturn: false
+      # 通过别名的方式配置扩展插件,多个英文逗号分隔,常用的插件有:
+      # 监控统计用的filter:stat
+      # 日志用的filter:log4j2
+      # 防御sql注入的filter:wall
+      filters: stat,wall,log4j2
       webStatFilter:
         enabled: true
       statViewServlet:
@@ -65,18 +70,49 @@ spring:
         allow:
         url-pattern: /druid/*
         # 控制台管理用户名和密码
-        login-username: scott
-        login-password: tiger
+        login-username: admin
+        login-password: admin
       filter:
         stat:
           enabled: true
           # 慢SQL记录
           log-slow-sql: true
-          slow-sql-millis: 1000
+          slow-sql-millis: 10000
           merge-sql: true
         wall:
           config:
             multi-statement-allow: true
+  quartz:
+    job-store-type: jdbc
+    jdbc:
+      initialize-schema: never
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: NbScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+            tablePrefix: QRTZ_
+            isClustered: true
+            clusterCheckinInterval: 10000
+            useProperties: false
+            dataSource: myDS
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10
+            threadPriority: 5
+            threadsInheritContextClassLoaderOfInitializingThread: true
+          dataSource:
+            myDS:
+              provider: hikaricp
+              driver: com.mysql.cj.jdbc.Driver
+              URL: jdbc:mysql://localhost:3306/coffee-test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true
+              user: root
+              password: 123456
+              validationQuery: SELECT 1
   # redis 配置
   redis:
     # 地址
@@ -98,4 +134,4 @@ spring:
         # 连接池的最大数据库连接数
         max-active: 8
         # #连接池最大阻塞等待时间(使用负值表示没有限制)
-        max-wait: -1ms
+        max-wait: -1ms

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

@@ -65,8 +65,8 @@ logging:
     path: ./logs
   logback:
     rollingpolicy:
-      max-file-size: 10MB
-      max-history: 7
+      max-file-size: 100MB
+      max-history: 15
   charset:
     console: UTF-8
 

+ 28 - 16
nb-admin/src/main/resources/logback-spring.xml

@@ -22,12 +22,16 @@
 
     <!-- 控制台输出 -->
     <appender name="sys_console" class="ch.qos.logback.core.rolling.RollingFileAppender">
-            <file>${LOG_PATH}/sys-console.log</file>
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+        <file>${LOG_PATH}/sys-console.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
             <!-- 日志文件名格式 -->
-            <fileNamePattern>${LOG_PATH}/sys-console.%d{yyyy-MM-dd}.log</fileNamePattern>
-            <!-- 日志最大 1天 -->
-            <maxHistory>1</maxHistory>
+            <fileNamePattern>${LOG_PATH}/sys-console.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!-- 日志最大的历史 15天 -->
+            <maxHistory>15</maxHistory>
+            <!-- 单个文件最大100MB -->
+            <maxFileSize>100MB</maxFileSize>
+            <!-- 总日志保留大小 -->
+            <totalSizeCap>10GB</totalSizeCap>
         </rollingPolicy>
         <encoder>
             <pattern>${log.pattern}</pattern>
@@ -42,12 +46,16 @@
     <!-- 系统日志输出 -->
     <appender name="sys_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
         <file>${LOG_PATH}/sys-info.log</file>
-        <!-- 循环政策:基于时间创建日志文件 -->
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+        <!-- 循环政策:基于时间和大小创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
             <!-- 日志文件名格式 -->
-            <fileNamePattern>${LOG_PATH}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
-            <!-- 日志最大的历史 60天 -->
-            <maxHistory>60</maxHistory>
+            <fileNamePattern>${LOG_PATH}/sys-info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!-- 日志最大的历史 15天 -->
+            <maxHistory>15</maxHistory>
+            <!-- 单个文件最大100MB -->
+            <maxFileSize>100MB</maxFileSize>
+            <!-- 总日志保留大小 -->
+            <totalSizeCap>10GB</totalSizeCap>
         </rollingPolicy>
         <encoder>
             <pattern>${log.pattern}</pattern>
@@ -64,12 +72,16 @@
 
     <appender name="sys_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
         <file>${LOG_PATH}/sys-error.log</file>
-        <!-- 循环政策:基于时间创建日志文件 -->
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+        <!-- 循环政策:基于时间和大小创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
             <!-- 日志文件名格式 -->
-            <fileNamePattern>${LOG_PATH}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
-            <!-- 日志最大的历史 60天 -->
-            <maxHistory>60</maxHistory>
+            <fileNamePattern>${LOG_PATH}/sys-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!-- 日志最大的历史 15天 -->
+            <maxHistory>15</maxHistory>
+            <!-- 单个文件最大100MB -->
+            <maxFileSize>100MB</maxFileSize>
+            <!-- 总日志保留大小 -->
+            <totalSizeCap>10GB</totalSizeCap>
         </rollingPolicy>
         <encoder>
             <pattern>${log.pattern}</pattern>
@@ -98,4 +110,4 @@
         <appender-ref ref="console"/>
     </root>
 
-</configuration> 
+</configuration>

+ 70 - 0
nb-core/src/main/java/com/nb/core/utils/CronExpressionUtil.java

@@ -0,0 +1,70 @@
+package com.nb.core.utils;
+
+/**
+ * @author 
+ * @version 1.0.0
+ * @ClassName CronExpressionUtil.java
+ * @Description Cron表达式工具类,提供将分钟数转换为Cron表达式的功能
+ * @createTime 2025年11月14日
+ */
+public class CronExpressionUtil {
+
+    /**
+     * 将分钟数转换为Cron表达式
+     * 
+     * @param minutes 间隔分钟数
+     * @return 对应的Cron表达式
+     * @throws IllegalArgumentException 当分钟数小于等于0时抛出异常
+     */
+    public static String minutesToCronExpression(int minutes) {
+        if (minutes <= 0) {
+            throw new IllegalArgumentException("分钟数必须大于0");
+        }
+        
+        // 对于大于等于60分钟的间隔,使用秒/分/时/日的表达式
+        if (minutes >= 60) {
+            // 使用 "0 0 0/小时 * * ?" 格式,表示从0点开始,每X小时执行一次
+            int hours = minutes / 60;
+            int remainingMinutes = minutes % 60;
+            
+            // 如果正好是整小时
+            if (remainingMinutes == 0) {
+                if (hours >= 24) {
+                    // 如果超过24小时,则转换为天
+                    int days = hours / 24;
+                    return String.format("0 0 0 */%d * ?", days);
+                } else {
+                    // 整小时表达式
+                    return String.format("0 0 0/%d * * ?", hours);
+                }
+            } else {
+                // 非整小时,使用 "0 分 0/小时 * * ?" 格式
+                if (hours >= 24) {
+                    // 如果超过24小时,转换为天
+                    int days = hours / 24;
+                    return String.format("0 %d 0 */%d * ?", remainingMinutes, days);
+                } else {
+                    return String.format("0 %d 0/%d * * ?", remainingMinutes, hours);
+                }
+            }
+        }
+        
+        // 分钟表达式(小于60分钟)
+        return String.format("0 0/%d * * * ?", minutes);
+    }
+    
+    /**
+     * 验证生成的Cron表达式是否有效(简单验证)
+     * 
+     * @param cronExpression Cron表达式
+     * @return 是否有效
+     */
+    public static boolean isValidCronExpression(String cronExpression) {
+        if (cronExpression == null || cronExpression.trim().isEmpty()) {
+            return false;
+        }
+        
+        String[] parts = cronExpression.split("\\s+");
+        return parts.length >= 6;
+    }
+}

+ 70 - 0
nb-core/src/main/java/com/nb/core/utils/DateCompareUtil.java

@@ -0,0 +1,70 @@
+package com.nb.core.utils;
+
+import cn.hutool.core.date.DateUtil;
+
+import java.util.Date;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DateCompareUtil.java
+ * @Description 日期比较工具类,提供按不同精度进行日期比较的方法
+ * @createTime 2025年11月14日
+ */
+public class DateCompareUtil {
+
+    /**
+     * 按年月日时分秒进行比较,忽略毫秒部分
+     *
+     * @param date1 第一个日期
+     * @param date2 第二个日期
+     * @return 如果两个日期的年月日时分秒相同返回true,否则返回false
+     */
+    public static boolean isSameDateTimeIgnoreMillis(Date date1, Date date2) {
+        if (date1 == null && date2 == null) {
+            return true;
+        }
+        if (date1 == null || date2 == null) {
+            return false;
+        }
+
+        String format = "yyyy-MM-dd HH:mm:ss";
+        return DateUtil.format(date1, format).equals(DateUtil.format(date2, format));
+    }
+
+    /**
+     * 按年月日进行比较
+     *
+     * @param date1 第一个日期
+     * @param date2 第二个日期
+     * @return 如果两个日期的年月日相同返回true,否则返回false
+     */
+    public static boolean isSameDay(Date date1, Date date2) {
+        if (date1 == null && date2 == null) {
+            return true;
+        }
+        if (date1 == null || date2 == null) {
+            return false;
+        }
+
+        return DateUtil.isSameDay(date1, date2);
+    }
+
+    /**
+     * 按年月日时分秒毫秒进行精确比较
+     *
+     * @param date1 第一个日期
+     * @param date2 第二个日期
+     * @return 如果两个日期完全相同返回true,否则返回false
+     */
+    public static boolean isExactlySame(Date date1, Date date2) {
+        if (date1 == null && date2 == null) {
+            return true;
+        }
+        if (date1 == null || date2 == null) {
+            return false;
+        }
+
+        return date1.equals(date2);
+    }
+}

+ 6 - 9
nb-service/web-service/pom.xml

@@ -59,13 +59,6 @@
             <artifactId>nb-oss</artifactId>
         </dependency>
 
-
-        <dependency>
-            <groupId>org.springframework.amqp</groupId>
-            <artifactId>spring-rabbit</artifactId>
-        </dependency>
-
-
         <dependency>
             <groupId>org.python</groupId>
             <artifactId>jython-standalone</artifactId>
@@ -94,6 +87,12 @@
             <artifactId>easy-captcha</artifactId>
         </dependency>
 
+        <!-- 引入 Quartz 依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-quartz</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
@@ -104,7 +103,5 @@
             <groupId>com.tuoren</groupId>
             <artifactId>app-assistant-api</artifactId>
         </dependency>
-
-
     </dependencies>
 </project>

+ 74 - 81
nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/HospitalManager.java

@@ -1,23 +1,14 @@
 package com.nb.web.service.bus.hospital;
 
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.date.DateUnit;
-import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.hutool.cron.CronUtil;
 import cn.hutool.extra.spring.SpringUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.nb.core.utils.CronExpressionUtil;
 import com.nb.web.api.bean.Script;
 import com.nb.web.api.entity.BusHospitalConfigEntity;
-import com.nb.web.api.entity.BusInfusionHistoryEntity;
-import com.nb.web.api.feign.query.PatientMonitorQuery;
-import com.nb.web.api.feign.result.PatientMonitorResult;
+import com.nb.web.api.entity.common.BusDeviceRunningEntity;
 import com.nb.web.service.bus.entity.*;
 import com.nb.web.service.bus.hospital.config.*;
 import com.nb.web.service.bus.hospital.config.bean.*;
@@ -27,16 +18,14 @@ import com.nb.web.service.bus.hospital.script.ScriptManager;
 import com.nb.web.service.bus.service.*;
 import com.nb.core.cache.ConfigStorage;
 import com.nb.core.cache.manager.ConfigStorageManager;
-import com.nb.web.api.entity.common.BusDeviceRunningEntity;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
+import org.quartz.*;
 
 import java.util.*;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 /**
  * @author lifang
@@ -87,6 +76,13 @@ public class HospitalManager {
     private LocalBusPatientService patientService;
 
     private LocalBusInfusionHistoryService infusionHistoryService;
+    
+    // 注入Quartz调度器
+    private Scheduler quartzScheduler;
+    
+    // 任务组名
+    private static final String JOB_GROUP = "HIS_DATA_PULL_GROUP";
+    
     public HospitalManager(String hospitalId,
                            ScriptManager scriptManager,
                            ConfigStorageManager configStorageManager) {
@@ -102,36 +98,8 @@ public class HospitalManager {
         this.codeHandler=new HospitalPatientCodeHandler(storage,hospitalId);
         this.infusionHistoryService=SpringUtil.getBean(LocalBusInfusionHistoryService.class);
         this.patientService=SpringUtil.getBean(LocalBusPatientService.class);
+        this.quartzScheduler = SpringUtil.getBean(Scheduler.class);
         init(configStorageManager);
-
-//        singleOffsetsDeviceExecutor.scheduleWithFixedDelay(()->{
-//                    try {
-//                        PatientMonitorQuery query = new PatientMonitorQuery();
-//                        query.setTenantId(this.getHospitalId());
-//                        query.setInfusionFinished(true);
-//                        query.setDeviceStatus(Arrays.asList(0,5));
-//                        List<PatientMonitorResult> patientMonitorResults = patientService.selectAll(query);
-//                        if(CollectionUtil.isEmpty(patientMonitorResults)){
-//                            return;
-//                        }
-//                        patientMonitorResults
-//                                .forEach(infusionInfo->{
-//                                    BusDeviceRunningEntity source = BeanUtil.toBean(infusionInfo, BusDeviceRunningEntity.class);
-//                                    source.setRunState(infusionInfo.getDeviceRunState());
-//                                    source.setAlarm(infusionInfo.getDeviceAlarm());
-//                                    source.setInfusionId(infusionInfo.getInfusionId());
-//                                    source.setUploadTime(infusionInfo.getLastUploadTime());
-//                                    source.setTenantId(this.getHospitalId());
-//                                    extraConfigHandler.handler(source);
-//                                    autoUndoConfigHandler.handler(source);
-//                                    finishMonitorConfigHandler.handler(source);
-//                                });
-//                    }catch (Exception e){
-//                        e.printStackTrace();
-//                    }
-//                },
-//                //1-10分钟内启动,间隔1天启动
-//                RandomUtil.randomInt(1,10),  Math.addExact(1440, RandomUtil.randomInt(1,12)),TimeUnit.MINUTES);
     }
 
     private void init(ConfigStorageManager configStorageManager){
@@ -150,7 +118,7 @@ public class HospitalManager {
      */
     public void refreshInfo(){
         BusHospitalEntity hospital = hospitalService.getById(hospitalId);
-        log.info("医院【{}】,刷新信息,info【{}】",hospitalId,hospital);
+        log.info("医院【{}】,刷新信息,info【{}】",hospitalId,hospital.getName());
         storage.setConfig("info",hospital);
         storage.setConfig("strategy",hospital.getStrategy());
 
@@ -254,53 +222,78 @@ public class HospitalManager {
             return;
         }
         if(!Boolean.TRUE.equals(updateConfig.getEnable())||updateConfig.getInterval()<0){
-            if(hisSchedule !=null&&!hisSchedule.isCancelled()){
-                //如果有定时任务正在运行,则关闭
-                hisSchedule.cancel(true);
-            }
+            // 如果有定时任务正在运行,则关闭
+            cancelQuartzJob();
             return;
         }
         //参数未改变
         if(ObjectUtil.isNotNull(this.getUpdateConfig())&&ObjectUtil.equals(this.getUpdateConfig().getInterval(),updateConfig.getInterval())){
             return;
         }else {
-            if(hisSchedule!=null){
-                //取消上次循环
-                hisSchedule.cancel(true);
-            }
-            hisSchedule = singleHisExecutor.scheduleAtFixedRate(this::scheduleHis, 0, updateConfig.getInterval(),TimeUnit.MINUTES);
+            // 取消之前的任务
+            cancelQuartzJob();
+            
+            // 创建新的Quartz任务
+            createQuartzJob(updateConfig);
         }
         this.updateConfig=updateConfig;
     }
-
+    
     /**
-     * 描述: 定时从his拉取数据
-     * @author lifang
-     * @date 2022/6/18 15:20
-     * @param
-     * @return void
+     * 取消Quartz任务
      */
-    private void scheduleHis(){
-        log.info("[定时拉取病人数据],hospitalId:{}",hospitalId);
-        //拉取最新的50条输注信息,更新病人数据
-        Page<BusInfusionHistoryEntity> infusionHistoryPage = new Page<>(0,50,false);
-        infusionHistoryPage= infusionHistoryService.page(infusionHistoryPage, new QueryWrapper<BusInfusionHistoryEntity>().lambda().eq(BusInfusionHistoryEntity::getTenantId, hospitalId)
-                .eq(BusInfusionHistoryEntity::getFinished,false)
-                .orderByDesc(BusInfusionHistoryEntity::getLastUploadTime));
-        List<BusInfusionHistoryEntity> records = infusionHistoryPage.getRecords();
-        if(CollUtil.isNotEmpty(records)){
-            records.stream().map(BusInfusionHistoryEntity::getPatientCode).collect(Collectors.toSet())
-                    .forEach(patientCode->{
-                        log.info("[拉取病人信息],hospitalId:{},patientCode:{}",hospitalId,patientCode);
-                        try {
-                            this.getScriptSession()
-                                    .asyncGetPatientInfo(patientCode,3,TimeUnit.SECONDS,false);
-                        }catch (Exception e){
-                            log.warn("[拉取病人信息失败],",e);
-                        }
-
-                    });
+    private void cancelQuartzJob() {
+        try {
+            String jobName = "HIS_DATA_PULL_" + hospitalId;
+            JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP);
+            
+            // 检查任务是否存在
+            if (quartzScheduler.checkExists(jobKey)) {
+                // 暂停并删除任务
+                quartzScheduler.deleteJob(jobKey);
+                log.info("成功取消HIS数据拉取任务,hospitalId:{}", hospitalId);
+            }
+        } catch (SchedulerException e) {
+            log.warn("取消HIS数据拉取任务失败,hospitalId:{}", hospitalId, e);
         }
     }
-
-}
+    
+    /**
+     * 创建Quartz任务
+     * @param updateConfig 更新配置
+     */
+    private void createQuartzJob(HisUpdateEntity updateConfig) {
+        try {
+            String jobName = "HIS_DATA_PULL_" + hospitalId;
+            JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP);
+            
+            // 先删除已存在的任务
+            if (quartzScheduler.checkExists(jobKey)) {
+                quartzScheduler.deleteJob(jobKey);
+            }
+            
+            // 创建JobDetail
+            JobDetail jobDetail = JobBuilder.newJob(HospitalHisDataPullJob.class)
+                    .withIdentity(jobKey)
+                    .storeDurably()
+                    .usingJobData("hospitalId", hospitalId)
+                    .build();
+            
+            // 创建CronTrigger
+            // 根据间隔时间生成cron表达式(每X分钟执行一次)
+            String cronExpression = CronExpressionUtil.minutesToCronExpression(updateConfig.getInterval());
+            CronTrigger trigger = TriggerBuilder.newTrigger()
+                    .withIdentity("trigger_" + jobName, JOB_GROUP)
+                    .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)
+                            .withMisfireHandlingInstructionIgnoreMisfires()) // 立即执行
+                    .build();
+            
+            // 调度任务
+            quartzScheduler.scheduleJob(jobDetail, trigger);
+            
+            log.info("成功创建HIS数据拉取任务,hospitalId:{},cron表达式:{}", hospitalId, cronExpression);
+        } catch (SchedulerException e) {
+            log.error("创建HIS数据拉取任务失败,hospitalId:{}", hospitalId, e);
+        }
+    }
+}

+ 2 - 5
nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/HospitalManagerRegister.java

@@ -61,12 +61,9 @@ public class HospitalManagerRegister {
             hospitalManager.refreshScript();
         }
         if(his){
-            if(hospitalManager.getInfo()!=null){
+            if(hospitalManager.getInfo()!=null&&hospitalManager.getInfo().getUpdateConfig()!=null){
                 hospitalManager.refreshUpdateConfig(hospitalManager.getInfo().getUpdateConfig());
             }
         }
     }
-
-
-
-}
+}

+ 10 - 2
nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/his/strategy/onlynew/DefaultHisNewStrategyHandler.java

@@ -1,8 +1,10 @@
 package com.nb.web.service.bus.hospital.his.strategy.onlynew;
 
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
+import com.nb.core.utils.DateCompareUtil;
 import com.nb.web.api.entity.BusClinicEntity;
 import com.nb.web.service.bus.service.LocalBusClinicService;
 import lombok.AllArgsConstructor;
@@ -53,7 +55,8 @@ public class DefaultHisNewStrategyHandler implements HisNewStrategyHandler {
             target.sort(Comparator.comparing(BusClinicEntity::getStartTime));
             //获取最新的临床数据
             BusClinicEntity newClinic = target.get(target.size() - 1);
-            if(clinic.getStartTime().equals(newClinic.getStartTime())){
+            // 使用按年月日时分秒进行比较的方式判断是否为同一天数据
+            if(DateCompareUtil.isSameDateTimeIgnoreMillis(clinic.getStartTime(), newClinic.getStartTime())){
                 //临床数据未发生变化
                 clinicService.compareFromHis(clinic,newClinic);
                 insert=false;
@@ -76,4 +79,9 @@ public class DefaultHisNewStrategyHandler implements HisNewStrategyHandler {
     public boolean apply(List<BusClinicEntity> source, List<BusClinicEntity> target) {
         return CollectionUtil.isNotEmpty(source);
     }
-}
+
+    public static void main(String[] args) {
+        System.out.println(DateCompareUtil.isSameDateTimeIgnoreMillis(DateUtil.parse("2025-08-01T00:00:00.004"),DateUtil.parse("2025-08-01T00:00:00")));
+        System.out.println(DateUtil.parse("2025-08-01T00:00:00").equals(DateUtil.parse("2025-08-01T00:00:00")));
+    }
+}

+ 2 - 1
nb-service/web-service/src/main/java/com/nb/web/service/bus/hospital/his/strategy/part/DefaultHisPartStrategyHandler.java

@@ -3,6 +3,7 @@ package com.nb.web.service.bus.hospital.his.strategy.part;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.nb.core.utils.DateCompareUtil;
 import com.nb.web.api.entity.BusClinicEntity;
 import com.nb.web.service.bus.hospital.his.strategy.HisStrategyHandler;
 import com.nb.web.service.bus.hospital.his.strategy.all.HisAllStrategyHandler;
@@ -58,7 +59,7 @@ public class DefaultHisPartStrategyHandler implements HisStrategyHandler {
             int start=0;
             for (; start < target.size(); start++) {
                 BusClinicEntity existClinic = target.get(start);
-                if(existClinic.getStartTime().equals(earliest.getStartTime())){
+                if(DateCompareUtil.isSameDateTimeIgnoreMillis(existClinic.getStartTime(),earliest.getStartTime())){
                     break;
                 }
                 if(existClinic.getStartTime().after(earliest.getStartTime())){

+ 7 - 26
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusClinicService.java

@@ -12,7 +12,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.nb.core.exception.CustomException;
+import com.nb.core.utils.DateCompareUtil;
 import com.nb.web.api.bean.FormulaDrugDetailDomain;
 import com.nb.web.api.entity.BusDeviceEntity;
 import com.nb.web.api.entity.BusEvaluationEntity;
@@ -195,7 +195,7 @@ public class LocalBusClinicService extends BaseService<BusClinicMapper, BusClini
         source.setFinished(target.getFinished());
         this.updateById(source);
         //手术开始时间发生变化,重新计算输注数据
-        if(source.getStartTime()!=null&&source.getStartTime()!=target.getStartTime()){
+        if(source.getStartTime()!=null&&!DateCompareUtil.isSameDateTimeIgnoreMillis(source.getStartTime(),target.getStartTime())){
             infusionHistoryService.adjustInfusionByClinic(source.getId(),source.getPatientId(),source.getTenantId(),source.getStartTime());
         }
     }
@@ -447,33 +447,14 @@ public class LocalBusClinicService extends BaseService<BusClinicMapper, BusClini
     }
 
     public void batchHandleLiquid(LiquidBatchHandleDTO source) {
-        if(StrUtil.isBlank(source.getLiquidExecutor())&&
-                StrUtil.isBlank(source.getLiquidChecker())&&
-                ObjectUtil.isNull(source.getLiquidTime())&&
-                StrUtil.isBlank(source.getLiquidMethod())){
-            return;
-        }
-        if(StrUtil.isNotBlank(source.getLiquidChecker())||
-                ObjectUtil.isNotNull(source.getLiquidTime())||
-                StrUtil.isNotBlank(source.getLiquidMethod())){
-            if(StrUtil.isBlank(source.getLiquidExecutor())){
-                throw new CustomException("废液处理执行人不能为空");
-            }
-            if(StrUtil.isBlank(source.getLiquidMethod())){
-                throw new CustomException("废液处理方式不能为空");
-            }
-            if(ObjectUtil.isNull(source.getLiquidTime())){
-                throw new CustomException("废液处理时间不能为空");
-            }
-        }
         List<String> clinicIds = source.getClinicIds();
         this.baseMapper.update(null,new LambdaUpdateWrapper<BusClinicEntity>()
                 .in(BusClinicEntity::getId,clinicIds)
-                .set(StrUtil.isNotBlank(source.getLiquidExecutor()),BusClinicEntity::getLiquidExecutor,source.getLiquidExecutor())
-                .set(StrUtil.isNotBlank(source.getLiquidChecker()),BusClinicEntity::getLiquidChecker,source.getLiquidChecker())
-                .set(ObjectUtil.isNotNull(source.getLiquidTime()),BusClinicEntity::getLiquidTime,source.getLiquidTime())
-                .set(StrUtil.isNotBlank(source.getLiquidMethod()),BusClinicEntity::getLiquidMethod,source.getLiquidMethod())
-                .set(StrUtil.isNotBlank(source.getLiquidRemark()),BusClinicEntity::getLiquidRemark,source.getLiquidRemark()));
+                .set(BusClinicEntity::getLiquidExecutor,source.getLiquidExecutor())
+                .set(BusClinicEntity::getLiquidChecker,source.getLiquidChecker())
+                .set(BusClinicEntity::getLiquidTime,source.getLiquidTime())
+                .set(BusClinicEntity::getLiquidMethod,source.getLiquidMethod())
+                .set(BusClinicEntity::getLiquidRemark,source.getLiquidRemark()));
     }
 
     public List<BusLiquidListVO> selectLiquidByIds(Collection<String> ids) {

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

@@ -35,6 +35,7 @@ import com.nb.web.api.feign.IPatientClient;
 import com.nb.web.api.feign.query.DoctorPatientMonitorQuery;
 import com.nb.web.api.feign.result.*;
 import com.nb.web.api.feign.query.PatientMonitorQuery;
+import com.nb.web.service.bus.controller.vo.BusLiquidListVO;
 import com.nb.web.service.bus.entity.*;
 import com.nb.web.api.enums.DeviceAlarmEnum;
 import com.nb.web.api.enums.DeviceStatusEnum;
@@ -824,7 +825,7 @@ public class LocalBusPatientService extends BaseService<BusPatientMapper, BusPat
                 result.setEvaluate(3);
             }else {
                 DateTime date = DateUtil.offset(result.getEvalTime(), DateField.MINUTE, interval);
-                result.setEvaluate(ObjectUtil.compare(date,now)>0?2:1);
+                result.setEvaluate(ObjectUtil.compare(date,now)>0?1:2);
             }
         }
         return results;

+ 109 - 0
nb-service/web-service/src/main/java/com/nb/web/service/quartz/job/service/impl/SysJobServiceImpl.java

@@ -0,0 +1,109 @@
+package com.nb.web.service.quartz.job.service.impl;
+
+import com.nb.web.service.quartz.constant.ScheduleConstants;
+import com.nb.web.service.quartz.exception.TaskException;
+import com.nb.web.service.quartz.job.mapper.SysJobMapper;
+import com.nb.web.service.quartz.job.po.SysJobPO;
+import com.nb.web.service.quartz.job.service.ISysJobService;
+import com.nb.web.service.quartz.util.ScheduleUtils;
+import org.quartz.JobDataMap;
+import org.quartz.JobKey;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.Collections;
+import java.util.List;
+
+/**
+@author npy
+@create 2024-08-26-8:54
+*/
+@Service
+public class SysJobServiceImpl implements ISysJobService {
+
+    @Autowired
+    private Scheduler scheduler;
+
+    @Autowired
+    private SysJobMapper jobMapper;
+
+
+    /**
+     * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据)
+     */
+    @PostConstruct
+    public void init() throws SchedulerException, TaskException
+    {
+        scheduler.clear();
+    }
+    @Override
+    public List<SysJobPO> selectJobList(SysJobPO job) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public SysJobPO selectJobById(Long jobId) {
+        return null;
+    }
+
+    @Override
+    public int pauseJob(SysJobPO job) throws SchedulerException {
+        return 0;
+    }
+
+    @Override
+    public int resumeJob(SysJobPO job) throws SchedulerException {
+        return 0;
+    }
+
+    @Override
+    public int deleteJob(SysJobPO job) throws SchedulerException {
+        return 0;
+    }
+
+    @Override
+    public void deleteJobByIds(Long[] jobIds) throws SchedulerException {
+
+    }
+
+    @Override
+    public int changeStatus(SysJobPO job) throws SchedulerException {
+        return 0;
+    }
+
+    @Override
+    public boolean run(SysJobPO job) throws SchedulerException {
+        boolean result = false;
+        Long jobId = Long.valueOf(job.getJobId());
+        String jobGroup = job.getJobGroup();
+        SysJobPO properties = jobMapper.selectJobById(jobId);
+        // 参数
+        JobDataMap dataMap = new JobDataMap();
+        dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties);
+        JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup);
+        if (scheduler.checkExists(jobKey))
+        {
+            result = true;
+            scheduler.triggerJob(jobKey, dataMap);
+        }
+        return result;
+    }
+
+    @Override
+    public int insertJob(SysJobPO job) throws SchedulerException, TaskException {
+        return 0;
+    }
+
+    @Override
+    public int updateJob(SysJobPO job) throws SchedulerException, TaskException {
+        return 0;
+    }
+
+    @Override
+    public boolean checkCronExpressionIsValid(String cronExpression) {
+        return false;
+    }
+}

+ 105 - 0
nb-service/web-service/src/main/java/com/nb/web/service/quartz/task/HospitalHisDataPullTask.java

@@ -0,0 +1,105 @@
+package com.nb.web.service.quartz.task;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.nb.web.api.entity.BusInfusionHistoryEntity;
+import com.nb.web.service.bus.hospital.HospitalManager;
+import com.nb.web.service.bus.hospital.HospitalManagerRegister;
+import com.nb.web.service.bus.service.LocalBusHospitalService;
+import com.nb.web.service.bus.service.LocalBusInfusionHistoryService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * 医院HIS数据拉取任务
+ * 用于定时从HIS系统拉取病人信息
+ */
+@Component("hospitalHisDataPullTask")
+@Slf4j
+public class HospitalHisDataPullTask {
+
+    @Autowired
+    private LocalBusHospitalService hospitalService;
+
+    @Autowired
+    private LocalBusInfusionHistoryService infusionHistoryService;
+
+    @Autowired
+    private HospitalManagerRegister managerRegister;
+
+    /**
+     * 定时拉取HIS数据
+     * @param hospitalId 医院ID,如果为空则拉取所有医院的数据
+     */
+    public void pullHisData(String hospitalId) {
+        log.info("[定时拉取病人数据]开始执行任务,hospitalId:{}", hospitalId);
+        
+        try {
+            // 如果指定了医院ID,则只处理该医院的数据
+            if (StrUtil.isNotEmpty(hospitalId)) {
+                pullHospitalData(hospitalId);
+            } else {
+                // 否则处理所有医院的数据
+                List<String> hospitalIds = hospitalService.list().stream()
+                        .map(entity -> entity.getId())
+                        .collect(Collectors.toList());
+                for (String hid : hospitalIds) {
+                    pullHospitalData(hid);
+                }
+            }
+            
+            log.info("[定时拉取病人数据]任务执行完成,hospitalId:{}", hospitalId);
+        } catch (Exception e) {
+            log.error("[定时拉取病人数据]任务执行异常,hospitalId:{}", hospitalId, e);
+        }
+    }
+
+    /**
+     * 拉取指定医院的数据
+     * @param hospitalId 医院ID
+     */
+    private void pullHospitalData(String hospitalId) {
+        try {
+            // 获取医院管理器
+            HospitalManager hospitalManager = managerRegister.get(hospitalId);
+            if (hospitalManager == null) {
+                log.warn("[定时拉取病人数据]未找到医院管理器,hospitalId:{}", hospitalId);
+                return;
+            }
+            // 拉取最新的9999条输注信息,更新病人数据
+            Page<BusInfusionHistoryEntity> infusionHistoryPage = new Page<>(0, 9999, false);
+            infusionHistoryPage = infusionHistoryService.page(
+                    infusionHistoryPage,
+                    new QueryWrapper<BusInfusionHistoryEntity>().lambda()
+                            .eq(BusInfusionHistoryEntity::getTenantId, hospitalId)
+                            .eq(BusInfusionHistoryEntity::getFinished, false)
+                            .orderByDesc(BusInfusionHistoryEntity::getLastUploadTime)
+            );
+            List<BusInfusionHistoryEntity> records = infusionHistoryPage.getRecords();
+            if (CollUtil.isNotEmpty(records)) {
+                Set<String> patientCodes = records.stream()
+                        .map(BusInfusionHistoryEntity::getPatientCode)
+                        .collect(Collectors.toSet());
+                for (String patientCode : patientCodes) {
+                    log.info("[拉取病人信息]hospitalId:{}, patientCode:{}", hospitalId, patientCode);
+                    try {
+                        hospitalManager.getScriptSession()
+                                .asyncGetPatientInfo(patientCode, 3, TimeUnit.SECONDS, false);
+                    } catch (Exception e) {
+                        log.warn("[拉取病人信息失败]hospitalId:{}, patientCode:{}", hospitalId, patientCode, e);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("[定时拉取病人数据]处理医院数据异常,hospitalId:{}", hospitalId, e);
+        }
+    }
+}

+ 107 - 0
nb-service/web-service/src/main/java/com/nb/web/service/quartz/util/AbstractQuartzJob.java

@@ -0,0 +1,107 @@
+package com.nb.web.service.quartz.util;
+
+import com.nb.web.service.quartz.constant.Constants;
+import com.nb.web.service.quartz.constant.ScheduleConstants;
+import com.nb.web.service.quartz.job.po.SysJobPO;
+import com.nb.web.service.quartz.jobLog.po.SysJobLogPO;
+import com.nb.web.service.quartz.jobLog.service.ISysJobLogService;
+import org.apache.commons.lang3.StringUtils;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * 抽象quartz调用
+ *
+ * @author ruoyi
+ */
+public abstract class AbstractQuartzJob implements Job
+{
+    private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class);
+
+    /**
+     * 线程本地变量
+     */
+    private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();
+
+    @Override
+    public void execute(JobExecutionContext context) throws JobExecutionException
+    {
+        SysJobPO sysJob = new SysJobPO();
+        BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
+        try
+        {
+            before(context, sysJob);
+            if (sysJob != null)
+            {
+                doExecute(context, sysJob);
+            }
+            after(context, sysJob, null);
+        }
+        catch (Exception e)
+        {
+            log.error("任务执行异常  - :", e);
+            after(context, sysJob, e);
+        }
+    }
+
+    /**
+     * 执行前
+     *
+     * @param context 工作执行上下文对象
+     * @param sysJob 系统计划任务
+     */
+    protected void before(JobExecutionContext context, SysJobPO sysJob)
+    {
+        threadLocal.set(new Date());
+    }
+
+    /**
+     * 执行后
+     *
+     * @param context 工作执行上下文对象
+     * @param sysJob 系统计划任务
+     */
+    protected void after(JobExecutionContext context, SysJobPO sysJob, Exception e)
+    {
+        Date startTime = threadLocal.get();
+        threadLocal.remove();
+
+        final SysJobLogPO sysJobLog = new SysJobLogPO();
+        sysJobLog.setJobName(sysJob.getJobName());
+        sysJobLog.setJobGroup(sysJob.getJobGroup());
+        sysJobLog.setInvokeTarget(sysJob.getInvokeTarget());
+        sysJobLog.setStartTime(startTime);
+        sysJobLog.setEndTime(new Date());
+        long runMs = sysJobLog.getEndTime().getTime() - sysJobLog.getStartTime().getTime();
+        sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒");
+        sysJobLog.setId(String.valueOf(UUID.randomUUID().toString().replace("-", "").substring(0, 16).hashCode()& 0xFFFF));
+        if (e != null)
+        {
+            sysJobLog.setStatus(Constants.FAIL);
+            String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000);
+            sysJobLog.setExceptionInfo(errorMsg);
+        }
+        else
+        {
+            sysJobLog.setStatus(Constants.SUCCESS);
+        }
+
+        // 写入数据库当中
+//        SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog);
+    }
+
+    /**
+     * 执行方法,由子类重载
+     *
+     * @param context 工作执行上下文对象
+     * @param sysJob 系统计划任务
+     * @throws Exception 执行过程中的异常
+     */
+    protected abstract void doExecute(JobExecutionContext context, SysJobPO sysJob) throws Exception;
+}

+ 8 - 8
nb-service/web-service/src/main/resources/mapper/bus/BusPatientMapper.xml

@@ -46,7 +46,7 @@
         <result column="max_dose" property="maxDose"/>
         <result column="last_upload_time" property="lastUploadTime"/>
         <result column="product_no" property="productNo"/>
-        <!--<result column="self_control_count" property="selfControlCount"/>-->
+<!--        <result column="self_control_count" property="selfControlCount"/>-->
         <result column="self_control_lock_time" property="selfControlLockTime"/>
         <result column="pca_valid_count" property="pcaValidCount"/>
         <result column="pca_invalid_count" property="pcaInvalidCount"/>
@@ -128,7 +128,7 @@
         c.`patient_name` as name,
         c.patient_age as age,
         c.ward,
-        c.bed_no,
+        COALESCE(c.manual_bedno, c.bed_no) as bed_no,
         c.id as clinic_id,
         c.`surgery_name` as clinic_name,
         i.device_id as device_id,
@@ -160,7 +160,7 @@
             c.`patient_name` as name,
             c.patient_age as age,
             c.ward as ward,
-            c.bed_no as bed_no,
+            COALESCE(c.manual_bedno, c.bed_no) as bed_no,
             c.`surgery_name` as surgery_name,
             c.weight as weight,
             c.height as height,
@@ -245,7 +245,7 @@
         c.surgery_doctor as surgery_doctor,
         c.surgery_name as surgery_name,
         c.ward as ward,
-        c.bed_no as bed_no,
+        COALESCE(c.manual_bedno, c.bed_no) as bed_no,
         c.eval_time as eval_time,
         c.manage_type as manage_type,
         c.abnormal as abnormal,
@@ -458,7 +458,7 @@
         c.surgery_doctor as surgery_doctor,
         c.surgery_name as surgery_name,
         c.ward as ward,
-        c.bed_no as bed_no,
+        COALESCE(c.manual_bedno, c.bed_no) as bed_no,
         c.eval_time as eval_time,
         bh.code as hospital_code
         from
@@ -570,7 +570,7 @@
         <!-- 临床信息 -->
         c.patient_name AS patient_name,
         c.ward AS ward,
-        c.bed_no AS bed_no,
+        COALESCE(i.bed_no, c.bed_no) as bed_no,
         c.ana_doctor AS ana_doctor,
         c.surgery_name AS surge_name,
         c.ana_type AS ana_type,
@@ -646,7 +646,7 @@
                 </foreach>
             </if>
             <if test="query.bedNo != null">
-                AND c.bed_no LIKE CONCAT('%', #{query.bedNo}, '%')
+                AND IFNULL(c.manual_bedno, c.bed_no) LIKE CONCAT('%', #{query.bedNo}, '%')
             </if>
             <if test="query.anaDoctor != null">
                 AND c.ana_doctor LIKE CONCAT('%', #{query.anaDoctor}, '%')
@@ -722,4 +722,4 @@
             order by c.bed_no ASC  <!-- 按病区和床号升序 -->
         </if>
     </select>
-</mapper>
+</mapper>