From 41b81f06821ce8e997309d7c429c24bd671d77f0 Mon Sep 17 00:00:00 2001
From: xiezubing1 <xiezubing@ihup.org.cn>
Date: Mon, 8 Nov 2021 17:09:14 +0800
Subject: [PATCH 1/3] =?UTF-8?q?[Fix]=E5=90=8C=E6=AD=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 pom.xml                                       |  19 +-
 .../main/java/com/ruoyi/RuoYiApplication.java |   2 +-
 .../controller/common/CaptchaController.java  |  12 +-
 .../monitor/SysUserOnlineController.java      |  12 +-
 .../src/main/resources/application-druid.yml  | 110 ++++----
 .../src/main/resources/application.yml        |  52 ++--
 ruoyi-admin/src/main/resources/logback.xml    | 102 ++++----
 .../main/resources/mybatis/mybatis-config.xml |   2 +-
 ruoyi-common/pom.xml                          |  10 +-
 .../com/ruoyi/common/utils/DictUtils.java     |  30 +--
 .../ruoyi/framework/aspectj/LogAspect.java    |  10 +-
 .../ruoyi/framework/config/MyBatisConfig.java | 246 ++++++++----------
 .../impl/SameUrlDataInterceptor.java          |  10 +-
 .../web/service/SysLoginService.java          |  16 +-
 .../web/service/SysRegisterService.java       |  12 +-
 .../framework/web/service/TokenService.java   |  10 +-
 .../ruoyi/quartz/util/AbstractQuartzJob.java  |  23 +-
 .../service/impl/SysConfigServiceImpl.java    |  40 +--
 18 files changed, 369 insertions(+), 349 deletions(-)

diff --git a/pom.xml b/pom.xml
index 2f3dd728d..d90fb8339 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 	<modelVersion>4.0.0</modelVersion>
-	
+
     <groupId>com.ruoyi</groupId>
     <artifactId>ruoyi</artifactId>
     <version>3.7.0</version>
@@ -11,7 +11,7 @@
     <name>ruoyi</name>
     <url>http://www.ruoyi.vip</url>
     <description>若依管理系统</description>
-    
+
     <properties>
         <ruoyi.version>3.7.0</ruoyi.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -22,7 +22,8 @@
         <bitwalker.version>1.21</bitwalker.version>
         <swagger.version>3.0.0</swagger.version>
         <kaptcha.version>2.3.2</kaptcha.version>
-        <mybatis-spring-boot.version>2.2.0</mybatis-spring-boot.version>
+        <!--<mybatis-spring-boot.version>2.2.0</mybatis-spring-boot.version>-->
+        <mybatis-plus.version>3.4.2</mybatis-plus.version>
         <pagehelper.boot.version>1.4.0</pagehelper.boot.version>
         <fastjson.version>1.2.78</fastjson.version>
         <oshi.version>5.8.2</oshi.version>
@@ -34,7 +35,7 @@
         <velocity.version>1.7</velocity.version>
         <jwt.version>0.9.1</jwt.version>
     </properties>
-	
+
     <!-- 依赖声明 -->
     <dependencyManagement>
         <dependencies>
@@ -63,10 +64,16 @@
             </dependency>
 
             <!-- SpringBoot集成mybatis框架 -->
-            <dependency>
+            <!--<dependency>
                 <groupId>org.mybatis.spring.boot</groupId>
                 <artifactId>mybatis-spring-boot-starter</artifactId>
                 <version>${mybatis-spring-boot.version}</version>
+            </dependency>-->
+            <!-- Mybatis-Plus 集成mybatis-plus-->
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-boot-starter</artifactId>
+                <version>${mybatis-plus.version}</version>
             </dependency>
 
             <!-- pagehelper 分页插件 -->
@@ -263,4 +270,4 @@
         </pluginRepository>
     </pluginRepositories>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
index e3c56ee54..eb99b9442 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 
 /**
  * 启动程序
- * 
+ *
  * @author ruoyi
  */
 @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
index 649fd115e..b6e4c0fe1 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
@@ -14,14 +14,14 @@ import org.springframework.web.bind.annotation.RestController;
 import com.google.code.kaptcha.Producer;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.redis.RedisUtils;
 import com.ruoyi.common.utils.sign.Base64;
 import com.ruoyi.common.utils.uuid.IdUtils;
 import com.ruoyi.system.service.ISysConfigService;
 
 /**
  * 验证码操作处理
- * 
+ *
  * @author ruoyi
  */
 @RestController
@@ -34,12 +34,12 @@ public class CaptchaController
     private Producer captchaProducerMath;
 
     @Autowired
-    private RedisCache redisCache;
-    
+    private RedisUtils redisUtils;
+
     // 验证码类型
     @Value("${ruoyi.captchaType}")
     private String captchaType;
-    
+
     @Autowired
     private ISysConfigService configService;
     /**
@@ -77,7 +77,7 @@ public class CaptchaController
             image = captchaProducer.createImage(capStr);
         }
 
-        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
+        redisUtils.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
         // 转换流信息写出
         FastByteArrayOutputStream os = new FastByteArrayOutputStream();
         try
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java
index 4ca306d70..f93bd5ed4 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java
@@ -17,7 +17,7 @@ import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.core.page.TableDataInfo;
-import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.redis.RedisUtils;
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.domain.SysUserOnline;
@@ -25,7 +25,7 @@ import com.ruoyi.system.service.ISysUserOnlineService;
 
 /**
  * 在线用户监控
- * 
+ *
  * @author ruoyi
  */
 @RestController
@@ -36,17 +36,17 @@ public class SysUserOnlineController extends BaseController
     private ISysUserOnlineService userOnlineService;
 
     @Autowired
-    private RedisCache redisCache;
+    private RedisUtils redisUtils;
 
     @PreAuthorize("@ss.hasPermi('monitor:online:list')")
     @GetMapping("/list")
     public TableDataInfo list(String ipaddr, String userName)
     {
-        Collection<String> keys = redisCache.keys(Constants.LOGIN_TOKEN_KEY + "*");
+        Collection<String> keys = redisUtils.keys(Constants.LOGIN_TOKEN_KEY + "*");
         List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
         for (String key : keys)
         {
-            LoginUser user = redisCache.getCacheObject(key);
+            LoginUser user = redisUtils.getCacheObject(key);
             if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
             {
                 if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername()))
@@ -86,7 +86,7 @@ public class SysUserOnlineController extends BaseController
     @DeleteMapping("/{tokenId}")
     public AjaxResult forceLogout(@PathVariable String tokenId)
     {
-        redisCache.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId);
+        redisUtils.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId);
         return AjaxResult.success();
     }
 }
diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml
index 1f098e407..83fe8d024 100644
--- a/ruoyi-admin/src/main/resources/application-druid.yml
+++ b/ruoyi-admin/src/main/resources/application-druid.yml
@@ -1,57 +1,57 @@
 # 数据源配置
 spring:
-    datasource:
-        type: com.alibaba.druid.pool.DruidDataSource
-        driverClassName: com.mysql.cj.jdbc.Driver
-        druid:
-            # 主库数据源
-            master:
-                url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                username: root
-                password: password
-            # 从库数据源
-            slave:
-                # 从数据源开关/默认关闭
-                enabled: false
-                url: 
-                username: 
-                password: 
-            # 初始连接数
-            initialSize: 5
-            # 最小连接池数量
-            minIdle: 10
-            # 最大连接池数量
-            maxActive: 20
-            # 配置获取连接等待超时的时间
-            maxWait: 60000
-            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
-            timeBetweenEvictionRunsMillis: 60000
-            # 配置一个连接在池中最小生存的时间,单位是毫秒
-            minEvictableIdleTimeMillis: 300000
-            # 配置一个连接在池中最大生存的时间,单位是毫秒
-            maxEvictableIdleTimeMillis: 900000
-            # 配置检测连接是否有效
-            validationQuery: SELECT 1 FROM DUAL
-            testWhileIdle: true
-            testOnBorrow: false
-            testOnReturn: false
-            webStatFilter: 
-                enabled: true
-            statViewServlet:
-                enabled: true
-                # 设置白名单,不填则允许所有访问
-                allow:
-                url-pattern: /druid/*
-                # 控制台管理用户名和密码
-                login-username: ruoyi
-                login-password: 123456
-            filter:
-                stat:
-                    enabled: true
-                    # 慢SQL记录
-                    log-slow-sql: true
-                    slow-sql-millis: 1000
-                    merge-sql: true
-                wall:
-                    config:
-                        multi-statement-allow: true
\ No newline at end of file
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 主库数据源
+      master:
+        url: jdbc:mysql://localhost:3306/ry?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+        username: root
+        password: root
+      # 从库数据源
+      slave:
+        # 从数据源开关/默认关闭
+        enabled: false
+        url:
+        username:
+        password:
+      # 初始连接数
+      initialSize: 5
+      # 最小连接池数量
+      minIdle: 10
+      # 最大连接池数量
+      maxActive: 20
+      # 配置获取连接等待超时的时间
+      maxWait: 60000
+      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+      timeBetweenEvictionRunsMillis: 60000
+      # 配置一个连接在池中最小生存的时间,单位是毫秒
+      minEvictableIdleTimeMillis: 300000
+      # 配置一个连接在池中最大生存的时间,单位是毫秒
+      maxEvictableIdleTimeMillis: 900000
+      # 配置检测连接是否有效
+      validationQuery: SELECT 'x'
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: true
+        # 设置白名单,不填则允许所有访问
+        allow:
+        url-pattern: /druid/*
+        # 控制台管理用户名和密码
+        login-username: ruoyi
+        login-password: 123456
+      filter:
+        stat:
+          enabled: true
+          # 慢SQL记录
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index ae0ffbc9e..9236504f0 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -42,7 +42,7 @@ spring:
   messages:
     # 国际化资源文件路径
     basename: i18n/messages
-  profiles: 
+  profiles:
     active: druid
   # 文件上传
   servlet:
@@ -65,7 +65,7 @@ spring:
     # 数据库索引
     database: 0
     # 密码
-    password: 
+    password:
     # 连接超时时间
     timeout: 10s
     lettuce:
@@ -81,27 +81,39 @@ spring:
 
 # token配置
 token:
-    # 令牌自定义标识
-    header: Authorization
-    # 令牌密钥
-    secret: abcdefghijklmnopqrstuvwxyz
-    # 令牌有效期(默认30分钟)
-    expireTime: 30
-  
-# MyBatis配置
-mybatis:
-    # 搜索指定包别名
-    typeAliasesPackage: com.ruoyi.**.domain
-    # 配置mapper的扫描,找到所有的mapper.xml映射文件
-    mapperLocations: classpath*:mapper/**/*Mapper.xml
-    # 加载全局的配置文件
-    configLocation: classpath:mybatis/mybatis-config.xml
+  # 令牌自定义标识
+  header: Authorization
+  # 令牌密钥
+  secret: abcdefghijklmnopqrstuvwxyz
+  # 令牌有效期(默认30分钟)
+  expireTime: 30
+
+# MyBatis-Plus配置
+mybatis-plus:
+  type-aliases-package: com.ruoyi.**.domain
+  mapper-locations: classpath*:mapper/**/*Mapper.xml
+  #config-location: classpath:mybatis/mybatis-config.xml
+  global-config:
+    db-config:
+      id-type: auto
+      #字段策略 0:"忽略判断",1:"非 NULL 判断",2:"非空判断"
+      field-strategy: 2
+      refresh-mapper: true
+      #逻辑删除配置 0:"未删除" 1:"已删除"
+      logicDeleteValue: 0
+      logicNotDeleteValue: 1
+      db-type: mysql
+  configuration:
+    map-underscore-to-camel-case: true
+    cache-enabled: false
+    # 关闭日志
+    #logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl
 
 # PageHelper分页插件
