mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2025-09-17 16:56:39 +08:00
发布 4.0.0
This commit is contained in:
parent
dafb7477f6
commit
400ecdf0ab
3
.gitignore
vendored
3
.gitignore
vendored
@ -25,6 +25,9 @@ target/
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### JRebel ###
|
||||
rebel.xml
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/*
|
||||
|
12
README.md
12
README.md
@ -4,7 +4,7 @@
|
||||
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
|
||||
[](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
|
||||
<br>
|
||||
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
|
||||
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
@ -14,16 +14,15 @@
|
||||
> 系统演示: [传送门](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全方位升级(不兼容原框架) |
|
||||
| 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/) | 单体应用结构 |
|
||||
| Vue3分支 | RuoYi-Vue-Plus-UI | [UI地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus-UI) | 由于组件还未完善 仅供学习 |
|
||||
| 原框架 | RuoYi-Vue | [RuoYi-Vue官网](http://ruoyi.vip/) | 定期同步需要的功能 |
|
||||
| 前端开发框架 | Vue、Element UI | [Element UI官网](https://element.eleme.cn/#/zh-CN) | |
|
||||
| 后端开发框架 | SpringBoot | [SpringBoot官网](https://spring.io/projects/spring-boot/#learn) | |
|
||||
| 容器框架 | 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/) | 强解耦、强扩展 |
|
||||
| 关系数据库 | MySQL | [MySQL官网](https://dev.mysql.com/) | 适配 8.X 最低 5.7 |
|
||||
| 缓存数据库 | Redis | [Redis官网](https://redis.io/) | 适配 6.X 最低 4.X |
|
||||
@ -33,6 +32,7 @@
|
||||
| 序列化框架 | Jackson | [Jackson官网](https://github.com/FasterXML/jackson) | 统一使用 jackson 高效可靠 |
|
||||
| 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) | 普通队列、延迟队列、优先队列 等 |
|
||||
| 分布式锁 | Lock4j | [Lock4j官网](https://gitee.com/baomidou/lock4j) | 注解锁、工具锁 多种多样 |
|
||||
| 分布式幂等 | Redisson | [Lock4j文档](https://gitee.com/baomidou/lock4j) | 拦截重复提交 |
|
||||
| 分布式日志 | TLog | [TLog文档](https://yomahub.com/tlog/docs) | 支持跟踪链路日志记录、性能分析、链路排查 |
|
||||
@ -74,8 +74,8 @@
|
||||
|
||||
* 同步升级 RuoYi-Vue
|
||||
* 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/)
|
||||
* satoken 分支 [RuoYi-Vue-Plus-satoken](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/)
|
||||
* 单模块 分支 [RuoYi-Vue-Plus-fast](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/)
|
||||
* 微服务 分支 [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)
|
||||
|
||||
## 加群与捐献
|
||||
|
93
pom.xml
93
pom.xml
@ -6,32 +6,33 @@
|
||||
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<version>4.0.0</version>
|
||||
|
||||
<name>RuoYi-Vue-Plus</name>
|
||||
<url>https://gitee.com/JavaLionLi/RuoYi-Vue-Plus</url>
|
||||
<description>RuoYi-Vue-Plus后台管理系统</description>
|
||||
|
||||
<properties>
|
||||
<ruoyi-vue-plus.version>3.5.0</ruoyi-vue-plus.version>
|
||||
<spring-boot.version>2.5.8</spring-boot.version>
|
||||
<ruoyi-vue-plus.version>4.0.0</ruoyi-vue-plus.version>
|
||||
<spring-boot.version>2.6.3</spring-boot.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<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>
|
||||
<knife4j.version>3.0.3</knife4j.version>
|
||||
<swagger-annotations.version>1.5.22</swagger-annotations.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>
|
||||
<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>
|
||||
<hutool.version>5.7.18</hutool.version>
|
||||
<hutool.version>5.7.20</hutool.version>
|
||||
<okhttp.version>4.9.2</okhttp.version>
|
||||
<spring-boot-admin.version>2.5.5</spring-boot-admin.version>
|
||||
<redisson.version>3.16.7</redisson.version>
|
||||
<spring-boot-admin.version>2.6.2</spring-boot-admin.version>
|
||||
<redisson.version>3.16.8</redisson.version>
|
||||
<lock4j.version>2.2.1</lock4j.version>
|
||||
<dynamic-ds.version>3.5.0</dynamic-ds.version>
|
||||
<tlog.version>1.3.6</tlog.version>
|
||||
@ -41,10 +42,10 @@
|
||||
<jaxb.version>3.0.1</jaxb.version>
|
||||
|
||||
<!-- OSS 配置 -->
|
||||
<qiniu.version>7.9.0</qiniu.version>
|
||||
<aliyun.oss.version>3.13.1</aliyun.oss.version>
|
||||
<qcloud.cos.version>5.6.58</qcloud.cos.version>
|
||||
<minio.version>8.3.4</minio.version>
|
||||
<qiniu.version>7.9.2</qiniu.version>
|
||||
<aliyun.oss.version>3.14.0</aliyun.oss.version>
|
||||
<qcloud.cos.version>5.6.68</qcloud.cos.version>
|
||||
<minio.version>8.3.5</minio.version>
|
||||
|
||||
<!-- docker 配置 -->
|
||||
<docker.registry.url>localhost</docker.registry.url>
|
||||
@ -67,6 +68,15 @@
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- hutool 的依赖配置-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-bom</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里数据库连接池 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
@ -128,6 +138,19 @@
|
||||
<version>${velocity.version}</version>
|
||||
</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-->
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
@ -159,36 +182,6 @@
|
||||
<version>${p6spy.version}</version>
|
||||
</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>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
@ -251,7 +244,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<version>3.9.0</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
@ -261,8 +254,18 @@
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<!--打包该目录下的 application.yml -->
|
||||
<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>
|
||||
</resource>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.5.0</version>
|
||||
<version>4.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>ruoyi-extend</artifactId>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-extend</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.5.0</version>
|
||||
<version>4.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
@ -34,6 +34,11 @@
|
||||
<artifactId>spring-boot-admin-starter-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -9,6 +9,6 @@ spring:
|
||||
# 设置 Spring Boot Admin Server 地址
|
||||
url: http://localhost:9090/admin
|
||||
instance:
|
||||
prefer-ip: true # 注册实例时,优先使用 IP
|
||||
service-host-type: IP
|
||||
username: ruoyi
|
||||
password: 123456
|
||||
|
@ -9,6 +9,6 @@ spring:
|
||||
# 设置 Spring Boot Admin Server 地址
|
||||
url: http://172.30.0.90:9090/admin
|
||||
instance:
|
||||
prefer-ip: true # 注册实例时,优先使用 IP
|
||||
service-host-type: IP
|
||||
username: ruoyi
|
||||
password: 123456
|
||||
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-extend</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.5.0</version>
|
||||
<version>4.0.0</version>
|
||||
</parent>
|
||||
<artifactId>ruoyi-xxl-job-admin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
@ -99,19 +99,6 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</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 -->
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
|
@ -24,6 +24,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* index controller
|
||||
*
|
||||
* @author xuxueli 2015-12-19 16:13:16
|
||||
*/
|
||||
@Controller
|
||||
|
@ -19,6 +19,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* job code controller
|
||||
*
|
||||
* @author xuxueli 2015-12-19 16:13:16
|
||||
*/
|
||||
@Controller
|
||||
|
@ -20,6 +20,7 @@ import java.util.*;
|
||||
|
||||
/**
|
||||
* job group controller
|
||||
*
|
||||
* @author xuxueli 2016-10-02 20:52:56
|
||||
*/
|
||||
@Controller
|
||||
|
@ -1,6 +1,5 @@
|
||||
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.model.XxlJobGroup;
|
||||
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.servlet.http.HttpServletRequest;
|
||||
import java.text.ParseException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* index controller
|
||||
*
|
||||
* @author xuxueli 2015-12-19 16:13:16
|
||||
*/
|
||||
@Controller
|
||||
@ -91,6 +90,7 @@ public class JobInfoController {
|
||||
}
|
||||
return jobGroupList;
|
||||
}
|
||||
|
||||
public static void validPermission(HttpServletRequest request, int jobGroup) {
|
||||
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
|
||||
if (!loginUser.validPermission(jobGroup)) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
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.exception.XxlJobException;
|
||||
import com.xxl.job.admin.core.model.XxlJobGroup;
|
||||
import com.xxl.job.admin.core.model.XxlJobInfo;
|
||||
import com.xxl.job.admin.core.model.XxlJobLog;
|
||||
@ -33,6 +33,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* index controller
|
||||
*
|
||||
* @author xuxueli 2015-12-19 16:13:16
|
||||
*/
|
||||
@Controller
|
||||
|
@ -8,6 +8,7 @@ import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 权限限制
|
||||
*
|
||||
* @author xuxueli 2015-12-12 18:29:02
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.xxl.job.admin.controller.resolver;
|
||||
|
||||
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.core.biz.model.ReturnT;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -4,6 +4,7 @@ import java.util.Date;
|
||||
|
||||
/**
|
||||
* xxl-job log, used to track trigger process
|
||||
*
|
||||
* @author xuxueli 2015-12-19 23:19:09
|
||||
*/
|
||||
public class XxlJobLog {
|
||||
|
@ -4,6 +4,7 @@ import java.util.Date;
|
||||
|
||||
/**
|
||||
* xxl-job log for glue, used to track job code process
|
||||
*
|
||||
* @author xuxueli 2016-5-19 17:57:46
|
||||
*/
|
||||
public class XxlJobLogGlue {
|
||||
|
@ -23,6 +23,7 @@ public class JobCompleteHelper {
|
||||
private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class);
|
||||
|
||||
private static JobCompleteHelper instance = new JobCompleteHelper();
|
||||
|
||||
public static JobCompleteHelper getInstance() {
|
||||
return instance;
|
||||
}
|
||||
@ -32,6 +33,7 @@ public class JobCompleteHelper {
|
||||
private ThreadPoolExecutor callbackThreadPool = null;
|
||||
private Thread monitorThread;
|
||||
private volatile boolean toStop = false;
|
||||
|
||||
public void start() {
|
||||
|
||||
// for callback
|
||||
@ -180,5 +182,4 @@ public class JobCompleteHelper {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ public class JobFailMonitorHelper {
|
||||
private static Logger logger = LoggerFactory.getLogger(JobFailMonitorHelper.class);
|
||||
|
||||
private static JobFailMonitorHelper instance = new JobFailMonitorHelper();
|
||||
|
||||
public static JobFailMonitorHelper getInstance() {
|
||||
return instance;
|
||||
}
|
||||
@ -28,6 +29,7 @@ public class JobFailMonitorHelper {
|
||||
|
||||
private Thread monitorThread;
|
||||
private volatile boolean toStop = false;
|
||||
|
||||
public void start() {
|
||||
monitorThread = new Thread(new Runnable() {
|
||||
|
||||
|
@ -15,12 +15,14 @@ import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* job registry instance
|
||||
*
|
||||
* @author xuxueli 2016-10-02 19:10:24
|
||||
*/
|
||||
public class JobRegistryHelper {
|
||||
private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class);
|
||||
|
||||
private static JobRegistryHelper instance = new JobRegistryHelper();
|
||||
|
||||
public static JobRegistryHelper getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
@ -120,7 +120,6 @@ public class JobTriggerPoolHelper {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------------- helper ----------------------
|
||||
|
||||
private static JobTriggerPoolHelper helper = new JobTriggerPoolHelper();
|
||||
@ -128,6 +127,7 @@ public class JobTriggerPoolHelper {
|
||||
public static void toStart() {
|
||||
helper.start();
|
||||
}
|
||||
|
||||
public static void toStop() {
|
||||
helper.stop();
|
||||
}
|
||||
@ -135,12 +135,10 @@ public class JobTriggerPoolHelper {
|
||||
/**
|
||||
* @param jobId
|
||||
* @param triggerType
|
||||
* @param failRetryCount
|
||||
* >=0: use this param
|
||||
* @param failRetryCount >=0: use this param
|
||||
* <0: use param from job info config
|
||||
* @param executorShardingParam
|
||||
* @param executorParam
|
||||
* null: use job param
|
||||
* @param executorParam null: use job param
|
||||
* not null: cover job param
|
||||
*/
|
||||
public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam, String addressList) {
|
||||
|
@ -12,7 +12,7 @@ import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Jackson util
|
||||
*
|
||||
* <p>
|
||||
* 1、obj need private and set/get;
|
||||
* 2、do not support inner class;
|
||||
*
|
||||
@ -22,6 +22,7 @@ public class JacksonUtil {
|
||||
private static Logger logger = LoggerFactory.getLogger(JacksonUtil.class);
|
||||
|
||||
private final static ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public static ObjectMapper getInstance() {
|
||||
return objectMapper;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* job info
|
||||
*
|
||||
* @author xuxueli 2016-1-12 18:03:45
|
||||
*/
|
||||
@Mapper
|
||||
@ -21,6 +22,7 @@ public interface XxlJobInfoDao {
|
||||
@Param("jobDesc") String jobDesc,
|
||||
@Param("executorHandler") String executorHandler,
|
||||
@Param("author") String author);
|
||||
|
||||
public int pageListCount(@Param("offset") int offset,
|
||||
@Param("pagesize") int pagesize,
|
||||
@Param("jobGroup") int jobGroup,
|
||||
|
@ -10,6 +10,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* job log
|
||||
*
|
||||
* @author xuxueli 2016-1-12 18:03:06
|
||||
*/
|
||||
@Mapper
|
||||
@ -23,6 +24,7 @@ public interface XxlJobLogDao {
|
||||
@Param("triggerTimeStart") Date triggerTimeStart,
|
||||
@Param("triggerTimeEnd") Date triggerTimeEnd,
|
||||
@Param("logStatus") int logStatus);
|
||||
|
||||
public int pageListCount(@Param("offset") int offset,
|
||||
@Param("pagesize") int pagesize,
|
||||
@Param("jobGroup") int jobGroup,
|
||||
@ -49,6 +51,7 @@ public interface XxlJobLogDao {
|
||||
@Param("clearBeforeTime") Date clearBeforeTime,
|
||||
@Param("clearBeforeNum") int clearBeforeNum,
|
||||
@Param("pagesize") int pagesize);
|
||||
|
||||
public int clearLog(@Param("logIds") List<Long> logIds);
|
||||
|
||||
public List<Long> findFailJobLogIds(@Param("pagesize") int pagesize);
|
||||
|
@ -8,6 +8,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* job log for glue
|
||||
*
|
||||
* @author xuxueli 2016-5-19 18:04:56
|
||||
*/
|
||||
@Mapper
|
||||
|
@ -9,6 +9,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* job log
|
||||
*
|
||||
* @author xuxueli 2019-11-22
|
||||
*/
|
||||
@Mapper
|
||||
|
@ -3,6 +3,7 @@ package com.xxl.job.admin.dao;
|
||||
import com.xxl.job.admin.core.model.XxlJobUser;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -15,6 +16,7 @@ public interface XxlJobUserDao {
|
||||
@Param("pagesize") int pagesize,
|
||||
@Param("username") String username,
|
||||
@Param("role") int role);
|
||||
|
||||
public int pageListCount(@Param("offset") int offset,
|
||||
@Param("pagesize") int pagesize,
|
||||
@Param("username") String username,
|
||||
|
@ -46,6 +46,7 @@ public interface XxlJobService {
|
||||
/**
|
||||
* remove job
|
||||
* *
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
|
@ -25,6 +25,7 @@ import java.util.*;
|
||||
|
||||
/**
|
||||
* core job action for xxl-job
|
||||
*
|
||||
* @author xuxueli 2016-5-28 15:30:33
|
||||
*/
|
||||
@Service
|
||||
|
@ -9,7 +9,7 @@ spring:
|
||||
# 设置 Spring Boot Admin Server 地址
|
||||
url: http://localhost:9090/admin
|
||||
instance:
|
||||
prefer-ip: true # 注册实例时,优先使用 IP
|
||||
service-host-type: IP
|
||||
username: ruoyi
|
||||
password: 123456
|
||||
|
||||
|
@ -9,7 +9,7 @@ spring:
|
||||
# 设置 Spring Boot Admin Server 地址
|
||||
url: http://172.30.0.90:9090/admin
|
||||
instance:
|
||||
prefer-ip: true # 注册实例时,优先使用 IP
|
||||
service-host-type: IP
|
||||
username: ruoyi
|
||||
password: 123456
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ruoyi-vue-plus",
|
||||
"version": "3.5.0",
|
||||
"version": "4.0.0",
|
||||
"description": "RuoYi-Vue-Plus后台管理系统",
|
||||
"author": "LionLi",
|
||||
"license": "MIT",
|
||||
|
@ -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) {
|
||||
return request({
|
||||
|
@ -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
|
||||
})
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import request from '@/utils/request'
|
||||
import { praseStrEmpty } from "@/utils/ruoyi";
|
||||
import { parseStrEmpty } from "@/utils/ruoyi";
|
||||
|
||||
// 查询用户列表
|
||||
export function listUser(query) {
|
||||
@ -13,7 +13,7 @@ export function listUser(query) {
|
||||
// 查询用户详细
|
||||
export function getUser(userId) {
|
||||
return request({
|
||||
url: '/system/user/' + praseStrEmpty(userId),
|
||||
url: '/system/user/' + parseStrEmpty(userId),
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
@ -7,49 +7,62 @@
|
||||
.pt5 {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.pr5 {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.pb5 {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.mr5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.mb5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ml5 {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.mr10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ml0 {
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.mr20 {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.m20 {
|
||||
.ml20 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
@ -81,6 +94,7 @@
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table__body-wrapper {
|
||||
.el-button [class*="el-icon-"] + span {
|
||||
margin-left: 1px;
|
||||
|
@ -26,7 +26,7 @@
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<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-radio>
|
||||
</el-form-item>
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<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">
|
||||
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
||||
</el-link>
|
||||
|
@ -1,5 +1,10 @@
|
||||
<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">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
@ -7,10 +12,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isExternal } from '@/utils/validate'
|
||||
import { isExternal } from "@/utils/validate";
|
||||
|
||||
export default {
|
||||
name: 'ImagePreview',
|
||||
name: "ImagePreview",
|
||||
props: {
|
||||
src: {
|
||||
type: String,
|
||||
@ -18,28 +23,40 @@ export default {
|
||||
},
|
||||
width: {
|
||||
type: [Number, String],
|
||||
default: ''
|
||||
default: ""
|
||||
},
|
||||
height: {
|
||||
type: [Number, String],
|
||||
default: ''
|
||||
default: ""
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
realSrc() {
|
||||
if (isExternal(this.src)) {
|
||||
return this.src
|
||||
let real_src = this.src.split(",")[0];
|
||||
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() {
|
||||
return typeof this.width == 'string' ? this.width : `${this.width}px`
|
||||
return typeof this.width == "string" ? this.width : `${this.width}px`;
|
||||
},
|
||||
realHeight() {
|
||||
return typeof this.height == 'string' ? this.height : `${this.height}px`
|
||||
}
|
||||
}
|
||||
return typeof this.height == "string" ? this.height : `${this.height}px`;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div :class="{'hidden':hidden}" class="pagination-container">
|
||||
<el-pagination
|
||||
v-if="pageShow"
|
||||
:background="background"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@ -61,6 +62,11 @@ export default {
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageShow: true
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
currentPage: {
|
||||
get() {
|
||||
@ -81,6 +87,12 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
handleSizeChange(val) {
|
||||
if (this.currentPage * val > this.total) {
|
||||
this.pageShow = false;
|
||||
this.$nextTick(() => {
|
||||
this.pageShow = true
|
||||
})
|
||||
}
|
||||
this.$emit('pagination', { page: this.currentPage, limit: val })
|
||||
if (this.autoScroll) {
|
||||
scrollTo(0, 800)
|
||||
|
@ -17,7 +17,7 @@ import { download } from '@/utils/request'
|
||||
import './assets/icons' // icon
|
||||
import './permission' // permission control
|
||||
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 Pagination from "@/components/Pagination";
|
||||
@ -41,6 +41,7 @@ import DictData from '@/components/DictData'
|
||||
// 全局方法挂载
|
||||
Vue.prototype.getDicts = getDicts
|
||||
Vue.prototype.getConfigKey = getConfigKey
|
||||
Vue.prototype.updateConfigByKey = updateConfigByKey
|
||||
Vue.prototype.parseTime = parseTime
|
||||
Vue.prototype.resetForm = resetForm
|
||||
Vue.prototype.addDateRange = addDateRange
|
||||
|
@ -4,20 +4,21 @@ import router from '@/router';
|
||||
export default {
|
||||
// 刷新当前tab页签
|
||||
refreshPage(obj) {
|
||||
const { path, matched } = router.currentRoute;
|
||||
const { path, query, matched } = router.currentRoute;
|
||||
if (obj === undefined) {
|
||||
matched.forEach((m) => {
|
||||
if (m.components && m.components.default && 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(() => {
|
||||
const { path } = obj
|
||||
const { path, query } = obj
|
||||
router.replace({
|
||||
path: '/redirect' + path
|
||||
path: '/redirect' + path,
|
||||
query: query
|
||||
})
|
||||
})
|
||||
},
|
||||
|
@ -155,7 +155,7 @@ export const dynamicRoutes = [
|
||||
permissions: ['tool:gen:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
path: 'index/:tableId(\\d+)',
|
||||
component: () => import('@/views/tool/gen/editTable'),
|
||||
name: 'GenEdit',
|
||||
meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
|
||||
|
29
ruoyi-ui/src/utils/generator/drawingDefault.js
Normal file
29
ruoyi-ui/src/utils/generator/drawingDefault.js
Normal 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: '手机号格式错误'
|
||||
}]
|
||||
}
|
||||
]
|
@ -5,11 +5,11 @@ let confGlobal
|
||||
let someSpanIsNot24
|
||||
|
||||
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}
|
||||
<div slot="footer">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" @click="handelConfirm">确定</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>`
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ function mixinMethod(type) {
|
||||
close: `close() {
|
||||
this.$emit('update:visible', false)
|
||||
},`,
|
||||
handelConfirm: `handelConfirm() {
|
||||
handleConfirm: `handleConfirm() {
|
||||
this.$refs['${confGlobal.formRef}'].validate(valid => {
|
||||
if(!valid) return
|
||||
this.close()
|
||||
|
@ -4,9 +4,12 @@ import store from '@/store'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import errorCode from '@/utils/errorCode'
|
||||
import { tansParams, blobValidate } from "@/utils/ruoyi";
|
||||
import cache from '@/plugins/cache'
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
let downloadLoadingInstance;
|
||||
// 是否显示重新登录
|
||||
let isReloginShow;
|
||||
|
||||
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
|
||||
// 对应国际化资源文件后缀
|
||||
@ -23,6 +26,8 @@ const service = axios.create({
|
||||
service.interceptors.request.use(config => {
|
||||
// 是否需要设置 token
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
// 是否需要防止数据重复提交
|
||||
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
|
||||
if (getToken() && !isToken) {
|
||||
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
@ -33,6 +38,29 @@ service.interceptors.request.use(config => {
|
||||
config.params = {};
|
||||
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
|
||||
}, error => {
|
||||
console.log(error)
|
||||
@ -50,16 +78,25 @@ service.interceptors.response.use(res => {
|
||||
return res.data
|
||||
}
|
||||
if (code === 401) {
|
||||
if (!isReloginShow) {
|
||||
isReloginShow = true;
|
||||
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
|
||||
confirmButtonText: '重新登录',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
isReloginShow = false;
|
||||
store.dispatch('LogOut').then(() => {
|
||||
// 如果是登录页面不需要重新加载
|
||||
if (window.location.hash.indexOf("#/login") != 0) {
|
||||
location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
|
||||
}
|
||||
})
|
||||
}).catch(() => {});
|
||||
}).catch(() => {
|
||||
isReloginShow = false;
|
||||
});
|
||||
}
|
||||
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
} else if (code === 500) {
|
||||
Message({
|
||||
|
@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
/**
|
||||
* 通用js方法封装处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
@ -80,6 +82,9 @@ export function selectDictLabel(datas, value) {
|
||||
|
||||
// 回显数据字典(字符串数组)
|
||||
export function selectDictLabels(datas, value, separator) {
|
||||
if(value === undefined) {
|
||||
return "";
|
||||
}
|
||||
var actions = [];
|
||||
var currentSeparator = undefined === separator ? "," : separator;
|
||||
var temp = value.split(currentSeparator);
|
||||
@ -108,7 +113,7 @@ export function sprintf(str) {
|
||||
}
|
||||
|
||||
// 转换字符串,undefined,null等转化为""
|
||||
export function praseStrEmpty(str) {
|
||||
export function parseStrEmpty(str) {
|
||||
if (!str || str == "undefined" || str == "null") {
|
||||
return "";
|
||||
}
|
||||
|
@ -101,6 +101,70 @@
|
||||
<span>更新日志</span>
|
||||
</div>
|
||||
<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">
|
||||
<ol>
|
||||
<li>[重大更新] 重写数据权限实现</li>
|
||||
@ -644,7 +708,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
// 版本号
|
||||
version: "3.5.0",
|
||||
version: "4.0.0",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -56,7 +56,7 @@
|
||||
</el-form>
|
||||
<!-- 底部 -->
|
||||
<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>
|
||||
</template>
|
||||
|
@ -61,7 +61,7 @@
|
||||
</el-form>
|
||||
<!-- 底部 -->
|
||||
<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>
|
||||
</template>
|
||||
@ -124,7 +124,9 @@ export default {
|
||||
this.$refs.registerForm.validate(valid => {
|
||||
if (valid) {
|
||||
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;
|
||||
this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
|
||||
dangerouslyUseHTMLString: true,
|
||||
|
@ -106,6 +106,8 @@
|
||||
<treeselect v-model="form.parentId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级部门" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="部门名称" prop="deptName">
|
||||
<el-input v-model="form.deptName" placeholder="请输入部门名称" />
|
||||
@ -116,6 +118,8 @@
|
||||
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="负责人" prop="leader">
|
||||
<el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20" />
|
||||
@ -126,6 +130,8 @@
|
||||
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
|
||||
|
@ -187,7 +187,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listOss, delOss, changePreviewListResource } from "@/api/system/oss";
|
||||
import { listOss, delOss } from "@/api/system/oss";
|
||||
|
||||
export default {
|
||||
name: "Oss",
|
||||
@ -344,7 +344,7 @@ export default {
|
||||
handlePreviewListResource(previewListResource) {
|
||||
let text = previewListResource ? "启用" : "停用";
|
||||
this.$modal.confirm('确认要"' + text + '""预览列表图片"配置吗?').then(() => {
|
||||
return changePreviewListResource(previewListResource);
|
||||
return this.updateConfigByKey("sys.oss.previewListResource", previewListResource);
|
||||
}).then(() => {
|
||||
this.getList()
|
||||
this.$modal.msgSuccess(text + "成功");
|
||||
|
@ -495,7 +495,7 @@ export default {
|
||||
// 节点单击事件
|
||||
handleNodeClick(data) {
|
||||
this.queryParams.deptId = data.id;
|
||||
this.getList();
|
||||
this.handleQuery();
|
||||
},
|
||||
// 用户状态修改
|
||||
handleStatusChange(row) {
|
||||
|
@ -41,7 +41,7 @@
|
||||
<el-button @click="close">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handelConfirm">
|
||||
<el-button type="primary" @click="handleConfirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
@ -94,7 +94,7 @@ export default {
|
||||
close(e) {
|
||||
this.$emit('update:visible', false)
|
||||
},
|
||||
handelConfirm() {
|
||||
handleConfirm() {
|
||||
this.$refs.elForm.validate(valid => {
|
||||
if (!valid) return
|
||||
this.$emit('confirm', { ...this.formData })
|
||||
|
@ -59,7 +59,7 @@
|
||||
<div slot="footer">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handelConfirm"
|
||||
@click="handleConfirm"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
@ -133,7 +133,7 @@ export default {
|
||||
close() {
|
||||
this.$emit('update:visible', false)
|
||||
},
|
||||
handelConfirm() {
|
||||
handleConfirm() {
|
||||
this.$refs.elForm.validate(valid => {
|
||||
if (!valid) return
|
||||
if (this.dataType === 'number') {
|
||||
|
@ -146,7 +146,7 @@ import { beautifierConf, titleCase } from '@/utils/index'
|
||||
import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html'
|
||||
import { makeUpJs } from '@/utils/generator/js'
|
||||
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 CodeTypeDialog from './CodeTypeDialog'
|
||||
import DraggableItem from './DraggableItem'
|
||||
@ -171,15 +171,15 @@ export default {
|
||||
selectComponents,
|
||||
layoutComponents,
|
||||
labelWidth: 100,
|
||||
drawingList: drawingDefalut,
|
||||
drawingList: drawingDefault,
|
||||
drawingData: {},
|
||||
activeId: drawingDefalut[0].formId,
|
||||
activeId: drawingDefault[0].formId,
|
||||
drawerVisible: false,
|
||||
formData: {},
|
||||
dialogVisible: false,
|
||||
generateConf: null,
|
||||
showFileName: false,
|
||||
activeData: drawingDefalut[0]
|
||||
activeData: drawingDefault[0]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -33,6 +33,7 @@
|
||||
<el-option label="Double" value="Double" />
|
||||
<el-option label="BigDecimal" value="BigDecimal" />
|
||||
<el-option label="Date" value="Date" />
|
||||
<el-option label="Boolean" value="Boolean" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -158,7 +159,7 @@ export default {
|
||||
};
|
||||
},
|
||||
created() {
|
||||
const tableId = this.$route.query && this.$route.query.tableId;
|
||||
const tableId = this.$route.params && this.$route.params.tableId;
|
||||
if (tableId) {
|
||||
// 获取表详细信息
|
||||
getGenTable(tableId).then(res => {
|
||||
|
@ -321,7 +321,7 @@ export default {
|
||||
/** 修改按钮操作 */
|
||||
handleEditTable(row) {
|
||||
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) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.5.0</version>
|
||||
<version>4.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
@ -73,10 +73,15 @@
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- spring security 安全认证 -->
|
||||
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- Sa-Token 整合 jwt -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jwt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -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;
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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();
|
||||
}
|
@ -15,7 +15,7 @@ public class UnsignedMathGenerator implements CodeGenerator {
|
||||
|
||||
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);
|
||||
number2 = StringUtils.rightPad(number2, this.numberLength, CharUtil.SPACE);
|
||||
|
||||
return number1 + RandomUtil.randomChar(operators) + number2 + '=';
|
||||
return number1 + RandomUtil.randomChar(OPERATORS) + number2 + '=';
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,7 +2,6 @@ package com.ruoyi.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -13,7 +12,6 @@ import org.springframework.stereotype.Component;
|
||||
*/
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "ruoyi")
|
||||
public class RuoYiConfig {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
|
||||
/**
|
||||
* 通用常量信息
|
||||
*
|
||||
@ -66,7 +65,12 @@ public interface Constants {
|
||||
/**
|
||||
* 登录用户 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
|
||||
@ -103,41 +107,11 @@ public interface Constants {
|
||||
*/
|
||||
String TOKEN = "token";
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
String TOKEN_PREFIX = "Bearer ";
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@ -149,3 +123,4 @@ public interface Constants {
|
||||
String SYS_DICT_KEY = "sys_dict:";
|
||||
|
||||
}
|
||||
|
||||
|
@ -181,6 +181,11 @@ public interface GenConstants {
|
||||
*/
|
||||
String QUERY_LIKE = "LIKE";
|
||||
|
||||
/**
|
||||
* 相等查询
|
||||
*/
|
||||
String QUERY_EQ = "EQ";
|
||||
|
||||
/**
|
||||
* 需要
|
||||
*/
|
||||
|
@ -4,8 +4,9 @@ import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.excel.converters.Converter;
|
||||
import com.alibaba.excel.enums.CellDataTypeEnum;
|
||||
import com.alibaba.excel.metadata.CellData;
|
||||
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 lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -31,19 +32,19 @@ public class ExcelBigNumberConvert implements Converter<Long> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||
public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||
return Convert.toLong(cellData.getData());
|
||||
}
|
||||
|
||||
@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)) {
|
||||
String str = Convert.toStr(object);
|
||||
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);
|
||||
return cellData;
|
||||
}
|
||||
|
@ -2,10 +2,12 @@ package com.ruoyi.common.convert;
|
||||
|
||||
import cn.hutool.core.annotation.AnnotationUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.excel.converters.Converter;
|
||||
import com.alibaba.excel.enums.CellDataTypeEnum;
|
||||
import com.alibaba.excel.metadata.CellData;
|
||||
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.ruoyi.common.annotation.ExcelDictFormat;
|
||||
import com.ruoyi.common.core.service.DictService;
|
||||
@ -35,7 +37,7 @@ public class ExcelDictConvert implements Converter<Object> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||
public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||
ExcelDictFormat anno = getAnnotation(contentProperty.getField());
|
||||
String type = anno.dictType();
|
||||
String label = cellData.getStringValue();
|
||||
@ -49,9 +51,9 @@ public class ExcelDictConvert implements Converter<Object> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||
if (StringUtils.isNull(object)) {
|
||||
return new CellData<>("");
|
||||
public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||
if (ObjectUtil.isNull(object)) {
|
||||
return new WriteCellData<>("");
|
||||
}
|
||||
ExcelDictFormat anno = getAnnotation(contentProperty.getField());
|
||||
String type = anno.dictType();
|
||||
@ -62,7 +64,7 @@ public class ExcelDictConvert implements Converter<Object> {
|
||||
} else {
|
||||
label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator());
|
||||
}
|
||||
return new CellData<>(label);
|
||||
return new WriteCellData<>(label);
|
||||
}
|
||||
|
||||
private ExcelDictFormat getAnnotation(Field field) {
|
||||
|
@ -1,53 +1,25 @@
|
||||
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.utils.SecurityUtils;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* web层通用数据处理
|
||||
*
|
||||
* @author ruoyi
|
||||
* @author Lion Li
|
||||
*/
|
||||
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 影响行数
|
||||
* @return 操作结果
|
||||
*/
|
||||
protected AjaxResult<Void> toAjax(int rows) {
|
||||
return rows > 0 ? AjaxResult.success() : AjaxResult.error();
|
||||
protected R<Void> toAjax(int rows) {
|
||||
return rows > 0 ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,8 +28,8 @@ public class BaseController {
|
||||
* @param result 结果
|
||||
* @return 操作结果
|
||||
*/
|
||||
protected AjaxResult<Void> toAjax(boolean result) {
|
||||
return result ? success() : error();
|
||||
protected R<Void> toAjax(boolean result) {
|
||||
return result ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,27 +43,27 @@ public class BaseController {
|
||||
* 获取用户缓存信息
|
||||
*/
|
||||
public LoginUser getLoginUser() {
|
||||
return SecurityUtils.getLoginUser();
|
||||
return LoginHelper.getLoginUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户id
|
||||
*/
|
||||
public Long getUserId() {
|
||||
return getLoginUser().getUserId();
|
||||
return LoginHelper.getUserId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录部门id
|
||||
*/
|
||||
public Long getDeptId() {
|
||||
return getLoginUser().getDeptId();
|
||||
return LoginHelper.getDeptId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户名
|
||||
*/
|
||||
public String getUsername() {
|
||||
return getLoginUser().getUsername();
|
||||
return LoginHelper.getUsername();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
@ -18,7 +17,6 @@ import java.util.Map;
|
||||
*/
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class BaseEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -7,7 +7,6 @@ import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.sql.SqlUtil;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ -18,7 +17,6 @@ import java.io.Serializable;
|
||||
*/
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PageQuery implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
84
ruoyi/src/main/java/com/ruoyi/common/core/domain/R.java
Normal file
84
ruoyi/src/main/java/com/ruoyi/common/core/domain/R.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -17,7 +16,6 @@ import java.util.List;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class TreeEntity extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -1,8 +1,6 @@
|
||||
package com.ruoyi.common.core.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
@ -14,8 +12,6 @@ import java.util.Date;
|
||||
*/
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class OperLogDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -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;
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -8,10 +8,10 @@ import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
@ -22,7 +22,6 @@ import javax.validation.constraints.Size;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_dept")
|
||||
@ApiModel("部门业务对象")
|
||||
public class SysDept extends TreeEntity {
|
||||
@ -47,8 +46,8 @@ public class SysDept extends TreeEntity {
|
||||
* 显示顺序
|
||||
*/
|
||||
@ApiModelProperty(value = "显示顺序")
|
||||
@NotBlank(message = "显示顺序不能为空")
|
||||
private String orderNum;
|
||||
@NotNull(message = "显示顺序不能为空")
|
||||
private Long orderNum;
|
||||
|
||||
/**
|
||||
* 负责人
|
||||
|
@ -12,7 +12,6 @@ import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
@ -25,7 +24,6 @@ import javax.validation.constraints.Size;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_dict_data")
|
||||
@ExcelIgnoreUnannotated
|
||||
@ApiModel("字典数据业务对象")
|
||||
|
@ -24,7 +24,6 @@ import javax.validation.constraints.Size;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_dict_type")
|
||||
@ExcelIgnoreUnannotated
|
||||
@ApiModel("字典类型业务对象")
|
||||
|
@ -8,9 +8,9 @@ import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
@ -21,7 +21,6 @@ import javax.validation.constraints.Size;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_menu")
|
||||
@ApiModel("菜单权限业务对象")
|
||||
public class SysMenu extends TreeEntity {
|
||||
@ -45,8 +44,8 @@ public class SysMenu extends TreeEntity {
|
||||
* 显示顺序
|
||||
*/
|
||||
@ApiModelProperty(value = "显示顺序")
|
||||
@NotBlank(message = "显示顺序不能为空")
|
||||
private String orderNum;
|
||||
@NotNull(message = "显示顺序不能为空")
|
||||
private Long orderNum;
|
||||
|
||||
/**
|
||||
* 路由地址
|
||||
|
@ -13,7 +13,6 @@ import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
@ -27,7 +26,6 @@ import javax.validation.constraints.Size;
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_role")
|
||||
@ExcelIgnoreUnannotated
|
||||
public class SysRole extends BaseEntity {
|
||||
|
@ -3,14 +3,15 @@ package com.ruoyi.common.core.domain.entity;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.ruoyi.common.annotation.Sensitive;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import com.ruoyi.common.enums.SensitiveStrategy;
|
||||
import com.ruoyi.common.xss.Xss;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@ -27,7 +28,6 @@ import java.util.List;
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_user")
|
||||
@ApiModel("用户信息业务对象")
|
||||
public class SysUser extends BaseEntity {
|
||||
@ -62,9 +62,16 @@ public class SysUser extends BaseEntity {
|
||||
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
|
||||
private String nickName;
|
||||
|
||||
/**
|
||||
* 用户类型(sys_user系统用户)
|
||||
*/
|
||||
@ApiModelProperty(value = "用户类型")
|
||||
private String userType;
|
||||
|
||||
/**
|
||||
* 用户邮箱
|
||||
*/
|
||||
@Sensitive(strategy = SensitiveStrategy.EMAIL)
|
||||
@ApiModelProperty(value = "用户邮箱")
|
||||
@Email(message = "邮箱格式不正确")
|
||||
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
||||
@ -73,6 +80,7 @@ public class SysUser extends BaseEntity {
|
||||
/**
|
||||
* 手机号码
|
||||
*/
|
||||
@Sensitive(strategy = SensitiveStrategy.PHONE)
|
||||
@ApiModelProperty(value = "手机号码")
|
||||
private String phonenumber;
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
package com.ruoyi.common.core.domain.model;
|
||||
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
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
|
||||
@Accessors(chain = true)
|
||||
@ApiModel("用户登录对象")
|
||||
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 = "用户名")
|
||||
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 = "用户密码")
|
||||
private String password;
|
||||
|
||||
@ -38,6 +44,6 @@ public class LoginBody {
|
||||
* 唯一标识
|
||||
*/
|
||||
@ApiModelProperty(value = "唯一标识")
|
||||
private String uuid = "";
|
||||
private String uuid;
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
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.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;
|
||||
|
||||
/**
|
||||
@ -18,8 +17,7 @@ import java.util.Set;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class LoginUser implements UserDetails {
|
||||
public class LoginUser implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ -33,11 +31,21 @@ public class LoginUser implements UserDetails {
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 部门名
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 用户唯一标识
|
||||
*/
|
||||
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 password;
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
private List<RoleDTO> roles;
|
||||
|
||||
/**
|
||||
* 账户是否未过期,过期无法验证
|
||||
* 数据权限 当前角色ID
|
||||
*/
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 指定用户是否解锁,锁定的用户无法进行身份验证
|
||||
* 获取登录id
|
||||
*/
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
public String getLoginId() {
|
||||
return userType + LoginHelper.JOIN_CODE + userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
|
||||
*/
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否可用 ,禁用的用户不能身份验证
|
||||
*/
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,21 @@
|
||||
package com.ruoyi.common.core.domain.model;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 用户注册对象
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel("用户注册对象")
|
||||
public class RegisterBody extends LoginBody {
|
||||
|
||||
@ApiModelProperty(value = "用户类型")
|
||||
private String userType;
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@ApiModel("分页响应对象")
|
||||
public class TableDataInfo<T> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.ruoyi.common.core.service;
|
||||
|
||||
/**
|
||||
* 脱敏服务
|
||||
* 默认管理员不过滤
|
||||
* 需自行根据业务重写实现
|
||||
*
|
||||
* @author Lion Li
|
||||
* @version 3.6.0
|
||||
*/
|
||||
public interface SensitiveService {
|
||||
|
||||
/**
|
||||
* 是否脱敏
|
||||
*/
|
||||
boolean isSensitive();
|
||||
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package com.ruoyi.common.core.service;
|
||||
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* token验证处理
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface TokenService {
|
||||
|
||||
/**
|
||||
* 获取用户身份信息
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
LoginUser getLoginUser(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 设置用户身份信息
|
||||
*/
|
||||
void setLoginUser(LoginUser loginUser);
|
||||
|
||||
/**
|
||||
* 删除用户身份信息
|
||||
*/
|
||||
void delLoginUser(String token);
|
||||
|
||||
/**
|
||||
* 创建令牌
|
||||
*
|
||||
* @param loginUser 用户信息
|
||||
* @return 令牌
|
||||
*/
|
||||
String createToken(LoginUser loginUser);
|
||||
|
||||
/**
|
||||
* 验证令牌有效期,相差不足20分钟,自动刷新缓存
|
||||
*
|
||||
* @param loginUser
|
||||
* @return 令牌
|
||||
*/
|
||||
void verifyToken(LoginUser loginUser);
|
||||
|
||||
/**
|
||||
* 刷新令牌有效期
|
||||
*
|
||||
* @param loginUser 登录信息
|
||||
*/
|
||||
void refreshToken(LoginUser loginUser);
|
||||
|
||||
/**
|
||||
* 设置用户代理信息
|
||||
*
|
||||
* @param loginUser 登录信息
|
||||
*/
|
||||
void setUserAgent(LoginUser loginUser);
|
||||
|
||||
/**
|
||||
* 从令牌中获取用户名
|
||||
*
|
||||
* @param token 令牌
|
||||
* @return 用户名
|
||||
*/
|
||||
String getUsernameFromToken(String token);
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.ruoyi.common.core.service;
|
||||
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
|
||||
/**
|
||||
* 通用 用户业务
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public interface UserService {
|
||||
|
||||
/**
|
||||
* 通过用户名查询用户
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return 用户对象信息
|
||||
*/
|
||||
SysUser selectUserByUserName(String userName);
|
||||
|
||||
/**
|
||||
* 通过用户ID查询用户
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 用户对象信息
|
||||
*/
|
||||
SysUser selectUserById(Long userId);
|
||||
|
||||
}
|
@ -6,10 +6,10 @@ import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 数据权限类型
|
||||
*
|
||||
* <p>
|
||||
* 语法支持 spel 模板表达式
|
||||
*
|
||||
* 内置数据 user 当前用户 内容参考 SysUser
|
||||
* <p>
|
||||
* 内置数据 user 当前用户 内容参考 LoginUser
|
||||
* 如需扩展数据 可使用 {@link com.ruoyi.common.helper.DataPermissionHelper} 操作
|
||||
* 内置服务 sdss 系统数据权限服务 内容参考 SysDataScopeService
|
||||
* 如需扩展更多自定义服务 可以参考 sdss 自行编写
|
||||
|
@ -1,27 +0,0 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 数据源
|
||||
*
|
||||
* @author Lion Li
|
||||
* @deprecated 3.6.0 移除
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Deprecated
|
||||
public enum DataSourceType {
|
||||
/**
|
||||
* 主库
|
||||
*/
|
||||
MASTER("master"),
|
||||
|
||||
/**
|
||||
* 从库
|
||||
*/
|
||||
SLAVE("slave");
|
||||
|
||||
@Getter
|
||||
private final String source;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user