发布 4.0.0

This commit is contained in:
疯狂的狮子li 2022-02-18 11:37:21 +08:00
parent dafb7477f6
commit 400ecdf0ab
348 changed files with 10651 additions and 10508 deletions

3
.gitignore vendored
View File

@ -25,6 +25,9 @@ target/
*.iml *.iml
*.ipr *.ipr
### JRebel ###
rebel.xml
### NetBeans ### ### NetBeans ###
nbproject/private/ nbproject/private/
build/* build/*

View File

@ -4,7 +4,7 @@
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE) [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
[![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
<br> <br>
[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-3.5.0-success.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus) [![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-4.0.0-success.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.5-blue.svg)]() [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.5-blue.svg)]()
[![JDK-8+](https://img.shields.io/badge/JDK-8-green.svg)]() [![JDK-8+](https://img.shields.io/badge/JDK-8-green.svg)]()
[![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]() [![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]()
@ -14,16 +14,15 @@
> 系统演示: [传送门](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/系统演示?sort_id=4836388) > 系统演示: [传送门](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/系统演示?sort_id=4836388)
| 功能介绍 | 使用技术 | 文档地址 | 特性注意事项 | | 功能介绍 | 使用技术 | 文档地址 | 特性注意事项 |
|---|---|---|---| |----------|---------------------|---------------------------------------------------------------------------------------------------|----------------------------|
| 当前框架 | RuoYi-Vue-Plus | [RuoYi-Vue-Plus文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages) | 重写RuoYi-Vue全方位升级(不兼容原框架) | | 当前框架 | RuoYi-Vue-Plus | [RuoYi-Vue-Plus文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages) | 重写RuoYi-Vue全方位升级(不兼容原框架) |
| satoken分支 | RuoYi-Vue-Plus-satoken | [satoken分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/) | 高可读性 扩展性(推荐使用) | | 微服务分支 | RuoYi-Cloud-Plus | [微服务分支地址](https://gitee.com/JavaLionLi/RuoYi-Cloud-Plus) | 重写RuoYi-Cloud全方位升级(不兼容原框架) |
| 单体分支 | RuoYi-Vue-Plus-fast | [fast分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) | 单体应用结构 | | 单体分支 | RuoYi-Vue-Plus-fast | [fast分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) | 单体应用结构 |
| Vue3分支 | RuoYi-Vue-Plus-UI | [UI地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus-UI) | 由于组件还未完善 仅供学习 | | Vue3分支 | RuoYi-Vue-Plus-UI | [UI地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus-UI) | 由于组件还未完善 仅供学习 |
| 原框架 | RuoYi-Vue | [RuoYi-Vue官网](http://ruoyi.vip/) | 定期同步需要的功能 | | 原框架 | RuoYi-Vue | [RuoYi-Vue官网](http://ruoyi.vip/) | 定期同步需要的功能 |
| 前端开发框架 | Vue、Element UI | [Element UI官网](https://element.eleme.cn/#/zh-CN) | | | 前端开发框架 | Vue、Element UI | [Element UI官网](https://element.eleme.cn/#/zh-CN) | |
| 后端开发框架 | SpringBoot | [SpringBoot官网](https://spring.io/projects/spring-boot/#learn) | | | 后端开发框架 | SpringBoot | [SpringBoot官网](https://spring.io/projects/spring-boot/#learn) | |
| 容器框架 | Undertow | [Undertow官网](https://undertow.io/) | 基于 XNIO 的高性能容器 | | 容器框架 | Undertow | [Undertow官网](https://undertow.io/) | 基于 XNIO 的高性能容器 |
| 权限认证框架 | Spring Security、Jwt | [SpringSecurity官网](https://spring.io/projects/spring-security#learn) | 支持多终端认证系统 |
| 权限认证框架 | Sa-Token、Jwt | [Sa-Token官网](https://sa-token.dev33.cn/) | 强解耦、强扩展 | | 权限认证框架 | Sa-Token、Jwt | [Sa-Token官网](https://sa-token.dev33.cn/) | 强解耦、强扩展 |
| 关系数据库 | MySQL | [MySQL官网](https://dev.mysql.com/) | 适配 8.X 最低 5.7 | | 关系数据库 | MySQL | [MySQL官网](https://dev.mysql.com/) | 适配 8.X 最低 5.7 |
| 缓存数据库 | Redis | [Redis官网](https://redis.io/) | 适配 6.X 最低 4.X | | 缓存数据库 | Redis | [Redis官网](https://redis.io/) | 适配 6.X 最低 4.X |
@ -33,6 +32,7 @@
| 序列化框架 | Jackson | [Jackson官网](https://github.com/FasterXML/jackson) | 统一使用 jackson 高效可靠 | | 序列化框架 | Jackson | [Jackson官网](https://github.com/FasterXML/jackson) | 统一使用 jackson 高效可靠 |
| Redis客户端 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 支持单机、集群配置 | | Redis客户端 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 支持单机、集群配置 |
| 分布式限流 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 全局、请求IP、集群ID 多种限流 | | 分布式限流 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 全局、请求IP、集群ID 多种限流 |
| 分布式队列 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 普通队列、延迟队列、优先队列 等 |
| 分布式锁 | Lock4j | [Lock4j官网](https://gitee.com/baomidou/lock4j) | 注解锁、工具锁 多种多样 | | 分布式锁 | Lock4j | [Lock4j官网](https://gitee.com/baomidou/lock4j) | 注解锁、工具锁 多种多样 |
| 分布式幂等 | Redisson | [Lock4j文档](https://gitee.com/baomidou/lock4j) | 拦截重复提交 | | 分布式幂等 | Redisson | [Lock4j文档](https://gitee.com/baomidou/lock4j) | 拦截重复提交 |
| 分布式日志 | TLog | [TLog文档](https://yomahub.com/tlog/docs) | 支持跟踪链路日志记录、性能分析、链路排查 | | 分布式日志 | TLog | [TLog文档](https://yomahub.com/tlog/docs) | 支持跟踪链路日志记录、性能分析、链路排查 |
@ -74,8 +74,8 @@
* 同步升级 RuoYi-Vue * 同步升级 RuoYi-Vue
* GitHub 地址 [RuoYi-Vue-Plus-github](https://github.com/JavaLionLi/RuoYi-Vue-Plus) * GitHub 地址 [RuoYi-Vue-Plus-github](https://github.com/JavaLionLi/RuoYi-Vue-Plus)
* 单模块 fast 分支 [RuoYi-Vue-Plus-fast](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) * 单模块 分支 [RuoYi-Vue-Plus-fast](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/)
* satoken 分支 [RuoYi-Vue-Plus-satoken](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/) * 微服务 分支 [RuoYi-Cloud-Plus](https://gitee.com/JavaLionLi/RuoYi-Cloud-Plus)
* 用户扩展项目 [扩展项目列表](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4478302&doc_id=1469725) * 用户扩展项目 [扩展项目列表](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4478302&doc_id=1469725)
## 加群与捐献 ## 加群与捐献

93
pom.xml
View File

@ -6,32 +6,33 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<version>3.5.0</version> <version>4.0.0</version>
<name>RuoYi-Vue-Plus</name> <name>RuoYi-Vue-Plus</name>
<url>https://gitee.com/JavaLionLi/RuoYi-Vue-Plus</url> <url>https://gitee.com/JavaLionLi/RuoYi-Vue-Plus</url>
<description>RuoYi-Vue-Plus后台管理系统</description> <description>RuoYi-Vue-Plus后台管理系统</description>
<properties> <properties>
<ruoyi-vue-plus.version>3.5.0</ruoyi-vue-plus.version> <ruoyi-vue-plus.version>4.0.0</ruoyi-vue-plus.version>
<spring-boot.version>2.5.8</spring-boot.version> <spring-boot.version>2.6.3</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version> <maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
<druid.version>1.2.8</druid.version> <druid.version>1.2.8</druid.version>
<knife4j.version>3.0.3</knife4j.version> <knife4j.version>3.0.3</knife4j.version>
<swagger-annotations.version>1.5.22</swagger-annotations.version> <swagger-annotations.version>1.5.22</swagger-annotations.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<easyexcel.version>2.2.11</easyexcel.version> <easyexcel.version>3.0.5</easyexcel.version>
<cglib.version>3.3.0</cglib.version> <cglib.version>3.3.0</cglib.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<mybatis-plus.version>3.4.3.4</mybatis-plus.version> <satoken.version>1.29.0</satoken.version>
<mybatis-plus.version>3.5.1</mybatis-plus.version>
<p6spy.version>3.9.1</p6spy.version> <p6spy.version>3.9.1</p6spy.version>
<hutool.version>5.7.18</hutool.version> <hutool.version>5.7.20</hutool.version>
<okhttp.version>4.9.2</okhttp.version> <okhttp.version>4.9.2</okhttp.version>
<spring-boot-admin.version>2.5.5</spring-boot-admin.version> <spring-boot-admin.version>2.6.2</spring-boot-admin.version>
<redisson.version>3.16.7</redisson.version> <redisson.version>3.16.8</redisson.version>
<lock4j.version>2.2.1</lock4j.version> <lock4j.version>2.2.1</lock4j.version>
<dynamic-ds.version>3.5.0</dynamic-ds.version> <dynamic-ds.version>3.5.0</dynamic-ds.version>
<tlog.version>1.3.6</tlog.version> <tlog.version>1.3.6</tlog.version>
@ -41,10 +42,10 @@
<jaxb.version>3.0.1</jaxb.version> <jaxb.version>3.0.1</jaxb.version>
<!-- OSS 配置 --> <!-- OSS 配置 -->
<qiniu.version>7.9.0</qiniu.version> <qiniu.version>7.9.2</qiniu.version>
<aliyun.oss.version>3.13.1</aliyun.oss.version> <aliyun.oss.version>3.14.0</aliyun.oss.version>
<qcloud.cos.version>5.6.58</qcloud.cos.version> <qcloud.cos.version>5.6.68</qcloud.cos.version>
<minio.version>8.3.4</minio.version> <minio.version>8.3.5</minio.version>
<!-- docker 配置 --> <!-- docker 配置 -->
<docker.registry.url>localhost</docker.registry.url> <docker.registry.url>localhost</docker.registry.url>
@ -67,6 +68,15 @@
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<!-- hutool 的依赖配置-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-bom</artifactId>
<version>${hutool.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 阿里数据库连接池 --> <!-- 阿里数据库连接池 -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
@ -128,6 +138,19 @@
<version>${velocity.version}</version> <version>${velocity.version}</version>
</dependency> </dependency>
<!-- Sa-Token 权限认证, 在线文档http://sa-token.dev33.cn/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>${satoken.version}</version>
</dependency>
<!-- Sa-Token 整合 jwt -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
<version>${satoken.version}</version>
</dependency>
<!-- jdk11 缺失依赖 jaxb--> <!-- jdk11 缺失依赖 jaxb-->
<dependency> <dependency>
<groupId>com.sun.xml.bind</groupId> <groupId>com.sun.xml.bind</groupId>
@ -159,36 +182,6 @@
<version>${p6spy.version}</version> <version>${p6spy.version}</version>
</dependency> </dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-captcha</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-extra</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-jwt</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.squareup.okhttp3</groupId> <groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId> <artifactId>okhttp</artifactId>
@ -251,7 +244,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version> <version>3.9.0</version>
<configuration> <configuration>
<source>${java.version}</source> <source>${java.version}</source>
<target>${java.version}</target> <target>${java.version}</target>
@ -261,8 +254,18 @@
</plugins> </plugins>
<resources> <resources>
<resource> <resource>
<!--打包该目录下的 application.yml -->
<directory>src/main/resources</directory> <directory>src/main/resources</directory>
<!-- 关闭过滤 -->
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<!-- 引入所有 匹配文件进行过滤 -->
<includes>
<include>application*</include>
<include>bootstrap*</include>
<include>banner*</include>
</includes>
<!-- 启用过滤 即该资源中的变量将会被过滤器中的值替换 --> <!-- 启用过滤 即该资源中的变量将会被过滤器中的值替换 -->
<filtering>true</filtering> <filtering>true</filtering>
</resource> </resource>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.5.0</version> <version>4.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-extend</artifactId> <artifactId>ruoyi-extend</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-extend</artifactId> <artifactId>ruoyi-extend</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.5.0</version> <version>4.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -34,6 +34,11 @@
<artifactId>spring-boot-admin-starter-client</artifactId> <artifactId>spring-boot-admin-starter-client</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -13,7 +13,7 @@ public class MonitorAdminApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(MonitorAdminApplication.class, args); SpringApplication.run(MonitorAdminApplication.class, args);
System.out.println("Admin 监控启动成功" ); System.out.println("Admin 监控启动成功");
} }
} }

View File

@ -0,0 +1,40 @@
package com.ruoyi.monitor.admin.notifier;
import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
import de.codecentric.boot.admin.server.notify.AbstractEventNotifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
/**
* 自定义事件通知处理
*
* @author Lion Li
*/
@Slf4j
@Component
public class CustomNotifier extends AbstractEventNotifier {
protected CustomNotifier(InstanceRepository repository) {
super(repository);
}
@Override
@SuppressWarnings("all")
protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
return Mono.fromRunnable(() -> {
// 实例状态改变事件
if (event instanceof InstanceStatusChangedEvent) {
String registName = instance.getRegistration().getName();
String instanceId = event.getInstance().getValue();
String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus();
log.info("Instance Status Change: [{}],[{}],[{}]", registName, instanceId, status);
}
});
}
}

View File

@ -9,6 +9,6 @@ spring:
# 设置 Spring Boot Admin Server 地址 # 设置 Spring Boot Admin Server 地址
url: http://localhost:9090/admin url: http://localhost:9090/admin
instance: instance:
prefer-ip: true # 注册实例时,优先使用 IP service-host-type: IP
username: ruoyi username: ruoyi
password: 123456 password: 123456

View File

@ -9,6 +9,6 @@ spring:
# 设置 Spring Boot Admin Server 地址 # 设置 Spring Boot Admin Server 地址
url: http://172.30.0.90:9090/admin url: http://172.30.0.90:9090/admin
instance: instance:
prefer-ip: true # 注册实例时,优先使用 IP service-host-type: IP
username: ruoyi username: ruoyi
password: 123456 password: 123456

View File

@ -4,7 +4,7 @@
<parent> <parent>
<artifactId>ruoyi-extend</artifactId> <artifactId>ruoyi-extend</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.5.0</version> <version>4.0.0</version>
</parent> </parent>
<artifactId>ruoyi-xxl-job-admin</artifactId> <artifactId>ruoyi-xxl-job-admin</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -99,19 +99,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
<nonFilteredFileExtension>jks</nonFilteredFileExtension>
<nonFilteredFileExtension>woff</nonFilteredFileExtension>
<nonFilteredFileExtension>woff2</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
<!-- docker --> <!-- docker -->
<plugin> <plugin>
<groupId>com.spotify</groupId> <groupId>com.spotify</groupId>

View File

@ -24,6 +24,7 @@ import java.util.Map;
/** /**
* index controller * index controller
*
* @author xuxueli 2015-12-19 16:13:16 * @author xuxueli 2015-12-19 16:13:16
*/ */
@Controller @Controller
@ -52,27 +53,27 @@ public class IndexController {
} }
@RequestMapping("/toLogin") @RequestMapping("/toLogin")
@PermissionLimit(limit=false) @PermissionLimit(limit = false)
public ModelAndView toLogin(HttpServletRequest request, HttpServletResponse response,ModelAndView modelAndView) { public ModelAndView toLogin(HttpServletRequest request, HttpServletResponse response, ModelAndView modelAndView) {
if (loginService.ifLogin(request, response) != null) { if (loginService.ifLogin(request, response) != null) {
modelAndView.setView(new RedirectView("/",true,false)); modelAndView.setView(new RedirectView("/" , true, false));
return modelAndView; return modelAndView;
} }
return new ModelAndView("login"); return new ModelAndView("login");
} }
@RequestMapping(value="login", method=RequestMethod.POST) @RequestMapping(value = "login" , method = RequestMethod.POST)
@ResponseBody @ResponseBody
@PermissionLimit(limit=false) @PermissionLimit(limit = false)
public ReturnT<String> loginDo(HttpServletRequest request, HttpServletResponse response, String userName, String password, String ifRemember){ public ReturnT<String> loginDo(HttpServletRequest request, HttpServletResponse response, String userName, String password, String ifRemember) {
boolean ifRem = (ifRemember!=null && ifRemember.trim().length()>0 && "on".equals(ifRemember))?true:false; boolean ifRem = (ifRemember != null && ifRemember.trim().length() > 0 && "on".equals(ifRemember)) ? true : false;
return loginService.login(request, response, userName, password, ifRem); return loginService.login(request, response, userName, password, ifRem);
} }
@RequestMapping(value="logout", method=RequestMethod.POST) @RequestMapping(value = "logout" , method = RequestMethod.POST)
@ResponseBody @ResponseBody
@PermissionLimit(limit=false) @PermissionLimit(limit = false)
public ReturnT<String> logout(HttpServletRequest request, HttpServletResponse response){ public ReturnT<String> logout(HttpServletRequest request, HttpServletResponse response) {
return loginService.logout(request, response); return loginService.logout(request, response);
} }

View File

@ -19,6 +19,7 @@ import java.util.List;
/** /**
* job code controller * job code controller
*
* @author xuxueli 2015-12-19 16:13:16 * @author xuxueli 2015-12-19 16:13:16
*/ */
@Controller @Controller
@ -46,10 +47,10 @@ public class JobCodeController {
JobInfoController.validPermission(request, jobInfo.getJobGroup()); JobInfoController.validPermission(request, jobInfo.getJobGroup());
// Glue类型-字典 // Glue类型-字典
model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); model.addAttribute("GlueTypeEnum" , GlueTypeEnum.values());
model.addAttribute("jobInfo", jobInfo); model.addAttribute("jobInfo" , jobInfo);
model.addAttribute("jobLogGlues", jobLogGlues); model.addAttribute("jobLogGlues" , jobLogGlues);
return "jobcode/jobcode.index"; return "jobcode/jobcode.index";
} }
@ -57,10 +58,10 @@ public class JobCodeController {
@ResponseBody @ResponseBody
public ReturnT<String> save(Model model, int id, String glueSource, String glueRemark) { public ReturnT<String> save(Model model, int id, String glueSource, String glueRemark) {
// valid // valid
if (glueRemark==null) { if (glueRemark == null) {
return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_glue_remark")) ); return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_glue_remark")));
} }
if (glueRemark.length()<4 || glueRemark.length()>100) { if (glueRemark.length() < 4 || glueRemark.length() > 100) {
return new ReturnT<String>(500, I18nUtil.getString("jobinfo_glue_remark_limit")); return new ReturnT<String>(500, I18nUtil.getString("jobinfo_glue_remark_limit"));
} }
XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(id); XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(id);

View File