-pagehelper: 
+pagehelper:
   helperDialect: mysql
   supportMethodsArguments: true
-  params: count=countSql 
+  params: count=countSql
 
 # Swagger配置
 swagger:
@@ -111,7 +123,7 @@ swagger:
   pathMapping: /dev-api
 
 # 防止XSS攻击
-xss: 
+xss:
   # 过滤开关
   enabled: true
   # 排除链接(多个用逗号分隔)
diff --git a/ruoyi-admin/src/main/resources/logback.xml b/ruoyi-admin/src/main/resources/logback.xml
index d69a57207..d8329bd02 100644
--- a/ruoyi-admin/src/main/resources/logback.xml
+++ b/ruoyi-admin/src/main/resources/logback.xml
@@ -1,31 +1,43 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration>
     <!-- 日志存放路径 -->
-	<property name="log.path" value="/home/ruoyi/logs" />
+    <property name="log.path" value="/home/ruoyi/logs" />
     <!-- 日志输出格式 -->
-	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
+    <!--<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />-->
 
-	<!-- 控制台输出 -->
-	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
-		<encoder>
-			<pattern>${log.pattern}</pattern>
-		</encoder>
-	</appender>
-	
-	<!-- 系统日志输出 -->
-	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
-	    <file>${log.path}/sys-info.log</file>
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
+    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
+    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
+    <!-- 彩色日志格式 -->
+<!--
+    <property name="log.pattern" value="${log.pattern:-%clr(%d{HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(-&#45;&#45;){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+-->
+    <!--<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />-->
+    <!--<property name="log.pattern" value="%d{HH:mm:ss.SSS} %magenta([%thread]) %customcolor(%-5level) %cyan(%logger{15}) - %msg%n" />-->
+    <property name="log.pattern" value="%d{HH:mm:ss.SSS} %green(%-5level) [%thread] %cyan(%logger{20}) - [%method,%line] : %msg%n" />
+
+    <!-- 控制台输出 -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <!-- 系统日志输出 -->
+    <appender name="file_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.TimeBasedRollingPolicy">
             <!-- 日志文件名格式 -->
-			<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
-			<!-- 日志最大的历史 60天 -->
-			<maxHistory>60</maxHistory>
-		</rollingPolicy>
-		<encoder>
-			<pattern>${log.pattern}</pattern>
-		</encoder>
-		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
             <!-- 过滤的级别 -->
             <level>INFO</level>
             <!-- 匹配时的操作:接收(记录) -->
@@ -33,16 +45,16 @@
             <!-- 不匹配时的操作:拒绝(不记录) -->
             <onMismatch>DENY</onMismatch>
         </filter>
-	</appender>
-	
-	<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
-	    <file>${log.path}/sys-error.log</file>
+    </appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/sys-error.log</file>
         <!-- 循环政策:基于时间创建日志文件 -->
         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
             <!-- 日志文件名格式 -->
             <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
-			<!-- 日志最大的历史 60天 -->
-			<maxHistory>60</maxHistory>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
         </rollingPolicy>
         <encoder>
             <pattern>${log.pattern}</pattern>
@@ -50,16 +62,16 @@
         <filter class="ch.qos.logback.classic.filter.LevelFilter">
             <!-- 过滤的级别 -->
             <level>ERROR</level>
-			<!-- 匹配时的操作:接收(记录) -->
+            <!-- 匹配时的操作:接收(记录) -->
             <onMatch>ACCEPT</onMatch>
-			<!-- 不匹配时的操作:拒绝(不记录) -->
+            <!-- 不匹配时的操作:拒绝(不记录) -->
             <onMismatch>DENY</onMismatch>
         </filter>
     </appender>
-	
-	<!-- 用户访问日志输出  -->
+
+    <!-- 用户访问日志输出  -->
     <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
-		<file>${log.path}/sys-user.log</file>
+        <file>${log.path}/sys-user.log</file>
         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
             <!-- 按天回滚 daily -->
             <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
@@ -70,24 +82,24 @@
             <pattern>${log.pattern}</pattern>
         </encoder>
     </appender>
-	
-	<!-- 系统模块日志级别控制  -->
-	<logger name="com.ruoyi" level="info" />
-	<!-- Spring日志级别控制  -->
-	<logger name="org.springframework" level="warn" />
 
-	<root level="info">
-		<appender-ref ref="console" />
-	</root>
-	
-	<!--系统操作日志-->
+    <!-- 系统模块日志级别控制  -->
+    <logger name="com.ruoyi" level="info" />
+    <!-- Spring日志级别控制  -->
+    <logger name="org.springframework" level="warn" />
+
+    <root level="info">
+        <appender-ref ref="console" />
+    </root>
+
+    <!--系统操作日志-->
     <root level="info">
         <appender-ref ref="file_info" />
         <appender-ref ref="file_error" />
     </root>
-	
-	<!--系统用户操作日志-->
+
+    <!--系统用户操作日志-->
     <logger name="sys-user" level="info">
         <appender-ref ref="sys-user"/>
     </logger>
-</configuration> 
\ No newline at end of file
+</configuration>
diff --git a/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml b/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml
index 4b8c49628..23d3b3ad3 100644
--- a/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml
+++ b/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml
@@ -16,5 +16,5 @@ PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
         <!-- 使用驼峰命名法转换字段 -->
 		<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
 	</settings>
-	
+
 </configuration>
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index 278434bbe..dae6f8fd4 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -35,6 +35,12 @@
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
 
+        <!-- Mybatis-Plus 集成mybatis-plus-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+        </dependency>
+
         <!-- pagehelper 分页插件 -->
         <dependency>
             <groupId>com.github.pagehelper</groupId>
@@ -52,7 +58,7 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
-  
+
         <!-- JSON工具类 -->
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
@@ -127,4 +133,4 @@
 
     </dependencies>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java
index 16e7fca11..922a344a0 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java
@@ -4,12 +4,12 @@ import java.util.Collection;
 import java.util.List;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.entity.SysDictData;
-import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.redis.RedisUtils;
 import com.ruoyi.common.utils.spring.SpringUtils;
 
 /**
  * 字典工具类
- * 
+ *
  * @author ruoyi
  */
 public class DictUtils
@@ -21,24 +21,24 @@ public class DictUtils
 
     /**
      * 设置字典缓存
-     * 
+     *
      * @param key 参数键
      * @param dictDatas 字典数据列表
      */
     public static void setDictCache(String key, List<SysDictData> dictDatas)
     {
-        SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas);
+        SpringUtils.getBean(RedisUtils.class).setCacheObject(getCacheKey(key), dictDatas);
     }
 
     /**
      * 获取字典缓存
-     * 
+     *
      * @param key 参数键
      * @return dictDatas 字典数据列表
      */
     public static List<SysDictData> getDictCache(String key)
     {
-        Object cacheObj = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
+        Object cacheObj = SpringUtils.getBean(RedisUtils.class).getCacheObject(getCacheKey(key));
         if (StringUtils.isNotNull(cacheObj))
         {
             List<SysDictData> dictDatas = StringUtils.cast(cacheObj);
@@ -49,7 +49,7 @@ public class DictUtils
 
     /**
      * 根据字典类型和字典值获取字典标签
-     * 
+     *
      * @param dictType 字典类型
      * @param dictValue 字典值
      * @return 字典标签
@@ -61,7 +61,7 @@ public class DictUtils
 
     /**
      * 根据字典类型和字典标签获取字典值
-     * 
+     *
      * @param dictType 字典类型
      * @param dictLabel 字典标签
      * @return 字典值
@@ -73,7 +73,7 @@ public class DictUtils
 
     /**
      * 根据字典类型和字典值获取字典标签
-     * 
+     *
      * @param dictType 字典类型
      * @param dictValue 字典值
      * @param separator 分隔符
@@ -113,7 +113,7 @@ public class DictUtils
 
     /**
      * 根据字典类型和字典标签获取字典值
-     * 
+     *
      * @param dictType 字典类型
      * @param dictLabel 字典标签
      * @param separator 分隔符
@@ -153,12 +153,12 @@ public class DictUtils
 
     /**
      * 删除指定字典缓存
-     * 
+     *
      * @param key 字典键
      */
     public static void removeDictCache(String key)
     {
-        SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key));
+        SpringUtils.getBean(RedisUtils.class).deleteObject(getCacheKey(key));
     }
 
     /**
@@ -166,13 +166,13 @@ public class DictUtils
      */
     public static void clearDictCache()
     {
-        Collection<String> keys = SpringUtils.getBean(RedisCache.class).keys(Constants.SYS_DICT_KEY + "*");
-        SpringUtils.getBean(RedisCache.class).deleteObject(keys);
+        Collection<String> keys = SpringUtils.getBean(RedisUtils.class).keys(Constants.SYS_DICT_KEY + "*");
+        SpringUtils.getBean(RedisUtils.class).deleteObject(keys);
     }
 
     /**
      * 设置cache key
-     * 
+     *
      * @param configKey 参数键
      * @return 缓存键key
      */
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
index a2aaf2229..bb1a298cb 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
@@ -29,7 +29,7 @@ import com.ruoyi.system.domain.SysOperLog;
 
 /**
  * 操作日志记录处理
- * 
+ *
  * @author ruoyi
  */
 @Aspect
@@ -51,7 +51,7 @@ public class LogAspect
 
     /**
      * 拦截异常操作
-     * 
+     *
      * @param joinPoint 切点
      * @param e 异常
      */
@@ -108,7 +108,7 @@ public class LogAspect
 
     /**
      * 获取注解中对方法的描述信息 用于Controller层注解
-     * 
+     *
      * @param log 日志
      * @param operLog 操作日志
      * @throws Exception
@@ -136,7 +136,7 @@ public class LogAspect
 
     /**
      * 获取请求的参数,放到log中
-     * 
+     *
      * @param operLog 操作日志
      * @throws Exception 异常
      */
@@ -183,7 +183,7 @@ public class LogAspect
 
     /**
      * 判断是否需要过滤的对象。
-     * 
+     *
      * @param o 对象信息。
      * @return 如果是需要过滤的对象,则返回true;否则返回false。
      */
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java
index e30fe74fe..5055a25d2 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java
@@ -1,132 +1,114 @@
-package com.ruoyi.framework.config;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import javax.sql.DataSource;
-import org.apache.ibatis.io.VFS;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.mybatis.spring.SqlSessionFactoryBean;
-import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.Environment;
-import org.springframework.core.io.DefaultResourceLoader;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
-import org.springframework.core.io.support.ResourcePatternResolver;
-import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.util.ClassUtils;
-import com.ruoyi.common.utils.StringUtils;
-
-/**
- * Mybatis支持*匹配扫描包
- * 
- * @author ruoyi
- */
-@Configuration
-public class MyBatisConfig
-{
-    @Autowired
-    private Environment env;
-
-    static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
-
-    public static String setTypeAliasesPackage(String typeAliasesPackage)
-    {
-        ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
-        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
-        List<String> allResult = new ArrayList<String>();
-        try
-        {
-            for (String aliasesPackage : typeAliasesPackage.split(","))
-            {
-                List<String> result = new ArrayList<String>();
-                aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
-                        + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
-                Resource[] resources = resolver.getResources(aliasesPackage);
-                if (resources != null && resources.length > 0)
-                {
-                    MetadataReader metadataReader = null;
-                    for (Resource resource : resources)
-                    {
-                        if (resource.isReadable())
-                        {
-                            metadataReader = metadataReaderFactory.getMetadataReader(resource);
-                            try
-                            {
-                                result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
-                            }
-                            catch (ClassNotFoundException e)
-                            {
-                                e.printStackTrace();
-                            }
-                        }
-                    }
-                }
-                if (result.size() > 0)
-                {
-                    HashSet<String> hashResult = new HashSet<String>(result);
-                    allResult.addAll(hashResult);
-                }
-            }
-            if (allResult.size() > 0)
-            {
-                typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
-            }
-            else
-            {
-                throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
-            }
-        }
-        catch (IOException e)
-        {
-            e.printStackTrace();
-        }
-        return typeAliasesPackage;
-    }
-
-    public Resource[] resolveMapperLocations(String[] mapperLocations)
-    {
-        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
-        List<Resource> resources = new ArrayList<Resource>();
-        if (mapperLocations != null)
-        {
-            for (String mapperLocation : mapperLocations)
-            {
-                try
-                {
-                    Resource[] mappers = resourceResolver.getResources(mapperLocation);
-                    resources.addAll(Arrays.asList(mappers));
-                }
-                catch (IOException e)
-                {
-                    // ignore
-                }
-            }
-        }
-        return resources.toArray(new Resource[resources.size()]);
-    }
-
-    @Bean
-    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
-    {
-        String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
-        String mapperLocations = env.getProperty("mybatis.mapperLocations");
-        String configLocation = env.getProperty("mybatis.configLocation");
-        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
-        VFS.addImplClass(SpringBootVFS.class);
-
-        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
-        sessionFactory.setDataSource(dataSource);
-        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
-        sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
-        sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
-        return sessionFactory.getObject();
-    }
-}
\ No newline at end of file
+//package com.ruoyi.framework.config;
+//
+//import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
+//import com.ruoyi.common.utils.StringUtils;
+//import org.apache.ibatis.io.VFS;
+//import org.apache.ibatis.session.SqlSessionFactory;
+//import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.core.env.Environment;
+//import org.springframework.core.io.DefaultResourceLoader;
+//import org.springframework.core.io.Resource;
+//import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+//import org.springframework.core.io.support.ResourcePatternResolver;
+//import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
+//import org.springframework.core.type.classreading.MetadataReader;
+//import org.springframework.core.type.classreading.MetadataReaderFactory;
+//import org.springframework.util.ClassUtils;
+//
+//import javax.sql.DataSource;
+//import java.io.IOException;
+//import java.util.ArrayList;
+//import java.util.Arrays;
+//import java.util.HashSet;
+//import java.util.List;
+//
+///**
+// * Mybatis支持*匹配扫描包
+// *
+// * @author ruoyi
+// */
+//@Configuration
+//public class MyBatisConfig {
+//    @Autowired
+//    private Environment env;
+//
+//    static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
+//
+//    public static String setTypeAliasesPackage(String typeAliasesPackage) {
+//        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+//        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
+//        List<String> allResult = new ArrayList<>();
+//        try {
+//            for (String aliasesPackage : typeAliasesPackage.split(",")) {
+//                List<String> result = new ArrayList<>();
+//                aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+//                        + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
+//                Resource[] resources = resolver.getResources(aliasesPackage);
+//                if (resources != null && resources.length > 0) {
+//                    MetadataReader metadataReader = null;
+//                    for (Resource resource : resources) {
+//                        if (resource.isReadable()) {
+//                            metadataReader = metadataReaderFactory.getMetadataReader(resource);
+//                            try {
+//                                result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
+//                            } catch (ClassNotFoundException e) {
+//                                e.printStackTrace();
+//                            }
+//                        }
+//                    }
+//                }
+//                if (result.size() > 0) {
+//                    HashSet<String> hashResult = new HashSet<>(result);
+//                    allResult.addAll(hashResult);
+//                }
+//            }
+//            if (allResult.size() > 0) {
+//                typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
+//            } else {
+//                throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
+//            }
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//        }
+//        return typeAliasesPackage;
+//    }
+//
+//    public Resource[] resolveMapperLocations(String[] mapperLocations) {
+//        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
+//        List<Resource> resources = new ArrayList<>();
+//        if (mapperLocations != null) {
+//            for (String mapperLocation : mapperLocations) {
+//                try {
+//                    Resource[] mappers = resourceResolver.getResources(mapperLocation);
+//                    resources.addAll(Arrays.asList(mappers));
+//                } catch (IOException e) {
+//                    // ignore
+//                }
+//            }
+//        }
+//        return resources.toArray(new Resource[resources.size()]);
+//    }
+//
+//    @Bean
+//    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
+//    {
+//        String typeAliasesPackage = env.getProperty("mybatis-plus.type-aliases-package");
+//        String mapperLocations = env.getProperty("mybatis-plus.mapper-locations");
+//        String configLocation = env.getProperty("mybatis.configLocation");
+//        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
+//        VFS.addImplClass(SpringBootVFS.class);
+//
+//       // final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
+//        MybatisSqlSessionFactoryBean sessionFactory=new MybatisSqlSessionFactoryBean();
+//        sessionFactory.setDataSource(dataSource);
+//        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
+//        sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
+//        sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
+//        //如果有enum也需要在第二步return之前加入,直接配置是没用的
+//        //sessionFactory.setTypeEnumsPackage("com.ruoyi.**.enums");
+//        return sessionFactory.getObject();
+//    }
+//}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
index 33c9c876b..93399ac0d 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
@@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
 import com.alibaba.fastjson.JSONObject;
 import com.ruoyi.common.annotation.RepeatSubmit;
 import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.redis.RedisUtils;
 import com.ruoyi.common.filter.RepeatedlyRequestWrapper;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.http.HttpHelper;
@@ -19,7 +19,7 @@ import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
 /**
  * 判断请求url和数据是否和上一次相同,
  * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。
- * 
+ *
  * @author ruoyi
  */
 @Component
@@ -34,7 +34,7 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
     private String header;
 
     @Autowired