@ -20,6 +20,7 @@ import java.util.*;
/** /**
* job group controller * job group controller
*
* @author xuxueli 2016-10-02 20:52:56 * @author xuxueli 2016-10-02 20:52:56
*/ */
@Controller @Controller
@ -51,44 +52,44 @@ public class JobGroupController {
// package result // package result
Map<String, Object> maps = new HashMap<String, Object>(); Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数 maps.put("recordsTotal" , list_count); // 总记录数
maps.put("recordsFiltered", list_count); // 过滤后的总记录数 maps.put("recordsFiltered" , list_count); // 过滤后的总记录数
maps.put("data", list); // 分页列表 maps.put("data" , list); // 分页列表
return maps; return maps;
} }
@RequestMapping("/save") @RequestMapping("/save")
@ResponseBody @ResponseBody
public ReturnT<String> save(XxlJobGroup xxlJobGroup){ public ReturnT<String> save(XxlJobGroup xxlJobGroup) {
// valid // valid
if (xxlJobGroup.getAppname()==null || xxlJobGroup.getAppname().trim().length()==0) { if (xxlJobGroup.getAppname() == null || xxlJobGroup.getAppname().trim().length() == 0) {
return new ReturnT<String>(500, (I18nUtil.getString("system_please_input")+"AppName") ); return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + "AppName"));
} }
if (xxlJobGroup.getAppname().length()<4 || xxlJobGroup.getAppname().length()>64) { if (xxlJobGroup.getAppname().length() < 4 || xxlJobGroup.getAppname().length() > 64) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_appname_length") ); return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_appname_length"));
} }
if (xxlJobGroup.getAppname().contains(">") || xxlJobGroup.getAppname().contains("<")) { if (xxlJobGroup.getAppname().contains(">") || xxlJobGroup.getAppname().contains("<")) {
return new ReturnT<String>(500, "AppName"+I18nUtil.getString("system_unvalid") ); return new ReturnT<String>(500, "AppName" + I18nUtil.getString("system_unvalid"));
} }
if (xxlJobGroup.getTitle()==null || xxlJobGroup.getTitle().trim().length()==0) { if (xxlJobGroup.getTitle() == null || xxlJobGroup.getTitle().trim().length() == 0) {
return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")) ); return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")));
} }
if (xxlJobGroup.getTitle().contains(">") || xxlJobGroup.getTitle().contains("<")) { if (xxlJobGroup.getTitle().contains(">") || xxlJobGroup.getTitle().contains("<")) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_title")+I18nUtil.getString("system_unvalid") ); return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_title") + I18nUtil.getString("system_unvalid"));
} }
if (xxlJobGroup.getAddressType()!=0) { if (xxlJobGroup.getAddressType() != 0) {
if (xxlJobGroup.getAddressList()==null || xxlJobGroup.getAddressList().trim().length()==0) { if (xxlJobGroup.getAddressList() == null || xxlJobGroup.getAddressList().trim().length() == 0) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_addressType_limit") ); return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_addressType_limit"));
} }
if (xxlJobGroup.getAddressList().contains(">") || xxlJobGroup.getAddressList().contains("<")) { if (xxlJobGroup.getAddressList().contains(">") || xxlJobGroup.getAddressList().contains("<")) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_registryList")+I18nUtil.getString("system_unvalid") ); return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_registryList") + I18nUtil.getString("system_unvalid"));
} }
String[] addresss = xxlJobGroup.getAddressList().split(","); String[] addresss = xxlJobGroup.getAddressList().split(",");
for (String item: addresss) { for (String item : addresss) {
if (item==null || item.trim().length()==0) { if (item == null || item.trim().length() == 0) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_registryList_unvalid") ); return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_registryList_unvalid"));
} }
} }
} }
@ -97,44 +98,44 @@ public class JobGroupController {
xxlJobGroup.setUpdateTime(new Date()); xxlJobGroup.setUpdateTime(new Date());
int ret = xxlJobGroupDao.save(xxlJobGroup); int ret = xxlJobGroupDao.save(xxlJobGroup);
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL; return (ret > 0) ? ReturnT.SUCCESS : ReturnT.FAIL;
} }
@RequestMapping("/update") @RequestMapping("/update")
@ResponseBody @ResponseBody
public ReturnT<String> update(XxlJobGroup xxlJobGroup){ public ReturnT<String> update(XxlJobGroup xxlJobGroup) {
// valid // valid
if (xxlJobGroup.getAppname()==null || xxlJobGroup.getAppname().trim().length()==0) { if (xxlJobGroup.getAppname() == null || xxlJobGroup.getAppname().trim().length() == 0) {
return new ReturnT<String>(500, (I18nUtil.getString("system_please_input")+"AppName") ); return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + "AppName"));
} }
if (xxlJobGroup.getAppname().length()<4 || xxlJobGroup.getAppname().length()>64) { if (xxlJobGroup.getAppname().length() < 4 || xxlJobGroup.getAppname().length() > 64) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_appname_length") ); return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_appname_length"));
} }
if (xxlJobGroup.getTitle()==null || xxlJobGroup.getTitle().trim().length()==0) { if (xxlJobGroup.getTitle() == null || xxlJobGroup.getTitle().trim().length() == 0) {
return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")) ); return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")));
} }
if (xxlJobGroup.getAddressType() == 0) { if (xxlJobGroup.getAddressType() == 0) {
// 0=自动注册 // 0=自动注册
List<String> registryList = findRegistryByAppName(xxlJobGroup.getAppname()); List<String> registryList = findRegistryByAppName(xxlJobGroup.getAppname());
String addressListStr = null; String addressListStr = null;
if (registryList!=null && !registryList.isEmpty()) { if (registryList != null && !registryList.isEmpty()) {
Collections.sort(registryList); Collections.sort(registryList);
addressListStr = ""; addressListStr = "";
for (String item:registryList) { for (String item : registryList) {
addressListStr += item + ","; addressListStr += item + ",";
} }
addressListStr = addressListStr.substring(0, addressListStr.length()-1); addressListStr = addressListStr.substring(0, addressListStr.length() - 1);
} }
xxlJobGroup.setAddressList(addressListStr); xxlJobGroup.setAddressList(addressListStr);
} else { } else {
// 1=手动录入 // 1=手动录入
if (xxlJobGroup.getAddressList()==null || xxlJobGroup.getAddressList().trim().length()==0) { if (xxlJobGroup.getAddressList() == null || xxlJobGroup.getAddressList().trim().length() == 0) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_addressType_limit") ); return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_addressType_limit"));
} }
String[] addresss = xxlJobGroup.getAddressList().split(","); String[] addresss = xxlJobGroup.getAddressList().split(",");
for (String item: addresss) { for (String item : addresss) {
if (item==null || item.trim().length()==0) { if (item == null || item.trim().length() == 0) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_registryList_unvalid") ); return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_registryList_unvalid"));
} }
} }
} }
@ -143,14 +144,14 @@ public class JobGroupController {
xxlJobGroup.setUpdateTime(new Date()); xxlJobGroup.setUpdateTime(new Date());
int ret = xxlJobGroupDao.update(xxlJobGroup); int ret = xxlJobGroupDao.update(xxlJobGroup);
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL; return (ret > 0) ? ReturnT.SUCCESS : ReturnT.FAIL;
} }
private List<String> findRegistryByAppName(String appnameParam){ private List<String> findRegistryByAppName(String appnameParam) {
HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>(); HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
List<XxlJobRegistry> list = xxlJobRegistryDao.findAll(RegistryConfig.DEAD_TIMEOUT, new Date()); List<XxlJobRegistry> list = xxlJobRegistryDao.findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
if (list != null) { if (list != null) {
for (XxlJobRegistry item: list) { for (XxlJobRegistry item : list) {
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) { if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
String appname = item.getRegistryKey(); String appname = item.getRegistryKey();
List<String> registryList = appAddressMap.get(appname); List<String> registryList = appAddressMap.get(appname);
@ -170,28 +171,28 @@ public class JobGroupController {
@RequestMapping("/remove") @RequestMapping("/remove")
@ResponseBody @ResponseBody
public ReturnT<String> remove(int id){ public ReturnT<String> remove(int id) {
// valid // valid
int count = xxlJobInfoDao.pageListCount(0, 10, id, -1, null, null, null); int count = xxlJobInfoDao.pageListCount(0, 10, id, -1, null, null, null);
if (count > 0) { if (count > 0) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_del_limit_0") ); return new ReturnT<String>(500, I18nUtil.getString("jobgroup_del_limit_0"));
} }
List<XxlJobGroup> allList = xxlJobGroupDao.findAll(); List<XxlJobGroup> allList = xxlJobGroupDao.findAll();
if (allList.size() == 1) { if (allList.size() == 1) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_del_limit_1") ); return new ReturnT<String>(500, I18nUtil.getString("jobgroup_del_limit_1"));
} }
int ret = xxlJobGroupDao.remove(id); int ret = xxlJobGroupDao.remove(id);
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL; return (ret > 0) ? ReturnT.SUCCESS : ReturnT.FAIL;
} }
@RequestMapping("/loadById") @RequestMapping("/loadById")
@ResponseBody @ResponseBody
public ReturnT<XxlJobGroup> loadById(int id){ public ReturnT<XxlJobGroup> loadById(int id) {
XxlJobGroup jobGroup = xxlJobGroupDao.load(id); XxlJobGroup jobGroup = xxlJobGroupDao.load(id);
return jobGroup!=null?new ReturnT<XxlJobGroup>(jobGroup):new ReturnT<XxlJobGroup>(ReturnT.FAIL_CODE, null); return jobGroup != null ? new ReturnT<XxlJobGroup>(jobGroup) : new ReturnT<XxlJobGroup>(ReturnT.FAIL_CODE, null);
} }
} }

View File

@ -1,6 +1,5 @@
package com.xxl.job.admin.controller; package com.xxl.job.admin.controller;
import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.exception.XxlJobException; import com.xxl.job.admin.core.exception.XxlJobException;
import com.xxl.job.admin.core.model.XxlJobGroup; import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobInfo;
@ -29,11 +28,11 @@ import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.util.*; import java.util.*;
/** /**
* index controller * index controller
*
* @author xuxueli 2015-12-19 16:13:16 * @author xuxueli 2015-12-19 16:13:16
*/ */
@Controller @Controller
@ -50,39 +49,39 @@ public class JobInfoController {
public String index(HttpServletRequest request, Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) { public String index(HttpServletRequest request, Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) {
// 枚举-字典 // 枚举-字典
model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表 model.addAttribute("ExecutorRouteStrategyEnum" , ExecutorRouteStrategyEnum.values()); // 路由策略-列表
model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典 model.addAttribute("GlueTypeEnum" , GlueTypeEnum.values()); // Glue类型-字典
model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典 model.addAttribute("ExecutorBlockStrategyEnum" , ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典
model.addAttribute("ScheduleTypeEnum", ScheduleTypeEnum.values()); // 调度类型 model.addAttribute("ScheduleTypeEnum" , ScheduleTypeEnum.values()); // 调度类型
model.addAttribute("MisfireStrategyEnum", MisfireStrategyEnum.values()); // 调度过期策略 model.addAttribute("MisfireStrategyEnum" , MisfireStrategyEnum.values()); // 调度过期策略
// 执行器列表 // 执行器列表
List<XxlJobGroup> jobGroupList_all = xxlJobGroupDao.findAll(); List<XxlJobGroup> jobGroupList_all = xxlJobGroupDao.findAll();
// filter group // filter group
List<XxlJobGroup> jobGroupList = filterJobGroupByRole(request, jobGroupList_all); List<XxlJobGroup> jobGroupList = filterJobGroupByRole(request, jobGroupList_all);
if (jobGroupList==null || jobGroupList.size()==0) { if (jobGroupList == null || jobGroupList.size() == 0) {
throw new XxlJobException(I18nUtil.getString("jobgroup_empty")); throw new XxlJobException(I18nUtil.getString("jobgroup_empty"));
} }
model.addAttribute("JobGroupList", jobGroupList); model.addAttribute("JobGroupList" , jobGroupList);
model.addAttribute("jobGroup", jobGroup); model.addAttribute("jobGroup" , jobGroup);
return "jobinfo/jobinfo.index"; return "jobinfo/jobinfo.index";
} }
public static List<XxlJobGroup> filterJobGroupByRole(HttpServletRequest request, List<XxlJobGroup> jobGroupList_all){ public static List<XxlJobGroup> filterJobGroupByRole(HttpServletRequest request, List<XxlJobGroup> jobGroupList_all) {
List<XxlJobGroup> jobGroupList = new ArrayList<>(); List<XxlJobGroup> jobGroupList = new ArrayList<>();
if (jobGroupList_all!=null && jobGroupList_all.size()>0) { if (jobGroupList_all != null && jobGroupList_all.size() > 0) {
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY); XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
if (loginUser.getRole() == 1) { if (loginUser.getRole() == 1) {
jobGroupList = jobGroupList_all; jobGroupList = jobGroupList_all;
} else { } else {
List<String> groupIdStrs = new ArrayList<>(); List<String> groupIdStrs = new ArrayList<>();
if (loginUser.getPermission()!=null && loginUser.getPermission().trim().length()>0) { if (loginUser.getPermission() != null && loginUser.getPermission().trim().length() > 0) {
groupIdStrs = Arrays.asList(loginUser.getPermission().trim().split(",")); groupIdStrs = Arrays.asList(loginUser.getPermission().trim().split(","));
} }
for (XxlJobGroup groupItem:jobGroupList_all) { for (XxlJobGroup groupItem : jobGroupList_all) {
if (groupIdStrs.contains(String.valueOf(groupItem.getId()))) { if (groupIdStrs.contains(String.valueOf(groupItem.getId()))) {
jobGroupList.add(groupItem); jobGroupList.add(groupItem);
} }
@ -91,10 +90,11 @@ public class JobInfoController {
} }
return jobGroupList; return jobGroupList;
} }
public static void validPermission(HttpServletRequest request, int jobGroup) { public static void validPermission(HttpServletRequest request, int jobGroup) {
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY); XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
if (!loginUser.validPermission(jobGroup)) { if (!loginUser.validPermission(jobGroup)) {
throw new RuntimeException(I18nUtil.getString("system_permission_limit") + "[username="+ loginUser.getUsername() +"]"); throw new RuntimeException(I18nUtil.getString("system_permission_limit") + "[username=" + loginUser.getUsername() + "]");
} }
} }
@ -171,7 +171,7 @@ public class JobInfoController {
} }
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
return new ReturnT<List<String>>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) + e.getMessage()); return new ReturnT<List<String>>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")) + e.getMessage());
} }
return new ReturnT<List<String>>(result); return new ReturnT<List<String>>(result);

View File

@ -1,7 +1,7 @@
package com.xxl.job.admin.controller; package com.xxl.job.admin.controller;
import com.xxl.job.admin.core.exception.XxlJobException;
import com.xxl.job.admin.core.complete.XxlJobCompleter; import com.xxl.job.admin.core.complete.XxlJobCompleter;
import com.xxl.job.admin.core.exception.XxlJobException;
import com.xxl.job.admin.core.model.XxlJobGroup; import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog; import com.xxl.job.admin.core.model.XxlJobLog;
@ -33,6 +33,7 @@ import java.util.Map;
/** /**
* index controller * index controller
*
* @author xuxueli 2015-12-19 16:13:16 * @author xuxueli 2015-12-19 16:13:16
*/ */
@Controller @Controller
@ -55,11 +56,11 @@ public class JobLogController {
// filter group // filter group
List<XxlJobGroup> jobGroupList = JobInfoController.filterJobGroupByRole(request, jobGroupList_all); List<XxlJobGroup> jobGroupList = JobInfoController.filterJobGroupByRole(request, jobGroupList_all);
if (jobGroupList==null || jobGroupList.size()==0) { if (jobGroupList == null || jobGroupList.size() == 0) {
throw new XxlJobException(I18nUtil.getString("jobgroup_empty")); throw new XxlJobException(I18nUtil.getString("jobgroup_empty"));
} }
model.addAttribute("JobGroupList", jobGroupList); model.addAttribute("JobGroupList" , jobGroupList);
// 任务 // 任务
if (jobId > 0) { if (jobId > 0) {
@ -68,7 +69,7 @@ public class JobLogController {
throw new RuntimeException(I18nUtil.getString("jobinfo_field_id") + I18nUtil.getString("system_unvalid")); throw new RuntimeException(I18nUtil.getString("jobinfo_field_id") + I18nUtil.getString("system_unvalid"));
} }
model.addAttribute("jobInfo", jobInfo); model.addAttribute("jobInfo" , jobInfo);
// valid permission // valid permission
JobInfoController.validPermission(request, jobInfo.getJobGroup()); JobInfoController.validPermission(request, jobInfo.getJobGroup());
@ -79,7 +80,7 @@ public class JobLogController {
@RequestMapping("/getJobsByGroup") @RequestMapping("/getJobsByGroup")
@ResponseBody @ResponseBody
public ReturnT<List<XxlJobInfo>> getJobsByGroup(int jobGroup){ public ReturnT<List<XxlJobInfo>> getJobsByGroup(int jobGroup) {
List<XxlJobInfo> list = xxlJobInfoDao.getJobsByGroup(jobGroup); List<XxlJobInfo> list = xxlJobInfoDao.getJobsByGroup(jobGroup);
return new ReturnT<List<XxlJobInfo>>(list); return new ReturnT<List<XxlJobInfo>>(list);
} }
@ -97,7 +98,7 @@ public class JobLogController {
// parse param // parse param
Date triggerTimeStart = null; Date triggerTimeStart = null;
Date triggerTimeEnd = null; Date triggerTimeEnd = null;
if (filterTime!=null && filterTime.trim().length()>0) { if (filterTime != null && filterTime.trim().length() > 0) {
String[] temp = filterTime.split(" - "); String[] temp = filterTime.split(" - ");
if (temp.length == 2) { if (temp.length == 2) {
triggerTimeStart = DateUtil.parseDateTime(temp[0]); triggerTimeStart = DateUtil.parseDateTime(temp[0]);
@ -111,14 +112,14 @@ public class JobLogController {
// package result // package result
Map<String, Object> maps = new HashMap<String, Object>(); Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数 maps.put("recordsTotal" , list_count); // 总记录数
maps.put("recordsFiltered", list_count); // 过滤后的总记录数 maps.put("recordsFiltered" , list_count); // 过滤后的总记录数
maps.put("data", list); // 分页列表 maps.put("data" , list); // 分页列表
return maps; return maps;
} }
@RequestMapping("/logDetailPage") @RequestMapping("/logDetailPage")
public String logDetailPage(int id, Model model){ public String logDetailPage(int id, Model model) {
// base check // base check
ReturnT<String> logStatue = ReturnT.SUCCESS; ReturnT<String> logStatue = ReturnT.SUCCESS;
@ -127,23 +128,23 @@ public class JobLogController {
throw new RuntimeException(I18nUtil.getString("joblog_logid_unvalid")); throw new RuntimeException(I18nUtil.getString("joblog_logid_unvalid"));
} }
model.addAttribute("triggerCode", jobLog.getTriggerCode()); model.addAttribute("triggerCode" , jobLog.getTriggerCode());
model.addAttribute("handleCode", jobLog.getHandleCode()); model.addAttribute("handleCode" , jobLog.getHandleCode());
model.addAttribute("executorAddress", jobLog.getExecutorAddress()); model.addAttribute("executorAddress" , jobLog.getExecutorAddress());
model.addAttribute("triggerTime", jobLog.getTriggerTime().getTime()); model.addAttribute("triggerTime" , jobLog.getTriggerTime().getTime());
model.addAttribute("logId", jobLog.getId()); model.addAttribute("logId" , jobLog.getId());
return "joblog/joblog.detail"; return "joblog/joblog.detail";
} }
@RequestMapping("/logDetailCat") @RequestMapping("/logDetailCat")
@ResponseBody @ResponseBody
public ReturnT<LogResult> logDetailCat(String executorAddress, long triggerTime, long logId, int fromLineNum){ public ReturnT<LogResult> logDetailCat(String executorAddress, long triggerTime, long logId, int fromLineNum) {
try { try {
ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(executorAddress); ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(executorAddress);
ReturnT<LogResult> logResult = executorBiz.log(new LogParam(triggerTime, logId, fromLineNum)); ReturnT<LogResult> logResult = executorBiz.log(new LogParam(triggerTime, logId, fromLineNum));
// is end // is end
if (logResult.getContent()!=null && logResult.getContent().getFromLineNum() > logResult.getContent().getToLineNum()) { if (logResult.getContent() != null && logResult.getContent().getFromLineNum() > logResult.getContent().getToLineNum()) {
XxlJobLog jobLog = xxlJobLogDao.load(logId); XxlJobLog jobLog = xxlJobLogDao.load(logId);
if (jobLog.getHandleCode() > 0) { if (jobLog.getHandleCode() > 0) {
logResult.getContent().setEnd(true); logResult.getContent().setEnd(true);
@ -159,11 +160,11 @@ public class JobLogController {
@RequestMapping("/logKill") @RequestMapping("/logKill")
@ResponseBody @ResponseBody
public ReturnT<String> logKill(int id){ public ReturnT<String> logKill(int id) {
// base check // base check
XxlJobLog log = xxlJobLogDao.load(id); XxlJobLog log = xxlJobLogDao.load(id);
XxlJobInfo jobInfo = xxlJobInfoDao.loadById(log.getJobId()); XxlJobInfo jobInfo = xxlJobInfoDao.loadById(log.getJobId());
if (jobInfo==null) { if (jobInfo == null) {
return new ReturnT<String>(500, I18nUtil.getString("jobinfo_glue_jobid_unvalid")); return new ReturnT<String>(500, I18nUtil.getString("jobinfo_glue_jobid_unvalid"));
} }
if (ReturnT.SUCCESS_CODE != log.getTriggerCode()) { if (ReturnT.SUCCESS_CODE != log.getTriggerCode()) {
@ -182,7 +183,7 @@ public class JobLogController {
if (ReturnT.SUCCESS_CODE == runResult.getCode()) { if (ReturnT.SUCCESS_CODE == runResult.getCode()) {
log.setHandleCode(ReturnT.FAIL_CODE); log.setHandleCode(ReturnT.FAIL_CODE);
log.setHandleMsg( I18nUtil.getString("joblog_kill_log_byman")+":" + (runResult.getMsg()!=null?runResult.getMsg():"")); log.setHandleMsg(I18nUtil.getString("joblog_kill_log_byman") + ":" + (runResult.getMsg() != null ? runResult.getMsg() : ""));
log.setHandleTime(new Date()); log.setHandleTime(new Date());
XxlJobCompleter.updateHandleInfoAndFinish(log); XxlJobCompleter.updateHandleInfoAndFinish(log);
return new ReturnT<String>(runResult.getMsg()); return new ReturnT<String>(runResult.getMsg());
@ -193,7 +194,7 @@ public class JobLogController {
@RequestMapping("/clearLog") @RequestMapping("/clearLog")
@ResponseBody @ResponseBody
public ReturnT<String> clearLog(int jobGroup, int jobId, int type){ public ReturnT<String> clearLog(int jobGroup, int jobId, int type) {
Date clearBeforeTime = null; Date clearBeforeTime = null;
int clearBeforeNum = 0; int clearBeforeNum = 0;
@ -222,10 +223,10 @@ public class JobLogController {
List<Long> logIds = null; List<Long> logIds = null;
do { do {
logIds = xxlJobLogDao.findClearLogIds(jobGroup, jobId, clearBeforeTime, clearBeforeNum, 1000); logIds = xxlJobLogDao.findClearLogIds(jobGroup, jobId, clearBeforeTime, clearBeforeNum, 1000);
if (logIds!=null && logIds.size()>0) { if (logIds != null && logIds.size() > 0) {
xxlJobLogDao.clearLog(logIds); xxlJobLogDao.clearLog(logIds);
} }
} while (logIds!=null && logIds.size()>0); } while (logIds != null && logIds.size() > 0);
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} }

View File

@ -40,7 +40,7 @@ public class UserController {
// 执行器列表 // 执行器列表
List<XxlJobGroup> groupList = xxlJobGroupDao.findAll(); List<XxlJobGroup> groupList = xxlJobGroupDao.findAll();
model.addAttribute("groupList", groupList); model.addAttribute("groupList" , groupList);
return "user/user.index"; return "user/user.index";
} }
@ -57,17 +57,17 @@ public class UserController {
int list_count = xxlJobUserDao.pageListCount(start, length, username, role); int list_count = xxlJobUserDao.pageListCount(start, length, username, role);
// filter // filter
if (list!=null && list.size()>0) { if (list != null && list.size() > 0) {
for (XxlJobUser item: list) { for (XxlJobUser item : list) {
item.setPassword(null); item.setPassword(null);
} }
} }
// package result // package result
Map<String, Object> maps = new HashMap<String, Object>(); Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数 maps.put("recordsTotal" , list_count); // 总记录数
maps.put("recordsFiltered", list_count); // 过滤后的总记录数 maps.put("recordsFiltered" , list_count); // 过滤后的总记录数
maps.put("data", list); // 分页列表 maps.put("data" , list); // 分页列表
return maps; return maps;
} }
@ -78,19 +78,19 @@ public class UserController {
// valid username // valid username
if (!StringUtils.hasText(xxlJobUser.getUsername())) { if (!StringUtils.hasText(xxlJobUser.getUsername())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_please_input")+I18nUtil.getString("user_username") ); return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_please_input") + I18nUtil.getString("user_username"));
} }
xxlJobUser.setUsername(xxlJobUser.getUsername().trim()); xxlJobUser.setUsername(xxlJobUser.getUsername().trim());
if (!(xxlJobUser.getUsername().length()>=4 && xxlJobUser.getUsername().length()<=20)) { if (!(xxlJobUser.getUsername().length() >= 4 && xxlJobUser.getUsername().length() <= 20)) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit")+"[4-20]" ); return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit") + "[4-20]");
} }
// valid password // valid password
if (!StringUtils.hasText(xxlJobUser.getPassword())) { if (!StringUtils.hasText(xxlJobUser.getPassword())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_please_input")+I18nUtil.getString("user_password") ); return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_please_input") + I18nUtil.getString("user_password"));
} }
xxlJobUser.setPassword(xxlJobUser.getPassword().trim()); xxlJobUser.setPassword(xxlJobUser.getPassword().trim());
if (!(xxlJobUser.getPassword().length()>=4 && xxlJobUser.getPassword().length()<=20)) { if (!(xxlJobUser.getPassword().length() >= 4 && xxlJobUser.getPassword().length() <= 20)) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit")+"[4-20]" ); return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit") + "[4-20]");
} }
// md5 password // md5 password
xxlJobUser.setPassword(DigestUtils.md5DigestAsHex(xxlJobUser.getPassword().getBytes())); xxlJobUser.setPassword(DigestUtils.md5DigestAsHex(xxlJobUser.getPassword().getBytes()));
@ -98,7 +98,7 @@ public class UserController {
// check repeat // check repeat
XxlJobUser existUser = xxlJobUserDao.loadByUserName(xxlJobUser.getUsername()); XxlJobUser existUser = xxlJobUserDao.loadByUserName(xxlJobUser.getUsername());
if (existUser != null) { if (existUser != null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("user_username_repeat") ); return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("user_username_repeat"));
} }
// write // write
@ -120,8 +120,8 @@ public class UserController {
// valid password // valid password
if (StringUtils.hasText(xxlJobUser.getPassword())) { if (StringUtils.hasText(xxlJobUser.getPassword())) {
xxlJobUser.setPassword(xxlJobUser.getPassword().trim()); xxlJobUser.setPassword(xxlJobUser.getPassword().trim());
if (!(xxlJobUser.getPassword().length()>=4 && xxlJobUser.getPassword().length()<=20)) { if (!(xxlJobUser.getPassword().length() >= 4 && xxlJobUser.getPassword().length() <= 20)) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit")+"[4-20]" ); return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit") + "[4-20]");
} }
// md5 password // md5 password
xxlJobUser.setPassword(DigestUtils.md5DigestAsHex(xxlJobUser.getPassword().getBytes())); xxlJobUser.setPassword(DigestUtils.md5DigestAsHex(xxlJobUser.getPassword().getBytes()));
@ -151,15 +151,15 @@ public class UserController {
@RequestMapping("/updatePwd") @RequestMapping("/updatePwd")
@ResponseBody @ResponseBody
public ReturnT<String> updatePwd(HttpServletRequest request, String password){ public ReturnT<String> updatePwd(HttpServletRequest request, String password) {
// valid password // valid password
if (password==null || password.trim().length()==0){ if (password == null || password.trim().length() == 0) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), "密码不可为空"); return new ReturnT<String>(ReturnT.FAIL.getCode(), "密码不可为空");
} }
password = password.trim(); password = password.trim();
if (!(password.length()>=4 && password.length()<=20)) { if (!(password.length() >= 4 && password.length() <= 20)) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit")+"[4-20]" ); return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit") + "[4-20]");
} }
// md5 password // md5 password

View File

@ -8,6 +8,7 @@ import java.lang.annotation.Target;
/** /**
* 权限限制 * 权限限制
*
* @author xuxueli 2015-12-12 18:29:02 * @author xuxueli 2015-12-12 18:29:02
*/ */
@Target(ElementType.METHOD) @Target(ElementType.METHOD)

View File

@ -24,17 +24,17 @@ public class CookieInterceptor implements AsyncHandlerInterceptor {
ModelAndView modelAndView) throws Exception { ModelAndView modelAndView) throws Exception {
// cookie // cookie
if (modelAndView!=null && request.getCookies()!=null && request.getCookies().length>0) { if (modelAndView != null && request.getCookies() != null && request.getCookies().length > 0) {
HashMap<String, Cookie> cookieMap = new HashMap<String, Cookie>(); HashMap<String, Cookie> cookieMap = new HashMap<String, Cookie>();
for (Cookie ck : request.getCookies()) { for (Cookie ck : request.getCookies()) {
cookieMap.put(ck.getName(), ck); cookieMap.put(ck.getName(), ck);
} }
modelAndView.addObject("cookieMap", cookieMap); modelAndView.addObject("cookieMap" , cookieMap);
} }
// static method // static method
if (modelAndView != null) { if (modelAndView != null) {
modelAndView.addObject("I18nUtil", FtlUtil.generateStaticModel(I18nUtil.class.getName())); modelAndView.addObject("I18nUtil" , FtlUtil.generateStaticModel(I18nUtil.class.getName()));
} }
AsyncHandlerInterceptor.super.postHandle(request, response, handler, modelAndView); AsyncHandlerInterceptor.super.postHandle(request, response, handler, modelAndView);

View File

@ -33,9 +33,9 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
// if need login // if need login
boolean needLogin = true; boolean needLogin = true;
boolean needAdminuser = false; boolean needAdminuser = false;
HandlerMethod method = (HandlerMethod)handler; HandlerMethod method = (HandlerMethod) handler;
PermissionLimit permission = method.getMethodAnnotation(PermissionLimit.class); PermissionLimit permission = method.getMethodAnnotation(PermissionLimit.class);
if (permission!=null) { if (permission != null) {
needLogin = permission.limit(); needLogin = permission.limit();
needAdminuser = permission.adminuser(); needAdminuser = permission.adminuser();
} }
@ -44,10 +44,10 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
XxlJobUser loginUser = loginService.ifLogin(request, response); XxlJobUser loginUser = loginService.ifLogin(request, response);
if (loginUser == null) { if (loginUser == null) {
response.setStatus(302); response.setStatus(302);
response.setHeader("location", request.getContextPath()+"/toLogin"); response.setHeader("location" , request.getContextPath() + "/toLogin");
return false; return false;
} }
if (needAdminuser && loginUser.getRole()!=1) { if (needAdminuser && loginUser.getRole() != 1) {
throw new RuntimeException(I18nUtil.getString("system_permission_limit")); throw new RuntimeException(I18nUtil.getString("system_permission_limit"));
} }
request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser); request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser);

View File

@ -1,8 +1,8 @@
package com.xxl.job.admin.controller.resolver; package com.xxl.job.admin.controller.resolver;
import com.xxl.job.admin.core.exception.XxlJobException; import com.xxl.job.admin.core.exception.XxlJobException;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.admin.core.util.JacksonUtil; import com.xxl.job.admin.core.util.JacksonUtil;
import com.xxl.job.core.biz.model.ReturnT;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -29,13 +29,13 @@ public class WebExceptionResolver implements HandlerExceptionResolver {
HttpServletResponse response, Object handler, Exception ex) { HttpServletResponse response, Object handler, Exception ex) {
if (!(ex instanceof XxlJobException)) { if (!(ex instanceof XxlJobException)) {
logger.error("WebExceptionResolver:{}", ex); logger.error("WebExceptionResolver:{}" , ex);
} }
// if json // if json
boolean isJson = false; boolean isJson = false;
if (handler instanceof HandlerMethod) { if (handler instanceof HandlerMethod) {
HandlerMethod method = (HandlerMethod)handler; HandlerMethod method = (HandlerMethod) handler;
ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class); ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class);
if (responseBody != null) { if (responseBody != null) {
isJson = true; isJson = true;
@ -43,7 +43,7 @@ public class WebExceptionResolver implements HandlerExceptionResolver {
} }
// error result // error result
ReturnT<String> errorResult = new ReturnT<String>(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n", "<br/>")); ReturnT<String> errorResult = new ReturnT<String>(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n" , "<br/>"));
// response // response
ModelAndView mv = new ModelAndView(); ModelAndView mv = new ModelAndView();
@ -57,7 +57,7 @@ public class WebExceptionResolver implements HandlerExceptionResolver {
return mv; return mv;
} else { } else {
mv.addObject("exceptionMsg", errorResult.getMsg()); mv.addObject("exceptionMsg" , errorResult.getMsg());
mv.setViewName("/common/common.exception"); mv.setViewName("/common/common.exception");
return mv; return mv;
} }

View File

@ -4,6 +4,7 @@ import java.util.Date;
/** /**
* xxl-job log, used to track trigger process * xxl-job log, used to track trigger process
*
* @author xuxueli 2015-12-19 23:19:09 * @author xuxueli 2015-12-19 23:19:09
*/ */
public class XxlJobLog { public class XxlJobLog {

View File

@ -4,6 +4,7 @@ import java.util.Date;
/** /**
* xxl-job log for glue, used to track job code process * xxl-job log for glue, used to track job code process
*
* @author xuxueli 2016-5-19 17:57:46 * @author xuxueli 2016-5-19 17:57:46
*/ */
public class XxlJobLogGlue { public class XxlJobLogGlue {

View File

@ -54,7 +54,7 @@ public class XxlJobUser {
} }
// plugin // plugin
public boolean validPermission(int jobGroup){ public boolean validPermission(int jobGroup) {
if (this.role == 1) { if (this.role == 1) {
return true; return true;
} else { } else {

View File

@ -23,7 +23,8 @@ public class JobCompleteHelper {
private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class); private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class);
private static JobCompleteHelper instance = new JobCompleteHelper(); private static JobCompleteHelper instance = new JobCompleteHelper();
public static JobCompleteHelper getInstance(){
public static JobCompleteHelper getInstance() {
return instance; return instance;
} }
@ -32,7 +33,8 @@ public class JobCompleteHelper {
private ThreadPoolExecutor callbackThreadPool = null; private ThreadPoolExecutor callbackThreadPool = null;
private Thread monitorThread; private Thread monitorThread;
private volatile boolean toStop = false; private volatile boolean toStop = false;
public void start(){
public void start() {
// for callback // for callback
callbackThreadPool = new ThreadPoolExecutor( callbackThreadPool = new ThreadPoolExecutor(
@ -78,15 +80,15 @@ public class JobCompleteHelper {
Date losedTime = DateUtil.addMinutes(new Date(), -10); Date losedTime = DateUtil.addMinutes(new Date(), -10);
List<Long> losedJobIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLostJobIds(losedTime); List<Long> losedJobIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLostJobIds(losedTime);
if (losedJobIds!=null && losedJobIds.size()>0) { if (losedJobIds != null && losedJobIds.size() > 0) {
for (Long logId: losedJobIds) { for (Long logId : losedJobIds) {
XxlJobLog jobLog = new XxlJobLog(); XxlJobLog jobLog = new XxlJobLog();
jobLog.setId(logId); jobLog.setId(logId);
jobLog.setHandleTime(new Date()); jobLog.setHandleTime(new Date());
jobLog.setHandleCode(ReturnT.FAIL_CODE); jobLog.setHandleCode(ReturnT.FAIL_CODE);
jobLog.setHandleMsg( I18nUtil.getString("joblog_lost_fail") ); jobLog.setHandleMsg(I18nUtil.getString("joblog_lost_fail"));
XxlJobCompleter.updateHandleInfoAndFinish(jobLog); XxlJobCompleter.updateHandleInfoAndFinish(jobLog);
} }
@ -94,7 +96,7 @@ public class JobCompleteHelper {
} }
} catch (Exception e) { } catch (Exception e) {
if (!toStop) { if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e); logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}" , e);
} }
} }
@ -117,7 +119,7 @@ public class JobCompleteHelper {
monitorThread.start(); monitorThread.start();
} }
public void toStop(){ public void toStop() {
toStop = true; toStop = true;
// stop registryOrRemoveThreadPool // stop registryOrRemoveThreadPool
@ -140,10 +142,10 @@ public class JobCompleteHelper {
callbackThreadPool.execute(new Runnable() { callbackThreadPool.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
for (HandleCallbackParam handleCallbackParam: callbackParamList) { for (HandleCallbackParam handleCallbackParam : callbackParamList) {
ReturnT<String> callbackResult = callback(handleCallbackParam); ReturnT<String> callbackResult = callback(handleCallbackParam);
logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}", logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}" ,
(callbackResult.getCode()== ReturnT.SUCCESS_CODE?"success":"fail"), handleCallbackParam, callbackResult); (callbackResult.getCode() == ReturnT.SUCCESS_CODE ? "success" : "fail"), handleCallbackParam, callbackResult);
} }
} }
}); });
@ -163,7 +165,7 @@ public class JobCompleteHelper {
// handle msg // handle msg
StringBuffer handleMsg = new StringBuffer(); StringBuffer handleMsg = new StringBuffer();
if (log.getHandleMsg()!=null) { if (log.getHandleMsg() != null) {
handleMsg.append(log.getHandleMsg()).append("<br>"); handleMsg.append(log.getHandleMsg()).append("<br>");
} }
if (handleCallbackParam.getHandleMsg() != null) { if (handleCallbackParam.getHandleMsg() != null) {
@ -180,5 +182,4 @@ public class JobCompleteHelper {
} }
} }

View File

@ -20,7 +20,8 @@ public class JobFailMonitorHelper {
private static Logger logger = LoggerFactory.getLogger(JobFailMonitorHelper.class); private static Logger logger = LoggerFactory.getLogger(JobFailMonitorHelper.class);
private static JobFailMonitorHelper instance = new JobFailMonitorHelper(); private static JobFailMonitorHelper instance = new JobFailMonitorHelper();
public static JobFailMonitorHelper getInstance(){
public static JobFailMonitorHelper getInstance() {
return instance; return instance;
} }
@ -28,7 +29,8 @@ public class JobFailMonitorHelper {
private Thread monitorThread; private Thread monitorThread;
private volatile boolean toStop = false; private volatile boolean toStop = false;
public void start(){
public void start() {
monitorThread = new Thread(new Runnable() { monitorThread = new Thread(new Runnable() {
@Override @Override
@ -39,8 +41,8 @@ public class JobFailMonitorHelper {
try { try {
List<Long> failLogIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findFailJobLogIds(1000); List<Long> failLogIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findFailJobLogIds(1000);
if (failLogIds!=null && !failLogIds.isEmpty()) { if (failLogIds != null && !failLogIds.isEmpty()) {
for (long failLogId: failLogIds) { for (long failLogId : failLogIds) {
// lock log // lock log
int lockRet = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, 0, -1); int lockRet = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, 0, -1);
@ -52,17 +54,17 @@ public class JobFailMonitorHelper {
// 1fail retry monitor // 1fail retry monitor
if (log.getExecutorFailRetryCount() > 0) { if (log.getExecutorFailRetryCount() > 0) {
JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount()-1), log.getExecutorShardingParam(), log.getExecutorParam(), null); JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount() - 1), log.getExecutorShardingParam(), log.getExecutorParam(), null);
String retryMsg = "<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_type_retry") +"<<<<<<<<<<< </span><br>"; String retryMsg = "<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>" + I18nUtil.getString("jobconf_trigger_type_retry") + "<<<<<<<<<<< </span><br>";
log.setTriggerMsg(log.getTriggerMsg() + retryMsg); log.setTriggerMsg(log.getTriggerMsg() + retryMsg);
XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateTriggerInfo(log); XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateTriggerInfo(log);
} }
// 2fail alarm monitor // 2fail alarm monitor
int newAlarmStatus = 0; // 告警状态0-默认-1=锁定状态1-无需告警2-告警成功3-告警失败 int newAlarmStatus = 0; // 告警状态0-默认-1=锁定状态1-无需告警2-告警成功3-告警失败
if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) { if (info != null && info.getAlarmEmail() != null && info.getAlarmEmail().trim().length() > 0) {
boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log); boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log);
newAlarmStatus = alarmResult?2:3; newAlarmStatus = alarmResult ? 2 : 3;
} else { } else {
newAlarmStatus = 1; newAlarmStatus = 1;
} }
@ -73,7 +75,7 @@ public class JobFailMonitorHelper {
} catch (Exception e) { } catch (Exception e) {
if (!toStop) { if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e); logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}" , e);
} }
} }
@ -96,7 +98,7 @@ public class JobFailMonitorHelper {
monitorThread.start(); monitorThread.start();
} }
public void toStop(){ public void toStop() {
toStop = true; toStop = true;
// interrupt and wait // interrupt and wait
monitorThread.interrupt(); monitorThread.interrupt();

View File

@ -15,13 +15,15 @@ import java.util.concurrent.*;
/** /**
* job registry instance * job registry instance
*
* @author xuxueli 2016-10-02 19:10:24 * @author xuxueli 2016-10-02 19:10:24
*/ */
public class JobRegistryHelper { public class JobRegistryHelper {
private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class); private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class);
private static JobRegistryHelper instance = new JobRegistryHelper(); private static JobRegistryHelper instance = new JobRegistryHelper();
public static JobRegistryHelper getInstance(){
public static JobRegistryHelper getInstance() {
return instance; return instance;
} }
@ -29,7 +31,7 @@ public class JobRegistryHelper {
private Thread registryMonitorThread; private Thread registryMonitorThread;
private volatile boolean toStop = false; private volatile boolean toStop = false;
public void start(){ public void start() {
// for registry or remove // for registry or remove
registryOrRemoveThreadPool = new ThreadPoolExecutor( registryOrRemoveThreadPool = new ThreadPoolExecutor(
@ -60,11 +62,11 @@ public class JobRegistryHelper {
try { try {
// auto registry group // auto registry group
List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0); List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0);
if (groupList!=null && !groupList.isEmpty()) { if (groupList != null && !groupList.isEmpty()) {
// remove dead address (admin/executor) // remove dead address (admin/executor)
List<Integer> ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date()); List<Integer> ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
if (ids!=null && ids.size()>0) { if (ids != null && ids.size() > 0) {
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids); XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids);
} }
@ -72,7 +74,7 @@ public class JobRegistryHelper {
HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>(); HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date()); List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
if (list != null) { if (list != null) {
for (XxlJobRegistry item: list) { for (XxlJobRegistry item : list) {
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) { if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
String appname = item.getRegistryKey(); String appname = item.getRegistryKey();
List<String> registryList = appAddressMap.get(appname); List<String> registryList = appAddressMap.get(appname);
@ -89,17 +91,17 @@ public class JobRegistryHelper {
} }
// fresh group address // fresh group address
for (XxlJobGroup group: groupList) { for (XxlJobGroup group : groupList) {
List<String> registryList = appAddressMap.get(group.getAppname()); List<String> registryList = appAddressMap.get(group.getAppname());
String addressListStr = null; String addressListStr = null;
if (registryList!=null && !registryList.isEmpty()) { if (registryList != null && !registryList.isEmpty()) {
Collections.sort(registryList); Collections.sort(registryList);
StringBuilder addressListSB = new StringBuilder(); StringBuilder addressListSB = new StringBuilder();
for (String item:registryList) { for (String item : registryList) {
addressListSB.append(item).append(","); addressListSB.append(item).append(",");
} }
addressListStr = addressListSB.toString(); addressListStr = addressListSB.toString();
addressListStr = addressListStr.substring(0, addressListStr.length()-1); addressListStr = addressListStr.substring(0, addressListStr.length() - 1);
} }
group.setAddressList(addressListStr); group.setAddressList(addressListStr);
group.setUpdateTime(new Date()); group.setUpdateTime(new Date());
@ -109,14 +111,14 @@ public class JobRegistryHelper {
} }
} catch (Exception e) { } catch (Exception e) {
if (!toStop) { if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e); logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}" , e);
} }
} }
try { try {
TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT); TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
} catch (InterruptedException e) { } catch (InterruptedException e) {
if (!toStop) { if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e); logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}" , e);
} }
} }
} }
@ -128,7 +130,7 @@ public class JobRegistryHelper {
registryMonitorThread.start(); registryMonitorThread.start();
} }
public void toStop(){ public void toStop() {
toStop = true; toStop = true;
// stop registryOrRemoveThreadPool // stop registryOrRemoveThreadPool
@ -196,7 +198,7 @@ public class JobRegistryHelper {
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} }
private void freshGroupRegistryInfo(RegistryParam registryParam){ private void freshGroupRegistryInfo(RegistryParam registryParam) {
// Under consideration, prevent affecting core tables // Under consideration, prevent affecting core tables
} }

View File

@ -24,7 +24,7 @@ public class JobTriggerPoolHelper {
private ThreadPoolExecutor fastTriggerPool = null; private ThreadPoolExecutor fastTriggerPool = null;
private ThreadPoolExecutor slowTriggerPool = null; private ThreadPoolExecutor slowTriggerPool = null;
public void start(){ public void start() {
fastTriggerPool = new ThreadPoolExecutor( fastTriggerPool = new ThreadPoolExecutor(
10, 10,
XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax(), XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax(),
@ -62,7 +62,7 @@ public class JobTriggerPoolHelper {
// job timeout count // job timeout count
private volatile long minTim = System.currentTimeMillis()/60000; // ms > min private volatile long minTim = System.currentTimeMillis() / 60000; // ms > min
private volatile ConcurrentMap<Integer, AtomicInteger> jobTimeoutCountMap = new ConcurrentHashMap<>(); private volatile ConcurrentMap<Integer, AtomicInteger> jobTimeoutCountMap = new ConcurrentHashMap<>();
@ -79,7 +79,7 @@ public class JobTriggerPoolHelper {
// choose thread pool // choose thread pool
ThreadPoolExecutor triggerPool_ = fastTriggerPool; ThreadPoolExecutor triggerPool_ = fastTriggerPool;
AtomicInteger jobTimeoutCount = jobTimeoutCountMap.get(jobId); AtomicInteger jobTimeoutCount = jobTimeoutCountMap.get(jobId);
if (jobTimeoutCount!=null && jobTimeoutCount.get() > 10) { // job-timeout 10 times in 1 min if (jobTimeoutCount != null && jobTimeoutCount.get() > 10) { // job-timeout 10 times in 1 min
triggerPool_ = slowTriggerPool; triggerPool_ = slowTriggerPool;
} }
@ -98,14 +98,14 @@ public class JobTriggerPoolHelper {
} finally { } finally {
// check timeout-count-map // check timeout-count-map
long minTim_now = System.currentTimeMillis()/60000; long minTim_now = System.currentTimeMillis() / 60000;
if (minTim != minTim_now) { if (minTim != minTim_now) {
minTim = minTim_now; minTim = minTim_now;
jobTimeoutCountMap.clear(); jobTimeoutCountMap.clear();
} }
// incr timeout-count-map // incr timeout-count-map
long cost = System.currentTimeMillis()-start; long cost = System.currentTimeMillis() - start;
if (cost > 500) { // ob-timeout threshold 500ms if (cost > 500) { // ob-timeout threshold 500ms
AtomicInteger timeoutCount = jobTimeoutCountMap.putIfAbsent(jobId, new AtomicInteger(1)); AtomicInteger timeoutCount = jobTimeoutCountMap.putIfAbsent(jobId, new AtomicInteger(1));
if (timeoutCount != null) { if (timeoutCount != null) {
@ -120,7 +120,6 @@ public class JobTriggerPoolHelper {
} }
// ---------------------- helper ---------------------- // ---------------------- helper ----------------------
private static JobTriggerPoolHelper helper = new JobTriggerPoolHelper(); private static JobTriggerPoolHelper helper = new JobTriggerPoolHelper();
@ -128,6 +127,7 @@ public class JobTriggerPoolHelper {
public static void toStart() { public static void toStart() {
helper.start(); helper.start();
} }
public static void toStop() { public static void toStop() {
helper.stop(); helper.stop();
} }
@ -135,12 +135,10 @@ public class JobTriggerPoolHelper {
/** /**
* @param jobId * @param jobId
* @param triggerType * @param triggerType
* @param failRetryCount * @param failRetryCount >=0: use this param
* >=0: use this param
* <0: use param from job info config * <0: use param from job info config
* @param executorShardingParam * @param executorShardingParam
* @param executorParam * @param executorParam null: use job param
* null: use job param
* not null: cover job param * not null: cover job param
*/ */
public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam, String addressList) { public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam, String addressList) {

View File

@ -25,7 +25,7 @@ public class CookieUtil {
* @param ifRemember * @param ifRemember
*/ */
public static void set(HttpServletResponse response, String key, String value, boolean ifRemember) { public static void set(HttpServletResponse response, String key, String value, boolean ifRemember) {
int age = ifRemember?COOKIE_MAX_AGE:-1; int age = ifRemember ? COOKIE_MAX_AGE : -1;
set(response, key, value, null, COOKIE_PATH, age, true); set(response, key, value, null, COOKIE_PATH, age, true);
} }
@ -91,7 +91,7 @@ public class CookieUtil {
public static void remove(HttpServletRequest request, HttpServletResponse response, String key) { public static void remove(HttpServletRequest request, HttpServletResponse response, String key) {
Cookie cookie = get(request, key); Cookie cookie = get(request, key);
if (cookie != null) { if (cookie != null) {
set(response, key, "", null, COOKIE_PATH, 0, true); set(response, key, "" , null, COOKIE_PATH, 0, true);
} }
} }

View File

@ -12,7 +12,7 @@ import java.io.IOException;
/** /**
* Jackson util * Jackson util
* * <p>
* 1obj need private and set/get * 1obj need private and set/get
* 2do not support inner class * 2do not support inner class
* *
@ -22,6 +22,7 @@ public class JacksonUtil {
private static Logger logger = LoggerFactory.getLogger(JacksonUtil.class); private static Logger logger = LoggerFactory.getLogger(JacksonUtil.class);
private final static ObjectMapper objectMapper = new ObjectMapper(); private final static ObjectMapper objectMapper = new ObjectMapper();
public static ObjectMapper getInstance() { public static ObjectMapper getInstance() {
return objectMapper; return objectMapper;
} }

View File

@ -9,6 +9,7 @@ import java.util.List;
/** /**
* job info * job info
*
* @author xuxueli 2016-1-12 18:03:45 * @author xuxueli 2016-1-12 18:03:45
*/ */
@Mapper @Mapper
@ -21,6 +22,7 @@ public interface XxlJobInfoDao {
@Param("jobDesc") String jobDesc, @Param("jobDesc") String jobDesc,
@Param("executorHandler") String executorHandler, @Param("executorHandler") String executorHandler,
@Param("author") String author); @Param("author") String author);
public int pageListCount(@Param("offset") int offset, public int pageListCount(@Param("offset") int offset,
@Param("pagesize") int pagesize, @Param("pagesize") int pagesize,
@Param("jobGroup") int jobGroup, @Param("jobGroup") int jobGroup,
@ -41,7 +43,7 @@ public interface XxlJobInfoDao {
public int findAllCount(); public int findAllCount();
public List<XxlJobInfo> scheduleJobQuery(@Param("maxNextTime") long maxNextTime, @Param("pagesize") int pagesize ); public List<XxlJobInfo> scheduleJobQuery(@Param("maxNextTime") long maxNextTime, @Param("pagesize") int pagesize);
public int scheduleUpdate(XxlJobInfo xxlJobInfo); public int scheduleUpdate(XxlJobInfo xxlJobInfo);

View File

@ -10,6 +10,7 @@ import java.util.Map;
/** /**
* job log * job log
*
* @author xuxueli 2016-1-12 18:03:06 * @author xuxueli 2016-1-12 18:03:06
*/ */
@Mapper @Mapper
@ -23,6 +24,7 @@ public interface XxlJobLogDao {
@Param("triggerTimeStart") Date triggerTimeStart, @Param("triggerTimeStart") Date triggerTimeStart,
@Param("triggerTimeEnd") Date triggerTimeEnd, @Param("triggerTimeEnd") Date triggerTimeEnd,
@Param("logStatus") int logStatus); @Param("logStatus") int logStatus);
public int pageListCount(@Param("offset") int offset, public int pageListCount(@Param("offset") int offset,
@Param("pagesize") int pagesize, @Param("pagesize") int pagesize,
@Param("jobGroup") int jobGroup, @Param("jobGroup") int jobGroup,
@ -49,6 +51,7 @@ public interface XxlJobLogDao {
@Param("clearBeforeTime") Date clearBeforeTime, @Param("clearBeforeTime") Date clearBeforeTime,
@Param("clearBeforeNum") int clearBeforeNum, @Param("clearBeforeNum") int clearBeforeNum,
@Param("pagesize") int pagesize); @Param("pagesize") int pagesize);
public int clearLog(@Param("logIds") List<Long> logIds); public int clearLog(@Param("logIds") List<Long> logIds);
public List<Long> findFailJobLogIds(@Param("pagesize") int pagesize); public List<Long> findFailJobLogIds(@Param("pagesize") int pagesize);

View File

@ -8,6 +8,7 @@ import java.util.List;
/** /**
* job log for glue * job log for glue
*
* @author xuxueli 2016-5-19 18:04:56 * @author xuxueli 2016-5-19 18:04:56
*/ */
@Mapper @Mapper

View File

@ -9,6 +9,7 @@ import java.util.List;
/** /**
* job log * job log
*
* @author xuxueli 2019-11-22 * @author xuxueli 2019-11-22
*/ */
@Mapper @Mapper

View File

@ -3,6 +3,7 @@ package com.xxl.job.admin.dao;
import com.xxl.job.admin.core.model.XxlJobUser; import com.xxl.job.admin.core.model.XxlJobUser;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
/** /**
@ -15,6 +16,7 @@ public interface XxlJobUserDao {
@Param("pagesize") int pagesize, @Param("pagesize") int pagesize,
@Param("username") String username, @Param("username") String username,
@Param("role") int role); @Param("role") int role);
public int pageListCount(@Param("offset") int offset, public int pageListCount(@Param("offset") int offset,
@Param("pagesize") int pagesize, @Param("pagesize") int pagesize,
@Param("username") String username, @Param("username") String username,

View File

@ -46,6 +46,7 @@ public interface XxlJobService {
/** /**
* remove job * remove job
* * * *
*
* @param id * @param id
* @return * @return
*/ */
@ -72,7 +73,7 @@ public interface XxlJobService {
* *
* @return * @return
*/ */
public Map<String,Object> dashboardInfo(); public Map<String, Object> dashboardInfo();
/** /**
* chart info * chart info
@ -81,6 +82,6 @@ public interface XxlJobService {
* @param endDate * @param endDate
* @return * @return
*/ */
public ReturnT<Map<String,Object>> chartInfo(Date startDate, Date endDate); public ReturnT<Map<String, Object>> chartInfo(Date startDate, Date endDate);
} }

View File

@ -25,6 +25,7 @@ import java.util.*;
/** /**
* core job action for xxl-job * core job action for xxl-job
*
* @author xuxueli 2016-5-28 15:30:33 * @author xuxueli 2016-5-28 15:30:33
*/ */
@Service @Service
@ -51,9 +52,9 @@ public class XxlJobServiceImpl implements XxlJobService {
// package result // package result
Map<String, Object> maps = new HashMap<String, Object>(); Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数 maps.put("recordsTotal" , list_count); // 总记录数
maps.put("recordsFiltered", list_count); // 过滤后的总记录数 maps.put("recordsFiltered" , list_count); // 过滤后的总记录数
maps.put("data", list); // 分页列表 maps.put("data" , list); // 分页列表
return maps; return maps;
} }
@ -63,83 +64,83 @@ public class XxlJobServiceImpl implements XxlJobService {
// valid base // valid base
XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup()); XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup());
if (group == null) { if (group == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose")+I18nUtil.getString("jobinfo_field_jobgroup")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose") + I18nUtil.getString("jobinfo_field_jobgroup")));
} }
if (jobInfo.getJobDesc()==null || jobInfo.getJobDesc().trim().length()==0) { if (jobInfo.getJobDesc() == null || jobInfo.getJobDesc().trim().length() == 0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_jobdesc")));
} }
if (jobInfo.getAuthor()==null || jobInfo.getAuthor().trim().length()==0) { if (jobInfo.getAuthor() == null || jobInfo.getAuthor().trim().length() == 0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_author")));
} }
// valid trigger // valid trigger
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null); ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null);
if (scheduleTypeEnum == null) { if (scheduleTypeEnum == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
if (scheduleTypeEnum == ScheduleTypeEnum.CRON) { if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
if (jobInfo.getScheduleConf()==null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) { if (jobInfo.getScheduleConf() == null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron"+I18nUtil.getString("system_unvalid")); return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron" + I18nUtil.getString("system_unvalid"));
} }
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE/* || scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) { } else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE/* || scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
if (jobInfo.getScheduleConf() == null) { if (jobInfo.getScheduleConf() == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")));
} }
try { try {
int fixSecond = Integer.valueOf(jobInfo.getScheduleConf()); int fixSecond = Integer.valueOf(jobInfo.getScheduleConf());
if (fixSecond < 1) { if (fixSecond < 1) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
} catch (Exception e) { } catch (Exception e) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
} }
// valid job // valid job
if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) { if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype") + I18nUtil.getString("system_unvalid")));
} }
if (GlueTypeEnum.BEAN==GlueTypeEnum.match(jobInfo.getGlueType()) && (jobInfo.getExecutorHandler()==null || jobInfo.getExecutorHandler().trim().length()==0) ) { if (GlueTypeEnum.BEAN == GlueTypeEnum.match(jobInfo.getGlueType()) && (jobInfo.getExecutorHandler() == null || jobInfo.getExecutorHandler().trim().length() == 0)) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+"JobHandler") ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + "JobHandler"));
} }
// fix "\r" in shell // fix "\r" in shell
if (GlueTypeEnum.GLUE_SHELL==GlueTypeEnum.match(jobInfo.getGlueType()) && jobInfo.getGlueSource()!=null) { if (GlueTypeEnum.GLUE_SHELL == GlueTypeEnum.match(jobInfo.getGlueType()) && jobInfo.getGlueSource() != null) {
jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", "")); jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r" , ""));
} }
// valid advanced // valid advanced
if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) { if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy") + I18nUtil.getString("system_unvalid")));
} }
if (MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), null) == null) { if (MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("misfire_strategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("misfire_strategy") + I18nUtil.getString("system_unvalid")));
} }
if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) { if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy") + I18nUtil.getString("system_unvalid")));
} }
// ChildJobId valid // ChildJobId valid
if (jobInfo.getChildJobId()!=null && jobInfo.getChildJobId().trim().length()>0) { if (jobInfo.getChildJobId() != null && jobInfo.getChildJobId().trim().length() > 0) {
String[] childJobIds = jobInfo.getChildJobId().split(","); String[] childJobIds = jobInfo.getChildJobId().split(",");
for (String childJobIdItem: childJobIds) { for (String childJobIdItem : childJobIds) {
if (childJobIdItem!=null && childJobIdItem.trim().length()>0 && isNumeric(childJobIdItem)) { if (childJobIdItem != null && childJobIdItem.trim().length() > 0 && isNumeric(childJobIdItem)) {
XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.parseInt(childJobIdItem)); XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.parseInt(childJobIdItem));
if (childJobInfo==null) { if (childJobInfo == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, return new ReturnT<String>(ReturnT.FAIL_CODE,
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_not_found")), childJobIdItem)); MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_not_found")), childJobIdItem));
} }
} else { } else {
return new ReturnT<String>(ReturnT.FAIL_CODE, return new ReturnT<String>(ReturnT.FAIL_CODE,
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_unvalid")), childJobIdItem)); MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_unvalid")), childJobIdItem));
} }
} }
// join , avoid "xxx,," // join , avoid "xxx,,"
String temp = ""; String temp = "";
for (String item:childJobIds) { for (String item : childJobIds) {
temp += item + ","; temp += item + ",";
} }
temp = temp.substring(0, temp.length()-1); temp = temp.substring(0, temp.length() - 1);
jobInfo.setChildJobId(temp); jobInfo.setChildJobId(temp);
} }
@ -150,13 +151,13 @@ public class XxlJobServiceImpl implements XxlJobService {
jobInfo.setGlueUpdatetime(new Date()); jobInfo.setGlueUpdatetime(new Date());
xxlJobInfoDao.save(jobInfo); xxlJobInfoDao.save(jobInfo);
if (jobInfo.getId() < 1) { if (jobInfo.getId() < 1) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add") + I18nUtil.getString("system_fail")));
} }
return new ReturnT<String>(String.valueOf(jobInfo.getId())); return new ReturnT<String>(String.valueOf(jobInfo.getId()));
} }
private boolean isNumeric(String str){ private boolean isNumeric(String str) {
try { try {
int result = Integer.valueOf(str); int result = Integer.valueOf(str);
return true; return true;
@ -169,69 +170,69 @@ public class XxlJobServiceImpl implements XxlJobService {
public ReturnT<String> update(XxlJobInfo jobInfo) { public ReturnT<String> update(XxlJobInfo jobInfo) {
// valid base // valid base
if (jobInfo.getJobDesc()==null || jobInfo.getJobDesc().trim().length()==0) { if (jobInfo.getJobDesc() == null || jobInfo.getJobDesc().trim().length() == 0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_jobdesc")));
} }
if (jobInfo.getAuthor()==null || jobInfo.getAuthor().trim().length()==0) { if (jobInfo.getAuthor() == null || jobInfo.getAuthor().trim().length() == 0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_author")));
} }
// valid trigger // valid trigger
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null); ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null);
if (scheduleTypeEnum == null) { if (scheduleTypeEnum == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
if (scheduleTypeEnum == ScheduleTypeEnum.CRON) { if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
if (jobInfo.getScheduleConf()==null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) { if (jobInfo.getScheduleConf() == null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron"+I18nUtil.getString("system_unvalid") ); return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron" + I18nUtil.getString("system_unvalid"));
} }
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE /*|| scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) { } else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE /*|| scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
if (jobInfo.getScheduleConf() == null) { if (jobInfo.getScheduleConf() == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
try { try {
int fixSecond = Integer.valueOf(jobInfo.getScheduleConf()); int fixSecond = Integer.valueOf(jobInfo.getScheduleConf());
if (fixSecond < 1) { if (fixSecond < 1) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
} catch (Exception e) { } catch (Exception e) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
} }
// valid advanced // valid advanced
if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) { if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy") + I18nUtil.getString("system_unvalid")));
} }
if (MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), null) == null) { if (MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("misfire_strategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("misfire_strategy") + I18nUtil.getString("system_unvalid")));
} }
if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) { if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy") + I18nUtil.getString("system_unvalid")));
} }
// ChildJobId valid // ChildJobId valid
if (jobInfo.getChildJobId()!=null && jobInfo.getChildJobId().trim().length()>0) { if (jobInfo.getChildJobId() != null && jobInfo.getChildJobId().trim().length() > 0) {
String[] childJobIds = jobInfo.getChildJobId().split(","); String[] childJobIds = jobInfo.getChildJobId().split(",");
for (String childJobIdItem: childJobIds) { for (String childJobIdItem : childJobIds) {
if (childJobIdItem!=null && childJobIdItem.trim().length()>0 && isNumeric(childJobIdItem)) { if (childJobIdItem != null && childJobIdItem.trim().length() > 0 && isNumeric(childJobIdItem)) {
XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.parseInt(childJobIdItem)); XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.parseInt(childJobIdItem));
if (childJobInfo==null) { if (childJobInfo == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, return new ReturnT<String>(ReturnT.FAIL_CODE,
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_not_found")), childJobIdItem)); MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_not_found")), childJobIdItem));
} }
} else { } else {
return new ReturnT<String>(ReturnT.FAIL_CODE, return new ReturnT<String>(ReturnT.FAIL_CODE,
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_unvalid")), childJobIdItem)); MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_unvalid")), childJobIdItem));
} }
} }
// join , avoid "xxx,," // join , avoid "xxx,,"
String temp = ""; String temp = "";
for (String item:childJobIds) { for (String item : childJobIds) {
temp += item + ","; temp += item + ",";
} }
temp = temp.substring(0, temp.length()-1); temp = temp.substring(0, temp.length() - 1);
jobInfo.setChildJobId(temp); jobInfo.setChildJobId(temp);
} }
@ -239,13 +240,13 @@ public class XxlJobServiceImpl implements XxlJobService {
// group valid // group valid
XxlJobGroup jobGroup = xxlJobGroupDao.load(jobInfo.getJobGroup()); XxlJobGroup jobGroup = xxlJobGroupDao.load(jobInfo.getJobGroup());
if (jobGroup == null) { if (jobGroup == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_jobgroup")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_jobgroup") + I18nUtil.getString("system_unvalid")));
} }
// stage job info // stage job info
XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId()); XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId());
if (exists_jobInfo == null) { if (exists_jobInfo == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id")+I18nUtil.getString("system_not_found")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id") + I18nUtil.getString("system_not_found")));
} }
// next trigger time (5s后生效避开预读周期) // next trigger time (5s后生效避开预读周期)
@ -255,12 +256,12 @@ public class XxlJobServiceImpl implements XxlJobService {
try { try {
Date nextValidTime = JobScheduleHelper.generateNextValidTime(jobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS)); Date nextValidTime = JobScheduleHelper.generateNextValidTime(jobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));
if (nextValidTime == null) { if (nextValidTime == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
nextTriggerTime = nextValidTime.getTime(); nextTriggerTime = nextValidTime.getTime();
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
} }
@ -307,7 +308,7 @@ public class XxlJobServiceImpl implements XxlJobService {
// valid // valid
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(xxlJobInfo.getScheduleType(), ScheduleTypeEnum.NONE); ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(xxlJobInfo.getScheduleType(), ScheduleTypeEnum.NONE);
if (ScheduleTypeEnum.NONE == scheduleTypeEnum) { if (ScheduleTypeEnum.NONE == scheduleTypeEnum) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type_none_limit_start")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type_none_limit_start")));
} }
// next trigger time (5s后生效避开预读周期) // next trigger time (5s后生效避开预读周期)
@ -315,12 +316,12 @@ public class XxlJobServiceImpl implements XxlJobService {
try { try {
Date nextValidTime = JobScheduleHelper.generateNextValidTime(xxlJobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS)); Date nextValidTime = JobScheduleHelper.generateNextValidTime(xxlJobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));
if (nextValidTime == null) { if (nextValidTime == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
nextTriggerTime = nextValidTime.getTime(); nextTriggerTime = nextValidTime.getTime();
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
} }
xxlJobInfo.setTriggerStatus(1); xxlJobInfo.setTriggerStatus(1);
@ -361,9 +362,9 @@ public class XxlJobServiceImpl implements XxlJobService {
Set<String> executorAddressSet = new HashSet<String>(); Set<String> executorAddressSet = new HashSet<String>();
List<XxlJobGroup> groupList = xxlJobGroupDao.findAll(); List<XxlJobGroup> groupList = xxlJobGroupDao.findAll();
if (groupList!=null && !groupList.isEmpty()) { if (groupList != null && !groupList.isEmpty()) {
for (XxlJobGroup group: groupList) { for (XxlJobGroup group : groupList) {
if (group.getRegistryList()!=null && !group.getRegistryList().isEmpty()) { if (group.getRegistryList() != null && !group.getRegistryList().isEmpty()) {
executorAddressSet.addAll(group.getRegistryList()); executorAddressSet.addAll(group.getRegistryList());
} }
} }
@ -372,10 +373,10 @@ public class XxlJobServiceImpl implements XxlJobService {
int executorCount = executorAddressSet.size(); int executorCount = executorAddressSet.size();
Map<String, Object> dashboardMap = new HashMap<String, Object>(); Map<String, Object> dashboardMap = new HashMap<String, Object>();
dashboardMap.put("jobInfoCount", jobInfoCount); dashboardMap.put("jobInfoCount" , jobInfoCount);
dashboardMap.put("jobLogCount", jobLogCount); dashboardMap.put("jobLogCount" , jobLogCount);
dashboardMap.put("jobLogSuccessCount", jobLogSuccessCount); dashboardMap.put("jobLogSuccessCount" , jobLogSuccessCount);
dashboardMap.put("executorCount", executorCount); dashboardMap.put("executorCount" , executorCount);
return dashboardMap; return dashboardMap;
} }
@ -393,8 +394,8 @@ public class XxlJobServiceImpl implements XxlJobService {
List<XxlJobLogReport> logReportList = xxlJobLogReportDao.queryLogReport(startDate, endDate); List<XxlJobLogReport> logReportList = xxlJobLogReportDao.queryLogReport(startDate, endDate);
if (logReportList!=null && logReportList.size()>0) { if (logReportList != null && logReportList.size() > 0) {
for (XxlJobLogReport item: logReportList) { for (XxlJobLogReport item : logReportList) {
String day = DateUtil.formatDate(item.getTriggerDay()); String day = DateUtil.formatDate(item.getTriggerDay());
int triggerDayCountRunning = item.getRunningCount(); int triggerDayCountRunning = item.getRunningCount();
int triggerDayCountSuc = item.getSucCount(); int triggerDayCountSuc = item.getSucCount();
@ -419,14 +420,14 @@ public class XxlJobServiceImpl implements XxlJobService {
} }
Map<String, Object> result = new HashMap<String, Object>(); Map<String, Object> result = new HashMap<String, Object>();
result.put("triggerDayList", triggerDayList); result.put("triggerDayList" , triggerDayList);
result.put("triggerDayCountRunningList", triggerDayCountRunningList); result.put("triggerDayCountRunningList" , triggerDayCountRunningList);
result.put("triggerDayCountSucList", triggerDayCountSucList); result.put("triggerDayCountSucList" , triggerDayCountSucList);
result.put("triggerDayCountFailList", triggerDayCountFailList); result.put("triggerDayCountFailList" , triggerDayCountFailList);
result.put("triggerCountRunningTotal", triggerCountRunningTotal); result.put("triggerCountRunningTotal" , triggerCountRunningTotal);
result.put("triggerCountSucTotal", triggerCountSucTotal); result.put("triggerCountSucTotal" , triggerCountSucTotal);
result.put("triggerCountFailTotal", triggerCountFailTotal); result.put("triggerCountFailTotal" , triggerCountFailTotal);
return new ReturnT<Map<String, Object>>(result); return new ReturnT<Map<String, Object>>(result);
} }

View File

@ -9,7 +9,7 @@ spring:
# 设置 Spring Boot Admin Server 地址 # 设置 Spring Boot Admin Server 地址
url: http://localhost:9090/admin url: http://localhost:9090/admin
instance: instance:
prefer-ip: true # 注册实例时,优先使用 IP service-host-type: IP
username: ruoyi username: ruoyi
password: 123456 password: 123456

View File

@ -9,7 +9,7 @@ spring:
# 设置 Spring Boot Admin Server 地址 # 设置 Spring Boot Admin Server 地址
url: http://172.30.0.90:9090/admin url: http://172.30.0.90:9090/admin
instance: instance:
prefer-ip: true # 注册实例时,优先使用 IP service-host-type: IP
username: ruoyi username: ruoyi
password: 123456 password: 123456

View File

@ -1,6 +1,6 @@
{ {
"name": "ruoyi-vue-plus", "name": "ruoyi-vue-plus",
"version": "3.5.0", "version": "4.0.0",
"description": "RuoYi-Vue-Plus后台管理系统", "description": "RuoYi-Vue-Plus后台管理系统",
"author": "LionLi", "author": "LionLi",
"license": "MIT", "license": "MIT",

View File

@ -43,6 +43,18 @@ export function updateConfig(data) {
}) })
} }
// 修改参数配置
export function updateConfigByKey(key, value) {
return request({
url: '/system/config/updateByKey',
method: 'put',
data: {
configKey: key,
configValue: value
}
})
}
// 删除参数配置 // 删除参数配置
export function delConfig(configId) { export function delConfig(configId) {
return request({ return request({

View File

@ -17,13 +17,3 @@ export function delOss(ossId) {
}) })
} }
export function changePreviewListResource(previewListResource) {
const data = {
previewListResource
}
return request({
url: '/system/oss/changePreviewListResource',
method: 'put',
data: data
})
}

View File

@ -1,5 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
import { praseStrEmpty } from "@/utils/ruoyi"; import { parseStrEmpty } from "@/utils/ruoyi";
// 查询用户列表 // 查询用户列表
export function listUser(query) { export function listUser(query) {
@ -13,7 +13,7 @@ export function listUser(query) {
// 查询用户详细 // 查询用户详细
export function getUser(userId) { export function getUser(userId) {
return request({ return request({
url: '/system/user/' + praseStrEmpty(userId), url: '/system/user/' + parseStrEmpty(userId),
method: 'get' method: 'get'
}) })
} }

View File

@ -1,55 +1,68 @@
/** /**
* 通用css样式布局处理 * 通用css样式布局处理
* Copyright (c) 2019 ruoyi * Copyright (c) 2019 ruoyi
*/ */
/** 基础通用 **/ /** 基础通用 **/
.pt5 { .pt5 {
padding-top: 5px; padding-top: 5px;
} }
.pr5 { .pr5 {
padding-right: 5px; padding-right: 5px;
} }
.pb5 { .pb5 {
padding-bottom: 5px; padding-bottom: 5px;
} }
.mt5 { .mt5 {
margin-top: 5px; margin-top: 5px;
} }
.mr5 { .mr5 {
margin-right: 5px; margin-right: 5px;
} }
.mb5 { .mb5 {
margin-bottom: 5px; margin-bottom: 5px;
} }
.mb8 { .mb8 {
margin-bottom: 8px; margin-bottom: 8px;
} }
.ml5 { .ml5 {
margin-left: 5px; margin-left: 5px;
} }
.mt10 { .mt10 {
margin-top: 10px; margin-top: 10px;
} }
.mr10 { .mr10 {
margin-right: 10px; margin-right: 10px;
} }
.mb10 { .mb10 {
margin-bottom: 10px; margin-bottom: 10px;
} }
.ml0 { .ml10 {
margin-left: 10px; margin-left: 10px;
} }
.mt20 { .mt20 {
margin-top: 20px; margin-top: 20px;
} }
.mr20 { .mr20 {
margin-right: 20px; margin-right: 20px;
} }
.mb20 { .mb20 {
margin-bottom: 20px; margin-bottom: 20px;
} }
.m20 { .ml20 {
margin-left: 20px; margin-left: 20px;
} }
@ -81,6 +94,7 @@
font-size: 13px; font-size: 13px;
} }
} }
.el-table__body-wrapper { .el-table__body-wrapper {
.el-button [class*="el-icon-"] + span { .el-button [class*="el-icon-"] + span {
margin-left: 1px; margin-left: 1px;
@ -90,11 +104,11 @@
/** 表单布局 **/ /** 表单布局 **/
.form-header { .form-header {
font-size:15px; font-size: 15px;
color:#6379bb; color: #6379bb;
border-bottom:1px solid #ddd; border-bottom: 1px solid #ddd;
margin:8px 10px 25px 10px; margin: 8px 10px 25px 10px;
padding-bottom:5px padding-bottom: 5px
} }
/** 表格布局 **/ /** 表格布局 **/
@ -111,7 +125,7 @@
margin-top: 5px; margin-top: 5px;
border: 1px solid #e5e6e7; border: 1px solid #e5e6e7;
background: #FFFFFF none; background: #FFFFFF none;
border-radius:4px; border-radius: 4px;
} }
.pagination-container .el-pagination { .pagination-container .el-pagination {
@ -119,7 +133,7 @@
position: absolute; position: absolute;
} }
@media ( max-width : 768px) { @media (max-width: 768px) {
.pagination-container .el-pagination > .el-pagination__jump { .pagination-container .el-pagination > .el-pagination__jump {
display: none !important; display: none !important;
} }
@ -261,10 +275,10 @@
} }
/* 拖拽列样式 */ /* 拖拽列样式 */
.sortable-ghost{ .sortable-ghost {
opacity: .8; opacity: .8;
color: #fff!important; color: #fff !important;
background: #42b983!important; background: #42b983 !important;
} }
.top-right-btn { .top-right-btn {

View File

@ -26,7 +26,7 @@
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :label="4">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option> <el-option v-for="item in 24" :key="item" :value="item-1">{{item-1}}</el-option>
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>

View File

@ -26,7 +26,7 @@
<!-- 文件列表 --> <!-- 文件列表 -->
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul"> <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
<li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList"> <li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
<el-link :href="`${file.url}`" :underline="false" target="_blank"> <el-link :href="`${file.url}`" :underline="false" target="_blank">
<span class="el-icon-document"> {{ getFileName(file.name) }} </span> <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
</el-link> </el-link>

View File

@ -1,5 +1,10 @@
<template> <template>
<el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="[`${realSrc}`]"> <el-image
:src="`${realSrc}`"
fit="cover"
:style="`width:${realWidth};height:${realHeight};`"
:preview-src-list="realSrcList"
>
<div slot="error" class="image-slot"> <div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i> <i class="el-icon-picture-outline"></i>
</div> </div>
@ -7,10 +12,10 @@
</template> </template>
<script> <script>
import { isExternal } from '@/utils/validate' import { isExternal } from "@/utils/validate";
export default { export default {
name: 'ImagePreview', name: "ImagePreview",
props: { props: {
src: { src: {
type: String, type: String,
@ -18,28 +23,40 @@ export default {
}, },
width: { width: {
type: [Number, String], type: [Number, String],
default: '' default: ""
}, },
height: { height: {
type: [Number, String], type: [Number, String],
default: '' default: ""
} }
}, },
computed: { computed: {
realSrc() { realSrc() {
if (isExternal(this.src)) { let real_src = this.src.split(",")[0];
return this.src if (isExternal(real_src)) {
return real_src;
} }
return process.env.VUE_APP_BASE_API + this.src return process.env.VUE_APP_BASE_API + real_src;
},
realSrcList() {
let real_src_list = this.src.split(",");
let srcList = [];
real_src_list.forEach(item => {
if (isExternal(item)) {
return srcList.push(item);
}
return srcList.push(process.env.VUE_APP_BASE_API + item);
});
return srcList;
}, },
realWidth() { realWidth() {
return typeof this.width == 'string' ? this.width : `${this.width}px` return typeof this.width == "string" ? this.width : `${this.width}px`;
}, },
realHeight() { realHeight() {
return typeof this.height == 'string' ? this.height : `${this.height}px` return typeof this.height == "string" ? this.height : `${this.height}px`;
} }
} },
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,6 +1,7 @@
<template> <template>
<div :class="{'hidden':hidden}" class="pagination-container"> <div :class="{'hidden':hidden}" class="pagination-container">
<el-pagination <el-pagination
v-if="pageShow"
:background="background" :background="background"
:current-page.sync="currentPage" :current-page.sync="currentPage"
:page-size.sync="pageSize" :page-size.sync="pageSize"
@ -61,6 +62,11 @@ export default {
default: false default: false
} }
}, },
data() {
return {
pageShow: true
};
},
computed: { computed: {
currentPage: { currentPage: {
get() { get() {
@ -81,6 +87,12 @@ export default {
}, },
methods: { methods: {
handleSizeChange(val) { handleSizeChange(val) {
if (this.currentPage * val > this.total) {
this.pageShow = false;
this.$nextTick(() => {
this.pageShow = true
})
}
this.$emit('pagination', { page: this.currentPage, limit: val }) this.$emit('pagination', { page: this.currentPage, limit: val })
if (this.autoScroll) { if (this.autoScroll) {
scrollTo(0, 800) scrollTo(0, 800)

View File

@ -17,7 +17,7 @@ import { download } from '@/utils/request'
import './assets/icons' // icon import './assets/icons' // icon
import './permission' // permission control import './permission' // permission control
import { getDicts } from "@/api/system/dict/data"; import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config"; import { getConfigKey, updateConfigByKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"; import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
// 分页组件 // 分页组件
import Pagination from "@/components/Pagination"; import Pagination from "@/components/Pagination";
@ -41,6 +41,7 @@ import DictData from '@/components/DictData'
// 全局方法挂载 // 全局方法挂载
Vue.prototype.getDicts = getDicts Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey Vue.prototype.getConfigKey = getConfigKey
Vue.prototype.updateConfigByKey = updateConfigByKey
Vue.prototype.parseTime = parseTime Vue.prototype.parseTime = parseTime
Vue.prototype.resetForm = resetForm Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange Vue.prototype.addDateRange = addDateRange

View File

@ -4,20 +4,21 @@ import router from '@/router';
export default { export default {
// 刷新当前tab页签 // 刷新当前tab页签
refreshPage(obj) { refreshPage(obj) {
const { path, matched } = router.currentRoute; const { path, query, matched } = router.currentRoute;
if (obj === undefined) { if (obj === undefined) {
matched.forEach((m) => { matched.forEach((m) => {
if (m.components && m.components.default && m.components.default.name) { if (m.components && m.components.default && m.components.default.name) {
if (!['Layout', 'ParentView'].includes(m.components.default.name)) { if (!['Layout', 'ParentView'].includes(m.components.default.name)) {
obj = { name: m.components.default.name, path: path }; obj = { name: m.components.default.name, path: path, query: query };
} }
} }
}); });
} }
return store.dispatch('tagsView/delCachedView', obj).then(() => { return store.dispatch('tagsView/delCachedView', obj).then(() => {
const { path } = obj const { path, query } = obj
router.replace({ router.replace({
path: '/redirect' + path path: '/redirect' + path,
query: query
}) })
}) })
}, },

View File

@ -155,7 +155,7 @@ export const dynamicRoutes = [
permissions: ['tool:gen:edit'], permissions: ['tool:gen:edit'],
children: [ children: [
{ {
path: 'index', path: 'index/:tableId(\\d+)',
component: () => import('@/views/tool/gen/editTable'), component: () => import('@/views/tool/gen/editTable'),
name: 'GenEdit', name: 'GenEdit',
meta: { title: '修改生成配置', activeMenu: '/tool/gen' } meta: { title: '修改生成配置', activeMenu: '/tool/gen' }

View File

@ -0,0 +1,29 @@
export default [
{
layout: 'colFormItem',
tagIcon: 'input',
label: '手机号',
vModel: 'mobile',
formId: 6,
tag: 'el-input',
placeholder: '请输入手机号',
defaultValue: '',
span: 24,
style: { width: '100%' },
clearable: true,
prepend: '',
append: '',
'prefix-icon': 'el-icon-mobile',
'suffix-icon': '',
maxlength: 11,
'show-word-limit': true,
readonly: false,
disabled: false,
required: true,
changeTag: true,
regList: [{
pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
message: '手机号格式错误'
}]
}
]

View File

@ -5,11 +5,11 @@ let confGlobal
let someSpanIsNot24 let someSpanIsNot24
export function dialogWrapper(str) { export function dialogWrapper(str) {
return `<el-dialog v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" title="Dialog Titile"> return `<el-dialog v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" title="Dialog Title">
${str} ${str}
<div slot="footer"> <div slot="footer">
<el-button @click="close">取消</el-button> <el-button @click="close">取消</el-button>
<el-button type="primary" @click="handelConfirm">确定</el-button> <el-button type="primary" @click="handleConfirm">确定</el-button>
</div> </div>
</el-dialog>` </el-dialog>`
} }

View File

@ -98,7 +98,7 @@ function mixinMethod(type) {
close: `close() { close: `close() {
this.$emit('update:visible', false) this.$emit('update:visible', false)
},`, },`,
handelConfirm: `handelConfirm() { handleConfirm: `handleConfirm() {
this.$refs['${confGlobal.formRef}'].validate(valid => { this.$refs['${confGlobal.formRef}'].validate(valid => {
if(!valid) return if(!valid) return
this.close() this.close()

View File

@ -4,9 +4,12 @@ import store from '@/store'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode' import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi"; import { tansParams, blobValidate } from "@/utils/ruoyi";
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver' import { saveAs } from 'file-saver'
let downloadLoadingInstance; let downloadLoadingInstance;
// 是否显示重新登录
let isReloginShow;
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 对应国际化资源文件后缀 // 对应国际化资源文件后缀
@ -23,6 +26,8 @@ const service = axios.create({
service.interceptors.request.use(config => { service.interceptors.request.use(config => {
// 是否需要设置 token // 是否需要设置 token
const isToken = (config.headers || {}).isToken === false const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
if (getToken() && !isToken) { if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
} }
@ -33,6 +38,29 @@ service.interceptors.request.use(config => {
config.params = {}; config.params = {};
config.url = url; config.url = url;
} }
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
const sessionObj = cache.session.getJSON('sessionObj')
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
cache.session.setJSON('sessionObj', requestObj)
} else {
const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
const message = '数据正在处理,请勿重复提交';
console.warn(`[${s_url}]: ` + message)
return Promise.reject(new Error(message))
} else {
cache.session.setJSON('sessionObj', requestObj)
}
}
}
return config return config
}, error => { }, error => {
console.log(error) console.log(error)
@ -50,16 +78,25 @@ service.interceptors.response.use(res => {
return res.data return res.data
} }
if (code === 401) { if (code === 401) {
if (!isReloginShow) {
isReloginShow = true;
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录', confirmButtonText: '重新登录',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
} }
).then(() => { ).then(() => {
isReloginShow = false;
store.dispatch('LogOut').then(() => { store.dispatch('LogOut').then(() => {
// 如果是登录页面不需要重新加载
if (window.location.hash.indexOf("#/login") != 0) {
location.href = process.env.VUE_APP_CONTEXT_PATH + "index"; location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
}
}) })
}).catch(() => {}); }).catch(() => {
isReloginShow = false;
});
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。') return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) { } else if (code === 500) {
Message({ Message({

View File

@ -1,3 +1,5 @@
/** /**
* 通用js方法封装处理 * 通用js方法封装处理
* Copyright (c) 2019 ruoyi * Copyright (c) 2019 ruoyi
@ -16,7 +18,7 @@ export function parseTime(time, pattern) {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time) time = parseInt(time)
} else if (typeof time === 'string') { } else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm),''); time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
} }
if ((typeof time === 'number') && (time.toString().length === 10)) { if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000 time = time * 1000
@ -80,6 +82,9 @@ export function selectDictLabel(datas, value) {
// 回显数据字典(字符串数组) // 回显数据字典(字符串数组)
export function selectDictLabels(datas, value, separator) { export function selectDictLabels(datas, value, separator) {
if(value === undefined) {
return "";
}
var actions = []; var actions = [];
var currentSeparator = undefined === separator ? "," : separator; var currentSeparator = undefined === separator ? "," : separator;
var temp = value.split(currentSeparator); var temp = value.split(currentSeparator);
@ -108,7 +113,7 @@ export function sprintf(str) {
} }
// 转换字符串undefined,null等转化为"" // 转换字符串undefined,null等转化为""
export function praseStrEmpty(str) { export function parseStrEmpty(str) {
if (!str || str == "undefined" || str == "null") { if (!str || str == "undefined" || str == "null") {
return ""; return "";
} }
@ -124,7 +129,7 @@ export function mergeRecursive(source, target) {
} else { } else {
source[p] = target[p]; source[p] = target[p];
} }
} catch(e) { } catch (e) {
source[p] = target[p]; source[p] = target[p];
} }
} }

View File

@ -101,6 +101,70 @@
<span>更新日志</span> <span>更新日志</span>
</div> </div>
<el-collapse accordion> <el-collapse accordion>
<el-collapse-item title="v4.0.0 - 2022-02-18">
<ol>
<li>[重大更新] 重写项目整体结构 数据处理下沉至Mapper符合MVC规范 减少循环依赖</li>
<li>[重磅更新] 主分支与satoken分支合并 权限统一使用 sa-token</li>
<li>[重磅更新] 适配升级 SpringBoot 2.6</li>
<li>[重磅更新] EasyExcel大版本升级3.X</li>
<li>[重磅更新] 移除链式调用注解 因链式调用不符合java规范 导致很多问题</li>
<li>[重磅更新] 增加 轻量级 分布式队列 支持</li>
<li>[重磅更新] 增加 数据脱敏注解 使用序列化控制脱敏 支持多种表达式</li>
<li>[重磅更新] 重构 使用 Spring 简化 oss 模块代码</li>
<li>[重磅更新] 重构 调整返回类型为 R 精简 Controller 代码</li>
<li>update springboot 2.5.8 => 2.6.3</li>
<li>update mybatis-plus 3.4.3.4 => 3.5.1</li>
<li>update maven-jar-plugin 3.2.0 => 3.2.2</li>
<li>update maven-war-plugin 3.2.0 => 3.2.2</li>
<li>update maven-compiler-plugin 3.1 => 3.9.0</li>
<li>update hutool 5.7.18 => 5.7.20</li>
<li>update springboot-admin 2.6.0 => 2.6.2</li>
<li>update redisson 3.16.7 => 3.16.8</li>
<li>update qiniu 7.9.0 => 7.9.2</li>
<li>update aliyun 3.13.1 => 3.14.0</li>
<li>update qcloud 5.6.58 => 5.6.68</li>
<li>update minio 8.3.4 => 8.3.5</li>
<li>update 用户管理部门查询选择节点后分页参数初始</li>
<li>update 防重复提交标识组合key + url + header</li>
<li>update 接口文档增加 basic 账号密码验证</li>
<li>update 用户修改减少一次角色列表关联查询</li>
<li>update 优化部门修改缩放后出现的错位问题</li>
<li>update 指定 maven 资源过滤为具体文件 防止错误过滤</li>
<li>update hutool 引入改为 bom 依赖项引入</li>
<li>update 降低开发环境 redis连接池数量</li>
<li>update 升级 springboot 2.6.X 解决 springfox 兼容性问题</li>
<li>update 优化多用户体系处理 更名 LoginUtils LoginHelper 支持 LoginUser 多级缓存</li>
<li>update 优化加载字典缓存数据</li>
<li>update 数据库更改 对接多用户体系</li>
<li>update 移除掉 StringUtils 语义不明确的api方法 使用特定工具替换</li>
<li>update 优化登录注册在接口通过`@Validated`注解进行数据基础校验</li>
<li>update 优化 查询登录用户数据 统一走缓存</li>
<li>update 优化 redisson 配置 去除掉不常用的配置 使用默认配置</li>
<li>update 用户访问控制时校验数据权限防止越权</li>
<li>update 修改用户注册报未登录警告</li>
<li>update 调整oss预览开关 使用前端直接调用更改配置参数</li>
<li>update 使用 satoken 自带的 BCrypt 工具 替换 Security 加密工具 减少依赖</li>
<li>update 优化 TreeBuildUtils 工具 使用反射自动获取顶级父id</li>
<li>update 使用 hutool Dict 优化 JsonUtils 防止类型解析异常</li>
<li>update 优化代码生成 使用新 JsonUtils.parseMap 方法</li>
<li>update 更新 所有 oss 均支持 https 配置</li>
<li>add 增加 RedisUtils 工具 hasKey 检查key存在方法</li>
<li>add 增加 监控中心 自定义事件通知</li>
<li>add 增加 3.X update 4.0 更新sql</li>
<li>fix 修复登录失效后多次请求提示多次弹窗问题</li>
<li>fix 修复 StringUtils 通配符匹配无效</li>
<li>fix 修复选项卡点击右键刷新丢失参数问题</li>
<li>fix 修复 数据权限 缓存方法名错误问题</li>
<li>fix 修复自定义组件`file-upload`无法显示第一个文件列表显示的文件比实际文件少一个的问题</li>
<li>fix 修复因升级 sa-token 导致 doLogin 无法获取 token 问题</li>
<li>fix 修复分页组件请求两次问题</li>
<li>remove 移除过期代码 分页工具相关</li>
<li>remove 移除过期代码 多数据源切换</li>
<li>remove 移除过期代码 数据权限</li>
<li>3.X 版本进入维护阶段 不进行更新 只修复bug 持续维护到2022年10月</li>
<li>4.X 版本公测将近一个月 大部分bug已修复 官网主分支更改为 4.X 版本 推荐使用</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.5.0 - 2021-12-28"> <el-collapse-item title="v3.5.0 - 2021-12-28">
<ol> <ol>
<li>[重大更新] 重写数据权限实现</li> <li>[重大更新] 重写数据权限实现</li>
@ -644,7 +708,7 @@ export default {
data() { data() {
return { return {
// //
version: "3.5.0", version: "4.0.0",
}; };
}, },
methods: { methods: {

View File

@ -56,7 +56,7 @@
</el-form> </el-form>
<!-- 底部 --> <!-- 底部 -->
<div class="el-login-footer"> <div class="el-login-footer">
<span>Copyright © 2018-2021 ruoyi.vip All Rights Reserved.</span> <span>Copyright © 2018-2022 ruoyi.vip All Rights Reserved.</span>
</div> </div>
</div> </div>
</template> </template>

View File

@ -61,7 +61,7 @@
</el-form> </el-form>
<!-- 底部 --> <!-- 底部 -->
<div class="el-register-footer"> <div class="el-register-footer">
<span>Copyright © 2018-2021 ruoyi.vip All Rights Reserved.</span> <span>Copyright © 2018-2022 ruoyi.vip All Rights Reserved.</span>
</div> </div>
</div> </div>
</template> </template>
@ -124,7 +124,9 @@ export default {
this.$refs.registerForm.validate(valid => { this.$refs.registerForm.validate(valid => {
if (valid) { if (valid) {
this.loading = true; this.loading = true;
register(this.registerForm).then(res => { let registerForm = this.registerForm;
registerForm.userType = "sys_user"
register(registerForm).then(res => {
const username = this.registerForm.username; const username = this.registerForm.username;
this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', { this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
dangerouslyUseHTMLString: true, dangerouslyUseHTMLString: true,

View File

@ -106,6 +106,8 @@
<treeselect v-model="form.parentId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级部门" /> <treeselect v-model="form.parentId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级部门" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="部门名称" prop="deptName"> <el-form-item label="部门名称" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入部门名称" /> <el-input v-model="form.deptName" placeholder="请输入部门名称" />
@ -116,6 +118,8 @@
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" /> <el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="负责人" prop="leader"> <el-form-item label="负责人" prop="leader">
<el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20" /> <el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20" />
@ -126,6 +130,8 @@
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" /> <el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="邮箱" prop="email"> <el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" /> <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />

View File

@ -187,7 +187,7 @@
</template> </template>
<script> <script>
import { listOss, delOss, changePreviewListResource } from "@/api/system/oss"; import { listOss, delOss } from "@/api/system/oss";
export default { export default {
name: "Oss", name: "Oss",
@ -344,7 +344,7 @@ export default {
handlePreviewListResource(previewListResource) { handlePreviewListResource(previewListResource) {
let text = previewListResource ? "启用" : "停用"; let text = previewListResource ? "启用" : "停用";
this.$modal.confirm('确认要"' + text + '""预览列表图片"配置吗?').then(() => { this.$modal.confirm('确认要"' + text + '""预览列表图片"配置吗?').then(() => {
return changePreviewListResource(previewListResource); return this.updateConfigByKey("sys.oss.previewListResource", previewListResource);
}).then(() => { }).then(() => {
this.getList() this.getList()
this.$modal.msgSuccess(text + "成功"); this.$modal.msgSuccess(text + "成功");

View File

@ -495,7 +495,7 @@ export default {
// //
handleNodeClick(data) { handleNodeClick(data) {
this.queryParams.deptId = data.id; this.queryParams.deptId = data.id;
this.getList(); this.handleQuery();
}, },
// //
handleStatusChange(row) { handleStatusChange(row) {

View File

@ -41,7 +41,7 @@
<el-button @click="close"> <el-button @click="close">
取消 取消
</el-button> </el-button>
<el-button type="primary" @click="handelConfirm"> <el-button type="primary" @click="handleConfirm">
确定 确定
</el-button> </el-button>
</div> </div>
@ -94,7 +94,7 @@ export default {
close(e) { close(e) {
this.$emit('update:visible', false) this.$emit('update:visible', false)
}, },
handelConfirm() { handleConfirm() {
this.$refs.elForm.validate(valid => { this.$refs.elForm.validate(valid => {
if (!valid) return if (!valid) return
this.$emit('confirm', { ...this.formData }) this.$emit('confirm', { ...this.formData })

View File

@ -59,7 +59,7 @@
<div slot="footer"> <div slot="footer">
<el-button <el-button
type="primary" type="primary"
@click="handelConfirm" @click="handleConfirm"
> >
确定 确定
</el-button> </el-button>
@ -133,7 +133,7 @@ export default {
close() { close() {
this.$emit('update:visible', false) this.$emit('update:visible', false)
}, },
handelConfirm() { handleConfirm() {
this.$refs.elForm.validate(valid => { this.$refs.elForm.validate(valid => {
if (!valid) return if (!valid) return
if (this.dataType === 'number') { if (this.dataType === 'number') {

View File

@ -146,7 +146,7 @@ import { beautifierConf, titleCase } from '@/utils/index'
import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html' import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html'
import { makeUpJs } from '@/utils/generator/js' import { makeUpJs } from '@/utils/generator/js'
import { makeUpCss } from '@/utils/generator/css' import { makeUpCss } from '@/utils/generator/css'
import drawingDefalut from '@/utils/generator/drawingDefalut' import drawingDefault from '@/utils/generator/drawingDefault'
import logo from '@/assets/logo/logo.png' import logo from '@/assets/logo/logo.png'
import CodeTypeDialog from './CodeTypeDialog' import CodeTypeDialog from './CodeTypeDialog'
import DraggableItem from './DraggableItem' import DraggableItem from './DraggableItem'
@ -171,15 +171,15 @@ export default {
selectComponents, selectComponents,
layoutComponents, layoutComponents,
labelWidth: 100, labelWidth: 100,
drawingList: drawingDefalut, drawingList: drawingDefault,
drawingData: {}, drawingData: {},
activeId: drawingDefalut[0].formId, activeId: drawingDefault[0].formId,
drawerVisible: false, drawerVisible: false,
formData: {}, formData: {},
dialogVisible: false, dialogVisible: false,
generateConf: null, generateConf: null,
showFileName: false, showFileName: false,
activeData: drawingDefalut[0] activeData: drawingDefault[0]
} }
}, },
created() { created() {

View File

@ -33,6 +33,7 @@
<el-option label="Double" value="Double" /> <el-option label="Double" value="Double" />
<el-option label="BigDecimal" value="BigDecimal" /> <el-option label="BigDecimal" value="BigDecimal" />
<el-option label="Date" value="Date" /> <el-option label="Date" value="Date" />
<el-option label="Boolean" value="Boolean" />
</el-select> </el-select>
</template> </template>
</el-table-column> </el-table-column>
@ -158,7 +159,7 @@ export default {
}; };
}, },
created() { created() {
const tableId = this.$route.query && this.$route.query.tableId; const tableId = this.$route.params && this.$route.params.tableId;
if (tableId) { if (tableId) {
// //
getGenTable(tableId).then(res => { getGenTable(tableId).then(res => {

View File

@ -321,7 +321,7 @@ export default {
/** 修改按钮操作 */ /** 修改按钮操作 */
handleEditTable(row) { handleEditTable(row) {
const tableId = row.tableId || this.ids[0]; const tableId = row.tableId || this.ids[0];
this.$router.push({ path: '/tool/gen-edit/index', query: { tableId: tableId, pageNum: this.queryParams.pageNum } }); this.$router.push({ path: '/tool/gen-edit/index/' + tableId, query: { pageNum: this.queryParams.pageNum } });
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.5.0</version> <version>4.0.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -73,10 +73,15 @@
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
</dependency> </dependency>
<!-- spring security 安全认证 --> <!-- Sa-Token 权限认证, 在线文档http://sa-token.dev33.cn/ -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>cn.dev33</groupId>
<artifactId>spring-boot-starter-security</artifactId> <artifactId>sa-token-spring-boot-starter</artifactId>
</dependency>
<!-- Sa-Token 整合 jwt -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -1,32 +0,0 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.*;
/**
* 数据权限过滤注解
*
* @author ruoyi
* @deprecated 3.6.0 移除 {@link com.ruoyi.common.annotation.DataPermission}
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Deprecated
public @interface DataScope {
/**
* 部门表的别名
*/
String deptAlias() default "";
/**
* 用户表的别名
*/
String userAlias() default "";
/**
* 是否过滤用户权限
*/
boolean isUser() default false;
}

View File

@ -1,25 +0,0 @@
package com.ruoyi.common.annotation;
import com.ruoyi.common.enums.DataSourceType;
import java.lang.annotation.*;
/**
* 自定义多数据源切换注解
* <p>
* 优先级先方法后类如果方法覆盖了类上的数据源类型以方法的为准否则以类上的为准
*
* @author ruoyi
* @deprecated 3.6.0 移除 使用原生注解处理 方法更全 {@link com.baomidou.dynamic.datasource.annotation.DS}
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Deprecated
public @interface DataSource {
/**
* 切换数据源名称
*/
DataSourceType value() default DataSourceType.MASTER;
}

View File

@ -0,0 +1,24 @@
package com.ruoyi.common.annotation;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.ruoyi.common.enums.SensitiveStrategy;
import com.ruoyi.common.jackson.SensitiveJsonSerializer;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 数据脱敏注解
*
* @author zhujie
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive {
SensitiveStrategy strategy();
}

View File

@ -15,7 +15,7 @@ public class UnsignedMathGenerator implements CodeGenerator {
private static final long serialVersionUID = -5514819971774091076L; private static final long serialVersionUID = -5514819971774091076L;
private static final String operators = "+-*"; private static final String OPERATORS = "+-*";
/** /**
* 参与计算数字最大长度 * 参与计算数字最大长度
@ -48,7 +48,7 @@ public class UnsignedMathGenerator implements CodeGenerator {
number1 = StringUtils.rightPad(number1, this.numberLength, CharUtil.SPACE); number1 = StringUtils.rightPad(number1, this.numberLength, CharUtil.SPACE);
number2 = StringUtils.rightPad(number2, this.numberLength, CharUtil.SPACE); number2 = StringUtils.rightPad(number2, this.numberLength, CharUtil.SPACE);
return number1 + RandomUtil.randomChar(operators) + number2 + '='; return number1 + RandomUtil.randomChar(OPERATORS) + number2 + '=';
} }
@Override @Override

View File

@ -2,7 +2,6 @@ package com.ruoyi.common.config;
import lombok.Data; import lombok.Data;
import lombok.Getter; import lombok.Getter;
import lombok.experimental.Accessors;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -13,7 +12,6 @@ import org.springframework.stereotype.Component;
*/ */
@Data @Data
@Accessors(chain = true)
@Component @Component
@ConfigurationProperties(prefix = "ruoyi") @ConfigurationProperties(prefix = "ruoyi")
public class RuoYiConfig { public class RuoYiConfig {

View File

@ -1,6 +1,5 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
/** /**
* 通用常量信息 * 通用常量信息
* *
@ -66,7 +65,12 @@ public interface Constants {
/** /**
* 登录用户 redis key * 登录用户 redis key
*/ */
String LOGIN_TOKEN_KEY = "login_tokens:"; public static final String LOGIN_TOKEN_KEY = "Authorization:login:token:";
/**
* 在线用户 redis key
*/
public static final String ONLINE_TOKEN_KEY = "online_tokens:";
/** /**
* 防重提交 redis key * 防重提交 redis key
@ -103,41 +107,11 @@ public interface Constants {
*/ */
String TOKEN = "token"; String TOKEN = "token";
/**
* 令牌前缀
*/
String TOKEN_PREFIX = "Bearer ";
/** /**
* 令牌前缀 * 令牌前缀
*/ */
String LOGIN_USER_KEY = "login_user_key"; String LOGIN_USER_KEY = "login_user_key";
/**
* 用户ID
*/
String JWT_USERID = "userid";
/**
* 用户名称
*/
String JWT_USERNAME = "sub";
/**
* 用户头像
*/
String JWT_AVATAR = "avatar";
/**
* 创建时间
*/
String JWT_CREATED = "created";
/**
* 用户权限
*/
String JWT_AUTHORITIES = "authorities";
/** /**
* 参数管理 cache key * 参数管理 cache key
*/ */
@ -149,3 +123,4 @@ public interface Constants {
String SYS_DICT_KEY = "sys_dict:"; String SYS_DICT_KEY = "sys_dict:";
} }

View File

@ -181,6 +181,11 @@ public interface GenConstants {
*/ */
String QUERY_LIKE = "LIKE"; String QUERY_LIKE = "LIKE";
/**
* 相等查询
*/
String QUERY_EQ = "EQ";
/** /**
* 需要 * 需要
*/ */

View File

@ -4,8 +4,9 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -31,19 +32,19 @@ public class ExcelBigNumberConvert implements Converter<Long> {
} }
@Override @Override
public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
return Convert.toLong(cellData.getData()); return Convert.toLong(cellData.getData());
} }
@Override @Override
public CellData<Object> convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { public WriteCellData<Object> convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (ObjectUtil.isNotNull(object)) { if (ObjectUtil.isNotNull(object)) {
String str = Convert.toStr(object); String str = Convert.toStr(object);
if (str.length() > 15) { if (str.length() > 15) {
return new CellData<>(str); return new WriteCellData<>(str);
} }
} }
CellData<Object> cellData = new CellData<>(new BigDecimal(object)); WriteCellData<Object> cellData = new WriteCellData<>(new BigDecimal(object));
cellData.setType(CellDataTypeEnum.NUMBER); cellData.setType(CellDataTypeEnum.NUMBER);
return cellData; return cellData;
} }

View File

@ -2,10 +2,12 @@ package com.ruoyi.common.convert;
import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.ruoyi.common.annotation.ExcelDictFormat; import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.core.service.DictService; import com.ruoyi.common.core.service.DictService;
@ -35,7 +37,7 @@ public class ExcelDictConvert implements Converter<Object> {
} }
@Override @Override
public Object convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
ExcelDictFormat anno = getAnnotation(contentProperty.getField()); ExcelDictFormat anno = getAnnotation(contentProperty.getField());
String type = anno.dictType(); String type = anno.dictType();
String label = cellData.getStringValue(); String label = cellData.getStringValue();
@ -49,9 +51,9 @@ public class ExcelDictConvert implements Converter<Object> {
} }
@Override @Override
public CellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
if (StringUtils.isNull(object)) { if (ObjectUtil.isNull(object)) {
return new CellData<>(""); return new WriteCellData<>("");
} }
ExcelDictFormat anno = getAnnotation(contentProperty.getField()); ExcelDictFormat anno = getAnnotation(contentProperty.getField());
String type = anno.dictType(); String type = anno.dictType();
@ -62,7 +64,7 @@ public class ExcelDictConvert implements Converter<Object> {
} else { } else {
label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator()); label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator());
} }
return new CellData<>(label); return new WriteCellData<>(label);
} }
private ExcelDictFormat getAnnotation(Field field) { private ExcelDictFormat getAnnotation(Field field) {

View File

@ -1,53 +1,25 @@
package com.ruoyi.common.core.controller; package com.ruoyi.common.core.controller;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* web层通用数据处理 * web层通用数据处理
* *
* @author ruoyi * @author Lion Li
*/ */
public class BaseController { public class BaseController {
/**
* 返回成功
*/
public AjaxResult<Void> success() {
return AjaxResult.success();
}
/**
* 返回失败消息
*/
public AjaxResult<Void> error() {
return AjaxResult.error();
}
/**
* 返回成功消息
*/
public AjaxResult<Void> success(String message) {
return AjaxResult.success(message);
}
/**
* 返回失败消息
*/
public AjaxResult<Void> error(String message) {
return AjaxResult.error(message);
}
/** /**
* 响应返回结果 * 响应返回结果
* *
* @param rows 影响行数 * @param rows 影响行数
* @return 操作结果 * @return 操作结果
*/ */
protected AjaxResult<Void> toAjax(int rows) { protected R<Void> toAjax(int rows) {
return rows > 0 ? AjaxResult.success() : AjaxResult.error(); return rows > 0 ? R.ok() : R.fail();
} }
/** /**
@ -56,8 +28,8 @@ public class BaseController {
* @param result 结果 * @param result 结果
* @return 操作结果 * @return 操作结果
*/ */
protected AjaxResult<Void> toAjax(boolean result) { protected R<Void> toAjax(boolean result) {
return result ? success() : error(); return result ? R.ok() : R.fail();
} }
/** /**
@ -71,27 +43,27 @@ public class BaseController {
* 获取用户缓存信息 * 获取用户缓存信息
*/ */
public LoginUser getLoginUser() { public LoginUser getLoginUser() {
return SecurityUtils.getLoginUser(); return LoginHelper.getLoginUser();
} }
/** /**
* 获取登录用户id * 获取登录用户id
*/ */
public Long getUserId() { public Long getUserId() {
return getLoginUser().getUserId(); return LoginHelper.getUserId();
} }
/** /**
* 获取登录部门id * 获取登录部门id
*/ */
public Long getDeptId() { public Long getDeptId() {
return getLoginUser().getDeptId(); return LoginHelper.getDeptId();
} }
/** /**
* 获取登录用户名 * 获取登录用户名
*/ */
public String getUsername() { public String getUsername() {
return getLoginUser().getUsername(); return LoginHelper.getUsername();
} }
} }

View File

@ -1,134 +0,0 @@
package com.ruoyi.common.core.domain;
import cn.hutool.http.HttpStatus;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 操作消息提醒
*
* @author Lion Li
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ApiModel("请求响应对象")
public class AjaxResult<T> {
private static final long serialVersionUID = 1L;
/**
* 状态码
*/
@ApiModelProperty("消息状态码")
private int code;
/**
* 返回内容
*/
@ApiModelProperty("消息内容")
private String msg;
/**
* 数据对象
*/
@ApiModelProperty("数据对象")
private T data;
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param code 状态码
* @param msg 返回内容
*/
public AjaxResult(int code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static AjaxResult<Void> success() {
return AjaxResult.success("操作成功");
}
/**
* 返回成功数据
*
* @return 成功消息
*/
public static <T> AjaxResult<T> success(T data) {
return AjaxResult.success("操作成功", data);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @return 成功消息
*/
public static AjaxResult<Void> success(String msg) {
return AjaxResult.success(msg, null);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
*/
public static <T> AjaxResult<T> success(String msg, T data) {
return new AjaxResult<>(HttpStatus.HTTP_OK, msg, data);
}
/**
* 返回错误消息
*
* @return
*/
public static AjaxResult<Void> error() {
return AjaxResult.error("操作失败");
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult<Void> error(String msg) {
return AjaxResult.error(msg, null);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static <T> AjaxResult<T> error(String msg, T data) {
return new AjaxResult<>(HttpStatus.HTTP_INTERNAL_ERROR, msg, data);
}
/**
* 返回错误消息
*
* @param code 状态码
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult<Void> error(int code, String msg) {
return new AjaxResult<>(code, msg, null);
}
}

View File

@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
@ -18,7 +17,6 @@ import java.util.Map;
*/ */
@Data @Data
@Accessors(chain = true)
public class BaseEntity implements Serializable { public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -7,7 +7,6 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil; import com.ruoyi.common.utils.sql.SqlUtil;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable; import java.io.Serializable;
@ -18,7 +17,6 @@ import java.io.Serializable;
*/ */
@Data @Data
@Accessors(chain = true)
public class PageQuery implements Serializable { public class PageQuery implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -0,0 +1,84 @@
package com.ruoyi.common.core.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 响应信息主体
*
* @author Lion Li
*/
@Data
@NoArgsConstructor
@ApiModel("请求响应对象")
public class R<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 成功
*/
public static final int SUCCESS = 200;
/**
* 失败
*/
public static final int FAIL = 500;
@ApiModelProperty("消息状态码")
private int code;
@ApiModelProperty("消息内容")
private String msg;
@ApiModelProperty("数据对象")
private T data;
public static <T> R<T> ok() {
return restResult(null, SUCCESS, null);
}
public static <T> R<T> ok(T data) {
return restResult(data, SUCCESS, null);
}
public static <T> R<T> ok(String msg) {
return restResult(null, SUCCESS, msg);
}
public static <T> R<T> ok(String msg, T data) {
return restResult(data, SUCCESS, msg);
}
public static <T> R<T> fail() {
return restResult(null, FAIL, null);
}
public static <T> R<T> fail(String msg) {
return restResult(null, FAIL, msg);
}
public static <T> R<T> fail(T data) {
return restResult(data, FAIL, null);
}
public static <T> R<T> fail(String msg, T data) {
return restResult(data, FAIL, msg);
}
public static <T> R<T> fail(int code, String msg) {
return restResult(null, code, msg);
}
private static <T> R<T> restResult(T data, int code, String msg) {
R<T> r = new R<>();
r.setCode(code);
r.setData(data);
r.setMsg(msg);
return r;
}
}

View File

@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -17,7 +16,6 @@ import java.util.List;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class TreeEntity extends BaseEntity { public class TreeEntity extends BaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -1,8 +1,6 @@
package com.ruoyi.common.core.domain.dto; package com.ruoyi.common.core.domain.dto;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
@ -14,8 +12,6 @@ import java.util.Date;
*/ */
@Data @Data
@NoArgsConstructor
@Accessors(chain = true)
public class OperLogDTO implements Serializable { public class OperLogDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -0,0 +1,38 @@
package com.ruoyi.common.core.domain.dto;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 角色
*
* @author Lion Li
*/
@Data
@NoArgsConstructor
public class RoleDTO implements Serializable {
/**
* 角色ID
*/
private Long roleId;
/**
* 角色名称
*/
private String roleName;
/**
* 角色权限
*/
private String roleKey;
/**
* 数据范围1所有数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限5仅本人数据权限
*/
private String dataScope;
}

View File

@ -0,0 +1,61 @@
package com.ruoyi.common.core.domain.dto;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 当前在线会话
*
* @author ruoyi
*/
@Data
@NoArgsConstructor
public class UserOnlineDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 会话编号
*/
private String tokenId;
/**
* 部门名称
*/
private String deptName;
/**
* 用户名称
*/
private String userName;
/**
* 登录IP地址
*/
private String ipaddr;
/**
* 登录地址
*/
private String loginLocation;
/**
* 浏览器类型
*/
private String browser;
/**
* 操作系统
*/
private String os;
/**
* 登录时间
*/
private Long loginTime;
}

View File

@ -8,10 +8,10 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.Email; import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
/** /**
@ -22,7 +22,6 @@ import javax.validation.constraints.Size;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("sys_dept") @TableName("sys_dept")
@ApiModel("部门业务对象") @ApiModel("部门业务对象")
public class SysDept extends TreeEntity { public class SysDept extends TreeEntity {
@ -47,8 +46,8 @@ public class SysDept extends TreeEntity {
* 显示顺序 * 显示顺序
*/ */
@ApiModelProperty(value = "显示顺序") @ApiModelProperty(value = "显示顺序")
@NotBlank(message = "显示顺序不能为空") @NotNull(message = "显示顺序不能为空")
private String orderNum; private Long orderNum;
/** /**
* 负责人 * 负责人

View File

@ -12,7 +12,6 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
@ -25,7 +24,6 @@ import javax.validation.constraints.Size;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("sys_dict_data") @TableName("sys_dict_data")
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated
@ApiModel("字典数据业务对象") @ApiModel("字典数据业务对象")

View File

@ -24,7 +24,6 @@ import javax.validation.constraints.Size;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("sys_dict_type") @TableName("sys_dict_type")
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated
@ApiModel("字典类型业务对象") @ApiModel("字典类型业务对象")

View File

@ -8,9 +8,9 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
/** /**
@ -21,7 +21,6 @@ import javax.validation.constraints.Size;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("sys_menu") @TableName("sys_menu")
@ApiModel("菜单权限业务对象") @ApiModel("菜单权限业务对象")
public class SysMenu extends TreeEntity { public class SysMenu extends TreeEntity {
@ -45,8 +44,8 @@ public class SysMenu extends TreeEntity {
* 显示顺序 * 显示顺序
*/ */
@ApiModelProperty(value = "显示顺序") @ApiModelProperty(value = "显示顺序")
@NotBlank(message = "显示顺序不能为空") @NotNull(message = "显示顺序不能为空")
private String orderNum; private Long orderNum;
/** /**
* 路由地址 * 路由地址

View File

@ -13,7 +13,6 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
@ -27,7 +26,6 @@ import javax.validation.constraints.Size;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("sys_role") @TableName("sys_role")
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated
public class SysRole extends BaseEntity { public class SysRole extends BaseEntity {

View File

@ -3,14 +3,15 @@ package com.ruoyi.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.common.annotation.Sensitive;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.enums.SensitiveStrategy;
import com.ruoyi.common.xss.Xss; import com.ruoyi.common.xss.Xss;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import javax.validation.constraints.Email; import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
@ -27,7 +28,6 @@ import java.util.List;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("sys_user") @TableName("sys_user")
@ApiModel("用户信息业务对象") @ApiModel("用户信息业务对象")
public class SysUser extends BaseEntity { public class SysUser extends BaseEntity {
@ -62,9 +62,16 @@ public class SysUser extends BaseEntity {
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
private String nickName; private String nickName;
/**
* 用户类型sys_user系统用户
*/
@ApiModelProperty(value = "用户类型")
private String userType;
/** /**
* 用户邮箱 * 用户邮箱
*/ */
@Sensitive(strategy = SensitiveStrategy.EMAIL)
@ApiModelProperty(value = "用户邮箱") @ApiModelProperty(value = "用户邮箱")
@Email(message = "邮箱格式不正确") @Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
@ -73,6 +80,7 @@ public class SysUser extends BaseEntity {
/** /**
* 手机号码 * 手机号码
*/ */
@Sensitive(strategy = SensitiveStrategy.PHONE)
@ApiModelProperty(value = "手机号码") @ApiModelProperty(value = "手机号码")
private String phonenumber; private String phonenumber;

View File

@ -1,9 +1,12 @@
package com.ruoyi.common.core.domain.model; package com.ruoyi.common.core.domain.model;
import com.ruoyi.common.constant.UserConstants;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
/** /**
* 用户登录对象 * 用户登录对象
@ -12,19 +15,22 @@ import lombok.experimental.Accessors;
*/ */
@Data @Data
@Accessors(chain = true)
@ApiModel("用户登录对象") @ApiModel("用户登录对象")
public class LoginBody { public class LoginBody {
/** /**
* 用户名 * 用户名
*/ */
@NotBlank(message = "{user.username.not.blank}")
@Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
@ApiModelProperty(value = "用户名") @ApiModelProperty(value = "用户名")
private String username; private String username;
/** /**
* 用户密码 * 用户密码
*/ */
@NotBlank(message = "{user.password.not.blank}")
@Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
@ApiModelProperty(value = "用户密码") @ApiModelProperty(value = "用户密码")
private String password; private String password;
@ -38,6 +44,6 @@ public class LoginBody {
* 唯一标识 * 唯一标识
*/ */
@ApiModelProperty(value = "唯一标识") @ApiModelProperty(value = "唯一标识")
private String uuid = ""; private String uuid;
} }

View File

@ -1,13 +1,12 @@
package com.ruoyi.common.core.domain.model; package com.ruoyi.common.core.domain.model;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.ruoyi.common.core.domain.dto.RoleDTO;
import com.ruoyi.common.helper.LoginHelper;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection; import java.io.Serializable;
import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
@ -18,8 +17,7 @@ import java.util.Set;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@Accessors(chain = true) public class LoginUser implements Serializable {
public class LoginUser implements UserDetails {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -33,11 +31,21 @@ public class LoginUser implements UserDetails {
*/ */
private Long deptId; private Long deptId;
/**
* 部门名
*/
private String deptName;
/** /**
* 用户唯一标识 * 用户唯一标识
*/ */
private String token; private String token;
/**
* 用户类型
*/
private String userType;
/** /**
* 登录时间 * 登录时间
*/ */
@ -71,12 +79,12 @@ public class LoginUser implements UserDetails {
/** /**
* 菜单权限 * 菜单权限
*/ */
private Set<String> menuPermissions; private Set<String> menuPermission;
/** /**
* 角色权限 * 角色权限
*/ */
private Set<String> rolePermissions; private Set<String> rolePermission;
/** /**
* 用户名 * 用户名
@ -84,59 +92,20 @@ public class LoginUser implements UserDetails {
private String username; private String username;
/** /**
* 密码 * 角色对象
*/ */
private String password; private List<RoleDTO> roles;
@JsonIgnore
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
/** /**
* 账户是否未过期,过期无法验证 * 数据权限 当前角色ID
*/ */
@JsonIgnore private Long roleId;
@Override
public boolean isAccountNonExpired() {
return true;
}
/** /**
* 指定用户是否解锁,锁定的用户无法进行身份验证 * 获取登录id
*/ */
@JsonIgnore public String getLoginId() {
@Override return userType + LoginHelper.JOIN_CODE + userId;
public boolean isAccountNonLocked() {
return true;
} }
/**
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
*/
@JsonIgnore
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 是否可用 ,禁用的用户不能身份验证
*/
@JsonIgnore
@Override
public boolean isEnabled() {
return true;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
} }

View File

@ -1,13 +1,21 @@
package com.ruoyi.common.core.domain.model; package com.ruoyi.common.core.domain.model;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/** /**
* 用户注册对象 * 用户注册对象
* *
* @author Lion Li * @author Lion Li
*/ */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("用户注册对象") @ApiModel("用户注册对象")
public class RegisterBody extends LoginBody { public class RegisterBody extends LoginBody {
@ApiModelProperty(value = "用户类型")
private String userType;
} }

View File

@ -0,0 +1,229 @@
package com.ruoyi.common.core.mapper;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.ruoyi.common.utils.BeanCopyUtils;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 自定义 Mapper 接口, 实现 自定义扩展
*
* @param <M> mapper 泛型
* @param <T> table 泛型
* @param <V> vo 泛型
* @author Lion Li
* @since 2021-05-13
*/
@SuppressWarnings("unchecked")
public interface BaseMapperPlus<M, T, V> extends BaseMapper<T> {
Log log = LogFactory.getLog(BaseMapperPlus.class);
int DEFAULT_BATCH_SIZE = 1000;
default Class<V> currentVoClass() {
return (Class<V>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 2);
}
default Class<T> currentModelClass() {
return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 1);
}
default Class<M> currentMapperClass() {
return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 0);
}
default List<T> selectList() {
return this.selectList(new QueryWrapper<>());
}
/**
* 批量插入
*/
default boolean insertBatch(Collection<T> entityList) {
return insertBatch(entityList, DEFAULT_BATCH_SIZE);
}
/**
* 批量更新
*/
default boolean updateBatchById(Collection<T> entityList) {
return updateBatchById(entityList, DEFAULT_BATCH_SIZE);
}
/**
* 批量插入或更新
*/
default boolean insertOrUpdateBatch(Collection<T> entityList) {
return insertOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE);
}
/**
* 批量插入(包含限制条数)
*/
default boolean insertBatch(Collection<T> entityList, int batchSize) {
String sqlStatement = SqlHelper.getSqlStatement(this.currentMapperClass(), SqlMethod.INSERT_ONE);
return SqlHelper.executeBatch(this.currentModelClass(), log, entityList, batchSize,
(sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
}
/**
* 批量更新(包含限制条数)
*/
default boolean updateBatchById(Collection<T> entityList, int batchSize) {
String sqlStatement = SqlHelper.getSqlStatement(this.currentMapperClass(), SqlMethod.UPDATE_BY_ID);
return SqlHelper.executeBatch(this.currentModelClass(), log, entityList, batchSize,
(sqlSession, entity) -> {
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
param.put(Constants.ENTITY, entity);
sqlSession.update(sqlStatement, param);
});
}
/**
* 批量插入或更新(包含限制条数)
*/
default boolean insertOrUpdateBatch(Collection<T> entityList, int batchSize) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(this.currentModelClass());
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
String keyProperty = tableInfo.getKeyProperty();
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
return SqlHelper.saveOrUpdateBatch(this.currentModelClass(), this.currentMapperClass(), log, entityList, batchSize, (sqlSession, entity) -> {
Object idVal = tableInfo.getPropertyValue(entity, keyProperty);
String sqlStatement = SqlHelper.getSqlStatement(this.currentMapperClass(), SqlMethod.SELECT_BY_ID);
return StringUtils.checkValNull(idVal)
|| CollectionUtils.isEmpty(sqlSession.selectList(sqlStatement, entity));
}, (sqlSession, entity) -> {
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
param.put(Constants.ENTITY, entity);
String sqlStatement = SqlHelper.getSqlStatement(this.currentMapperClass(), SqlMethod.UPDATE_BY_ID);
sqlSession.update(sqlStatement, param);
});
}
/**
* 插入或更新(包含限制条数)
*/
default boolean insertOrUpdate(T entity) {
if (null != entity) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(this.currentModelClass());
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
String keyProperty = tableInfo.getKeyProperty();
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
Object idVal = tableInfo.getPropertyValue(entity, tableInfo.getKeyProperty());
return StringUtils.checkValNull(idVal) || Objects.isNull(selectById((Serializable) idVal)) ? insert(entity) > 0 : updateById(entity) > 0;
}
return false;
}
default V selectVoById(Serializable id) {
return selectVoById(id, this.currentVoClass());
}
/**
* 根据 ID 查询
*/
default <C> C selectVoById(Serializable id, Class<C> voClass) {
T obj = this.selectById(id);
if (ObjectUtil.isNull(obj)) {
return null;
}
return BeanCopyUtils.copy(obj, voClass);
}
default List<V> selectVoById(Collection<? extends Serializable> idList) {
return selectVoBatchIds(idList, this.currentVoClass());
}
/**
* 查询根据ID 批量查询
*/
default <C> List<C> selectVoBatchIds(Collection<? extends Serializable> idList, Class<C> voClass) {
List<T> list = this.selectBatchIds(idList);
if (CollUtil.isEmpty(list)) {
return CollUtil.newArrayList();
}
return BeanCopyUtils.copyList(list, voClass);
}
default List<V> selectVoByMap(Map<String, Object> map) {
return selectVoByMap(map, this.currentVoClass());
}
/**
* 查询根据 columnMap 条件
*/
default <C> List<C> selectVoByMap(Map<String, Object> map, Class<C> voClass) {
List<T> list = this.selectByMap(map);
if (CollUtil.isEmpty(list)) {
return CollUtil.newArrayList();
}
return BeanCopyUtils.copyList(list, voClass);
}
default V selectVoOne(Wrapper<T> wrapper) {
return selectVoOne(wrapper, this.currentVoClass());
}
/**
* 根据 entity 条件查询一条记录
*/
default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass) {
T obj = this.selectOne(wrapper);
if (ObjectUtil.isNull(obj)) {
return null;
}
return BeanCopyUtils.copy(obj, voClass);
}
default List<V> selectVoList(Wrapper<T> wrapper) {
return selectVoList(wrapper, this.currentVoClass());
}
/**
* 根据 entity 条件查询全部记录
*/
default <C> List<C> selectVoList(Wrapper<T> wrapper, Class<C> voClass) {
List<T> list = this.selectList(wrapper);
if (CollUtil.isEmpty(list)) {
return CollUtil.newArrayList();
}
return BeanCopyUtils.copyList(list, voClass);
}
default <P extends IPage<V>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper) {
return selectVoPage(page, wrapper, this.currentVoClass());
}
/**
* 分页查询VO
*/
default <C, P extends IPage<C>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<C> voClass) {
IPage<T> pageData = this.selectPage(page, wrapper);
IPage<C> voPage = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal());
if (CollUtil.isEmpty(pageData.getRecords())) {
return (P) voPage;
}
voPage.setRecords(BeanCopyUtils.copyList(pageData.getRecords(), voClass));
return (P) voPage;
}
}

View File

@ -1,98 +0,0 @@
package com.ruoyi.common.core.mybatisplus.core;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.BeanCopyUtils;
import org.apache.ibatis.annotations.Param;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 自定义 Mapper 接口, 实现 自定义扩展
*
* @author Lion Li
* @since 2021-05-13
*/
public interface BaseMapperPlus<T> extends BaseMapper<T> {
/**
* 单sql批量插入( 全量填充 )
*/
int insertAll(@Param("list") Collection<T> batchList);
/**
* 根据 ID 查询
*/
default <V> V selectVoById(Serializable id, Class<V> voClass){
T obj = this.selectById(id);
if (ObjectUtil.isNull(obj)) {
return null;
}
return BeanCopyUtils.copy(obj, voClass);
}
/**
* 查询根据ID 批量查询
*/
default <V> List<V> selectVoBatchIds(Collection<? extends Serializable> idList, Class<V> voClass){
List<T> list = this.selectBatchIds(idList);
if (CollUtil.isEmpty(list)) {
return CollUtil.newArrayList();
}
return BeanCopyUtils.copyList(list, voClass);
}
/**
* 查询根据 columnMap 条件
*/
default <V> List<V> selectVoByMap(Map<String, Object> map, Class<V> voClass){
List<T> list = this.selectByMap(map);
if (CollUtil.isEmpty(list)) {
return CollUtil.newArrayList();
}
return BeanCopyUtils.copyList(list, voClass);
}
/**
* 根据 entity 条件查询一条记录
*/
default <V> V selectVoOne(Wrapper<T> wrapper, Class<V> voClass) {
T obj = this.selectOne(wrapper);
if (ObjectUtil.isNull(obj)) {
return null;
}
return BeanCopyUtils.copy(obj, voClass);
}
/**
* 根据 entity 条件查询全部记录
*/
default <V> List<V> selectVoList(Wrapper<T> wrapper, Class<V> voClass) {
List<T> list = this.selectList(wrapper);
if (CollUtil.isEmpty(list)) {
return CollUtil.newArrayList();
}
return BeanCopyUtils.copyList(list, voClass);
}
/**
* 分页查询VO
*/
default <V, P extends IPage<V>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<V> voClass) {
IPage<T> pageData = this.selectPage(page, wrapper);
IPage<V> voPage = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal());
if (CollUtil.isEmpty(pageData.getRecords())) {
return (P) voPage;
}
voPage.setRecords(BeanCopyUtils.copyList(pageData.getRecords(), voClass));
return (P) voPage;
}
}

View File

@ -1,155 +0,0 @@
package com.ruoyi.common.core.mybatisplus.core;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.core.page.PagePlus;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
* 自定义 Service 接口, 实现 数据库实体与 vo 对象转换返回
*
* @param <T> 数据实体类
* @param <V> vo类
* @author Lion Li
*/
public interface IServicePlus<T, V> extends IService<T> {
/**
* @param id 主键id
* @return V对象
*/
V getVoById(Serializable id);
/**
* @param convertor 自定义转换器
*/
default V getVoById(Serializable id, Function<T, V> convertor) {
return convertor.apply(getById(id));
}
/**
* @param idList id列表
* @return V对象
*/
List<V> listVoByIds(Collection<? extends Serializable> idList);
/**
* @param convertor 自定义转换器
*/
default List<V> listVoByIds(Collection<? extends Serializable> idList,
Function<Collection<T>, List<V>> convertor) {
List<T> list = getBaseMapper().selectBatchIds(idList);
if (list == null) {
return null;
}
return convertor.apply(list);
}
/**
* @param columnMap 表字段 map 对象
* @return V对象
*/
List<V> listVoByMap(Map<String, Object> columnMap);
/**
* @param convertor 自定义转换器
*/
default List<V> listVoByMap(Map<String, Object> columnMap,
Function<Collection<T>, List<V>> convertor) {
List<T> list = getBaseMapper().selectByMap(columnMap);
if (list == null) {
return null;
}
return convertor.apply(list);
}
/**
* @param queryWrapper 查询条件
* @return V对象
*/
V getVoOne(Wrapper<T> queryWrapper);
/**
* @param convertor 自定义转换器
*/
default V getVoOne(Wrapper<T> queryWrapper, Function<T, V> convertor) {
return convertor.apply(getOne(queryWrapper, true));
}
/**
* @param queryWrapper 查询条件
* @return V对象
*/
List<V> listVo(Wrapper<T> queryWrapper);
/**
* @param convertor 自定义转换器
*/
default List<V> listVo(Wrapper<T> queryWrapper, Function<Collection<T>, List<V>> convertor) {
List<T> list = getBaseMapper().selectList(queryWrapper);
if (list == null) {
return null;
}
return convertor.apply(list);
}
default List<V> listVo() {
return listVo(Wrappers.emptyWrapper());
}
/**
* @param convertor 自定义转换器
*/
default List<V> listVo(Function<Collection<T>, List<V>> convertor) {
return listVo(Wrappers.emptyWrapper(), convertor);
}
/**
* @param page 分页对象
* @param queryWrapper 查询条件
* @return V对象
* @deprecated 3.6.0 移除 请使用 {@link ServicePlusImpl#pageVo(IPage, Wrapper)}
*/
@Deprecated
PagePlus<T, V> pageVo(PagePlus<T, V> page, Wrapper<T> queryWrapper);
/**
* @param convertor 自定义转换器
* @deprecated 3.6.0 移除 请使用 {@link ServicePlusImpl#pageVo(IPage, Wrapper)}
*/
@Deprecated
default PagePlus<T, V> pageVo(PagePlus<T, V> page, Wrapper<T> queryWrapper,
Function<Collection<T>, List<V>> convertor) {
PagePlus<T, V> result = getBaseMapper().selectPage(page, queryWrapper);
return result.setRecordsVo(convertor.apply(result.getRecords()));
}
/**
* @deprecated 3.6.0 移除 请使用 {@link ServicePlusImpl#pageVo(IPage, Wrapper)}
*/
@Deprecated
default PagePlus<T, V> pageVo(PagePlus<T, V> page) {
return pageVo(page, Wrappers.emptyWrapper());
}
/**
* @param convertor 自定义转换器
* @deprecated 3.6.0 移除 请使用 {@link ServicePlusImpl#pageVo(IPage, Wrapper)}
*/
@Deprecated
default PagePlus<T, V> pageVo(PagePlus<T, V> page, Function<Collection<T>, List<V>> convertor) {
return pageVo(page, Wrappers.emptyWrapper(), convertor);
}
boolean saveAll(Collection<T> entityList);
boolean saveOrUpdateAll(Collection<T> entityList);
}

View File

@ -1,226 +0,0 @@
package com.ruoyi.common.core.mybatisplus.core;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.page.PagePlus;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* IServicePlus 实现类
*
* @param <M> Mapper类
* @param <T> 数据实体类
* @param <V> vo类
* @author Lion Li
*/
@Slf4j
@SuppressWarnings("unchecked")
public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, V> extends ServiceImpl<M, T> implements IServicePlus<T, V> {
@Autowired
protected M baseMapper;
@Override
public M getBaseMapper() {
return baseMapper;
}
protected Class<T> entityClass = currentModelClass();
@Override
public Class<T> getEntityClass() {
return entityClass;
}
protected Class<M> mapperClass = currentMapperClass();
protected Class<V> voClass = currentVoClass();
public Class<V> getVoClass() {
return voClass;
}
@Override
protected Class<M> currentMapperClass() {
return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 0);
}
@Override
protected Class<T> currentModelClass() {
return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 1);
}
protected Class<V> currentVoClass() {
return (Class<V>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 2);
}
/**
* 单条执行性能差 适用于列表对象内容不确定
*/
@Override
public boolean saveBatch(Collection<T> entityList, int batchSize) {
return super.saveBatch(entityList, batchSize);
}
@Override
public boolean saveOrUpdate(T entity) {
return super.saveOrUpdate(entity);
}
/**
* 单条执行性能差 适用于列表对象内容不确定
*/
@Override
public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
return super.saveOrUpdateBatch(entityList, batchSize);
}
@Override
public boolean updateBatchById(Collection<T> entityList, int batchSize) {
return super.updateBatchById(entityList, batchSize);
}
/**
* 单sql批量插入( 全量填充 无视数据库默认值 )
* 适用于无脑插入
*/
@Override
public boolean saveBatch(Collection<T> entityList) {
return saveBatch(entityList, DEFAULT_BATCH_SIZE);
}
@Override
public boolean saveOrUpdateBatch(Collection<T> entityList) {
return saveOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE);
}
@Override
public boolean updateBatchById(Collection<T> entityList) {
return updateBatchById(entityList, DEFAULT_BATCH_SIZE);
}
/**
* 单sql批量插入( 全量填充 )
*/
@Override
public boolean saveAll(Collection<T> entityList) {
if (CollUtil.isEmpty(entityList)) {
return false;
}
return baseMapper.insertAll(entityList) == entityList.size();
}
/**
* 全量保存或更新 ( 按主键区分 )
*/
@Override
public boolean saveOrUpdateAll(Collection<T> entityList) {
if (CollUtil.isEmpty(entityList)) {
return false;
}
TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
String keyProperty = tableInfo.getKeyProperty();
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
List<T> addList = new ArrayList<>();
List<T> updateList = new ArrayList<>();
int row = 0;
for (T entity : entityList) {
Object id = ReflectUtils.invokeGetter(entity, keyProperty);
if (ObjectUtil.isNull(id)) {
addList.add(entity);
} else {
updateList.add(entity);
}
}
if (CollUtil.isNotEmpty(updateList) && updateBatchById(updateList)) {
row += updateList.size();
}
if (CollUtil.isNotEmpty(addList)) {
row += baseMapper.insertAll(addList);
}
return row == entityList.size();
}
/**
* 根据 ID 查询
*/
@Override
public V getVoById(Serializable id) {
return getBaseMapper().selectVoById(id, voClass);
}
/**
* 查询根据ID 批量查询
*/
@Override
public List<V> listVoByIds(Collection<? extends Serializable> idList) {
return getBaseMapper().selectVoBatchIds(idList, voClass);
}
/**
* 查询根据 columnMap 条件
*/
@Override
public List<V> listVoByMap(Map<String, Object> columnMap) {
return getBaseMapper().selectVoByMap(columnMap, voClass);
}
/**
* 根据 Wrapper查询一条记录 <br/>
* <p>结果集如果是多个会抛出异常随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
*/
@Override
public V getVoOne(Wrapper<T> queryWrapper) {
return getBaseMapper().selectVoOne(queryWrapper, voClass);
}
/**
* 查询列表
*/
@Override
public List<V> listVo(Wrapper<T> queryWrapper) {
return getBaseMapper().selectVoList(queryWrapper, voClass);
}
/**
* 翻页查询
* @deprecated 3.6.0 移除 请使用 {@link #pageVo(IPage, Wrapper)}
*/
@Override
@Deprecated
public PagePlus<T, V> pageVo(PagePlus<T, V> page, Wrapper<T> queryWrapper) {
PagePlus<T, V> result = getBaseMapper().selectPage(page, queryWrapper);
List<V> volist = BeanCopyUtils.copyList(result.getRecords(), voClass);
result.setRecordsVo(volist);
return result;
}
/**
* 翻页查询
*
* @param page 翻页对象
* @param queryWrapper 实体对象封装操作类
*/
public <P extends IPage<V>> P pageVo(IPage<T> page, Wrapper<T> queryWrapper) {
return getBaseMapper().selectVoPage(page, queryWrapper, voClass);
}
}

View File

@ -1,101 +0,0 @@
package com.ruoyi.common.core.mybatisplus.methods;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.ruoyi.common.utils.StringUtils;
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import java.util.List;
/**
* 单sql批量插入( 全量填充 )
*
* @author Lion Li
*/
public class InsertAll extends AbstractMethod {
private final static String[] FILL_PROPERTY = {"createTime", "createBy", "updateTime", "updateBy"};
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
final String sql = "<script>insert into %s %s values %s</script>";
final String fieldSql = prepareFieldSql(tableInfo);
final String valueSql = prepareValuesSqlForMysqlBatch(tableInfo);
KeyGenerator keyGenerator = new NoKeyGenerator();
String sqlMethod = "insertAll";
String keyProperty = null;
String keyColumn = null;
// 表包含主键处理逻辑,如果不包含主键当普通字段处理
if (StringUtils.isNotBlank(tableInfo.getKeyProperty())) {
if (tableInfo.getIdType() == IdType.AUTO) {
/** 自增主键 */
keyGenerator = new Jdbc3KeyGenerator();
keyProperty = tableInfo.getKeyProperty();
keyColumn = tableInfo.getKeyColumn();
} else {
if (null != tableInfo.getKeySequence()) {
keyGenerator = TableInfoHelper.genKeyGenerator(sqlMethod, tableInfo, builderAssistant);
keyProperty = tableInfo.getKeyProperty();
keyColumn = tableInfo.getKeyColumn();
}
}
}
final String sqlResult = String.format(sql, tableInfo.getTableName(), fieldSql, valueSql);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
return this.addInsertMappedStatement(mapperClass, modelClass, sqlMethod, sqlSource, keyGenerator, keyProperty, keyColumn);
}
private String prepareFieldSql(TableInfo tableInfo) {
StringBuilder fieldSql = new StringBuilder();
if (StringUtils.isNotBlank(tableInfo.getKeyColumn())) {
fieldSql.append(tableInfo.getKeyColumn()).append(",");
}
tableInfo.getFieldList().forEach(x -> fieldSql.append(x.getColumn()).append(","));
fieldSql.delete(fieldSql.length() - 1, fieldSql.length());
fieldSql.insert(0, "(");
fieldSql.append(")");
return fieldSql.toString();
}
private String prepareValuesSqlForMysqlBatch(TableInfo tableInfo) {
final StringBuilder valueSql = new StringBuilder();
valueSql.append("<foreach collection=\"list\" item=\"item\" index=\"index\" open=\"(\" separator=\"),(\" close=\")\">");
if (StringUtils.isNotBlank(tableInfo.getKeyColumn())) {
valueSql.append("\n#{item.").append(tableInfo.getKeyProperty()).append("},\n");
}
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
int last = fieldList.size() - 1;
for (int i = 0; i < fieldList.size(); i++) {
String property = fieldList.get(i).getProperty();
if (!StringUtils.equalsAny(property, FILL_PROPERTY)) {
valueSql.append("<if test=\"item.").append(property).append(" != null\">");
valueSql.append("#{item.").append(property).append("}");
if (i != last) {
valueSql.append(",");
}
valueSql.append("</if>");
valueSql.append("<if test=\"item.").append(property).append(" == null\">");
valueSql.append("DEFAULT");
if (i != last) {
valueSql.append(",");
}
valueSql.append("</if>");
} else {
valueSql.append("#{item.").append(property).append("}");
if (i != last) {
valueSql.append(",");
}
}
}
valueSql.append("</foreach>");
return valueSql.toString();
}
}

View File

@ -1,158 +0,0 @@
package com.ruoyi.common.core.page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 分页 Page 增强对象
*
* @param <T> 数据库实体
* @param <K> vo实体
* @author Lion Li
* @deprecated 3.6.0 删除 请使用 {@link com.ruoyi.common.core.domain.PageQuery#build()}
*/
@Data
@Accessors(chain = true)
@Deprecated
public class PagePlus<T,K> implements IPage<T> {
/**
* domain实体列表
*/
private List<T> records = Collections.emptyList();
/**
* vo实体列表
*/
private List<K> recordsVo = Collections.emptyList();
/**
* 总数
*/
private long total = 0L;
/**
* 页长度
*/
private long size = 10L;
/**
* 当前页
*/
private long current = 1L;
/**
* 排序字段信息
*/
private List<OrderItem> orders = new ArrayList<>();
/**
* 自动优化 COUNT SQL
*/
private boolean optimizeCountSql = true;
/**
* 是否进行 count 查询
*/
private boolean isSearchCount = true;
/**
* 是否命中count缓存
*/
private boolean hitCount = false;
/**
* countId
*/
private String countId;
/**
* 最大limit
*/
private Long maxLimit;
public PagePlus() {
}
public PagePlus(long current, long size) {
this(current, size, 0L);
}
public PagePlus(long current, long size, long total) {
this(current, size, total, true);
}
public PagePlus(long current, long size, boolean isSearchCount) {
this(current, size, 0L, isSearchCount);
}
public PagePlus(long current, long size, long total, boolean isSearchCount) {
if (current > 1L) {
this.current = current;
}
this.size = size;
this.total = total;
this.isSearchCount = isSearchCount;
}
@Override
public String countId() {
return this.getCountId();
}
@Override
public Long maxLimit() {
return this.getMaxLimit();
}
public PagePlus<T, K> addOrder(OrderItem... items) {
this.orders.addAll(Arrays.asList(items));
return this;
}
public PagePlus<T, K> addOrder(List<OrderItem> items) {
this.orders.addAll(items);
return this;
}
@Override
public List<OrderItem> orders() {
return this.getOrders();
}
@Override
public boolean optimizeCountSql() {
return this.optimizeCountSql;
}
@Override
public long getPages() {
// 解决 github issues/3208
return IPage.super.getPages();
}
public static <T,K> PagePlus<T,K> of(long current, long size) {
return of(current, size, 0);
}
public static <T,K> PagePlus<T,K> of(long current, long size, long total) {
return of(current, size, total, true);
}
public static <T,K> PagePlus<T,K> of(long current, long size, boolean searchCount) {
return of(current, size, 0, searchCount);
}
public static <T,K> PagePlus<T,K> of(long current, long size, long total, boolean searchCount) {
return new PagePlus<>(current, size, total, searchCount);
}
}

Some files were not shown because too many files have changed in this diff Show More