-    private RedisCache redisCache;
+    private RedisUtils redisUtils;
 
     @SuppressWarnings("unchecked")
     @Override
@@ -69,7 +69,7 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
         // 唯一标识(指定key + 消息头)
         String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey;
 
-        Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);
+        Object sessionObj = redisUtils.getCacheObject(cacheRepeatKey);
         if (sessionObj != null)
         {
             Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
@@ -84,7 +84,7 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
         }
         Map<String, Object> cacheMap = new HashMap<String, Object>();
         cacheMap.put(url, nowDataMap);
-        redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS);
+        redisUtils.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS);
         return false;
     }
 
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
index 2b5474327..ae980043a 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.redis.RedisUtils;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.exception.user.CaptchaException;
 import com.ruoyi.common.exception.user.CaptchaExpireException;
@@ -26,7 +26,7 @@ import com.ruoyi.system.service.ISysUserService;
 
 /**
  * 登录校验方法
- * 
+ *
  * @author ruoyi
  */
 @Component
@@ -39,8 +39,8 @@ public class SysLoginService
     private AuthenticationManager authenticationManager;
 
     @Autowired
-    private RedisCache redisCache;
-    
+    private RedisUtils redisUtils;
+
     @Autowired
     private ISysUserService userService;
 
@@ -49,7 +49,7 @@ public class SysLoginService
 
     /**
      * 登录验证
-     * 
+     *
      * @param username 用户名
      * @param password 密码
      * @param code 验证码
@@ -94,7 +94,7 @@ public class SysLoginService
 
     /**
      * 校验验证码
-     * 
+     *
      * @param username 用户名
      * @param code 验证码
      * @param uuid 唯一标识
@@ -103,8 +103,8 @@ public class SysLoginService
     public void validateCaptcha(String username, String code, String uuid)
     {
         String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
-        String captcha = redisCache.getCacheObject(verifyKey);
-        redisCache.deleteObject(verifyKey);
+        String captcha = redisUtils.getCacheObject(verifyKey);
+        redisUtils.deleteObject(verifyKey);
         if (captcha == null)
         {
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java
index 35a425c7d..976ecf07a 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java
@@ -6,7 +6,7 @@ import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.model.RegisterBody;
-import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.redis.RedisUtils;
 import com.ruoyi.common.exception.user.CaptchaException;
 import com.ruoyi.common.exception.user.CaptchaExpireException;
 import com.ruoyi.common.utils.MessageUtils;
@@ -19,7 +19,7 @@ import com.ruoyi.system.service.ISysUserService;
 
 /**
  * 注册校验方法
- * 
+ *
  * @author ruoyi
  */
 @Component
@@ -32,7 +32,7 @@ public class SysRegisterService
     private ISysConfigService configService;
 
     @Autowired
-    private RedisCache redisCache;
+    private RedisUtils redisUtils;
 
     /**
      * 注册
@@ -92,7 +92,7 @@ public class SysRegisterService
 
     /**
      * 校验验证码
-     * 
+     *
      * @param username 用户名
      * @param code 验证码
      * @param uuid 唯一标识
@@ -101,8 +101,8 @@ public class SysRegisterService
     public void validateCaptcha(String username, String code, String uuid)
     {
         String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
-        String captcha = redisCache.getCacheObject(verifyKey);
-        redisCache.deleteObject(verifyKey);
+        String captcha = redisUtils.getCacheObject(verifyKey);
+        redisUtils.deleteObject(verifyKey);
         if (captcha == null)
         {
             throw new CaptchaExpireException();
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
index 5b4c41466..439760d2f 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
@@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.redis.RedisUtils;
 import com.ruoyi.common.utils.ServletUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.ip.AddressUtils;
@@ -47,7 +47,7 @@ public class TokenService
     private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
 
     @Autowired
-    private RedisCache redisCache;
+    private RedisUtils redisUtils;
 
     /**
      * 获取用户身份信息
@@ -66,7 +66,7 @@ public class TokenService
                 // 解析对应的权限以及用户信息
                 String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
                 String userKey = getTokenKey(uuid);
-                LoginUser user = redisCache.getCacheObject(userKey);
+                LoginUser user = redisUtils.getCacheObject(userKey);
                 return user;
             }
             catch (Exception e)
@@ -95,7 +95,7 @@ public class TokenService
         if (StringUtils.isNotEmpty(token))
         {
             String userKey = getTokenKey(token);
-            redisCache.deleteObject(userKey);
+            redisUtils.deleteObject(userKey);
         }
     }
 
@@ -144,7 +144,7 @@ public class TokenService
         loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
         // 根据uuid将loginUser缓存
         String userKey = getTokenKey(loginUser.getToken());
-        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
+        redisUtils.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
     }
 
     /**
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java
index fd652d677..de564b309 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java
@@ -1,20 +1,21 @@
 package com.ruoyi.quartz.util;
 
-import java.util.Date;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.ScheduleConstants;
+import com.ruoyi.common.utils.ExceptionUtil;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.bean.BeanUtil;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.quartz.domain.SysJob;
+import com.ruoyi.quartz.domain.SysJobLog;
+import com.ruoyi.quartz.service.ISysJobLogService;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.constant.ScheduleConstants;
-import com.ruoyi.common.utils.ExceptionUtil;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.bean.BeanUtils;
-import com.ruoyi.common.utils.spring.SpringUtils;
-import com.ruoyi.quartz.domain.SysJob;
-import com.ruoyi.quartz.domain.SysJobLog;
-import com.ruoyi.quartz.service.ISysJobLogService;
+
+import java.util.Date;
 
 /**
  * 抽象quartz调用
@@ -34,7 +35,7 @@ public abstract class AbstractQuartzJob implements Job
     public void execute(JobExecutionContext context) throws JobExecutionException
     {
         SysJob sysJob = new SysJob();
-        BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
+        BeanUtil.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
         try
         {
             before(context, sysJob);
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
index f65c0f532..ebd1727fe 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
@@ -3,7 +3,7 @@ package com.ruoyi.system.service.impl;
 import com.ruoyi.common.annotation.DataSource;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.UserConstants;
-import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.redis.RedisUtils;
 import com.ruoyi.common.core.text.Convert;
 import com.ruoyi.common.enums.DataSourceType;
 import com.ruoyi.common.exception.ServiceException;
@@ -19,7 +19,7 @@ import java.util.List;
 
 /**
  * 参数配置 服务层实现
- * 
+ *
  * @author ruoyi
  */
 @Service
@@ -29,7 +29,7 @@ public class SysConfigServiceImpl implements ISysConfigService
     private SysConfigMapper configMapper;
 
     @Autowired
-    private RedisCache redisCache;
+    private RedisUtils redisUtils;
 
     /**
      * 项目启动时,初始化参数到缓存
@@ -42,7 +42,7 @@ public class SysConfigServiceImpl implements ISysConfigService
 
     /**
      * 查询参数配置信息
-     * 
+     *
      * @param configId 参数配置ID
      * @return 参数配置信息
      */
@@ -57,14 +57,14 @@ public class SysConfigServiceImpl implements ISysConfigService
 
     /**
      * 根据键名查询参数配置信息
-     * 
+     *
      * @param configKey 参数key
      * @return 参数键值
      */
     @Override
     public String selectConfigByKey(String configKey)
     {
-        String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey)));
+        String configValue = Convert.toStr(redisUtils.getCacheObject(getCacheKey(configKey)));
         if (StringUtils.isNotEmpty(configValue))
         {
             return configValue;
@@ -74,7 +74,7 @@ public class SysConfigServiceImpl implements ISysConfigService
         SysConfig retConfig = configMapper.selectConfig(config);
         if (StringUtils.isNotNull(retConfig))
         {
-            redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue());
+            redisUtils.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue());
             return retConfig.getConfigValue();
         }
         return StringUtils.EMPTY;
@@ -82,7 +82,7 @@ public class SysConfigServiceImpl implements ISysConfigService
 
     /**
      * 获取验证码开关
-     * 
+     *
      * @return true开启,false关闭
      */
     @Override
@@ -98,7 +98,7 @@ public class SysConfigServiceImpl implements ISysConfigService
 
     /**
      * 查询参数配置列表
-     * 
+     *
      * @param config 参数配置信息
      * @return 参数配置集合
      */
@@ -110,7 +110,7 @@ public class SysConfigServiceImpl implements ISysConfigService
 
     /**
      * 新增参数配置
-     * 
+     *
      * @param config 参数配置信息
      * @return 结果
      */
@@ -120,14 +120,14 @@ public class SysConfigServiceImpl implements ISysConfigService
         int row = configMapper.insertConfig(config);
         if (row > 0)
         {
-            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
+            redisUtils.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
         }
         return row;
     }
 
     /**
      * 修改参数配置
-     * 
+     *
      * @param config 参数配置信息
      * @return 结果
      */
@@ -137,14 +137,14 @@ public class SysConfigServiceImpl implements ISysConfigService
         int row = configMapper.updateConfig(config);
         if (row > 0)
         {
-            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
+            redisUtils.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
         }
         return row;
     }
 
     /**
      * 批量删除参数信息
-     * 
+     *
      * @param configIds 需要删除的参数ID
      * @return 结果
      */
@@ -159,7 +159,7 @@ public class SysConfigServiceImpl implements ISysConfigService
                 throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey()));
             }
             configMapper.deleteConfigById(configId);
-            redisCache.deleteObject(getCacheKey(config.getConfigKey()));
+            redisUtils.deleteObject(getCacheKey(config.getConfigKey()));
         }
     }
 
@@ -172,7 +172,7 @@ public class SysConfigServiceImpl implements ISysConfigService
         List<SysConfig> configsList = configMapper.selectConfigList(new SysConfig());
         for (SysConfig config : configsList)
         {
-            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
+            redisUtils.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
         }
     }
 
@@ -182,8 +182,8 @@ public class SysConfigServiceImpl implements ISysConfigService
     @Override
     public void clearConfigCache()
     {
-        Collection<String> keys = redisCache.keys(Constants.SYS_CONFIG_KEY + "*");
-        redisCache.deleteObject(keys);
+        Collection<String> keys = redisUtils.keys(Constants.SYS_CONFIG_KEY + "*");
+        redisUtils.deleteObject(keys);
     }
 
     /**
@@ -198,7 +198,7 @@ public class SysConfigServiceImpl implements ISysConfigService
 
     /**
      * 校验参数键名是否唯一
-     * 
+     *
      * @param config 参数配置信息
      * @return 结果
      */
@@ -216,7 +216,7 @@ public class SysConfigServiceImpl implements ISysConfigService
 
     /**
      * 设置cache key
-     * 
+     *
      * @param configKey 参数键
      * @return 缓存键key
      */

From 502caf358429852b7d22a363ab2807ef5d6e8b92 Mon Sep 17 00:00:00 2001
From: xiezubing1 <xiezubing@ihup.org.cn>
Date: Mon, 8 Nov 2021 17:11:00 +0800
Subject: [PATCH 2/3] =?UTF-8?q?[Fix]=E5=90=8C=E6=AD=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../system/EmrInfoOdsCopyController.java      | 103 +++++
 .../ruoyi/common/core/redis/RedisUtils.java   | 246 ++++++++++++
 .../com/ruoyi/common/utils/bean/BeanUtil.java | 112 ++++++
 .../ruoyi/system/domain/EmrInfoOdsCopy.java   | 363 ++++++++++++++++++
 .../system/mapper/EmrInfoOdsCopyMapper.java   |  61 +++
 .../service/IEmrInfoOdsCopyService.java       |  61 +++
 .../impl/EmrInfoOdsCopyServiceImpl.java       |  93 +++++
 .../mapper/system/EmrInfoOdsCopyMapper.xml    | 166 ++++++++
 8 files changed, 1205 insertions(+)
 create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/EmrInfoOdsCopyController.java
 create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisUtils.java
 create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanUtil.java
 create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/EmrInfoOdsCopy.java
 create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/EmrInfoOdsCopyMapper.java
 create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/IEmrInfoOdsCopyService.java
 create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EmrInfoOdsCopyServiceImpl.java
 create mode 100644 ruoyi-system/src/main/resources/mapper/system/EmrInfoOdsCopyMapper.xml

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/EmrInfoOdsCopyController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/EmrInfoOdsCopyController.java
new file mode 100644
index 000000000..8baa9f1b6
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/EmrInfoOdsCopyController.java
@@ -0,0 +1,103 @@
+package com.ruoyi.system.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.system.domain.EmrInfoOdsCopy;
+import com.ruoyi.system.service.IEmrInfoOdsCopyService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * emr原始数据Controller
+ * 
+ * @author ruoyi
+ * @date 2021-11-04
+ */
+@RestController
+@RequestMapping("/system/copy")
+public class EmrInfoOdsCopyController extends BaseController
+{
+    @Autowired
+    private IEmrInfoOdsCopyService emrInfoOdsCopyService;
+
+    /**
+     * 查询emr原始数据列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:copy:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(EmrInfoOdsCopy emrInfoOdsCopy)
+    {
+        startPage();
+        List<EmrInfoOdsCopy> list = emrInfoOdsCopyService.selectEmrInfoOdsCopyList(emrInfoOdsCopy);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出emr原始数据列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:copy:export')")
+    @Log(title = "emr原始数据", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(EmrInfoOdsCopy emrInfoOdsCopy)
+    {
+        List<EmrInfoOdsCopy> list = emrInfoOdsCopyService.selectEmrInfoOdsCopyList(emrInfoOdsCopy);
+        ExcelUtil<EmrInfoOdsCopy> util = new ExcelUtil<EmrInfoOdsCopy>(EmrInfoOdsCopy.class);
+        return util.exportExcel(list, "emr原始数据数据");
+    }
+
+    /**
+     * 获取emr原始数据详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:copy:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(emrInfoOdsCopyService.selectEmrInfoOdsCopyById(id));
+    }
+
+    /**
+     * 新增emr原始数据
+     */
+    @PreAuthorize("@ss.hasPermi('system:copy:add')")
+    @Log(title = "emr原始数据", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody EmrInfoOdsCopy emrInfoOdsCopy)
+    {
+        return toAjax(emrInfoOdsCopyService.insertEmrInfoOdsCopy(emrInfoOdsCopy));
+    }
+
+    /**
+     * 修改emr原始数据
+     */
+    @PreAuthorize("@ss.hasPermi('system:copy:edit')")
+    @Log(title = "emr原始数据", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody EmrInfoOdsCopy emrInfoOdsCopy)
+    {
+        return toAjax(emrInfoOdsCopyService.updateEmrInfoOdsCopy(emrInfoOdsCopy));
+    }
+
+    /**
+     * 删除emr原始数据
+     */
+    @PreAuthorize("@ss.hasPermi('system:copy:remove')")
+    @Log(title = "emr原始数据", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(emrInfoOdsCopyService.deleteEmrInfoOdsCopyByIds(ids));
+    }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisUtils.java
new file mode 100644
index 000000000..6cae91ce7
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisUtils.java
@@ -0,0 +1,246 @@
+package com.ruoyi.common.core.redis;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.BoundSetOperations;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Component;
+
+/**
+ * spring redis 工具类
+ *
+ * @author ruoyi
+ **/
+@SuppressWarnings(value = { "unchecked", "rawtypes" })
+@Component
+public class RedisUtils
+{
+    @Autowired
+    public RedisTemplate redisTemplate;
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key 缓存的键值
+     * @param value 缓存的值
+     */
+    public <T> void setCacheObject(final String key, final T value)
+    {
+        redisTemplate.opsForValue().set(key, value);
+    }
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key 缓存的键值
+     * @param value 缓存的值
+     * @param timeout 时间
+     * @param timeUnit 时间颗粒度
+     */
+    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
+    {
+        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key Redis键
+     * @param timeout 超时时间
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout)
+    {
+        return expire(key, timeout, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key Redis键
+     * @param timeout 超时时间
+     * @param unit 时间单位
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout, final TimeUnit unit)
+    {
+        return redisTemplate.expire(key, timeout, unit);
+    }
+
+    /**
+     * 获得缓存的基本对象。
+     *
+     * @param key 缓存键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> T getCacheObject(final String key)
+    {
+        ValueOperations<String, T> operation = redisTemplate.opsForValue();
+        return operation.get(key);
+    }
+
+    /**
+     * 删除单个对象
+     *
+     * @param key
+     */
+    public boolean deleteObject(final String key)
+    {
+        return redisTemplate.delete(key);
+    }
+
+    /**
+     * 删除集合对象
+     *
+     * @param collection 多个对象
+     * @return
+     */
+    public long deleteObject(final Collection collection)
+    {
+        return redisTemplate.delete(collection);
+    }
+
+    /**
+     * 缓存List数据
+     *
+     * @param key 缓存的键值
+     * @param dataList 待缓存的List数据
+     * @return 缓存的对象
+     */
+    public <T> long setCacheList(final String key, final List<T> dataList)
+    {
+        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+        return count == null ? 0 : count;
+    }
+
+    /**
+     * 获得缓存的list对象
+     *
+     * @param key 缓存的键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> List<T> getCacheList(final String key)
+    {
+        return redisTemplate.opsForList().range(key, 0, -1);
+    }
+
+    /**
+     * 缓存Set
+     *
+     * @param key 缓存键值
+     * @param dataSet 缓存的数据
+     * @return 缓存数据的对象
+     */
+    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
+    {
+        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
+        Iterator<T> it = dataSet.iterator();
+        while (it.hasNext())
+        {
+            setOperation.add(it.next());
+        }
+        return setOperation;
+    }
+
+    /**
+     * 获得缓存的set
+     *
+     * @param key
+     * @return
+     */
+    public <T> Set<T> getCacheSet(final String key)
+    {
+        return redisTemplate.opsForSet().members(key);
+    }
+
+    /**
+     * 缓存Map
+     *
+     * @param key
+     * @param dataMap
+     */
+    public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
+    {
+        if (dataMap != null) {
+            redisTemplate.opsForHash().putAll(key, dataMap);
+        }
+    }
+
+    /**
+     * 获得缓存的Map
+     *
+     * @param key
+     * @return
+     */
+    public <T> Map<String, T> getCacheMap(final String key)
+    {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    /**
+     * 往Hash中存入数据
+     *
+     * @param key Redis键
+     * @param hKey Hash键
+     * @param value 值
+     */
+    public <T> void setCacheMapValue(final String key, final String hKey, final T value)
+    {
+        redisTemplate.opsForHash().put(key, hKey, value);
+    }
+
+    /**
+     * 获取Hash中的数据
+     *
+     * @param key Redis键
+     * @param hKey Hash键
+     * @return Hash中的对象
+     */
+    public <T> T getCacheMapValue(final String key, final String hKey)
+    {
+        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
+        return opsForHash.get(key, hKey);
+    }
+
+    /**
+     * 删除Hash中的数据
+     *
+     * @param key
+     * @param mapkey
+     */
+    public void delCacheMapValue(final String key, final String hkey)
+    {
+        HashOperations hashOperations = redisTemplate.opsForHash();
+        hashOperations.delete(key, hkey);
+    }
+
+    /**
+     * 获取多个Hash中的数据
+     *
+     * @param key Redis键
+     * @param hKeys Hash键集合
+     * @return Hash对象集合
+     */
+    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
+    {
+        return redisTemplate.opsForHash().multiGet(key, hKeys);
+    }
+
+    /**
+     * 获得缓存的基本对象列表
+     *
+     * @param pattern 字符串前缀
+     * @return 对象列表
+     */
+    public Collection<String> keys(final String pattern)
+    {
+        return redisTemplate.keys(pattern);
+    }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanUtil.java
new file mode 100644
index 000000000..b02683d95
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanUtil.java
@@ -0,0 +1,112 @@
+package com.ruoyi.common.utils.bean;
+
+import org.springframework.beans.BeanUtils;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Bean 工具类
+ *
+ * @author ruoyi
+ */
+public class BeanUtil extends BeanUtils
+{
+    /** Bean方法名中属性名开始的下标 */
+    private static final int BEAN_METHOD_PROP_INDEX = 3;
+
+    /** * 匹配getter方法的正则表达式 */
+    private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");
+
+    /** * 匹配setter方法的正则表达式 */
+    private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");
+
+    /**
+     * Bean属性复制工具方法。
+     *
+     * @param dest 目标对象
+     * @param src 源对象
+     */
+    public static void copyBeanProp(Object dest, Object src)
+    {
+        try
+        {
+            copyProperties(src, dest);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 获取对象的setter方法。
+     *
+     * @param obj 对象
+     * @return 对象的setter方法列表
+     */
+    public static List<Method> getSetterMethods(Object obj)
+    {
+        // setter方法列表
+        List<Method> setterMethods = new ArrayList<Method>();
+
+        // 获取所有方法
+        Method[] methods = obj.getClass().getMethods();
+
+        // 查找setter方法
+
+        for (Method method : methods)
+        {
+            Matcher m = SET_PATTERN.matcher(method.getName());
+            if (m.matches() && (method.getParameterTypes().length == 1))
+            {
+                setterMethods.add(method);
+            }
+        }
+        // 返回setter方法列表
+        return setterMethods;
+    }
+
+    /**
+     * 获取对象的getter方法。
+     *
+     * @param obj 对象
+     * @return 对象的getter方法列表
+     */
+
+    public static List<Method> getGetterMethods(Object obj)
+    {
+        // getter方法列表
+        List<Method> getterMethods = new ArrayList<Method>();
+        // 获取所有方法
+        Method[] methods = obj.getClass().getMethods();
+        // 查找getter方法
+        for (Method method : methods)
+        {
+            Matcher m = GET_PATTERN.matcher(method.getName());
+            if (m.matches() && (method.getParameterTypes().length == 0))
+            {
+                getterMethods.add(method);
+            }
+        }
+        // 返回getter方法列表
+        return getterMethods;
+    }
+
+    /**
+     * 检查Bean方法名中的属性名是否相等。<br>
+     * 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。
+     *
+     * @param m1 方法名1
+     * @param m2 方法名2
+     * @return 属性名一样返回true,否则返回false
+     */
+
+    public static boolean isMethodPropEquals(String m1, String m2)
+    {
+        return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));
+    }
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/EmrInfoOdsCopy.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/EmrInfoOdsCopy.java
new file mode 100644
index 000000000..c31ff78af
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/EmrInfoOdsCopy.java
@@ -0,0 +1,363 @@
+package com.ruoyi.system.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * emr原始数据对象 emr_info_ods_copy
+ *
+ * @author ruoyi
+ * @date 2021-11-04
+ */
+public class EmrInfoOdsCopy extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键id */
+    private Long id;
+
+    /** 电子病历ID */
+    @Excel(name = "电子病历ID")
+    private Long emrId;
+
+    /** 科室编码 */
+    @Excel(name = "科室编码")
+    private String deptNumber;
+
+    /** 就诊科室 */
+    @Excel(name = "就诊科室")
+    private String treatmentDepartment;
+
+    /** 就诊日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "就诊日期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date treatmentDate;
+
+    /** 性别 */
+    @Excel(name = "性别")
+    private String sex;
+
+    /** 年龄 */
+    @Excel(name = "年龄")
+    private String age;
+
+    /** 身高 */
+    @Excel(name = "身高")
+    private String height;
+
+    /** 体重 */
+    @Excel(name = "体重")
+    private String weight;
+
+    /** 主诉 */
+    @Excel(name = "主诉")
+    private String chiefComplaint;
+
+    /** 现病史 */
+    @Excel(name = "现病史")
+    private String hsPresentIllness;
+
+    /** 体格检查 */
+    @Excel(name = "体格检查")
+    private String physicalExamination;
+
+    /** 初步诊断 */
+    @Excel(name = "初步诊断")
+    private String preliminaryDiagnosis;
+
+    /** 诊断ICD编码 */
+    @Excel(name = "诊断ICD编码")
+    private String icdId;
+
+    /** 病种中文名 */
+    @Excel(name = "病种中文名")
+    private String icdName;
+
+    /** 医生姓名 */
+    @Excel(name = "医生姓名")
+    private String doctorName;
+
+    /** 医生工号 */
+    @Excel(name = "医生工号")
+    private String doctorNumber;
+
+    /** 医生职称 */
+    @Excel(name = "医生职称")
+    private String doctorTitle;
+
+    /** 专科病历名称 */
+    @Excel(name = "专科病历名称")
+    private String specialRecord;
+
+    /** 状态0-未处理 1-已处理 */
+    @Excel(name = "状态0-未处理 1-已处理")
+    private Integer state;
+
+    /** 是否存在高危病种:0-不存在   1-存在 */
+    @Excel(name = "是否存在高危病种:0-不存在   1-存在")
+    private Integer isHightDisease;
+
+    /** 诊断结果一致率:是否落在小布top5内:0:不一致 1:一致 */
+    @Excel(name = "诊断结果一致率:是否落在小布top5内:0:不一致 1:一致")
+    private Integer isTop;
+
+    /** 是否为无依据诊断 :0-不是无依据诊断    1-是无依据诊断 */
+    @Excel(name = "是否为无依据诊断 :0-不是无依据诊断    1-是无依据诊断")
+    private Integer isGroundless;
+
+    /** 小布返回top5数组 */
+    @Excel(name = "小布返回top5数组")
+    private String xiaobuResult;
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+    public void setEmrId(Long emrId)
+    {
+        this.emrId = emrId;
+    }
+
+    public Long getEmrId()
+    {
+        return emrId;
+    }
+    public void setDeptNumber(String deptNumber)
+    {
+        this.deptNumber = deptNumber;
+    }
+
+    public String getDeptNumber()
+    {
+        return deptNumber;
+    }
+    public void setTreatmentDepartment(String treatmentDepartment)
+    {
+        this.treatmentDepartment = treatmentDepartment;
+    }
+
+    public String getTreatmentDepartment()
+    {
+        return treatmentDepartment;
+    }
+    public void setTreatmentDate(Date treatmentDate)
+    {
+        this.treatmentDate = treatmentDate;
+    }
+
+    public Date getTreatmentDate()
+    {
+        return treatmentDate;
+    }
+    public void setSex(String sex)
+    {
+        this.sex = sex;
+    }
+
+    public String getSex()
+    {
+        return sex;
+    }
+    public void setAge(String age)
+    {
+        this.age = age;
+    }
+
+    public String getAge()
+    {
+        return age;
+    }
+    public void setHeight(String height)
+    {
+        this.height = height;
+    }
+
+    public String getHeight()
+    {
+        return height;
+    }
+    public void setWeight(String weight)
+    {
+        this.weight = weight;
+    }
+
+    public String getWeight()
+    {
+        return weight;
+    }
+    public void setChiefComplaint(String chiefComplaint)
+    {
+        this.chiefComplaint = chiefComplaint;
+    }
+
+    public String getChiefComplaint()
+    {
+        return chiefComplaint;
+    }
+    public void setHsPresentIllness(String hsPresentIllness)
+    {
+        this.hsPresentIllness = hsPresentIllness;
+    }
+
+    public String getHsPresentIllness()
+    {
+        return hsPresentIllness;
+    }
+    public void setPhysicalExamination(String physicalExamination)
+    {
+        this.physicalExamination = physicalExamination;
+    }
+
+    public String getPhysicalExamination()
+    {
+        return physicalExamination;
+    }
+    public void setPreliminaryDiagnosis(String preliminaryDiagnosis)
+    {
+        this.preliminaryDiagnosis = preliminaryDiagnosis;
+    }
+
+    public String getPreliminaryDiagnosis()
+    {
+        return preliminaryDiagnosis;
+    }
+    public void setIcdId(String icdId)
+    {
+        this.icdId = icdId;
+    }
+
+    public String getIcdId()
+    {
+        return icdId;
+    }
+    public void setIcdName(String icdName)
+    {
+        this.icdName = icdName;
+    }
+
+    public String getIcdName()
+    {
+        return icdName;
+    }
+    public void setDoctorName(String doctorName)
+    {
+        this.doctorName = doctorName;
+    }
+
+    public String getDoctorName()
+    {
+        return doctorName;
+    }
+    public void setDoctorNumber(String doctorNumber)
+    {
+        this.doctorNumber = doctorNumber;
+    }
+
+    public String getDoctorNumber()
+    {
+        return doctorNumber;
+    }
+    public void setDoctorTitle(String doctorTitle)
+    {
+        this.doctorTitle = doctorTitle;
+    }
+
+    public String getDoctorTitle()
+    {
+        return doctorTitle;
+    }
+    public void setSpecialRecord(String specialRecord)
+    {
+        this.specialRecord = specialRecord;
+    }
+
+    public String getSpecialRecord()
+    {
+        return specialRecord;
+    }
+    public void setState(Integer state)
+    {
+        this.state = state;
+    }
+
+    public Integer getState()
+    {
+        return state;
+    }
+    public void setIsHightDisease(Integer isHightDisease)
+    {
+        this.isHightDisease = isHightDisease;
+    }
+
+    public Integer getIsHightDisease()
+    {
+        return isHightDisease;
+    }
+    public void setIsTop(Integer isTop)
+    {
+        this.isTop = isTop;
+    }
+
+    public Integer getIsTop()
+    {
+        return isTop;
+    }
+    public void setIsGroundless(Integer isGroundless)
+    {
+        this.isGroundless = isGroundless;
+    }
+
+    public Integer getIsGroundless()
+    {
+        return isGroundless;
+    }
+    public void setXiaobuResult(String xiaobuResult)
+    {
+        this.xiaobuResult = xiaobuResult;
+    }
+
+    public String getXiaobuResult()
+    {
+        return xiaobuResult;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("emrId", getEmrId())
+            .append("deptNumber", getDeptNumber())
+            .append("treatmentDepartment", getTreatmentDepartment())
+            .append("treatmentDate", getTreatmentDate())
+            .append("sex", getSex())
+            .append("age", getAge())
+            .append("height", getHeight())
+            .append("weight", getWeight())
+            .append("chiefComplaint", getChiefComplaint())
+            .append("hsPresentIllness", getHsPresentIllness())
+            .append("physicalExamination", getPhysicalExamination())
+            .append("preliminaryDiagnosis", getPreliminaryDiagnosis())
+            .append("icdId", getIcdId())
+            .append("icdName", getIcdName())
+            .append("doctorName", getDoctorName())
+            .append("doctorNumber", getDoctorNumber())
+            .append("doctorTitle", getDoctorTitle())
+            .append("specialRecord", getSpecialRecord())
+            .append("state", getState())
+            .append("isHightDisease", getIsHightDisease())
+            .append("isTop", getIsTop())
+            .append("isGroundless", getIsGroundless())
+            .append("xiaobuResult", getXiaobuResult())
+            .toString();
+    }
+
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/EmrInfoOdsCopyMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/EmrInfoOdsCopyMapper.java
new file mode 100644
index 000000000..f2f02618d
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/EmrInfoOdsCopyMapper.java
@@ -0,0 +1,61 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+import com.ruoyi.system.domain.EmrInfoOdsCopy;
+
+/**
+ * emr原始数据Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2021-11-04
+ */
+public interface EmrInfoOdsCopyMapper 
+{
+    /**
+     * 查询emr原始数据
+     * 
+     * @param id emr原始数据主键
+     * @return emr原始数据
+     */
+    public EmrInfoOdsCopy selectEmrInfoOdsCopyById(Long id);
+
+    /**
+     * 查询emr原始数据列表
+     * 
+     * @param emrInfoOdsCopy emr原始数据
+     * @return emr原始数据集合
+     */
+    public List<EmrInfoOdsCopy> selectEmrInfoOdsCopyList(EmrInfoOdsCopy emrInfoOdsCopy);
+
+    /**
+     * 新增emr原始数据
+     * 
+     * @param emrInfoOdsCopy emr原始数据
+     * @return 结果
+     */
+    public int insertEmrInfoOdsCopy(EmrInfoOdsCopy emrInfoOdsCopy);
+
+    /**
+     * 修改emr原始数据
+     * 
+     * @param emrInfoOdsCopy emr原始数据
+     * @return 结果
+     */
+    public int updateEmrInfoOdsCopy(EmrInfoOdsCopy emrInfoOdsCopy);
+
+    /**
+     * 删除emr原始数据
+     * 
+     * @param id emr原始数据主键
+     * @return 结果
+     */
+    public int deleteEmrInfoOdsCopyById(Long id);
+
+    /**
+     * 批量删除emr原始数据
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteEmrInfoOdsCopyByIds(Long[] ids);
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IEmrInfoOdsCopyService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IEmrInfoOdsCopyService.java
new file mode 100644
index 000000000..3665b6c14
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IEmrInfoOdsCopyService.java
@@ -0,0 +1,61 @@
+package com.ruoyi.system.service;
+
+import java.util.List;
+import com.ruoyi.system.domain.EmrInfoOdsCopy;
+
+/**
+ * emr原始数据Service接口
+ * 
+ * @author ruoyi
+ * @date 2021-11-04
+ */
+public interface IEmrInfoOdsCopyService 
+{
+    /**
+     * 查询emr原始数据
+     * 
+     * @param id emr原始数据主键
+     * @return emr原始数据
+     */
+    public EmrInfoOdsCopy selectEmrInfoOdsCopyById(Long id);
+
+    /**
+     * 查询emr原始数据列表
+     * 
+     * @param emrInfoOdsCopy emr原始数据
+     * @return emr原始数据集合
+     */
+    public List<EmrInfoOdsCopy> selectEmrInfoOdsCopyList(EmrInfoOdsCopy emrInfoOdsCopy);
+
+    /**
+     * 新增emr原始数据
+     * 
+     * @param emrInfoOdsCopy emr原始数据
+     * @return 结果
+     */
+    public int insertEmrInfoOdsCopy(EmrInfoOdsCopy emrInfoOdsCopy);
+
+    /**
+     * 修改emr原始数据
+     * 
+     * @param emrInfoOdsCopy emr原始数据
+     * @return 结果
+     */
+    public int updateEmrInfoOdsCopy(EmrInfoOdsCopy emrInfoOdsCopy);
+
+    /**
+     * 批量删除emr原始数据
+     * 
+     * @param ids 需要删除的emr原始数据主键集合
+     * @return 结果
+     */
+    public int deleteEmrInfoOdsCopyByIds(Long[] ids);
+
+    /**
+     * 删除emr原始数据信息
+     * 
+     * @param id emr原始数据主键
+     * @return 结果
+     */
+    public int deleteEmrInfoOdsCopyById(Long id);
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EmrInfoOdsCopyServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EmrInfoOdsCopyServiceImpl.java
new file mode 100644
index 000000000..82a6d5753
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EmrInfoOdsCopyServiceImpl.java
@@ -0,0 +1,93 @@
+package com.ruoyi.system.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.system.mapper.EmrInfoOdsCopyMapper;
+import com.ruoyi.system.domain.EmrInfoOdsCopy;
+import com.ruoyi.system.service.IEmrInfoOdsCopyService;
+
+/**
+ * emr原始数据Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2021-11-04
+ */
+@Service
+public class EmrInfoOdsCopyServiceImpl implements IEmrInfoOdsCopyService 
+{
+    @Autowired
+    private EmrInfoOdsCopyMapper emrInfoOdsCopyMapper;
+
+    /**
+     * 查询emr原始数据
+     * 
+     * @param id emr原始数据主键
+     * @return emr原始数据
+     */
+    @Override
+    public EmrInfoOdsCopy selectEmrInfoOdsCopyById(Long id)
+    {
+        return emrInfoOdsCopyMapper.selectEmrInfoOdsCopyById(id);
+    }
+
+    /**
+     * 查询emr原始数据列表
+     * 
+     * @param emrInfoOdsCopy emr原始数据
+     * @return emr原始数据
+     */
+    @Override
+    public List<EmrInfoOdsCopy> selectEmrInfoOdsCopyList(EmrInfoOdsCopy emrInfoOdsCopy)
+    {
+        return emrInfoOdsCopyMapper.selectEmrInfoOdsCopyList(emrInfoOdsCopy);
+    }
+
+    /**
+     * 新增emr原始数据
+     * 
+     * @param emrInfoOdsCopy emr原始数据
+     * @return 结果
+     */
+    @Override
+    public int insertEmrInfoOdsCopy(EmrInfoOdsCopy emrInfoOdsCopy)
+    {
+        return emrInfoOdsCopyMapper.insertEmrInfoOdsCopy(emrInfoOdsCopy);
+    }
+
+    /**
+     * 修改emr原始数据
+     * 
+     * @param emrInfoOdsCopy emr原始数据
+     * @return 结果
+     */
+    @Override
+    public int updateEmrInfoOdsCopy(EmrInfoOdsCopy emrInfoOdsCopy)
+    {
+        return emrInfoOdsCopyMapper.updateEmrInfoOdsCopy(emrInfoOdsCopy);
+    }
+
+    /**
+     * 批量删除emr原始数据
+     * 
+     * @param ids 需要删除的emr原始数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteEmrInfoOdsCopyByIds(Long[] ids)
+    {
+        return emrInfoOdsCopyMapper.deleteEmrInfoOdsCopyByIds(ids);
+    }
+
+    /**
+     * 删除emr原始数据信息
+     * 
+     * @param id emr原始数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteEmrInfoOdsCopyById(Long id)
+    {
+        return emrInfoOdsCopyMapper.deleteEmrInfoOdsCopyById(id);
+    }
+}
diff --git a/ruoyi-system/src/main/resources/mapper/system/EmrInfoOdsCopyMapper.xml b/ruoyi-system/src/main/resources/mapper/system/EmrInfoOdsCopyMapper.xml
new file mode 100644
index 000000000..2eb2cd07b
--- /dev/null
+++ b/ruoyi-system/src/main/resources/mapper/system/EmrInfoOdsCopyMapper.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.system.mapper.EmrInfoOdsCopyMapper">
+    
+    <resultMap type="EmrInfoOdsCopy" id="EmrInfoOdsCopyResult">
+        <result property="id"    column="id"    />
+        <result property="emrId"    column="emr_id"    />
+        <result property="deptNumber"    column="dept_number"    />
+        <result property="treatmentDepartment"    column="treatment_department"    />
+        <result property="treatmentDate"    column="treatment_date"    />
+        <result property="sex"    column="sex"    />
+        <result property="age"    column="age"    />
+        <result property="height"    column="height"    />
+        <result property="weight"    column="weight"    />
+        <result property="chiefComplaint"    column="chief_complaint"    />
+        <result property="hsPresentIllness"    column="hs_present_illness"    />
+        <result property="physicalExamination"    column="physical_examination"    />
+        <result property="preliminaryDiagnosis"    column="preliminary_diagnosis"    />
+        <result property="icdId"    column="icd_id"    />
+        <result property="icdName"    column="icd_name"    />
+        <result property="doctorName"    column="doctor_name"    />
+        <result property="doctorNumber"    column="doctor_number"    />
+        <result property="doctorTitle"    column="doctor_title"    />
+        <result property="specialRecord"    column="special_record"    />
+        <result property="state"    column="state"    />
+        <result property="isHightDisease"    column="is_hight_disease"    />
+        <result property="isTop"    column="is_top"    />
+        <result property="isGroundless"    column="is_groundless"    />
+        <result property="xiaobuResult"    column="xiaobu_result"    />
+    </resultMap>
+
+    <sql id="selectEmrInfoOdsCopyVo">
+        select id, emr_id, dept_number, treatment_department, treatment_date, sex, age, height, weight, chief_complaint, hs_present_illness, physical_examination, preliminary_diagnosis, icd_id, icd_name, doctor_name, doctor_number, doctor_title, special_record, state, is_hight_disease, is_top, is_groundless, xiaobu_result from emr_info_ods_copy
+    </sql>
+
+    <select id="selectEmrInfoOdsCopyList" parameterType="EmrInfoOdsCopy" resultMap="EmrInfoOdsCopyResult">
+        <include refid="selectEmrInfoOdsCopyVo"/>
+        <where>  
+            <if test="emrId != null "> and emr_id = #{emrId}</if>
+            <if test="deptNumber != null  and deptNumber != ''"> and dept_number = #{deptNumber}</if>
+            <if test="treatmentDepartment != null  and treatmentDepartment != ''"> and treatment_department = #{treatmentDepartment}</if>
+            <if test="treatmentDate != null "> and treatment_date = #{treatmentDate}</if>
+            <if test="sex != null  and sex != ''"> and sex = #{sex}</if>
+            <if test="age != null  and age != ''"> and age = #{age}</if>
+            <if test="height != null  and height != ''"> and height = #{height}</if>
+            <if test="weight != null  and weight != ''"> and weight = #{weight}</if>
+            <if test="chiefComplaint != null  and chiefComplaint != ''"> and chief_complaint = #{chiefComplaint}</if>
+            <if test="hsPresentIllness != null  and hsPresentIllness != ''"> and hs_present_illness = #{hsPresentIllness}</if>
+            <if test="physicalExamination != null  and physicalExamination != ''"> and physical_examination = #{physicalExamination}</if>
+            <if test="preliminaryDiagnosis != null  and preliminaryDiagnosis != ''"> and preliminary_diagnosis = #{preliminaryDiagnosis}</if>
+            <if test="icdId != null  and icdId != ''"> and icd_id = #{icdId}</if>
+            <if test="icdName != null  and icdName != ''"> and icd_name like concat('%', #{icdName}, '%')</if>
+            <if test="doctorName != null  and doctorName != ''"> and doctor_name like concat('%', #{doctorName}, '%')</if>
+            <if test="doctorNumber != null  and doctorNumber != ''"> and doctor_number = #{doctorNumber}</if>
+            <if test="doctorTitle != null  and doctorTitle != ''"> and doctor_title = #{doctorTitle}</if>
+            <if test="specialRecord != null  and specialRecord != ''"> and special_record = #{specialRecord}</if>
+            <if test="state != null "> and state = #{state}</if>
+            <if test="isHightDisease != null "> and is_hight_disease = #{isHightDisease}</if>
+            <if test="isTop != null "> and is_top = #{isTop}</if>
+            <if test="isGroundless != null "> and is_groundless = #{isGroundless}</if>
+            <if test="xiaobuResult != null  and xiaobuResult != ''"> and xiaobu_result = #{xiaobuResult}</if>
+        </where>
+    </select>
+    
+    <select id="selectEmrInfoOdsCopyById" parameterType="Long" resultMap="EmrInfoOdsCopyResult">
+        <include refid="selectEmrInfoOdsCopyVo"/>
+        where id = #{id}
+    </select>
+        
+    <insert id="insertEmrInfoOdsCopy" parameterType="EmrInfoOdsCopy" useGeneratedKeys="true" keyProperty="id">
+        insert into emr_info_ods_copy
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="emrId != null">emr_id,</if>
+            <if test="deptNumber != null">dept_number,</if>
+            <if test="treatmentDepartment != null">treatment_department,</if>
+            <if test="treatmentDate != null">treatment_date,</if>
+            <if test="sex != null">sex,</if>
+            <if test="age != null">age,</if>
+            <if test="height != null">height,</if>
+            <if test="weight != null">weight,</if>
+            <if test="chiefComplaint != null">chief_complaint,</if>
+            <if test="hsPresentIllness != null">hs_present_illness,</if>
+            <if test="physicalExamination != null">physical_examination,</if>
+            <if test="preliminaryDiagnosis != null">preliminary_diagnosis,</if>
+            <if test="icdId != null">icd_id,</if>
+            <if test="icdName != null">icd_name,</if>
+            <if test="doctorName != null">doctor_name,</if>
+            <if test="doctorNumber != null">doctor_number,</if>
+            <if test="doctorTitle != null">doctor_title,</if>
+            <if test="specialRecord != null">special_record,</if>
+            <if test="state != null">state,</if>
+            <if test="isHightDisease != null">is_hight_disease,</if>
+            <if test="isTop != null">is_top,</if>
+            <if test="isGroundless != null">is_groundless,</if>
+            <if test="xiaobuResult != null">xiaobu_result,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="emrId != null">#{emrId},</if>
+            <if test="deptNumber != null">#{deptNumber},</if>
+            <if test="treatmentDepartment != null">#{treatmentDepartment},</if>
+            <if test="treatmentDate != null">#{treatmentDate},</if>
+            <if test="sex != null">#{sex},</if>
+            <if test="age != null">#{age},</if>
+            <if test="height != null">#{height},</if>
+            <if test="weight != null">#{weight},</if>
+            <if test="chiefComplaint != null">#{chiefComplaint},</if>
+            <if test="hsPresentIllness != null">#{hsPresentIllness},</if>
+            <if test="physicalExamination != null">#{physicalExamination},</if>
+            <if test="preliminaryDiagnosis != null">#{preliminaryDiagnosis},</if>
+            <if test="icdId != null">#{icdId},</if>
+            <if test="icdName != null">#{icdName},</if>
+            <if test="doctorName != null">#{doctorName},</if>
+            <if test="doctorNumber != null">#{doctorNumber},</if>
+            <if test="doctorTitle != null">#{doctorTitle},</if>
+            <if test="specialRecord != null">#{specialRecord},</if>
+            <if test="state != null">#{state},</if>
+            <if test="isHightDisease != null">#{isHightDisease},</if>
+            <if test="isTop != null">#{isTop},</if>
+            <if test="isGroundless != null">#{isGroundless},</if>
+            <if test="xiaobuResult != null">#{xiaobuResult},</if>
+         </trim>
+    </insert>
+
+    <update id="updateEmrInfoOdsCopy" parameterType="EmrInfoOdsCopy">
+        update emr_info_ods_copy
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="emrId != null">emr_id = #{emrId},</if>
+            <if test="deptNumber != null">dept_number = #{deptNumber},</if>
+            <if test="treatmentDepartment != null">treatment_department = #{treatmentDepartment},</if>
+            <if test="treatmentDate != null">treatment_date = #{treatmentDate},</if>
+            <if test="sex != null">sex = #{sex},</if>
+            <if test="age != null">age = #{age},</if>
+            <if test="height != null">height = #{height},</if>
+            <if test="weight != null">weight = #{weight},</if>
+            <if test="chiefComplaint != null">chief_complaint = #{chiefComplaint},</if>
+            <if test="hsPresentIllness != null">hs_present_illness = #{hsPresentIllness},</if>
+            <if test="physicalExamination != null">physical_examination = #{physicalExamination},</if>
+            <if test="preliminaryDiagnosis != null">preliminary_diagnosis = #{preliminaryDiagnosis},</if>
+            <if test="icdId != null">icd_id = #{icdId},</if>
+            <if test="icdName != null">icd_name = #{icdName},</if>
+            <if test="doctorName != null">doctor_name = #{doctorName},</if>
+            <if test="doctorNumber != null">doctor_number = #{doctorNumber},</if>
+            <if test="doctorTitle != null">doctor_title = #{doctorTitle},</if>
+            <if test="specialRecord != null">special_record = #{specialRecord},</if>
+            <if test="state != null">state = #{state},</if>
+            <if test="isHightDisease != null">is_hight_disease = #{isHightDisease},</if>
+            <if test="isTop != null">is_top = #{isTop},</if>
+            <if test="isGroundless != null">is_groundless = #{isGroundless},</if>
+            <if test="xiaobuResult != null">xiaobu_result = #{xiaobuResult},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteEmrInfoOdsCopyById" parameterType="Long">
+        delete from emr_info_ods_copy where id = #{id}
+    </delete>
+
+    <delete id="deleteEmrInfoOdsCopyByIds" parameterType="String">
+        delete from emr_info_ods_copy where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>
\ No newline at end of file

From caf0a5edb0e92266fb2711ea8fd232780e69061e Mon Sep 17 00:00:00 2001
From: xiezubing1 <xiezubing@ihup.org.cn>
Date: Mon, 8 Nov 2021 17:15:23 +0800
Subject: [PATCH 3/3] =?UTF-8?q?[Fix]=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 dev | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 dev

diff --git a/dev b/dev
new file mode 100644
index 000000000..e69de29bb