mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2025-09-17 16:56:39 +08:00
🐣发布 4.3.0 正式版
This commit is contained in:
parent
c5f4dec559
commit
ee48cd7d01
@ -10,7 +10,7 @@ end_of_line = lf
|
|||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
||||||
[*.{json,yml}]
|
[*.{json,yml,yaml}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
|
22
README.md
22
README.md
@ -4,13 +4,16 @@
|
|||||||
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
|
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
|
||||||
[](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
|
[](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
|
||||||
<br>
|
<br>
|
||||||
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
|
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
|
|
||||||
> RuoYi-Vue-Plus 是重写 RuoYi-Vue 针对 `分布式集群` 场景全方位升级(不兼容原框架)
|
> RuoYi-Vue-Plus 是重写 RuoYi-Vue 针对 `分布式集群` 场景全方位升级(不兼容原框架)
|
||||||
|
|
||||||
|
> 项目代码、文档 均开源免费可商用 遵循开源协议在项目中保留开源协议文件即可<br>
|
||||||
|
活到老写到老 为兴趣而开源 为学习而开源 为让大家真正可以学到技术而开源
|
||||||
|
|
||||||
> 系统演示: [传送门](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/系统演示?sort_id=4836388)
|
> 系统演示: [传送门](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/系统演示?sort_id=4836388)
|
||||||
|
|
||||||
| 功能介绍 | 使用技术 | 文档地址 | 特性注意事项 |
|
| 功能介绍 | 使用技术 | 文档地址 | 特性注意事项 |
|
||||||
@ -46,7 +49,7 @@
|
|||||||
| 监控框架 | SpringBoot-Admin | [SpringBoot-Admin文档](https://codecentric.github.io/spring-boot-admin/current/) | 全方位服务监控 |
|
| 监控框架 | SpringBoot-Admin | [SpringBoot-Admin文档](https://codecentric.github.io/spring-boot-admin/current/) | 全方位服务监控 |
|
||||||
| 校验框架 | Validation | [Validation文档](https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/) | 增强接口安全性、严谨性 支持国际化 |
|
| 校验框架 | Validation | [Validation文档](https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/) | 增强接口安全性、严谨性 支持国际化 |
|
||||||
| Excel框架 | Alibaba EasyExcel | [EasyExcel文档](https://www.yuque.com/easyexcel/doc/easyexcel) | 性能优异 扩展性强 |
|
| Excel框架 | Alibaba EasyExcel | [EasyExcel文档](https://www.yuque.com/easyexcel/doc/easyexcel) | 性能优异 扩展性强 |
|
||||||
| 文档框架 | Knife4j | [Knife4j文档](https://doc.xiaominfo.com/knife4j/documentation/) | 美化接口文档 |
|
| 文档框架 | SpringDoc、javadoc | [接口文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=5805266&doc_id=1469725) | 无注解零入侵基于java注释 |
|
||||||
| 工具类框架 | Hutool、Lombok | [Hutool文档](https://www.hutool.cn/docs/) | 减少代码冗余 增加安全性 |
|
| 工具类框架 | Hutool、Lombok | [Hutool文档](https://www.hutool.cn/docs/) | 减少代码冗余 增加安全性 |
|
||||||
| 代码生成器 | 适配MP、Knife4j规范化代码 | [Hutool文档](https://www.hutool.cn/docs/) | 一键生成前后端代码 |
|
| 代码生成器 | 适配MP、Knife4j规范化代码 | [Hutool文档](https://www.hutool.cn/docs/) | 一键生成前后端代码 |
|
||||||
| 部署方式 | Docker | [Docker文档](https://docs.docker.com/) | 容器编排 一键部署业务集群 |
|
| 部署方式 | Docker | [Docker文档](https://docs.docker.com/) | 容器编排 一键部署业务集群 |
|
||||||
@ -56,11 +59,14 @@
|
|||||||
|
|
||||||
使用框架前请仔细阅读文档重点注意事项
|
使用框架前请仔细阅读文档重点注意事项
|
||||||
<br>
|
<br>
|
||||||
>[初始化项目 必看](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/关于初始化项目?sort_id=4164117)
|
>[初始化项目 必看](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4164117&doc_id=1469725)
|
||||||
>>[https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/关于初始化项目?sort_id=4164117](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/关于初始化项目?sort_id=4164117)
|
>>[https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4164117&doc_id=1469725](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4164117&doc_id=1469725)
|
||||||
>
|
>
|
||||||
>[部署项目 必看](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/关于应用部署?sort_id=4219382)
|
>[专栏与视频 入门必看](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=5473272&doc_id=1469725)
|
||||||
>>[https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/关于应用部署?sort_id=4219382](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/关于应用部署?sort_id=4219382)
|
>>[https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=5473272&doc_id=1469725](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=5473272&doc_id=1469725)
|
||||||
|
>
|
||||||
|
>[部署项目 必看](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4219382&doc_id=1469725)
|
||||||
|
>>[https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4219382&doc_id=1469725](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4219382&doc_id=1469725)
|
||||||
>
|
>
|
||||||
>[参考文档 Wiki](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages)
|
>[参考文档 Wiki](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages)
|
||||||
>>[https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages)
|
>>[https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages)
|
||||||
|
92
pom.xml
92
pom.xml
@ -6,53 +6,46 @@
|
|||||||
|
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<version>4.2.0</version>
|
<version>4.3.0</version>
|
||||||
|
|
||||||
<name>RuoYi-Vue-Plus</name>
|
<name>RuoYi-Vue-Plus</name>
|
||||||
<url>https://gitee.com/JavaLionLi/RuoYi-Vue-Plus</url>
|
<url>https://gitee.com/JavaLionLi/RuoYi-Vue-Plus</url>
|
||||||
<description>RuoYi-Vue-Plus后台管理系统</description>
|
<description>RuoYi-Vue-Plus后台管理系统</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<ruoyi-vue-plus.version>4.2.0</ruoyi-vue-plus.version>
|
<ruoyi-vue-plus.version>4.3.0</ruoyi-vue-plus.version>
|
||||||
<spring-boot.version>2.6.9</spring-boot.version>
|
<spring-boot.version>2.7.3</spring-boot.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
||||||
<spring-boot.mybatis>2.2.2</spring-boot.mybatis>
|
<spring-boot.mybatis>2.2.2</spring-boot.mybatis>
|
||||||
<druid.version>1.2.11</druid.version>
|
<druid.version>1.2.12</druid.version>
|
||||||
<knife4j.version>3.0.3</knife4j.version>
|
<springdoc.version>1.6.11</springdoc.version>
|
||||||
<swagger-annotations.version>1.5.22</swagger-annotations.version>
|
|
||||||
<poi.version>5.2.2</poi.version>
|
<poi.version>5.2.2</poi.version>
|
||||||
<easyexcel.version>3.1.1</easyexcel.version>
|
<easyexcel.version>3.1.1</easyexcel.version>
|
||||||
<velocity.version>2.3</velocity.version>
|
<velocity.version>2.3</velocity.version>
|
||||||
<satoken.version>1.30.0</satoken.version>
|
<satoken.version>1.30.0</satoken.version>
|
||||||
<mybatis-plus.version>3.5.2</mybatis-plus.version>
|
<mybatis-plus.version>3.5.2</mybatis-plus.version>
|
||||||
<p6spy.version>3.9.1</p6spy.version>
|
<p6spy.version>3.9.1</p6spy.version>
|
||||||
<hutool.version>5.8.3</hutool.version>
|
<hutool.version>5.8.6</hutool.version>
|
||||||
<okhttp.version>4.9.3</okhttp.version>
|
<okhttp.version>4.10.0</okhttp.version>
|
||||||
<spring-boot-admin.version>2.6.7</spring-boot-admin.version>
|
<spring-boot-admin.version>2.7.4</spring-boot-admin.version>
|
||||||
<redisson.version>3.17.4</redisson.version>
|
<redisson.version>3.17.6</redisson.version>
|
||||||
<lock4j.version>2.2.1</lock4j.version>
|
<lock4j.version>2.2.2</lock4j.version>
|
||||||
<dynamic-ds.version>3.5.1</dynamic-ds.version>
|
<dynamic-ds.version>3.5.2</dynamic-ds.version>
|
||||||
<tlog.version>1.4.3</tlog.version>
|
<tlog.version>1.4.3</tlog.version>
|
||||||
<xxl-job.version>2.3.1</xxl-job.version>
|
<xxl-job.version>2.3.1</xxl-job.version>
|
||||||
|
<lombok.version>1.18.24</lombok.version>
|
||||||
|
|
||||||
<!-- 统一 guava 版本 解决隐式漏洞问题 -->
|
<!-- 统一 guava 版本 解决隐式漏洞问题 -->
|
||||||
<guava.version>30.0-jre</guava.version>
|
<guava.version>31.1-jre</guava.version>
|
||||||
|
|
||||||
<!-- OSS 配置 -->
|
<!-- OSS 配置 -->
|
||||||
<aws-java-sdk-s3.version>1.12.248</aws-java-sdk-s3.version>
|
<aws-java-sdk-s3.version>1.12.300</aws-java-sdk-s3.version>
|
||||||
<!-- SMS 配置 -->
|
<!-- SMS 配置 -->
|
||||||
<aliyun.sms.version>2.0.9</aliyun.sms.version>
|
<aliyun.sms.version>2.0.18</aliyun.sms.version>
|
||||||
<tencent.sms.version>3.1.537</tencent.sms.version>
|
<tencent.sms.version>3.1.591</tencent.sms.version>
|
||||||
|
|
||||||
<!-- docker 配置 -->
|
|
||||||
<docker.registry.url>localhost</docker.registry.url>
|
|
||||||
<docker.registry.host>http://${docker.registry.url}:2375</docker.registry.host>
|
|
||||||
<docker.namespace>ruoyi</docker.namespace>
|
|
||||||
<docker.plugin.version>1.2.2</docker.plugin.version>
|
|
||||||
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<!-- 依赖声明 -->
|
<!-- 依赖声明 -->
|
||||||
@ -85,21 +78,21 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.xiaoymin</groupId>
|
<groupId>org.springdoc</groupId>
|
||||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
<artifactId>springdoc-openapi-webmvc-core</artifactId>
|
||||||
<version>${knife4j.version}</version>
|
<version>${springdoc.version}</version>
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>swagger-annotations</artifactId>
|
|
||||||
<groupId>io.swagger</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.swagger</groupId>
|
<groupId>org.springdoc</groupId>
|
||||||
<artifactId>swagger-annotations</artifactId>
|
<artifactId>springdoc-openapi-javadoc</artifactId>
|
||||||
<version>${swagger-annotations.version}</version>
|
<version>${springdoc.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -142,6 +135,12 @@
|
|||||||
<groupId>cn.dev33</groupId>
|
<groupId>cn.dev33</groupId>
|
||||||
<artifactId>sa-token-jwt</artifactId>
|
<artifactId>sa-token-jwt</artifactId>
|
||||||
<version>${satoken.version}</version>
|
<version>${satoken.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- dynamic-datasource 多数据源-->
|
<!-- dynamic-datasource 多数据源-->
|
||||||
@ -274,6 +273,23 @@
|
|||||||
<source>${java.version}</source>
|
<source>${java.version}</source>
|
||||||
<target>${java.version}</target>
|
<target>${java.version}</target>
|
||||||
<encoding>${project.build.sourceEncoding}</encoding>
|
<encoding>${project.build.sourceEncoding}</encoding>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>com.github.therapi</groupId>
|
||||||
|
<artifactId>therapi-runtime-javadoc-scribe</artifactId>
|
||||||
|
<version>0.15.0</version>
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
@ -329,8 +345,6 @@
|
|||||||
<!-- 环境标识,需要与配置文件的名称相对应 -->
|
<!-- 环境标识,需要与配置文件的名称相对应 -->
|
||||||
<profiles.active>local</profiles.active>
|
<profiles.active>local</profiles.active>
|
||||||
<logging.level>debug</logging.level>
|
<logging.level>debug</logging.level>
|
||||||
<knife4j.production>false</knife4j.production>
|
|
||||||
<endpoints.include>'*'</endpoints.include>
|
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
@ -339,8 +353,6 @@
|
|||||||
<!-- 环境标识,需要与配置文件的名称相对应 -->
|
<!-- 环境标识,需要与配置文件的名称相对应 -->
|
||||||
<profiles.active>dev</profiles.active>
|
<profiles.active>dev</profiles.active>
|
||||||
<logging.level>debug</logging.level>
|
<logging.level>debug</logging.level>
|
||||||
<knife4j.production>false</knife4j.production>
|
|
||||||
<endpoints.include>'*'</endpoints.include>
|
|
||||||
</properties>
|
</properties>
|
||||||
<activation>
|
<activation>
|
||||||
<!-- 默认环境 -->
|
<!-- 默认环境 -->
|
||||||
@ -352,8 +364,6 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<profiles.active>prod</profiles.active>
|
<profiles.active>prod</profiles.active>
|
||||||
<logging.level>warn</logging.level>
|
<logging.level>warn</logging.level>
|
||||||
<knife4j.production>true</knife4j.production>
|
|
||||||
<endpoints.include>health, info, logfile</endpoints.include>
|
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>4.2.0</version>
|
<version>4.3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>ruoyi-extend</artifactId>
|
<artifactId>ruoyi-extend</artifactId>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-extend</artifactId>
|
<artifactId>ruoyi-extend</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>4.2.0</version>
|
<version>4.3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@ -59,25 +59,6 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>com.spotify</groupId>
|
|
||||||
<artifactId>docker-maven-plugin</artifactId>
|
|
||||||
<version>${docker.plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<imageName>${docker.namespace}/${project.artifactId}:${project.version}</imageName>
|
|
||||||
<dockerDirectory>${project.basedir}</dockerDirectory>
|
|
||||||
<dockerHost>${docker.registry.host}</dockerHost>
|
|
||||||
<registryUrl>${docker.registry.url}</registryUrl>
|
|
||||||
<serverId>${docker.registry.url}</serverId>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<targetPath>/</targetPath>
|
|
||||||
<directory>${project.build.directory}</directory>
|
|
||||||
<include>${project.build.finalName}.jar</include>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.ruoyi.monitor.admin.config;
|
package com.ruoyi.monitor.admin.config;
|
||||||
|
|
||||||
import de.codecentric.boot.admin.server.config.AdminServerProperties;
|
import de.codecentric.boot.admin.server.config.AdminServerProperties;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,9 +12,8 @@ import org.springframework.security.web.authentication.SavedRequestAwareAuthenti
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Configuration
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
public class SecurityConfig {
|
||||||
|
|
||||||
private final String adminContextPath;
|
private final String adminContextPath;
|
||||||
|
|
||||||
@ -22,27 +21,30 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
this.adminContextPath = adminServerProperties.getContextPath();
|
this.adminContextPath = adminServerProperties.getContextPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Bean
|
||||||
protected void configure(HttpSecurity httpSecurity) throws Exception {
|
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
|
||||||
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
|
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
|
||||||
successHandler.setTargetUrlParameter("redirectTo");
|
successHandler.setTargetUrlParameter("redirectTo");
|
||||||
successHandler.setDefaultTargetUrl(adminContextPath + "/");
|
successHandler.setDefaultTargetUrl(adminContextPath + "/");
|
||||||
// admin监控 用户鉴权
|
|
||||||
httpSecurity.authorizeRequests()
|
return httpSecurity
|
||||||
//授予对所有静态资产和登录页面的公共访问权限。
|
.headers().frameOptions().disable()
|
||||||
.antMatchers(adminContextPath + "/assets/**").permitAll()
|
.and().authorizeRequests()
|
||||||
.antMatchers(adminContextPath + "/login").permitAll()
|
.antMatchers(adminContextPath + "/assets/**"
|
||||||
.antMatchers("/actuator").permitAll()
|
, adminContextPath + "/login"
|
||||||
.antMatchers("/actuator/**").permitAll()
|
, "/actuator"
|
||||||
//必须对每个其他请求进行身份验证
|
, "/actuator/**"
|
||||||
.anyRequest().authenticated().and()
|
).permitAll()
|
||||||
//配置登录和注销
|
.anyRequest().authenticated()
|
||||||
.formLogin().loginPage(adminContextPath + "/login")
|
.and()
|
||||||
.successHandler(successHandler).and()
|
.formLogin().loginPage(adminContextPath + "/login")
|
||||||
.logout().logoutUrl(adminContextPath + "/logout").and()
|
.successHandler(successHandler).and()
|
||||||
//启用HTTP-Basic支持。这是Spring Boot Admin Client注册所必需的
|
.logout().logoutUrl(adminContextPath + "/logout")
|
||||||
.httpBasic().and().csrf().disable()
|
.and()
|
||||||
.headers().frameOptions().disable();
|
.httpBasic().and()
|
||||||
|
.csrf()
|
||||||
|
.disable()
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,18 +14,29 @@ spring:
|
|||||||
password: 123456
|
password: 123456
|
||||||
boot:
|
boot:
|
||||||
admin:
|
admin:
|
||||||
|
ui:
|
||||||
|
title: RuoYi-Vue-Plus服务监控中心
|
||||||
context-path: /admin
|
context-path: /admin
|
||||||
|
|
||||||
--- # Actuator 监控端点的配置项
|
--- # Actuator 监控端点的配置项
|
||||||
management:
|
management:
|
||||||
endpoints:
|
endpoints:
|
||||||
web:
|
web:
|
||||||
# Actuator 提供的 API 接口的根目录。默认为 /actuator
|
|
||||||
base-path: /actuator
|
|
||||||
exposure:
|
exposure:
|
||||||
# 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
|
include: '*'
|
||||||
# 生产环境不建议放开所有 根据项目需求放开即可
|
|
||||||
include: @endpoints.include@
|
|
||||||
endpoint:
|
endpoint:
|
||||||
|
health:
|
||||||
|
show-details: ALWAYS
|
||||||
logfile:
|
logfile:
|
||||||
external-file: ./logs/ruoyi-monitor-admin.log
|
external-file: ./logs/ruoyi-monitor-admin.log
|
||||||
|
|
||||||
|
--- # 监控配置
|
||||||
|
spring.boot.admin.client:
|
||||||
|
# 增加客户端开关
|
||||||
|
enabled: true
|
||||||
|
# 设置 Spring Boot Admin Server 地址
|
||||||
|
url: http://localhost:9090/admin
|
||||||
|
instance:
|
||||||
|
service-host-type: IP
|
||||||
|
username: ruoyi
|
||||||
|
password: 123456
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-extend</artifactId>
|
<artifactId>ruoyi-extend</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>4.2.0</version>
|
<version>4.3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>ruoyi-xxl-job-admin</artifactId>
|
<artifactId>ruoyi-xxl-job-admin</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@ -96,27 +96,6 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- docker -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>com.spotify</groupId>
|
|
||||||
<artifactId>docker-maven-plugin</artifactId>
|
|
||||||
<version>${docker.plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<!-- made of '[a-z0-9-_.]' -->
|
|
||||||
<imageName>${docker.namespace}/${project.artifactId}:${project.version}</imageName>
|
|
||||||
<dockerDirectory>${project.basedir}</dockerDirectory>
|
|
||||||
<dockerHost>${docker.registry.host}</dockerHost>
|
|
||||||
<registryUrl>${docker.registry.url}</registryUrl>
|
|
||||||
<serverId>${docker.registry.url}</serverId>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<targetPath>/</targetPath>
|
|
||||||
<directory>${project.build.directory}</directory>
|
|
||||||
<include>${project.build.finalName}.jar</include>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
@ -21,10 +21,10 @@ import java.io.IOException;
|
|||||||
public class JacksonUtil {
|
public class JacksonUtil {
|
||||||
private static Logger logger = LoggerFactory.getLogger(JacksonUtil.class);
|
private static Logger logger = LoggerFactory.getLogger(JacksonUtil.class);
|
||||||
|
|
||||||
private final static ObjectMapper objectMapper = new ObjectMapper();
|
private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
public static ObjectMapper getInstance() {
|
public static ObjectMapper getInstance() {
|
||||||
return objectMapper;
|
return OBJECT_MAPPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
--- # 监控配置
|
--- # 监控配置
|
||||||
spring:
|
spring.boot.admin.client:
|
||||||
boot:
|
# 增加客户端开关
|
||||||
admin:
|
enabled: true
|
||||||
# Spring Boot Admin Client 客户端的相关配置
|
# 设置 Spring Boot Admin Server 地址
|
||||||
client:
|
url: http://localhost:9090/admin
|
||||||
# 增加客户端开关
|
instance:
|
||||||
enabled: true
|
service-host-type: IP
|
||||||
# 设置 Spring Boot Admin Server 地址
|
username: ruoyi
|
||||||
url: http://localhost:9090/admin
|
password: 123456
|
||||||
instance:
|
|
||||||
service-host-type: IP
|
|
||||||
username: ruoyi
|
|
||||||
password: 123456
|
|
||||||
|
|
||||||
--- # 数据库配置
|
--- # 数据库配置
|
||||||
spring:
|
spring:
|
||||||
|
@ -1,24 +1,20 @@
|
|||||||
--- # 监控配置
|
--- # 监控配置
|
||||||
spring:
|
spring.boot.admin.client:
|
||||||
boot:
|
# 增加客户端开关
|
||||||
admin:
|
enabled: true
|
||||||
# Spring Boot Admin Client 客户端的相关配置
|
# 设置 Spring Boot Admin Server 地址
|
||||||
client:
|
url: http://localhost:9090/admin
|
||||||
# 增加客户端开关
|
instance:
|
||||||
enabled: true
|
service-host-type: IP
|
||||||
# 设置 Spring Boot Admin Server 地址
|
username: ruoyi
|
||||||
url: http://172.30.0.90:9090/admin
|
password: 123456
|
||||||
instance:
|
|
||||||
service-host-type: IP
|
|
||||||
username: ruoyi
|
|
||||||
password: 123456
|
|
||||||
|
|
||||||
--- # 数据库配置
|
--- # 数据库配置
|
||||||
spring:
|
spring:
|
||||||
datasource:
|
datasource:
|
||||||
type: com.zaxxer.hikari.HikariDataSource
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://172.30.0.36:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
|
url: jdbc:mysql://127.0.0.1:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
|
||||||
username: root
|
username: root
|
||||||
password: root
|
password: root
|
||||||
hikari:
|
hikari:
|
||||||
|
@ -37,13 +37,11 @@ management:
|
|||||||
enabled: false
|
enabled: false
|
||||||
endpoints:
|
endpoints:
|
||||||
web:
|
web:
|
||||||
# Actuator 提供的 API 接口的根目录。默认为 /actuator
|
|
||||||
base-path: /actuator
|
|
||||||
exposure:
|
exposure:
|
||||||
# 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
|
include: '*'
|
||||||
# 生产环境不建议放开所有 根据项目需求放开即可
|
|
||||||
include: @endpoints.include@
|
|
||||||
endpoint:
|
endpoint:
|
||||||
|
health:
|
||||||
|
show-details: ALWAYS
|
||||||
logfile:
|
logfile:
|
||||||
external-file: ./logs/ruoyi-xxl-job-admin.log
|
external-file: ./logs/ruoyi-xxl-job-admin.log
|
||||||
|
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
# 页面标题
|
|
||||||
VUE_APP_TITLE = RuoYi-Vue-Plus后台管理系统
|
|
||||||
|
|
||||||
NODE_ENV = production
|
|
||||||
|
|
||||||
# 测试环境配置
|
|
||||||
ENV = 'staging'
|
|
||||||
|
|
||||||
# 应用访问路径 例如使用前缀 /admin/
|
|
||||||
VUE_APP_CONTEXT_PATH = '/'
|
|
||||||
|
|
||||||
# 监控地址
|
|
||||||
VUE_APP_MONITRO_ADMIN = '/admin/login'
|
|
||||||
|
|
||||||
# 监控地址
|
|
||||||
VUE_APP_XXL_JOB_ADMIN = '/xxl-job-admin'
|
|
||||||
|
|
||||||
# 若依管理系统/测试环境
|
|
||||||
VUE_APP_BASE_API = '/stage-api'
|
|
@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ruoyi-vue-plus",
|
"name": "ruoyi-vue-plus",
|
||||||
"version": "4.2.0",
|
"version": "4.3.0",
|
||||||
"description": "RuoYi-Vue-Plus后台管理系统",
|
"description": "RuoYi-Vue-Plus后台管理系统",
|
||||||
"author": "LionLi",
|
"author": "LionLi",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vue-cli-service serve",
|
"dev": "vue-cli-service serve",
|
||||||
"build:prod": "vue-cli-service build",
|
"build:prod": "vue-cli-service build",
|
||||||
"build:stage": "vue-cli-service build --mode staging",
|
|
||||||
"preview": "node build/index.js --preview",
|
"preview": "node build/index.js --preview",
|
||||||
"lint": "eslint --ext .js,.vue src"
|
"lint": "eslint --ext .js,.vue src"
|
||||||
},
|
},
|
||||||
|
@ -7,3 +7,51 @@ export function getCache() {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询缓存名称列表
|
||||||
|
export function listCacheName() {
|
||||||
|
return request({
|
||||||
|
url: '/monitor/cache/getNames',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询缓存键名列表
|
||||||
|
export function listCacheKey(cacheName) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor/cache/getKeys/' + cacheName,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询缓存内容
|
||||||
|
export function getCacheValue(cacheName, cacheKey) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理指定名称缓存
|
||||||
|
export function clearCacheName(cacheName) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor/cache/clearCacheName/' + cacheName,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理指定键名缓存
|
||||||
|
export function clearCacheKey(cacheName, cacheKey) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor/cache/clearCacheKey/'+ cacheName + "/" + cacheKey,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理全部缓存
|
||||||
|
export function clearCacheAll() {
|
||||||
|
return request({
|
||||||
|
url: '/monitor/cache/clearCacheAll',
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -17,6 +17,14 @@ export function delLogininfor(infoId) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解锁用户登录状态
|
||||||
|
export function unlockLogininfor(userName) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor/logininfor/unlock/' + userName,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 清空登录日志
|
// 清空登录日志
|
||||||
export function cleanLogininfor() {
|
export function cleanLogininfor() {
|
||||||
return request({
|
return request({
|
||||||
|
@ -25,22 +25,6 @@ export function getDept(deptId) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询部门下拉树结构
|
|
||||||
export function treeselect() {
|
|
||||||
return request({
|
|
||||||
url: '/system/dept/treeselect',
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据角色ID查询部门树结构
|
|
||||||
export function roleDeptTreeselect(roleId) {
|
|
||||||
return request({
|
|
||||||
url: '/system/dept/roleDeptTreeselect/' + roleId,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增部门
|
// 新增部门
|
||||||
export function addDept(data) {
|
export function addDept(data) {
|
||||||
return request({
|
return request({
|
||||||
@ -65,4 +49,4 @@ export function delDept(deptId) {
|
|||||||
url: '/system/dept/' + deptId,
|
url: '/system/dept/' + deptId,
|
||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ export function delOssConfig(ossConfigId) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户状态修改
|
// 对象存储状态修改
|
||||||
export function changeOssConfigStatus(ossConfigId, status, configKey) {
|
export function changeOssConfigStatus(ossConfigId, status, configKey) {
|
||||||
const data = {
|
const data = {
|
||||||
ossConfigId,
|
ossConfigId,
|
||||||
|
@ -109,3 +109,11 @@ export function authUserSelectAll(data) {
|
|||||||
params: data
|
params: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据角色ID查询部门树结构
|
||||||
|
export function deptTreeSelect(roleId) {
|
||||||
|
return request({
|
||||||
|
url: '/system/role/deptTree/' + roleId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -125,3 +125,11 @@ export function updateAuthRole(data) {
|
|||||||
params: data
|
params: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询部门下拉树结构
|
||||||
|
export function deptTreeSelect() {
|
||||||
|
return request({
|
||||||
|
url: '/system/user/deptTree',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
2
ruoyi-ui/src/assets/icons/svg/redis-list.svg
Normal file
2
ruoyi-ui/src/assets/icons/svg/redis-list.svg
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1656035183065" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3395" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
|
||||||
|
</style></defs><path d="M958.88 730.06H65.12c-18.28 0-33.12-14.82-33.12-33.12V68.91c0-18.29 14.83-33.12 33.12-33.12h893.77c18.28 0 33.12 14.82 33.12 33.12v628.03c-0.01 18.3-14.84 33.12-33.13 33.12zM98.23 663.83h827.53v-561.8H98.23v561.8z" p-id="3396"></path><path d="M512 954.55c-18.28 0-33.12-14.82-33.12-33.12V733.92c0-18.29 14.83-33.12 33.12-33.12s33.12 14.82 33.12 33.12v187.51c0 18.3-14.84 33.12-33.12 33.12z" p-id="3397"></path><path d="M762.01 988.21H261.99c-18.28 0-33.12-14.82-33.12-33.12 0-18.29 14.83-33.12 33.12-33.12h500.03c18.28 0 33.12 14.82 33.12 33.12-0.01 18.29-14.84 33.12-33.13 33.12zM514.74 578.55c-21.63 0-43.31-3.87-64.21-11.65-45.95-17.13-82.49-51.13-102.86-95.74-5.07-11.08-0.19-24.19 10.89-29.26 11.08-5.09 24.19-0.18 29.26 10.91 15.5 33.88 43.25 59.7 78.14 72.71 34.93 12.99 72.79 11.64 106.66-3.85 33.22-15.17 58.8-42.26 72.03-76.3 4.42-11.37 17.21-17.01 28.57-12.58 11.36 4.42 16.99 17.22 12.57 28.58-17.42 44.82-51.1 80.5-94.82 100.47-24.34 11.12-50.25 16.71-76.23 16.71z" p-id="3398"></path><path d="M325.27 528.78c-1.66 0-3.34-0.18-5.02-0.57-11.88-2.77-19.28-14.63-16.49-26.51l18.84-81c1.34-5.82 5-10.84 10.13-13.92 5.09-3.09 11.3-3.96 17.03-2.41l80.51 21.43c11.79 3.14 18.8 15.23 15.67 27.02-3.15 11.79-15.42 18.75-27.02 15.65l-58.49-15.57-13.69 58.81c-2.37 10.2-11.45 17.07-21.47 17.07zM360.8 351.01c-2.65 0-5.37-0.49-8-1.51-11.36-4.41-16.99-17.21-12.59-28.57 17.4-44.79 51.06-80.47 94.8-100.48 92.15-42.06 201.25-1.39 243.31 90.68 5.07 11.08 0.19 24.19-10.89 29.26-11.13 5.07-24.19 0.17-29.26-10.91-31.97-69.91-114.9-100.82-184.79-68.86-33.22 15.19-58.8 42.28-71.99 76.29-3.41 8.74-11.75 14.1-20.59 14.1z" p-id="3399"></path><path d="M684.68 376.74c-1.47 0-2.95-0.15-4.42-0.44l-81.61-16.68c-11.94-2.45-19.64-14.11-17.21-26.06 2.44-11.96 14.1-19.64 26.04-17.22l59.29 12.12 10.23-59.5c2.05-12 13.52-20.19 25.48-18.01 12.03 2.06 20.09 13.48 18.02 25.5l-14.08 81.96a22.089 22.089 0 0 1-9.29 14.49c-3.7 2.51-8.03 3.84-12.45 3.84z" p-id="3400"></path></svg>
|
After Width: | Height: | Size: 2.6 KiB |
@ -12,11 +12,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fade-transform */
|
/* fade-transform */
|
||||||
|
.fade-transform--move,
|
||||||
.fade-transform-leave-active,
|
.fade-transform-leave-active,
|
||||||
.fade-transform-enter-active {
|
.fade-transform-enter-active {
|
||||||
transition: all .5s;
|
transition: all .5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fade-transform-leave-active {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
.fade-transform-enter {
|
.fade-transform-enter {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateX(-30px);
|
transform: translateX(-30px);
|
||||||
|
@ -1,7 +1,23 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
import store from '@/store'
|
||||||
import DataDict from '@/utils/dict'
|
import DataDict from '@/utils/dict'
|
||||||
import { getDicts as getDicts } from '@/api/system/dict/data'
|
import { getDicts as getDicts } from '@/api/system/dict/data'
|
||||||
|
|
||||||
|
function searchDictByKey(dict, key) {
|
||||||
|
if (key == null && key == "") {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
for (let i = 0; i < dict.length; i++) {
|
||||||
|
if (dict[i].key == key) {
|
||||||
|
return dict[i].value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function install() {
|
function install() {
|
||||||
Vue.use(DataDict, {
|
Vue.use(DataDict, {
|
||||||
metas: {
|
metas: {
|
||||||
@ -9,7 +25,19 @@ function install() {
|
|||||||
labelField: 'dictLabel',
|
labelField: 'dictLabel',
|
||||||
valueField: 'dictValue',
|
valueField: 'dictValue',
|
||||||
request(dictMeta) {
|
request(dictMeta) {
|
||||||
return getDicts(dictMeta.type).then(res => res.data)
|
const storeDict = searchDictByKey(store.getters.dict, dictMeta.type)
|
||||||
|
if (storeDict) {
|
||||||
|
return new Promise(resolve => { resolve(storeDict) })
|
||||||
|
} else {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
getDicts(dictMeta.type).then(res => {
|
||||||
|
store.dispatch('dict/setDict', { key: dictMeta.type, value: res.data })
|
||||||
|
resolve(res.data)
|
||||||
|
}).catch(error => {
|
||||||
|
reject(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
class="upload-file-uploader"
|
class="upload-file-uploader"
|
||||||
ref="upload"
|
ref="fileUpload"
|
||||||
>
|
>
|
||||||
<!-- 上传按钮 -->
|
<!-- 上传按钮 -->
|
||||||
<el-button size="mini" type="primary">选取文件</el-button>
|
<el-button size="mini" type="primary">选取文件</el-button>
|
||||||
@ -157,22 +157,19 @@ export default {
|
|||||||
// 上传失败
|
// 上传失败
|
||||||
handleUploadError(err) {
|
handleUploadError(err) {
|
||||||
this.$modal.msgError("上传图片失败,请重试");
|
this.$modal.msgError("上传图片失败,请重试");
|
||||||
this.$modal.closeLoading()
|
this.$modal.closeLoading();
|
||||||
},
|
},
|
||||||
// 上传成功回调
|
// 上传成功回调
|
||||||
handleUploadSuccess(res, file) {
|
handleUploadSuccess(res, file) {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
|
this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
|
||||||
if (this.uploadList.length === this.number) {
|
this.uploadedSuccessfully();
|
||||||
this.fileList = this.fileList.concat(this.uploadList);
|
|
||||||
this.uploadList = [];
|
|
||||||
this.number = 0;
|
|
||||||
this.$emit("input", this.listToString(this.fileList));
|
|
||||||
this.$modal.closeLoading();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.$modal.msgError(res.msg);
|
this.number--;
|
||||||
this.$modal.closeLoading();
|
this.$modal.closeLoading();
|
||||||
|
this.$modal.msgError(res.msg);
|
||||||
|
this.$refs.fileUpload.handleRemove(file);
|
||||||
|
this.uploadedSuccessfully();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 删除文件
|
// 删除文件
|
||||||
@ -182,6 +179,16 @@ export default {
|
|||||||
this.fileList.splice(index, 1);
|
this.fileList.splice(index, 1);
|
||||||
this.$emit("input", this.listToString(this.fileList));
|
this.$emit("input", this.listToString(this.fileList));
|
||||||
},
|
},
|
||||||
|
// 上传结束处理
|
||||||
|
uploadedSuccessfully() {
|
||||||
|
if (this.number > 0 && this.uploadList.length === this.number) {
|
||||||
|
this.fileList = this.fileList.concat(this.uploadList);
|
||||||
|
this.uploadList = [];
|
||||||
|
this.number = 0;
|
||||||
|
this.$emit("input", this.listToString(this.fileList));
|
||||||
|
this.$modal.closeLoading();
|
||||||
|
}
|
||||||
|
},
|
||||||
// 获取文件名称
|
// 获取文件名称
|
||||||
getFileName(name) {
|
getFileName(name) {
|
||||||
// 如果是url那么取最后的名字 如果不是直接返回
|
// 如果是url那么取最后的名字 如果不是直接返回
|
||||||
|
@ -18,7 +18,7 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
src: {
|
src: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
default: ""
|
||||||
},
|
},
|
||||||
width: {
|
width: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
@ -31,10 +31,16 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
realSrc() {
|
realSrc() {
|
||||||
|
if (!this.src) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let real_src = this.src.split(",")[0];
|
let real_src = this.src.split(",")[0];
|
||||||
return real_src;
|
return real_src;
|
||||||
},
|
},
|
||||||
realSrcList() {
|
realSrcList() {
|
||||||
|
if (!this.src) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let real_src_list = this.src.split(",");
|
let real_src_list = this.src.split(",");
|
||||||
let srcList = [];
|
let srcList = [];
|
||||||
real_src_list.forEach(item => {
|
real_src_list.forEach(item => {
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
:limit="limit"
|
:limit="limit"
|
||||||
:on-error="handleUploadError"
|
:on-error="handleUploadError"
|
||||||
:on-exceed="handleExceed"
|
:on-exceed="handleExceed"
|
||||||
name="file"
|
ref="imageUpload"
|
||||||
:on-remove="handleRemove"
|
:on-remove="handleDelete"
|
||||||
:show-file-list="true"
|
:show-file-list="true"
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
:file-list="fileList"
|
:file-list="fileList"
|
||||||
@ -120,32 +120,6 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 删除图片
|
|
||||||
handleRemove(file, fileList) {
|
|
||||||
const findex = this.fileList.map(f => f.name).indexOf(file.name);
|
|
||||||
if(findex > -1) {
|
|
||||||
let ossId = this.fileList[findex].ossId;
|
|
||||||
delOss(ossId);
|
|
||||||
this.fileList.splice(findex, 1);
|
|
||||||
this.$emit("input", this.listToString(this.fileList));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 上传成功回调
|
|
||||||
handleUploadSuccess(res) {
|
|
||||||
if (res.code == 200) {
|
|
||||||
this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
|
|
||||||
if (this.uploadList.length === this.number) {
|
|
||||||
this.fileList = this.fileList.concat(this.uploadList);
|
|
||||||
this.uploadList = [];
|
|
||||||
this.number = 0;
|
|
||||||
this.$emit("input", this.listToString(this.fileList));
|
|
||||||
this.$modal.closeLoading();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.$modal.msgError(res.msg);
|
|
||||||
this.$modal.closeLoading();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 上传前loading加载
|
// 上传前loading加载
|
||||||
handleBeforeUpload(file) {
|
handleBeforeUpload(file) {
|
||||||
let isImg = false;
|
let isImg = false;
|
||||||
@ -181,11 +155,44 @@ export default {
|
|||||||
handleExceed() {
|
handleExceed() {
|
||||||
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
|
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
|
||||||
},
|
},
|
||||||
|
// 上传成功回调
|
||||||
|
handleUploadSuccess(res, file) {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
|
||||||
|
this.uploadedSuccessfully();
|
||||||
|
} else {
|
||||||
|
this.number--;
|
||||||
|
this.$modal.closeLoading();
|
||||||
|
this.$modal.msgError(res.msg);
|
||||||
|
this.$refs.imageUpload.handleRemove(file);
|
||||||
|
this.uploadedSuccessfully();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 删除图片
|
||||||
|
handleDelete(file) {
|
||||||
|
const findex = this.fileList.map(f => f.name).indexOf(file.name);
|
||||||
|
if(findex > -1) {
|
||||||
|
let ossId = this.fileList[findex].ossId;
|
||||||
|
delOss(ossId);
|
||||||
|
this.fileList.splice(findex, 1);
|
||||||
|
this.$emit("input", this.listToString(this.fileList));
|
||||||
|
}
|
||||||
|
},
|
||||||
// 上传失败
|
// 上传失败
|
||||||
handleUploadError(res) {
|
handleUploadError(res) {
|
||||||
this.$modal.msgError("上传图片失败,请重试");
|
this.$modal.msgError("上传图片失败,请重试");
|
||||||
this.$modal.closeLoading();
|
this.$modal.closeLoading();
|
||||||
},
|
},
|
||||||
|
// 上传结束处理
|
||||||
|
uploadedSuccessfully() {
|
||||||
|
if (this.number > 0 && this.uploadList.length === this.number) {
|
||||||
|
this.fileList = this.fileList.concat(this.uploadList);
|
||||||
|
this.uploadList = [];
|
||||||
|
this.number = 0;
|
||||||
|
this.$emit("input", this.listToString(this.fileList));
|
||||||
|
this.$modal.closeLoading();
|
||||||
|
}
|
||||||
|
},
|
||||||
// 预览
|
// 预览
|
||||||
handlePictureCardPreview(file) {
|
handlePictureCardPreview(file) {
|
||||||
this.dialogImageUrl = file.url;
|
this.dialogImageUrl = file.url;
|
||||||
@ -196,10 +203,12 @@ export default {
|
|||||||
let strs = "";
|
let strs = "";
|
||||||
separator = separator || ",";
|
separator = separator || ",";
|
||||||
for (let i in list) {
|
for (let i in list) {
|
||||||
strs += list[i].ossId + separator;
|
if (list[i].ossId) {
|
||||||
|
strs += list[i].ossId + separator;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return strs != "" ? strs.substr(0, strs.length - 1) : "";
|
return strs != "" ? strs.substr(0, strs.length - 1) : "";
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="rightPanel" :class="{show:show}" class="rightPanel-container">
|
<div ref="rightPanel" class="rightPanel-container">
|
||||||
<div class="rightPanel-background" />
|
<div class="rightPanel-background" />
|
||||||
<div class="rightPanel">
|
<div class="rightPanel">
|
||||||
<div class="rightPanel-items">
|
<div class="rightPanel-items">
|
||||||
@ -10,18 +10,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { addClass, removeClass } from '@/utils'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'RightPanel',
|
name: 'RightPanel',
|
||||||
props: {
|
props: {
|
||||||
clickNotClose: {
|
clickNotClose: {
|
||||||
default: false,
|
default: false,
|
||||||
type: Boolean
|
type: Boolean
|
||||||
},
|
|
||||||
buttonTop: {
|
|
||||||
default: 250,
|
|
||||||
type: Number
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -35,21 +29,13 @@ export default {
|
|||||||
value: val
|
value: val
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
theme() {
|
|
||||||
return this.$store.state.settings.theme
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
show(value) {
|
show(value) {
|
||||||
if (value && !this.clickNotClose) {
|
if (value && !this.clickNotClose) {
|
||||||
this.addEventClick()
|
this.addEventClick()
|
||||||
}
|
}
|
||||||
if (value) {
|
|
||||||
addClass(document.body, 'showRightPanel')
|
|
||||||
} else {
|
|
||||||
removeClass(document.body, 'showRightPanel')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -65,7 +51,7 @@ export default {
|
|||||||
window.addEventListener('click', this.closeSidebar)
|
window.addEventListener('click', this.closeSidebar)
|
||||||
},
|
},
|
||||||
closeSidebar(evt) {
|
closeSidebar(evt) {
|
||||||
const parent = evt.target.closest('.rightPanel')
|
const parent = evt.target.closest('.el-drawer__body')
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
this.show = false
|
this.show = false
|
||||||
window.removeEventListener('click', this.closeSidebar)
|
window.removeEventListener('click', this.closeSidebar)
|
||||||
@ -80,14 +66,6 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
.showRightPanel {
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
width: calc(100% - 15px);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.rightPanel-background {
|
.rightPanel-background {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -113,21 +91,6 @@ export default {
|
|||||||
z-index: 40000;
|
z-index: 40000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.show {
|
|
||||||
transition: all .3s cubic-bezier(.7, .3, .1, 1);
|
|
||||||
|
|
||||||
.rightPanel-background {
|
|
||||||
z-index: 20000;
|
|
||||||
opacity: 1;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightPanel {
|
|
||||||
transform: translate(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.handle-button {
|
.handle-button {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="top-right-btn">
|
<div class="top-right-btn" :style="style">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top">
|
<el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
|
||||||
<el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" />
|
<el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
|
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
|
||||||
@ -42,6 +42,23 @@ export default {
|
|||||||
columns: {
|
columns: {
|
||||||
type: Array,
|
type: Array,
|
||||||
},
|
},
|
||||||
|
search: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
gutter: {
|
||||||
|
type: Number,
|
||||||
|
default: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
style() {
|
||||||
|
const ret = {};
|
||||||
|
if (this.gutter) {
|
||||||
|
ret.marginRight = `${this.gutter / 2}px`;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// 显隐列初始默认隐藏列
|
// 显隐列初始默认隐藏列
|
||||||
|
@ -2,15 +2,19 @@
|
|||||||
<section class="app-main">
|
<section class="app-main">
|
||||||
<transition name="fade-transform" mode="out-in">
|
<transition name="fade-transform" mode="out-in">
|
||||||
<keep-alive :include="cachedViews">
|
<keep-alive :include="cachedViews">
|
||||||
<router-view :key="key" />
|
<router-view v-if="!$route.meta.link" :key="key" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
|
<iframe-toggle />
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import iframeToggle from "./IframeToggle/index"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AppMain',
|
name: 'AppMain',
|
||||||
|
components: { iframeToggle },
|
||||||
computed: {
|
computed: {
|
||||||
cachedViews() {
|
cachedViews() {
|
||||||
return this.$store.state.tagsView.cachedViews
|
return this.$store.state.tagsView.cachedViews
|
||||||
@ -31,7 +35,7 @@ export default {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fixed-header+.app-main {
|
.fixed-header + .app-main {
|
||||||
padding-top: 50px;
|
padding-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +45,7 @@ export default {
|
|||||||
min-height: calc(100vh - 84px);
|
min-height: calc(100vh - 84px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.fixed-header+.app-main {
|
.fixed-header + .app-main {
|
||||||
padding-top: 84px;
|
padding-top: 84px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
ruoyi-ui/src/layout/components/IframeToggle/index.vue
Normal file
24
ruoyi-ui/src/layout/components/IframeToggle/index.vue
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<template>
|
||||||
|
<transition-group name="fade-transform" mode="out-in">
|
||||||
|
<inner-link
|
||||||
|
v-for="(item, index) in iframeViews"
|
||||||
|
:key="item.path"
|
||||||
|
:iframeId="'iframe' + index"
|
||||||
|
v-show="$route.path === item.path"
|
||||||
|
:src="item.meta.link"
|
||||||
|
></inner-link>
|
||||||
|
</transition-group>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import InnerLink from "../InnerLink/index"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { InnerLink },
|
||||||
|
computed: {
|
||||||
|
iframeViews() {
|
||||||
|
return this.$store.state.tagsView.iframeViews
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,27 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<div :style="'height:' + height" v-loading="loading" element-loading-text="正在加载页面,请稍候!">
|
||||||
|
<iframe
|
||||||
|
:id="iframeId"
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
:src="src"
|
||||||
|
frameborder="no"
|
||||||
|
></iframe>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data() {
|
props: {
|
||||||
return {};
|
src: {
|
||||||
},
|
type: String,
|
||||||
render() {
|
default: "/"
|
||||||
const { $route: { meta: { link } }, } = this;
|
},
|
||||||
if ({ link }.link === "") {
|
iframeId: {
|
||||||
return "404";
|
type: String
|
||||||
}
|
}
|
||||||
let url = { link }.link;
|
|
||||||
const height = document.documentElement.clientHeight - 94.5 + "px";
|
|
||||||
const style = { height: height };
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={style}>
|
|
||||||
<iframe
|
|
||||||
src={url}
|
|
||||||
frameborder="no"
|
|
||||||
style="width: 100%; height: 100%"
|
|
||||||
scrolling="auto"
|
|
||||||
></iframe>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
height: document.documentElement.clientHeight - 94.5 + "px;"
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
var _this = this;
|
||||||
|
const iframeId = ("#" + this.iframeId).replace(/\//g, "\\/");
|
||||||
|
const iframe = document.querySelector(iframeId);
|
||||||
|
// iframe页面loading控制
|
||||||
|
if (iframe.attachEvent) {
|
||||||
|
this.loading = true;
|
||||||
|
iframe.attachEvent("onload", function () {
|
||||||
|
_this.loading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.loading = true;
|
||||||
|
iframe.onload = function () {
|
||||||
|
_this.loading = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,78 +1,76 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="drawer-container">
|
<el-drawer size="280px" :visible="visible" :with-header="false" :append-to-body="true" :show-close="false">
|
||||||
<div>
|
<div class="drawer-container">
|
||||||
<div class="setting-drawer-content">
|
<div>
|
||||||
<div class="setting-drawer-title">
|
<div class="setting-drawer-content">
|
||||||
<h3 class="drawer-title">主题风格设置</h3>
|
<div class="setting-drawer-title">
|
||||||
|
<h3 class="drawer-title">主题风格设置</h3>
|
||||||
|
</div>
|
||||||
|
<div class="setting-drawer-block-checbox">
|
||||||
|
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
|
||||||
|
<img src="@/assets/images/dark.svg" alt="dark">
|
||||||
|
<div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
||||||
|
<i aria-label="图标: check" class="anticon anticon-check">
|
||||||
|
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class="">
|
||||||
|
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
|
||||||
|
</svg>
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
|
||||||
|
<img src="@/assets/images/light.svg" alt="light">
|
||||||
|
<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
||||||
|
<i aria-label="图标: check" class="anticon anticon-check">
|
||||||
|
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class="">
|
||||||
|
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
|
||||||
|
</svg>
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="drawer-item">
|
||||||
|
<span>主题颜色</span>
|
||||||
|
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-drawer-block-checbox">
|
|
||||||
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
|
<el-divider/>
|
||||||
<img src="@/assets/images/dark.svg" alt="dark">
|
|
||||||
<div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
<h3 class="drawer-title">系统布局配置</h3>
|
||||||
<i aria-label="图标: check" class="anticon anticon-check">
|
|
||||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true"
|
<div class="drawer-item">
|
||||||
focusable="false" class="">
|
<span>开启 TopNav</span>
|
||||||
<path
|
<el-switch v-model="topNav" class="drawer-switch" />
|
||||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
|
|
||||||
</svg>
|
|
||||||
</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
|
|
||||||
<img src="@/assets/images/light.svg" alt="light">
|
|
||||||
<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
|
||||||
<i aria-label="图标: check" class="anticon anticon-check">
|
|
||||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true"
|
|
||||||
focusable="false" class="">
|
|
||||||
<path
|
|
||||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
|
|
||||||
</svg>
|
|
||||||
</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="drawer-item">
|
<div class="drawer-item">
|
||||||
<span>主题颜色</span>
|
<span>开启 Tags-Views</span>
|
||||||
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
|
<el-switch v-model="tagsView" class="drawer-switch" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="drawer-item">
|
||||||
|
<span>固定 Header</span>
|
||||||
|
<el-switch v-model="fixedHeader" class="drawer-switch" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="drawer-item">
|
||||||
|
<span>显示 Logo</span>
|
||||||
|
<el-switch v-model="sidebarLogo" class="drawer-switch" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="drawer-item">
|
||||||
|
<span>动态标题</span>
|
||||||
|
<el-switch v-model="dynamicTitle" class="drawer-switch" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-divider/>
|
||||||
|
|
||||||
|
<el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">保存配置</el-button>
|
||||||
|
<el-button size="small" plain icon="el-icon-refresh" @click="resetSetting">重置配置</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-divider/>
|
|
||||||
|
|
||||||
<h3 class="drawer-title">系统布局配置</h3>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>开启 TopNav</span>
|
|
||||||
<el-switch v-model="topNav" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>开启 Tags-Views</span>
|
|
||||||
<el-switch v-model="tagsView" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>固定 Header</span>
|
|
||||||
<el-switch v-model="fixedHeader" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>显示 Logo</span>
|
|
||||||
<el-switch v-model="sidebarLogo" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>动态标题</span>
|
|
||||||
<el-switch v-model="dynamicTitle" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider/>
|
|
||||||
|
|
||||||
<el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">保存配置</el-button>
|
|
||||||
<el-button size="small" plain icon="el-icon-refresh" @click="resetSetting">重置配置</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</el-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -87,6 +85,11 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
visible: {
|
||||||
|
get() {
|
||||||
|
return this.$store.state.settings.showSettings
|
||||||
|
}
|
||||||
|
},
|
||||||
fixedHeader: {
|
fixedHeader: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.settings.fixedHeader
|
return this.$store.state.settings.fixedHeader
|
||||||
@ -232,7 +235,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.drawer-container {
|
.drawer-container {
|
||||||
padding: 24px;
|
padding: 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
@ -133,6 +133,9 @@ export default {
|
|||||||
const { name } = this.$route
|
const { name } = this.$route
|
||||||
if (name) {
|
if (name) {
|
||||||
this.$store.dispatch('tagsView/addView', this.$route)
|
this.$store.dispatch('tagsView/addView', this.$route)
|
||||||
|
if (this.$route.meta.link) {
|
||||||
|
this.$store.dispatch('tagsView/addIframeView', this.$route)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
@ -153,6 +156,9 @@ export default {
|
|||||||
},
|
},
|
||||||
refreshSelectedTag(view) {
|
refreshSelectedTag(view) {
|
||||||
this.$tab.refreshPage(view);
|
this.$tab.refreshPage(view);
|
||||||
|
if (this.$route.meta.link) {
|
||||||
|
this.$store.dispatch('tagsView/delIframeView', this.$route)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
closeSelectedTag(view) {
|
closeSelectedTag(view) {
|
||||||
this.$tab.closePage(view).then(({ visitedViews }) => {
|
this.$tab.closePage(view).then(({ visitedViews }) => {
|
||||||
|
@ -2,6 +2,7 @@ const getters = {
|
|||||||
sidebar: state => state.app.sidebar,
|
sidebar: state => state.app.sidebar,
|
||||||
size: state => state.app.size,
|
size: state => state.app.size,
|
||||||
device: state => state.app.device,
|
device: state => state.app.device,
|
||||||
|
dict: state => state.dict.dict,
|
||||||
visitedViews: state => state.tagsView.visitedViews,
|
visitedViews: state => state.tagsView.visitedViews,
|
||||||
cachedViews: state => state.tagsView.cachedViews,
|
cachedViews: state => state.tagsView.cachedViews,
|
||||||
token: state => state.user.token,
|
token: state => state.user.token,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
import app from './modules/app'
|
import app from './modules/app'
|
||||||
|
import dict from './modules/dict'
|
||||||
import user from './modules/user'
|
import user from './modules/user'
|
||||||
import tagsView from './modules/tagsView'
|
import tagsView from './modules/tagsView'
|
||||||
import permission from './modules/permission'
|
import permission from './modules/permission'
|
||||||
@ -12,6 +13,7 @@ Vue.use(Vuex)
|
|||||||
const store = new Vuex.Store({
|
const store = new Vuex.Store({
|
||||||
modules: {
|
modules: {
|
||||||
app,
|
app,
|
||||||
|
dict,
|
||||||
user,
|
user,
|
||||||
tagsView,
|
tagsView,
|
||||||
permission,
|
permission,
|
||||||
|
50
ruoyi-ui/src/store/modules/dict.js
Normal file
50
ruoyi-ui/src/store/modules/dict.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
const state = {
|
||||||
|
dict: new Array()
|
||||||
|
}
|
||||||
|
const mutations = {
|
||||||
|
SET_DICT: (state, { key, value }) => {
|
||||||
|
if (key !== null && key !== "") {
|
||||||
|
state.dict.push({
|
||||||
|
key: key,
|
||||||
|
value: value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
REMOVE_DICT: (state, key) => {
|
||||||
|
try {
|
||||||
|
for (let i = 0; i < state.dict.length; i++) {
|
||||||
|
if (state.dict[i].key == key) {
|
||||||
|
state.dict.splice(i, i)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
CLEAN_DICT: (state) => {
|
||||||
|
state.dict = new Array()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
// 设置字典
|
||||||
|
setDict({ commit }, data) {
|
||||||
|
commit('SET_DICT', data)
|
||||||
|
},
|
||||||
|
// 删除字典
|
||||||
|
removeDict({ commit }, key) {
|
||||||
|
commit('REMOVE_DICT', key)
|
||||||
|
},
|
||||||
|
// 清空字典
|
||||||
|
cleanDict({ commit }) {
|
||||||
|
commit('CLEAN_DICT')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
mutations,
|
||||||
|
actions
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,18 @@
|
|||||||
const state = {
|
const state = {
|
||||||
visitedViews: [],
|
visitedViews: [],
|
||||||
cachedViews: []
|
cachedViews: [],
|
||||||
|
iframeViews: []
|
||||||
}
|
}
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
|
ADD_IFRAME_VIEW: (state, view) => {
|
||||||
|
if (state.iframeViews.some(v => v.path === view.path)) return
|
||||||
|
state.iframeViews.push(
|
||||||
|
Object.assign({}, view, {
|
||||||
|
title: view.meta.title || 'no-name'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
},
|
||||||
ADD_VISITED_VIEW: (state, view) => {
|
ADD_VISITED_VIEW: (state, view) => {
|
||||||
if (state.visitedViews.some(v => v.path === view.path)) return
|
if (state.visitedViews.some(v => v.path === view.path)) return
|
||||||
state.visitedViews.push(
|
state.visitedViews.push(
|
||||||
@ -18,7 +27,6 @@ const mutations = {
|
|||||||
state.cachedViews.push(view.name)
|
state.cachedViews.push(view.name)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
DEL_VISITED_VIEW: (state, view) => {
|
DEL_VISITED_VIEW: (state, view) => {
|
||||||
for (const [i, v] of state.visitedViews.entries()) {
|
for (const [i, v] of state.visitedViews.entries()) {
|
||||||
if (v.path === view.path) {
|
if (v.path === view.path) {
|
||||||
@ -26,6 +34,10 @@ const mutations = {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
|
||||||
|
},
|
||||||
|
DEL_IFRAME_VIEW: (state, view) => {
|
||||||
|
state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
|
||||||
},
|
},
|
||||||
DEL_CACHED_VIEW: (state, view) => {
|
DEL_CACHED_VIEW: (state, view) => {
|
||||||
const index = state.cachedViews.indexOf(view.name)
|
const index = state.cachedViews.indexOf(view.name)
|
||||||
@ -36,6 +48,7 @@ const mutations = {
|
|||||||
state.visitedViews = state.visitedViews.filter(v => {
|
state.visitedViews = state.visitedViews.filter(v => {
|
||||||
return v.meta.affix || v.path === view.path
|
return v.meta.affix || v.path === view.path
|
||||||
})
|
})
|
||||||
|
state.iframeViews = state.iframeViews.filter(item => item.path === view.path)
|
||||||
},
|
},
|
||||||
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
|
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
|
||||||
const index = state.cachedViews.indexOf(view.name)
|
const index = state.cachedViews.indexOf(view.name)
|
||||||
@ -45,16 +58,15 @@ const mutations = {
|
|||||||
state.cachedViews = []
|
state.cachedViews = []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
DEL_ALL_VISITED_VIEWS: state => {
|
DEL_ALL_VISITED_VIEWS: state => {
|
||||||
// keep affix tags
|
// keep affix tags
|
||||||
const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
|
const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
|
||||||
state.visitedViews = affixTags
|
state.visitedViews = affixTags
|
||||||
|
state.iframeViews = []
|
||||||
},
|
},
|
||||||
DEL_ALL_CACHED_VIEWS: state => {
|
DEL_ALL_CACHED_VIEWS: state => {
|
||||||
state.cachedViews = []
|
state.cachedViews = []
|
||||||
},
|
},
|
||||||
|
|
||||||
UPDATE_VISITED_VIEW: (state, view) => {
|
UPDATE_VISITED_VIEW: (state, view) => {
|
||||||
for (let v of state.visitedViews) {
|
for (let v of state.visitedViews) {
|
||||||
if (v.path === view.path) {
|
if (v.path === view.path) {
|
||||||
@ -63,7 +75,6 @@ const mutations = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
DEL_RIGHT_VIEWS: (state, view) => {
|
DEL_RIGHT_VIEWS: (state, view) => {
|
||||||
const index = state.visitedViews.findIndex(v => v.path === view.path)
|
const index = state.visitedViews.findIndex(v => v.path === view.path)
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
@ -77,10 +88,13 @@ const mutations = {
|
|||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
state.cachedViews.splice(i, 1)
|
state.cachedViews.splice(i, 1)
|
||||||
}
|
}
|
||||||
|
if(item.meta.link) {
|
||||||
|
const fi = state.iframeViews.findIndex(v => v.path === item.path)
|
||||||
|
state.iframeViews.splice(fi, 1)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
DEL_LEFT_VIEWS: (state, view) => {
|
DEL_LEFT_VIEWS: (state, view) => {
|
||||||
const index = state.visitedViews.findIndex(v => v.path === view.path)
|
const index = state.visitedViews.findIndex(v => v.path === view.path)
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
@ -94,6 +108,10 @@ const mutations = {
|
|||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
state.cachedViews.splice(i, 1)
|
state.cachedViews.splice(i, 1)
|
||||||
}
|
}
|
||||||
|
if(item.meta.link) {
|
||||||
|
const fi = state.iframeViews.findIndex(v => v.path === item.path)
|
||||||
|
state.iframeViews.splice(fi, 1)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -104,13 +122,15 @@ const actions = {
|
|||||||
dispatch('addVisitedView', view)
|
dispatch('addVisitedView', view)
|
||||||
dispatch('addCachedView', view)
|
dispatch('addCachedView', view)
|
||||||
},
|
},
|
||||||
|
addIframeView({ commit }, view) {
|
||||||
|
commit('ADD_IFRAME_VIEW', view)
|
||||||
|
},
|
||||||
addVisitedView({ commit }, view) {
|
addVisitedView({ commit }, view) {
|
||||||
commit('ADD_VISITED_VIEW', view)
|
commit('ADD_VISITED_VIEW', view)
|
||||||
},
|
},
|
||||||
addCachedView({ commit }, view) {
|
addCachedView({ commit }, view) {
|
||||||
commit('ADD_CACHED_VIEW', view)
|
commit('ADD_CACHED_VIEW', view)
|
||||||
},
|
},
|
||||||
|
|
||||||
delView({ dispatch, state }, view) {
|
delView({ dispatch, state }, view) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
dispatch('delVisitedView', view)
|
dispatch('delVisitedView', view)
|
||||||
@ -127,13 +147,18 @@ const actions = {
|
|||||||
resolve([...state.visitedViews])
|
resolve([...state.visitedViews])
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
delIframeView({ commit, state }, view) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
commit('DEL_IFRAME_VIEW', view)
|
||||||
|
resolve([...state.iframeViews])
|
||||||
|
})
|
||||||
|
},
|
||||||
delCachedView({ commit, state }, view) {
|
delCachedView({ commit, state }, view) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
commit('DEL_CACHED_VIEW', view)
|
commit('DEL_CACHED_VIEW', view)
|
||||||
resolve([...state.cachedViews])
|
resolve([...state.cachedViews])
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
delOthersViews({ dispatch, state }, view) {
|
delOthersViews({ dispatch, state }, view) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
dispatch('delOthersVisitedViews', view)
|
dispatch('delOthersVisitedViews', view)
|
||||||
@ -156,7 +181,6 @@ const actions = {
|
|||||||
resolve([...state.cachedViews])
|
resolve([...state.cachedViews])
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
delAllViews({ dispatch, state }, view) {
|
delAllViews({ dispatch, state }, view) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
dispatch('delAllVisitedViews', view)
|
dispatch('delAllVisitedViews', view)
|
||||||
@ -179,18 +203,15 @@ const actions = {
|
|||||||
resolve([...state.cachedViews])
|
resolve([...state.cachedViews])
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
updateVisitedView({ commit }, view) {
|
updateVisitedView({ commit }, view) {
|
||||||
commit('UPDATE_VISITED_VIEW', view)
|
commit('UPDATE_VISITED_VIEW', view)
|
||||||
},
|
},
|
||||||
|
|
||||||
delRightTags({ commit }, view) {
|
delRightTags({ commit }, view) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
commit('DEL_RIGHT_VIEWS', view)
|
commit('DEL_RIGHT_VIEWS', view)
|
||||||
resolve([...state.visitedViews])
|
resolve([...state.visitedViews])
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
delLeftTags({ commit }, view) {
|
delLeftTags({ commit }, view) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
commit('DEL_LEFT_VIEWS', view)
|
commit('DEL_LEFT_VIEWS', view)
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
* 监控框架 SpringBoot-Admin 全方位服务监控<br/>
|
* 监控框架 SpringBoot-Admin 全方位服务监控<br/>
|
||||||
* 校验框架 Validation 增强接口安全性 严谨性<br/>
|
* 校验框架 Validation 增强接口安全性 严谨性<br/>
|
||||||
* Excel框架 Alibaba EasyExcel 性能优异 扩展性强<br/>
|
* Excel框架 Alibaba EasyExcel 性能优异 扩展性强<br/>
|
||||||
* 文档框架 knife4j 美化接口文档<br/>
|
* 文档框架 SpringDoc、javadoc 无注解零入侵基于java注释<br/>
|
||||||
* 工具类框架 Hutool、Lombok 减少代码冗余 增加安全性<br/>
|
* 工具类框架 Hutool、Lombok 减少代码冗余 增加安全性<br/>
|
||||||
* 代码生成器 适配MP、Knife4j规范化代码 一键生成前后端代码<br/>
|
* 代码生成器 适配MP、Knife4j规范化代码 一键生成前后端代码<br/>
|
||||||
* 部署方式 Docker 容器编排 一键部署业务集群<br/>
|
* 部署方式 Docker 容器编排 一键部署业务集群<br/>
|
||||||
@ -81,7 +81,7 @@
|
|||||||
<h4>后端技术</h4>
|
<h4>后端技术</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>SpringBoot</li>
|
<li>SpringBoot</li>
|
||||||
<li>Spring Security</li>
|
<li>Sa-Token</li>
|
||||||
<li>JWT</li>
|
<li>JWT</li>
|
||||||
<li>MyBatis</li>
|
<li>MyBatis</li>
|
||||||
<li>Druid</li>
|
<li>Druid</li>
|
||||||
@ -114,7 +114,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 版本号
|
// 版本号
|
||||||
version: "4.2.0",
|
version: "4.3.0",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="code" v-if="captchaOnOff">
|
<el-form-item prop="code" v-if="captchaEnabled">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="loginForm.code"
|
v-model="loginForm.code"
|
||||||
auto-complete="off"
|
auto-complete="off"
|
||||||
@ -89,7 +89,7 @@ export default {
|
|||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
// 验证码开关
|
// 验证码开关
|
||||||
captchaOnOff: true,
|
captchaEnabled: true,
|
||||||
// 注册开关
|
// 注册开关
|
||||||
register: false,
|
register: false,
|
||||||
redirect: undefined
|
redirect: undefined
|
||||||
@ -110,8 +110,8 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
getCode() {
|
getCode() {
|
||||||
getCodeImg().then(res => {
|
getCodeImg().then(res => {
|
||||||
this.captchaOnOff = res.data.captchaOnOff === undefined ? true : res.data.captchaOnOff;
|
this.captchaEnabled = res.data.captchaEnabled === undefined ? true : res.data.captchaEnabled;
|
||||||
if (this.captchaOnOff) {
|
if (this.captchaEnabled) {
|
||||||
this.codeUrl = "data:image/gif;base64," + res.data.img;
|
this.codeUrl = "data:image/gif;base64," + res.data.img;
|
||||||
this.loginForm.uuid = res.data.uuid;
|
this.loginForm.uuid = res.data.uuid;
|
||||||
}
|
}
|
||||||
@ -144,7 +144,7 @@ export default {
|
|||||||
this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
|
this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (this.captchaOnOff) {
|
if (this.captchaEnabled) {
|
||||||
this.getCode();
|
this.getCode();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
22
ruoyi-ui/src/views/monitor/cache/index.vue
vendored
22
ruoyi-ui/src/views/monitor/cache/index.vue
vendored
@ -71,7 +71,7 @@ import { getCache } from "@/api/monitor/cache";
|
|||||||
import echarts from "echarts";
|
import echarts from "echarts";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Server",
|
name: "Cache",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 统计命令信息
|
// 统计命令信息
|
||||||
@ -79,8 +79,8 @@ export default {
|
|||||||
// 使用内存
|
// 使用内存
|
||||||
usedmemory: null,
|
usedmemory: null,
|
||||||
// cache信息
|
// cache信息
|
||||||
cache: [],
|
cache: []
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList();
|
||||||
@ -109,8 +109,8 @@ export default {
|
|||||||
data: response.data.commandStats,
|
data: response.data.commandStats,
|
||||||
animationEasing: "cubicInOut",
|
animationEasing: "cubicInOut",
|
||||||
animationDuration: 1000,
|
animationDuration: 1000,
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
});
|
});
|
||||||
this.usedmemory = echarts.init(this.$refs.usedmemory, "macarons");
|
this.usedmemory = echarts.init(this.$refs.usedmemory, "macarons");
|
||||||
this.usedmemory.setOption({
|
this.usedmemory.setOption({
|
||||||
@ -130,17 +130,17 @@ export default {
|
|||||||
{
|
{
|
||||||
value: parseFloat(this.cache.info.used_memory_human),
|
value: parseFloat(this.cache.info.used_memory_human),
|
||||||
name: "内存消耗",
|
name: "内存消耗",
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 打开加载层
|
// 打开加载层
|
||||||
openLoading() {
|
openLoading() {
|
||||||
this.$modal.loading("正在加载缓存监控数据,请稍候!");
|
this.$modal.loading("正在加载缓存监控数据,请稍候!");
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
241
ruoyi-ui/src/views/monitor/cache/list.vue
vendored
Normal file
241
ruoyi-ui/src/views/monitor/cache/list.vue
vendored
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-card style="height: calc(100vh - 125px)">
|
||||||
|
<div slot="header">
|
||||||
|
<span>缓存列表</span>
|
||||||
|
<el-button
|
||||||
|
style="float: right; padding: 3px 0"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-refresh-right"
|
||||||
|
@click="refreshCacheNames()"
|
||||||
|
></el-button>
|
||||||
|
</div>
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="cacheNames"
|
||||||
|
:height="tableHeight"
|
||||||
|
highlight-current-row
|
||||||
|
@row-click="getCacheKeys"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
label="序号"
|
||||||
|
width="60"
|
||||||
|
type="index"
|
||||||
|
></el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
label="缓存名称"
|
||||||
|
align="center"
|
||||||
|
prop="cacheName"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
:formatter="nameFormatter"
|
||||||
|
></el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
label="备注"
|
||||||
|
align="center"
|
||||||
|
prop="remark"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="操作"
|
||||||
|
width="60"
|
||||||
|
align="center"
|
||||||
|
class-name="small-padding fixed-width"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleClearCacheName(scope.row)"
|
||||||
|
></el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-card style="height: calc(100vh - 125px)">
|
||||||
|
<div slot="header">
|
||||||
|
<span>键名列表</span>
|
||||||
|
<el-button
|
||||||
|
style="float: right; padding: 3px 0"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-refresh-right"
|
||||||
|
@click="refreshCacheKeys()"
|
||||||
|
></el-button>
|
||||||
|
</div>
|
||||||
|
<el-table
|
||||||
|
v-loading="subLoading"
|
||||||
|
:data="cacheKeys"
|
||||||
|
:height="tableHeight"
|
||||||
|
highlight-current-row
|
||||||
|
@row-click="handleCacheValue"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
label="序号"
|
||||||
|
width="60"
|
||||||
|
type="index"
|
||||||
|
></el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="缓存键名"
|
||||||
|
align="center"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
:formatter="keyFormatter"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="操作"
|
||||||
|
width="60"
|
||||||
|
align="center"
|
||||||
|
class-name="small-padding fixed-width"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleClearCacheKey(scope.row)"
|
||||||
|
></el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-card :bordered="false" style="height: calc(100vh - 125px)">
|
||||||
|
<div slot="header">
|
||||||
|
<span>缓存内容</span>
|
||||||
|
<el-button
|
||||||
|
style="float: right; padding: 3px 0"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-refresh-right"
|
||||||
|
@click="handleClearCacheAll()"
|
||||||
|
>清理全部</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<el-form :model="cacheForm">
|
||||||
|
<el-row :gutter="32">
|
||||||
|
<el-col :offset="1" :span="22">
|
||||||
|
<el-form-item label="缓存名称:" prop="cacheName">
|
||||||
|
<el-input v-model="cacheForm.cacheName" :readOnly="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :offset="1" :span="22">
|
||||||
|
<el-form-item label="缓存键名:" prop="cacheKey">
|
||||||
|
<el-input v-model="cacheForm.cacheKey" :readOnly="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :offset="1" :span="22">
|
||||||
|
<el-form-item label="缓存内容:" prop="cacheValue">
|
||||||
|
<el-input
|
||||||
|
v-model="cacheForm.cacheValue"
|
||||||
|
type="textarea"
|
||||||
|
:rows="8"
|
||||||
|
:readOnly="true"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listCacheName, listCacheKey, getCacheValue, clearCacheName, clearCacheKey, clearCacheAll } from "@/api/monitor/cache";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "CacheList",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
cacheNames: [],
|
||||||
|
cacheKeys: [],
|
||||||
|
cacheForm: {},
|
||||||
|
loading: true,
|
||||||
|
subLoading: false,
|
||||||
|
nowCacheName: "",
|
||||||
|
tableHeight: window.innerHeight - 200
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getCacheNames();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询缓存名称列表 */
|
||||||
|
getCacheNames() {
|
||||||
|
this.loading = true;
|
||||||
|
listCacheName().then(response => {
|
||||||
|
this.cacheNames = response.data;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 刷新缓存名称列表 */
|
||||||
|
refreshCacheNames() {
|
||||||
|
this.getCacheNames();
|
||||||
|
this.$modal.msgSuccess("刷新缓存列表成功");
|
||||||
|
},
|
||||||
|
/** 清理指定名称缓存 */
|
||||||
|
handleClearCacheName(row) {
|
||||||
|
clearCacheName(row.cacheName).then(response => {
|
||||||
|
this.$modal.msgSuccess("清理缓存名称[" + this.nowCacheName + "]成功");
|
||||||
|
this.getCacheKeys();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 查询缓存键名列表 */
|
||||||
|
getCacheKeys(row) {
|
||||||
|
const cacheName = row !== undefined ? row.cacheName : this.nowCacheName;
|
||||||
|
if (cacheName === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.subLoading = true;
|
||||||
|
listCacheKey(cacheName).then(response => {
|
||||||
|
this.cacheKeys = response.data;
|
||||||
|
this.subLoading = false;
|
||||||
|
this.nowCacheName = cacheName;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 刷新缓存键名列表 */
|
||||||
|
refreshCacheKeys() {
|
||||||
|
this.getCacheKeys();
|
||||||
|
this.$modal.msgSuccess("刷新键名列表成功");
|
||||||
|
},
|
||||||
|
/** 清理指定键名缓存 */
|
||||||
|
handleClearCacheKey(cacheKey) {
|
||||||
|
clearCacheKey(this.nowCacheName, cacheKey).then(response => {
|
||||||
|
this.$modal.msgSuccess("清理缓存键名[" + cacheKey + "]成功");
|
||||||
|
this.getCacheKeys();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 列表前缀去除 */
|
||||||
|
nameFormatter(row) {
|
||||||
|
return row.cacheName.replace(":", "");
|
||||||
|
},
|
||||||
|
/** 键名前缀去除 */
|
||||||
|
keyFormatter(cacheKey) {
|
||||||
|
return cacheKey.replace(this.nowCacheName, "");
|
||||||
|
},
|
||||||
|
/** 查询缓存内容详细 */
|
||||||
|
handleCacheValue(cacheKey) {
|
||||||
|
getCacheValue(this.nowCacheName, cacheKey).then(response => {
|
||||||
|
this.cacheForm = response.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 清理全部缓存 */
|
||||||
|
handleClearCacheAll() {
|
||||||
|
clearCacheAll().then(response => {
|
||||||
|
this.$modal.msgSuccess("清理全部缓存成功");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -73,6 +73,17 @@
|
|||||||
v-hasPermi="['monitor:logininfor:remove']"
|
v-hasPermi="['monitor:logininfor:remove']"
|
||||||
>清空</el-button>
|
>清空</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-unlock"
|
||||||
|
size="mini"
|
||||||
|
:disabled="single"
|
||||||
|
@click="handleUnlock"
|
||||||
|
v-hasPermi="['monitor:logininfor:unlock']"
|
||||||
|
>解锁</el-button>
|
||||||
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button
|
||||||
type="warning"
|
type="warning"
|
||||||
@ -118,7 +129,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { list, delLogininfor, cleanLogininfor } from "@/api/monitor/logininfor";
|
import { list, delLogininfor, cleanLogininfor, unlockLogininfor } from "@/api/monitor/logininfor";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Logininfor",
|
name: "Logininfor",
|
||||||
@ -129,8 +140,12 @@ export default {
|
|||||||
loading: true,
|
loading: true,
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
|
// 非单个禁用
|
||||||
|
single: true,
|
||||||
// 非多个禁用
|
// 非多个禁用
|
||||||
multiple: true,
|
multiple: true,
|
||||||
|
// 选择用户名
|
||||||
|
selectName: "",
|
||||||
// 显示搜索条件
|
// 显示搜索条件
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
// 总条数
|
// 总条数
|
||||||
@ -180,7 +195,9 @@ export default {
|
|||||||
/** 多选框选中数据 */
|
/** 多选框选中数据 */
|
||||||
handleSelectionChange(selection) {
|
handleSelectionChange(selection) {
|
||||||
this.ids = selection.map(item => item.infoId)
|
this.ids = selection.map(item => item.infoId)
|
||||||
|
this.single = selection.length!=1
|
||||||
this.multiple = !selection.length
|
this.multiple = !selection.length
|
||||||
|
this.selectName = selection.map(item => item.userName);
|
||||||
},
|
},
|
||||||
/** 排序触发事件 */
|
/** 排序触发事件 */
|
||||||
handleSortChange(column, prop, order) {
|
handleSortChange(column, prop, order) {
|
||||||
@ -207,6 +224,15 @@ export default {
|
|||||||
this.$modal.msgSuccess("清空成功");
|
this.$modal.msgSuccess("清空成功");
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
},
|
},
|
||||||
|
/** 解锁按钮操作 */
|
||||||
|
handleUnlock() {
|
||||||
|
const username = this.selectName;
|
||||||
|
this.$modal.confirm('是否确认解锁用户"' + username + '"数据项?').then(function() {
|
||||||
|
return unlockLogininfor(username);
|
||||||
|
}).then(() => {
|
||||||
|
this.$modal.msgSuccess("用户" + username + "解锁成功");
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.download('monitor/logininfor/export', {
|
this.download('monitor/logininfor/export', {
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="code" v-if="captchaOnOff">
|
<el-form-item prop="code" v-if="captchaEnabled">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="registerForm.code"
|
v-model="registerForm.code"
|
||||||
auto-complete="off"
|
auto-complete="off"
|
||||||
@ -105,7 +105,7 @@ export default {
|
|||||||
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
|
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
|
||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
captchaOnOff: true
|
captchaEnabled: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@ -114,8 +114,8 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
getCode() {
|
getCode() {
|
||||||
getCodeImg().then(res => {
|
getCodeImg().then(res => {
|
||||||
this.captchaOnOff = res.data.captchaOnOff === undefined ? true : res.data.captchaOnOff;
|
this.captchaEnabled = res.data.captchaEnabled === undefined ? true : res.data.captchaEnabled;
|
||||||
if (this.captchaOnOff) {
|
if (this.captchaEnabled) {
|
||||||
this.codeUrl = "data:image/gif;base64," + res.data.img;
|
this.codeUrl = "data:image/gif;base64," + res.data.img;
|
||||||
this.registerForm.uuid = res.data.uuid;
|
this.registerForm.uuid = res.data.uuid;
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ export default {
|
|||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (this.captchaOnOff) {
|
if (this.captchaEnabled) {
|
||||||
this.getCode();
|
this.getCode();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -297,9 +297,13 @@ export default {
|
|||||||
this.form = response.data;
|
this.form = response.data;
|
||||||
this.open = true;
|
this.open = true;
|
||||||
this.title = "修改部门";
|
this.title = "修改部门";
|
||||||
});
|
listDeptExcludeChild(row.deptId).then(response => {
|
||||||
listDeptExcludeChild(row.deptId).then(response => {
|
this.deptOptions = this.handleTree(response.data, "deptId");
|
||||||
this.deptOptions = this.handleTree(response.data, "deptId");
|
if (this.deptOptions.length == 0) {
|
||||||
|
const noResultsOptions = { deptId: this.form.parentId, deptName: this.form.parentName, children: [] };
|
||||||
|
this.deptOptions.push(noResultsOptions);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
|
@ -163,7 +163,7 @@
|
|||||||
<el-option
|
<el-option
|
||||||
v-for="item in listClassOptions"
|
v-for="item in listClassOptions"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label + '(' + item.value + ')'"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -364,12 +364,14 @@ export default {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
if (this.form.dictCode != undefined) {
|
if (this.form.dictCode != undefined) {
|
||||||
updateData(this.form).then(response => {
|
updateData(this.form).then(response => {
|
||||||
|
this.$store.dispatch('dict/removeDict', this.queryParams.dictType);
|
||||||
this.$modal.msgSuccess("修改成功");
|
this.$modal.msgSuccess("修改成功");
|
||||||
this.open = false;
|
this.open = false;
|
||||||
this.getList();
|
this.getList();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addData(this.form).then(response => {
|
addData(this.form).then(response => {
|
||||||
|
this.$store.dispatch('dict/removeDict', this.queryParams.dictType);
|
||||||
this.$modal.msgSuccess("新增成功");
|
this.$modal.msgSuccess("新增成功");
|
||||||
this.open = false;
|
this.open = false;
|
||||||
this.getList();
|
this.getList();
|
||||||
@ -386,6 +388,7 @@ export default {
|
|||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.$modal.msgSuccess("删除成功");
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
this.$store.dispatch('dict/removeDict', this.queryParams.dictType);
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
|
@ -339,6 +339,7 @@ export default {
|
|||||||
handleRefreshCache() {
|
handleRefreshCache() {
|
||||||
refreshCache().then(() => {
|
refreshCache().then(() => {
|
||||||
this.$modal.msgSuccess("刷新成功");
|
this.$modal.msgSuccess("刷新成功");
|
||||||
|
this.$store.dispatch('dict/cleanDict');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@
|
|||||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="上级菜单">
|
<el-form-item label="上级菜单" prop="parentId">
|
||||||
<treeselect
|
<treeselect
|
||||||
v-model="form.parentId"
|
v-model="form.parentId"
|
||||||
:options="menuOptions"
|
:options="menuOptions"
|
||||||
@ -159,7 +159,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" v-if="form.menuType != 'F'">
|
<el-col :span="12" v-if="form.menuType != 'F'">
|
||||||
<el-form-item>
|
<el-form-item prop="isFrame">
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
<el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
|
<el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
|
||||||
<i class="el-icon-question"></i>
|
<i class="el-icon-question"></i>
|
||||||
@ -195,7 +195,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" v-if="form.menuType != 'M'">
|
<el-col :span="12" v-if="form.menuType != 'M'">
|
||||||
<el-form-item>
|
<el-form-item prop="perms">
|
||||||
<el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" />
|
<el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" />
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
<el-tooltip content="控制器中定义的权限字符,如:@SaCheckPermission('system:user:list')" placement="top">
|
<el-tooltip content="控制器中定义的权限字符,如:@SaCheckPermission('system:user:list')" placement="top">
|
||||||
@ -206,7 +206,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" v-if="form.menuType == 'C'">
|
<el-col :span="12" v-if="form.menuType == 'C'">
|
||||||
<el-form-item>
|
<el-form-item prop="queryParam">
|
||||||
<el-input v-model="form.queryParam" placeholder="请输入路由参数" maxlength="255" />
|
<el-input v-model="form.queryParam" placeholder="请输入路由参数" maxlength="255" />
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
<el-tooltip content='访问路由的默认传递参数,如:`{"id": 1, "name": "ry"}`' placement="top">
|
<el-tooltip content='访问路由的默认传递参数,如:`{"id": 1, "name": "ry"}`' placement="top">
|
||||||
@ -217,7 +217,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" v-if="form.menuType == 'C'">
|
<el-col :span="12" v-if="form.menuType == 'C'">
|
||||||
<el-form-item>
|
<el-form-item prop="isCache">
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
<el-tooltip content="选择是则会被`keep-alive`缓存,需要匹配组件的`name`和地址保持一致" placement="top">
|
<el-tooltip content="选择是则会被`keep-alive`缓存,需要匹配组件的`name`和地址保持一致" placement="top">
|
||||||
<i class="el-icon-question"></i>
|
<i class="el-icon-question"></i>
|
||||||
@ -231,7 +231,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" v-if="form.menuType != 'F'">
|
<el-col :span="12" v-if="form.menuType != 'F'">
|
||||||
<el-form-item>
|
<el-form-item prop="visible">
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
<el-tooltip content="选择隐藏则路由将不会出现在侧边栏,但仍然可以访问" placement="top">
|
<el-tooltip content="选择隐藏则路由将不会出现在侧边栏,但仍然可以访问" placement="top">
|
||||||
<i class="el-icon-question"></i>
|
<i class="el-icon-question"></i>
|
||||||
@ -248,7 +248,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" v-if="form.menuType != 'F'">
|
<el-col :span="12" v-if="form.menuType != 'F'">
|
||||||
<el-form-item>
|
<el-form-item prop="status">
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
<el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top">
|
<el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top">
|
||||||
<i class="el-icon-question"></i>
|
<i class="el-icon-question"></i>
|
||||||
|
@ -254,9 +254,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus } from "@/api/system/role";
|
import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus, deptTreeSelect } from "@/api/system/role";
|
||||||
import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu";
|
import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu";
|
||||||
import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/dept";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Role",
|
name: "Role",
|
||||||
@ -364,12 +363,6 @@ export default {
|
|||||||
this.menuOptions = response.data;
|
this.menuOptions = response.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/** 查询部门树结构 */
|
|
||||||
getDeptTreeselect() {
|
|
||||||
deptTreeselect().then(response => {
|
|
||||||
this.deptOptions = response.data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 所有菜单节点数据
|
// 所有菜单节点数据
|
||||||
getMenuAllCheckedKeys() {
|
getMenuAllCheckedKeys() {
|
||||||
// 目前被选中的菜单节点
|
// 目前被选中的菜单节点
|
||||||
@ -396,8 +389,8 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
/** 根据角色ID查询部门树结构 */
|
/** 根据角色ID查询部门树结构 */
|
||||||
getRoleDeptTreeselect(roleId) {
|
getDeptTree(roleId) {
|
||||||
return roleDeptTreeselect(roleId).then(response => {
|
return deptTreeSelect(roleId).then(response => {
|
||||||
this.deptOptions = response.data.depts;
|
this.deptOptions = response.data.depts;
|
||||||
return response;
|
return response;
|
||||||
});
|
});
|
||||||
@ -543,12 +536,12 @@ export default {
|
|||||||
/** 分配数据权限操作 */
|
/** 分配数据权限操作 */
|
||||||
handleDataScope(row) {
|
handleDataScope(row) {
|
||||||
this.reset();
|
this.reset();
|
||||||
const roleDeptTreeselect = this.getRoleDeptTreeselect(row.roleId);
|
const deptTreeSelect = this.getDeptTree(row.roleId);
|
||||||
getRole(row.roleId).then(response => {
|
getRole(row.roleId).then(response => {
|
||||||
this.form = response.data;
|
this.form = response.data;
|
||||||
this.openDataScope = true;
|
this.openDataScope = true;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
roleDeptTreeselect.then(res => {
|
deptTreeSelect.then(res => {
|
||||||
this.$refs.dept.setCheckedKeys(res.data.checkedKeys);
|
this.$refs.dept.setCheckedKeys(res.data.checkedKeys);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -612,3 +605,4 @@ export default {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -342,9 +342,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus } from "@/api/system/user";
|
import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from "@/api/system/user";
|
||||||
import { getToken } from "@/utils/auth";
|
import { getToken } from "@/utils/auth";
|
||||||
import { treeselect } from "@/api/system/dept";
|
|
||||||
import Treeselect from "@riophae/vue-treeselect";
|
import Treeselect from "@riophae/vue-treeselect";
|
||||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||||
|
|
||||||
@ -462,7 +461,7 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.getTreeselect();
|
this.getDeptTree();
|
||||||
this.getConfigKey("sys.user.initPassword").then(response => {
|
this.getConfigKey("sys.user.initPassword").then(response => {
|
||||||
this.initPassword = response.msg;
|
this.initPassword = response.msg;
|
||||||
});
|
});
|
||||||
@ -479,8 +478,8 @@ export default {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
/** 查询部门下拉树结构 */
|
/** 查询部门下拉树结构 */
|
||||||
getTreeselect() {
|
getDeptTree() {
|
||||||
treeselect().then(response => {
|
deptTreeSelect().then(response => {
|
||||||
this.deptOptions = response.data;
|
this.deptOptions = response.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -561,7 +560,6 @@ export default {
|
|||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.reset();
|
this.reset();
|
||||||
this.getTreeselect();
|
|
||||||
getUser().then(response => {
|
getUser().then(response => {
|
||||||
this.postOptions = response.data.posts;
|
this.postOptions = response.data.posts;
|
||||||
this.roleOptions = response.data.roles;
|
this.roleOptions = response.data.roles;
|
||||||
@ -573,7 +571,6 @@ export default {
|
|||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
handleUpdate(row) {
|
handleUpdate(row) {
|
||||||
this.reset();
|
this.reset();
|
||||||
this.getTreeselect();
|
|
||||||
const userId = row.userId || this.ids;
|
const userId = row.userId || this.ids;
|
||||||
getUser(userId).then(response => {
|
getUser(userId).then(response => {
|
||||||
this.form = response.data.user;
|
this.form = response.data.user;
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
<userInfo :user="user" />
|
<userInfo :user="user" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="修改密码" name="resetPwd">
|
<el-tab-pane label="修改密码" name="resetPwd">
|
||||||
<resetPwd :user="user" />
|
<resetPwd />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password/>
|
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="确认密码" prop="confirmPassword">
|
<el-form-item label="确认密码" prop="confirmPassword">
|
||||||
<el-input v-model="user.confirmPassword" placeholder="请确认密码" type="password" show-password/>
|
<el-input v-model="user.confirmPassword" placeholder="请确认新密码" type="password" show-password/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" size="mini" @click="submit">保存</el-button>
|
<el-button type="primary" size="mini" @click="submit">保存</el-button>
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
<template>
|
|
||||||
<i-frame :src="url" />
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import iFrame from "@/components/iFrame/index";
|
|
||||||
export default {
|
|
||||||
name: "Swagger",
|
|
||||||
components: { iFrame },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
url: process.env.VUE_APP_BASE_API + "/doc.html"
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
@ -61,6 +61,7 @@ module.exports = {
|
|||||||
plugins: [
|
plugins: [
|
||||||
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
|
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
|
||||||
new CompressionPlugin({
|
new CompressionPlugin({
|
||||||
|
cache: false, // 不启用文件缓存
|
||||||
test: /\.(js|css|html)?$/i, // 压缩文件格式
|
test: /\.(js|css|html)?$/i, // 压缩文件格式
|
||||||
filename: '[path].gz[query]', // 压缩后的文件名
|
filename: '[path].gz[query]', // 压缩后的文件名
|
||||||
algorithm: 'gzip', // 使用gzip压缩
|
algorithm: 'gzip', // 使用gzip压缩
|
||||||
|
@ -8,8 +8,10 @@ RUN mkdir -p /ruoyi/server/temp
|
|||||||
|
|
||||||
WORKDIR /ruoyi/server
|
WORKDIR /ruoyi/server
|
||||||
|
|
||||||
EXPOSE 8080
|
ENV SERVER_PORT=8080
|
||||||
|
|
||||||
|
EXPOSE ${SERVER_PORT}
|
||||||
|
|
||||||
ADD ./target/ruoyi-admin.jar ./app.jar
|
ADD ./target/ruoyi-admin.jar ./app.jar
|
||||||
|
|
||||||
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
|
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Dserver.port=${SERVER_PORT}","-jar", "app.jar"]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>4.2.0</version>
|
<version>4.3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@ -53,13 +53,13 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.xiaoymin</groupId>
|
<groupId>org.springdoc</groupId>
|
||||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
<artifactId>springdoc-openapi-webmvc-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.swagger</groupId>
|
<groupId>org.springdoc</groupId>
|
||||||
<artifactId>swagger-annotations</artifactId>
|
<artifactId>springdoc-openapi-javadoc</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Mysql驱动包 -->
|
<!-- Mysql驱动包 -->
|
||||||
@ -269,31 +269,12 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.2.2</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
<warName>${project.artifactId}</warName>
|
<warName>${project.artifactId}</warName>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>com.spotify</groupId>
|
|
||||||
<artifactId>docker-maven-plugin</artifactId>
|
|
||||||
<version>${docker.plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<imageName>${docker.namespace}/ruoyi-server:${project.version}</imageName>
|
|
||||||
<dockerDirectory>${project.basedir}</dockerDirectory>
|
|
||||||
<dockerHost>${docker.registry.host}</dockerHost>
|
|
||||||
<registryUrl>${docker.registry.url}</registryUrl>
|
|
||||||
<serverId>${docker.registry.url}</serverId>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<targetPath>/</targetPath>
|
|
||||||
<directory>${project.build.directory}</directory>
|
|
||||||
<include>${project.build.finalName}.jar</include>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ import java.lang.annotation.*;
|
|||||||
/**
|
/**
|
||||||
* 数据权限
|
* 数据权限
|
||||||
*
|
*
|
||||||
|
* 一个注解只能对应一个模板
|
||||||
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
* @version 3.5.0
|
* @version 3.5.0
|
||||||
*/
|
*/
|
||||||
@ -16,11 +18,11 @@ public @interface DataColumn {
|
|||||||
/**
|
/**
|
||||||
* 占位符关键字
|
* 占位符关键字
|
||||||
*/
|
*/
|
||||||
String key() default "deptName";
|
String[] key() default "deptName";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 占位符替换值
|
* 占位符替换值
|
||||||
*/
|
*/
|
||||||
String value() default "dept_id";
|
String[] value() default "dept_id";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.ruoyi.common.annotation;
|
package com.ruoyi.common.annotation;
|
||||||
|
|
||||||
import com.ruoyi.common.constant.Constants;
|
import com.ruoyi.common.constant.CacheConstants;
|
||||||
import com.ruoyi.common.enums.LimitType;
|
import com.ruoyi.common.enums.LimitType;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
@ -17,7 +17,7 @@ public @interface RateLimiter {
|
|||||||
/**
|
/**
|
||||||
* 限流key
|
* 限流key
|
||||||
*/
|
*/
|
||||||
String key() default Constants.RATE_LIMIT_KEY;
|
String key() default CacheConstants.RATE_LIMIT_KEY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 限流时间,单位秒
|
* 限流时间,单位秒
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.ruoyi.common.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存的key 常量
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public interface CacheConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录用户 redis key
|
||||||
|
*/
|
||||||
|
String LOGIN_TOKEN_KEY = "Authorization:login:token:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在线用户 redis key
|
||||||
|
*/
|
||||||
|
String ONLINE_TOKEN_KEY = "online_tokens:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码 redis key
|
||||||
|
*/
|
||||||
|
String CAPTCHA_CODE_KEY = "captcha_codes:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数管理 cache key
|
||||||
|
*/
|
||||||
|
String SYS_CONFIG_KEY = "sys_config:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典管理 cache key
|
||||||
|
*/
|
||||||
|
String SYS_DICT_KEY = "sys_dict:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 防重提交 redis key
|
||||||
|
*/
|
||||||
|
String REPEAT_SUBMIT_KEY = "repeat_submit:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限流 redis key
|
||||||
|
*/
|
||||||
|
String RATE_LIMIT_KEY = "rate_limit:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录账户密码错误次数 redis key
|
||||||
|
*/
|
||||||
|
String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.ruoyi.common.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存组名称常量
|
||||||
|
* <p>
|
||||||
|
* key 格式为 cacheNames#ttl#maxIdleTime#maxSize
|
||||||
|
* <p>
|
||||||
|
* ttl 过期时间 如果设置为0则不过期 默认为0
|
||||||
|
* maxIdleTime 最大空闲时间 根据LRU算法清理空闲数据 如果设置为0则不检测 默认为0
|
||||||
|
* maxSize 组最大长度 根据LRU算法清理溢出数据 如果设置为0则无限长 默认为0
|
||||||
|
* <p>
|
||||||
|
* 例子: test#60s、test#0#60s、test#0#1m#1000、test#1h#0#500
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
|
public interface CacheNames {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 演示案例
|
||||||
|
*/
|
||||||
|
String DEMO_CACHE = "demo:cache#60s#10m#20";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统配置
|
||||||
|
*/
|
||||||
|
String SYS_CONFIG = "sys_config";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据字典
|
||||||
|
*/
|
||||||
|
String SYS_DICT = "sys_dict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OSS内容
|
||||||
|
*/
|
||||||
|
String SYS_OSS = "sys_oss#30d";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OSS配置
|
||||||
|
*/
|
||||||
|
String SYS_OSS_CONFIG = "sys_oss_config";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在线用户
|
||||||
|
*/
|
||||||
|
String ONLINE_TOKEN = "online_tokens";
|
||||||
|
|
||||||
|
}
|
@ -17,6 +17,11 @@ public interface Constants {
|
|||||||
*/
|
*/
|
||||||
String GBK = "GBK";
|
String GBK = "GBK";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* www主域
|
||||||
|
*/
|
||||||
|
String WWW = "www.";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* http请求
|
* http请求
|
||||||
*/
|
*/
|
||||||
@ -57,70 +62,15 @@ public interface Constants {
|
|||||||
*/
|
*/
|
||||||
String LOGIN_FAIL = "Error";
|
String LOGIN_FAIL = "Error";
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证码 redis key
|
|
||||||
*/
|
|
||||||
String CAPTCHA_CODE_KEY = "captcha_codes:";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录用户 redis key
|
|
||||||
*/
|
|
||||||
String LOGIN_TOKEN_KEY = "Authorization:login:token:";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 在线用户 redis key
|
|
||||||
*/
|
|
||||||
String ONLINE_TOKEN_KEY = "online_tokens:";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 防重提交 redis key
|
|
||||||
*/
|
|
||||||
String REPEAT_SUBMIT_KEY = "repeat_submit:";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 限流 redis key
|
|
||||||
*/
|
|
||||||
String RATE_LIMIT_KEY = "rate_limit:";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码有效期(分钟)
|
* 验证码有效期(分钟)
|
||||||
*/
|
*/
|
||||||
Integer CAPTCHA_EXPIRATION = 2;
|
Integer CAPTCHA_EXPIRATION = 2;
|
||||||
|
|
||||||
/**
|
|
||||||
* 登陆错误 redis key
|
|
||||||
*/
|
|
||||||
String LOGIN_ERROR = "login_error:";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录错误次数
|
|
||||||
*/
|
|
||||||
Integer LOGIN_ERROR_NUMBER = 5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录错误限制时间(分钟)
|
|
||||||
*/
|
|
||||||
Integer LOGIN_ERROR_LIMIT_TIME = 10;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 令牌
|
* 令牌
|
||||||
*/
|
*/
|
||||||
String TOKEN = "token";
|
String TOKEN = "token";
|
||||||
|
|
||||||
/**
|
|
||||||
* 令牌前缀
|
|
||||||
*/
|
|
||||||
String LOGIN_USER_KEY = "login_user_key";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 参数管理 cache key
|
|
||||||
*/
|
|
||||||
String SYS_CONFIG_KEY = "sys_config:";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字典管理 cache key
|
|
||||||
*/
|
|
||||||
String SYS_DICT_KEY = "sys_dict:";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package com.ruoyi.common.core.domain;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@ -24,42 +23,36 @@ public class BaseEntity implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 搜索值
|
* 搜索值
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "搜索值")
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private String searchValue;
|
private String searchValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建者
|
* 创建者
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "创建者")
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private String createBy;
|
private String createBy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建时间
|
* 创建时间
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "创建时间")
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新者
|
* 更新者
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "更新者")
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
private String updateBy;
|
private String updateBy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新时间
|
* 更新时间
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "更新时间")
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
private Date updateTime;
|
private Date updateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求参数
|
* 请求参数
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "请求参数")
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private Map<String, Object> params = new HashMap<>();
|
private Map<String, Object> params = new HashMap<>();
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.sql.SqlUtil;
|
import com.ruoyi.common.utils.sql.SqlUtil;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@ -24,25 +23,21 @@ public class PageQuery implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 分页大小
|
* 分页大小
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty("分页大小")
|
|
||||||
private Integer pageSize;
|
private Integer pageSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前页数
|
* 当前页数
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty("当前页数")
|
|
||||||
private Integer pageNum;
|
private Integer pageNum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排序列
|
* 排序列
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty("排序列")
|
|
||||||
private String orderByColumn;
|
private String orderByColumn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排序的方向desc或者asc
|
* 排序的方向desc或者asc
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "排序的方向", example = "asc,desc")
|
|
||||||
private String isAsc;
|
private String isAsc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.ruoyi.common.core.domain;
|
package com.ruoyi.common.core.domain;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
@ -14,7 +12,6 @@ import java.io.Serializable;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ApiModel("请求响应对象")
|
|
||||||
public class R<T> implements Serializable {
|
public class R<T> implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@ -28,13 +25,10 @@ public class R<T> implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public static final int FAIL = 500;
|
public static final int FAIL = 500;
|
||||||
|
|
||||||
@ApiModelProperty("消息状态码")
|
|
||||||
private int code;
|
private int code;
|
||||||
|
|
||||||
@ApiModelProperty("消息内容")
|
|
||||||
private String msg;
|
private String msg;
|
||||||
|
|
||||||
@ApiModelProperty("数据对象")
|
|
||||||
private T data;
|
private T data;
|
||||||
|
|
||||||
public static <T> R<T> ok() {
|
public static <T> R<T> ok() {
|
||||||
@ -81,4 +75,11 @@ public class R<T> implements Serializable {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean isError() {
|
||||||
|
return !isSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isSuccess() {
|
||||||
|
return R.SUCCESS == getCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.ruoyi.common.core.domain;
|
package com.ruoyi.common.core.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
@ -24,20 +23,17 @@ public class TreeEntity<T> extends BaseEntity {
|
|||||||
* 父菜单名称
|
* 父菜单名称
|
||||||
*/
|
*/
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
@ApiModelProperty(value = "父菜单名称")
|
|
||||||
private String parentName;
|
private String parentName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 父菜单ID
|
* 父菜单ID
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "父菜单ID")
|
|
||||||
private Long parentId;
|
private Long parentId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 子部门
|
* 子部门
|
||||||
*/
|
*/
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
@ApiModelProperty(value = "子部门")
|
|
||||||
private List<T> children = new ArrayList<>();
|
private List<T> children = new ArrayList<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.ruoyi.common.core.domain.TreeEntity;
|
import com.ruoyi.common.core.domain.TreeEntity;
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
@ -23,21 +21,18 @@ import javax.validation.constraints.Size;
|
|||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("sys_dept")
|
@TableName("sys_dept")
|
||||||
@ApiModel("部门业务对象")
|
|
||||||
public class SysDept extends TreeEntity<SysDept> {
|
public class SysDept extends TreeEntity<SysDept> {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门ID
|
* 部门ID
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "部门id")
|
|
||||||
@TableId(value = "dept_id")
|
@TableId(value = "dept_id")
|
||||||
private Long deptId;
|
private Long deptId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门名称
|
* 部门名称
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "部门名称")
|
|
||||||
@NotBlank(message = "部门名称不能为空")
|
@NotBlank(message = "部门名称不能为空")
|
||||||
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
|
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
|
||||||
private String deptName;
|
private String deptName;
|
||||||
@ -45,27 +40,23 @@ public class SysDept extends TreeEntity<SysDept> {
|
|||||||
/**
|
/**
|
||||||
* 显示顺序
|
* 显示顺序
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "显示顺序")
|
|
||||||
@NotNull(message = "显示顺序不能为空")
|
@NotNull(message = "显示顺序不能为空")
|
||||||
private Integer orderNum;
|
private Integer orderNum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 负责人
|
* 负责人
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "负责人")
|
|
||||||
private String leader;
|
private String leader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 联系电话
|
* 联系电话
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "联系电话")
|
|
||||||
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
|
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
|
||||||
private String phone;
|
private String phone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 邮箱
|
* 邮箱
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "邮箱")
|
|
||||||
@Email(message = "邮箱格式不正确")
|
@Email(message = "邮箱格式不正确")
|
||||||
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
||||||
private String email;
|
private String email;
|
||||||
@ -73,20 +64,17 @@ public class SysDept extends TreeEntity<SysDept> {
|
|||||||
/**
|
/**
|
||||||
* 部门状态:0正常,1停用
|
* 部门状态:0正常,1停用
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "部门状态:0正常,1停用")
|
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除标志(0代表存在 2代表删除)
|
* 删除标志(0代表存在 2代表删除)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "删除标志(0代表存在 2代表删除)")
|
|
||||||
@TableLogic
|
@TableLogic
|
||||||
private String delFlag;
|
private String delFlag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 祖级列表
|
* 祖级列表
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "祖级列表")
|
|
||||||
private String ancestors;
|
private String ancestors;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,6 @@ import com.ruoyi.common.annotation.ExcelDictFormat;
|
|||||||
import com.ruoyi.common.constant.UserConstants;
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
import com.ruoyi.common.convert.ExcelDictConvert;
|
import com.ruoyi.common.convert.ExcelDictConvert;
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
@ -26,13 +24,11 @@ import javax.validation.constraints.Size;
|
|||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("sys_dict_data")
|
@TableName("sys_dict_data")
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
@ApiModel("字典数据业务对象")
|
|
||||||
public class SysDictData extends BaseEntity {
|
public class SysDictData extends BaseEntity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典编码
|
* 字典编码
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "字典编码")
|
|
||||||
@ExcelProperty(value = "字典编码")
|
@ExcelProperty(value = "字典编码")
|
||||||
@TableId(value = "dict_code")
|
@TableId(value = "dict_code")
|
||||||
private Long dictCode;
|
private Long dictCode;
|
||||||
@ -40,14 +36,12 @@ public class SysDictData extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 字典排序
|
* 字典排序
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "字典排序")
|
|
||||||
@ExcelProperty(value = "字典排序")
|
@ExcelProperty(value = "字典排序")
|
||||||
private Integer dictSort;
|
private Integer dictSort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典标签
|
* 字典标签
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "字典标签")
|
|
||||||
@ExcelProperty(value = "字典标签")
|
@ExcelProperty(value = "字典标签")
|
||||||
@NotBlank(message = "字典标签不能为空")
|
@NotBlank(message = "字典标签不能为空")
|
||||||
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
|
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
|
||||||
@ -56,7 +50,6 @@ public class SysDictData extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 字典键值
|
* 字典键值
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "字典键值")
|
|
||||||
@ExcelProperty(value = "字典键值")
|
@ExcelProperty(value = "字典键值")
|
||||||
@NotBlank(message = "字典键值不能为空")
|
@NotBlank(message = "字典键值不能为空")
|
||||||
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
|
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
|
||||||
@ -65,7 +58,6 @@ public class SysDictData extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 字典类型
|
* 字典类型
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "字典类型")
|
|
||||||
@ExcelProperty(value = "字典类型")
|
@ExcelProperty(value = "字典类型")
|
||||||
@NotBlank(message = "字典类型不能为空")
|
@NotBlank(message = "字典类型不能为空")
|
||||||
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
|
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
|
||||||
@ -74,20 +66,17 @@ public class SysDictData extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 样式属性(其他样式扩展)
|
* 样式属性(其他样式扩展)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "样式属性(其他样式扩展)")
|
|
||||||
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
|
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
|
||||||
private String cssClass;
|
private String cssClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表格字典样式
|
* 表格字典样式
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "表格字典样式")
|
|
||||||
private String listClass;
|
private String listClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否默认(Y是 N否)
|
* 是否默认(Y是 N否)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "是否默认(Y是 N否)")
|
|
||||||
@ExcelProperty(value = "是否默认", converter = ExcelDictConvert.class)
|
@ExcelProperty(value = "是否默认", converter = ExcelDictConvert.class)
|
||||||
@ExcelDictFormat(dictType = "sys_yes_no")
|
@ExcelDictFormat(dictType = "sys_yes_no")
|
||||||
private String isDefault;
|
private String isDefault;
|
||||||
@ -95,7 +84,6 @@ public class SysDictData extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 状态(0正常 1停用)
|
* 状态(0正常 1停用)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "状态(0正常 1停用)")
|
|
||||||
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
|
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
|
||||||
@ExcelDictFormat(dictType = "sys_normal_disable")
|
@ExcelDictFormat(dictType = "sys_normal_disable")
|
||||||
private String status;
|
private String status;
|
||||||
@ -103,7 +91,6 @@ public class SysDictData extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "备注")
|
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
public boolean getDefault() {
|
public boolean getDefault() {
|
||||||
|
@ -7,11 +7,8 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
|||||||
import com.ruoyi.common.annotation.ExcelDictFormat;
|
import com.ruoyi.common.annotation.ExcelDictFormat;
|
||||||
import com.ruoyi.common.convert.ExcelDictConvert;
|
import com.ruoyi.common.convert.ExcelDictConvert;
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.Pattern;
|
import javax.validation.constraints.Pattern;
|
||||||
@ -27,13 +24,11 @@ import javax.validation.constraints.Size;
|
|||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("sys_dict_type")
|
@TableName("sys_dict_type")
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
@ApiModel("字典类型业务对象")
|
|
||||||
public class SysDictType extends BaseEntity {
|
public class SysDictType extends BaseEntity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典主键
|
* 字典主键
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "字典主键")
|
|
||||||
@ExcelProperty(value = "字典主键")
|
@ExcelProperty(value = "字典主键")
|
||||||
@TableId(value = "dict_id")
|
@TableId(value = "dict_id")
|
||||||
private Long dictId;
|
private Long dictId;
|
||||||
@ -41,7 +36,6 @@ public class SysDictType extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 字典名称
|
* 字典名称
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "字典名称")
|
|
||||||
@ExcelProperty(value = "字典名称")
|
@ExcelProperty(value = "字典名称")
|
||||||
@NotBlank(message = "字典名称不能为空")
|
@NotBlank(message = "字典名称不能为空")
|
||||||
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
|
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
|
||||||
@ -50,7 +44,6 @@ public class SysDictType extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 字典类型
|
* 字典类型
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "字典类型")
|
|
||||||
@ExcelProperty(value = "字典类型")
|
@ExcelProperty(value = "字典类型")
|
||||||
@NotBlank(message = "字典类型不能为空")
|
@NotBlank(message = "字典类型不能为空")
|
||||||
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
|
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
|
||||||
@ -60,7 +53,6 @@ public class SysDictType extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 状态(0正常 1停用)
|
* 状态(0正常 1停用)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "状态(0正常 1停用)")
|
|
||||||
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
|
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
|
||||||
@ExcelDictFormat(dictType = "sys_normal_disable")
|
@ExcelDictFormat(dictType = "sys_normal_disable")
|
||||||
private String status;
|
private String status;
|
||||||
@ -68,7 +60,6 @@ public class SysDictType extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "备注")
|
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.ruoyi.common.core.domain.TreeEntity;
|
import com.ruoyi.common.core.domain.TreeEntity;
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
@ -22,20 +20,17 @@ import javax.validation.constraints.Size;
|
|||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("sys_menu")
|
@TableName("sys_menu")
|
||||||
@ApiModel("菜单权限业务对象")
|
|
||||||
public class SysMenu extends TreeEntity<SysMenu> {
|
public class SysMenu extends TreeEntity<SysMenu> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单ID
|
* 菜单ID
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "菜单ID")
|
|
||||||
@TableId(value = "menu_id")
|
@TableId(value = "menu_id")
|
||||||
private Long menuId;
|
private Long menuId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单名称
|
* 菜单名称
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "菜单名称")
|
|
||||||
@NotBlank(message = "菜单名称不能为空")
|
@NotBlank(message = "菜单名称不能为空")
|
||||||
@Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
|
@Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
|
||||||
private String menuName;
|
private String menuName;
|
||||||
@ -43,65 +38,55 @@ public class SysMenu extends TreeEntity<SysMenu> {
|
|||||||
/**
|
/**
|
||||||
* 显示顺序
|
* 显示顺序
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "显示顺序")
|
|
||||||
@NotNull(message = "显示顺序不能为空")
|
@NotNull(message = "显示顺序不能为空")
|
||||||
private Integer orderNum;
|
private Integer orderNum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 路由地址
|
* 路由地址
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "路由地址")
|
|
||||||
@Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
|
@Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
|
||||||
private String path;
|
private String path;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组件路径
|
* 组件路径
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "组件路径")
|
|
||||||
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
|
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
|
||||||
private String component;
|
private String component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 路由参数
|
* 路由参数
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "路由参数")
|
|
||||||
private String queryParam;
|
private String queryParam;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否为外链(0是 1否)
|
* 是否为外链(0是 1否)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "是否为外链(0是 1否)")
|
|
||||||
private String isFrame;
|
private String isFrame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否缓存(0缓存 1不缓存)
|
* 是否缓存(0缓存 1不缓存)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "是否缓存(0缓存 1不缓存)")
|
|
||||||
private String isCache;
|
private String isCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型(M目录 C菜单 F按钮)
|
* 类型(M目录 C菜单 F按钮)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "类型(M目录 C菜单 F按钮)")
|
|
||||||
@NotBlank(message = "菜单类型不能为空")
|
@NotBlank(message = "菜单类型不能为空")
|
||||||
private String menuType;
|
private String menuType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示状态(0显示 1隐藏)
|
* 显示状态(0显示 1隐藏)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "显示状态(0显示 1隐藏)")
|
|
||||||
private String visible;
|
private String visible;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单状态(0显示 1隐藏)
|
* 菜单状态(0正常 1停用)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "菜单状态(0显示 1隐藏)")
|
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限字符串
|
* 权限字符串
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "权限字符串")
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
@Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
|
@Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
|
||||||
private String perms;
|
private String perms;
|
||||||
@ -109,13 +94,11 @@ public class SysMenu extends TreeEntity<SysMenu> {
|
|||||||
/**
|
/**
|
||||||
* 菜单图标
|
* 菜单图标
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "菜单图标")
|
|
||||||
private String icon;
|
private String icon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "备注")
|
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import com.ruoyi.common.annotation.ExcelDictFormat;
|
|||||||
import com.ruoyi.common.constant.UserConstants;
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
import com.ruoyi.common.convert.ExcelDictConvert;
|
import com.ruoyi.common.convert.ExcelDictConvert;
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -18,6 +17,7 @@ import lombok.NoArgsConstructor;
|
|||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.Size;
|
import javax.validation.constraints.Size;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色表 sys_role
|
* 角色表 sys_role
|
||||||
@ -35,7 +35,6 @@ public class SysRole extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 角色ID
|
* 角色ID
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "角色ID")
|
|
||||||
@ExcelProperty(value = "角色序号")
|
@ExcelProperty(value = "角色序号")
|
||||||
@TableId(value = "role_id")
|
@TableId(value = "role_id")
|
||||||
private Long roleId;
|
private Long roleId;
|
||||||
@ -43,7 +42,6 @@ public class SysRole extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 角色名称
|
* 角色名称
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "角色名称")
|
|
||||||
@ExcelProperty(value = "角色名称")
|
@ExcelProperty(value = "角色名称")
|
||||||
@NotBlank(message = "角色名称不能为空")
|
@NotBlank(message = "角色名称不能为空")
|
||||||
@Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
|
@Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
|
||||||
@ -52,7 +50,6 @@ public class SysRole extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 角色权限
|
* 角色权限
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "角色权限")
|
|
||||||
@ExcelProperty(value = "角色权限")
|
@ExcelProperty(value = "角色权限")
|
||||||
@NotBlank(message = "权限字符不能为空")
|
@NotBlank(message = "权限字符不能为空")
|
||||||
@Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
|
@Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
|
||||||
@ -61,7 +58,6 @@ public class SysRole extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 角色排序
|
* 角色排序
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "角色排序")
|
|
||||||
@ExcelProperty(value = "角色排序")
|
@ExcelProperty(value = "角色排序")
|
||||||
@NotNull(message = "显示顺序不能为空")
|
@NotNull(message = "显示顺序不能为空")
|
||||||
private Integer roleSort;
|
private Integer roleSort;
|
||||||
@ -69,7 +65,6 @@ public class SysRole extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限)
|
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限)")
|
|
||||||
@ExcelProperty(value = "数据范围", converter = ExcelDictConvert.class)
|
@ExcelProperty(value = "数据范围", converter = ExcelDictConvert.class)
|
||||||
@ExcelDictFormat(readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
|
@ExcelDictFormat(readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
|
||||||
private String dataScope;
|
private String dataScope;
|
||||||
@ -77,62 +72,59 @@ public class SysRole extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示)
|
* 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示)")
|
|
||||||
private Boolean menuCheckStrictly;
|
private Boolean menuCheckStrictly;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 )
|
* 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 )
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 )")
|
|
||||||
private Boolean deptCheckStrictly;
|
private Boolean deptCheckStrictly;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色状态(0正常 1停用)
|
* 角色状态(0正常 1停用)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "角色状态(0正常 1停用)")
|
|
||||||
@ExcelProperty(value = "角色状态", converter = ExcelDictConvert.class)
|
@ExcelProperty(value = "角色状态", converter = ExcelDictConvert.class)
|
||||||
@ExcelDictFormat(dictType = "sys_common_status")
|
@ExcelDictFormat(dictType = "sys_normal_disable")
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除标志(0代表存在 2代表删除)
|
* 删除标志(0代表存在 2代表删除)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "删除标志(0代表存在 2代表删除)")
|
|
||||||
@TableLogic
|
@TableLogic
|
||||||
private String delFlag;
|
private String delFlag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "备注")
|
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户是否存在此角色标识 默认不存在
|
* 用户是否存在此角色标识 默认不存在
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "用户是否存在此角色标识 默认不存在")
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private boolean flag = false;
|
private boolean flag = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单组
|
* 菜单组
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "菜单组")
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private Long[] menuIds;
|
private Long[] menuIds;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门组(数据权限)
|
* 部门组(数据权限)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "部门组(数据权限)")
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private Long[] deptIds;
|
private Long[] deptIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色菜单权限
|
||||||
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Set<String> permissions;
|
||||||
|
|
||||||
public SysRole(Long roleId) {
|
public SysRole(Long roleId) {
|
||||||
this.roleId = roleId;
|
this.roleId = roleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiModelProperty(value = "是否管理员")
|
|
||||||
public boolean isAdmin() {
|
public boolean isAdmin() {
|
||||||
return UserConstants.ADMIN_ID.equals(this.roleId);
|
return UserConstants.ADMIN_ID.equals(this.roleId);
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
package com.ruoyi.common.core.domain.entity;
|
package com.ruoyi.common.core.domain.entity;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.*;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.ruoyi.common.annotation.Sensitive;
|
import com.ruoyi.common.annotation.Sensitive;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
import com.ruoyi.common.enums.SensitiveStrategy;
|
import com.ruoyi.common.enums.SensitiveStrategy;
|
||||||
import com.ruoyi.common.xss.Xss;
|
import com.ruoyi.common.xss.Xss;
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -30,26 +26,22 @@ import java.util.List;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableName("sys_user")
|
@TableName("sys_user")
|
||||||
@ApiModel("用户信息业务对象")
|
|
||||||
public class SysUser extends BaseEntity {
|
public class SysUser extends BaseEntity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户ID
|
* 用户ID
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "用户ID")
|
|
||||||
@TableId(value = "user_id")
|
@TableId(value = "user_id")
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门ID
|
* 部门ID
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "部门ID")
|
|
||||||
private Long deptId;
|
private Long deptId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户账号
|
* 用户账号
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "用户账号")
|
|
||||||
@Xss(message = "用户账号不能包含脚本字符")
|
@Xss(message = "用户账号不能包含脚本字符")
|
||||||
@NotBlank(message = "用户账号不能为空")
|
@NotBlank(message = "用户账号不能为空")
|
||||||
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
|
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
|
||||||
@ -58,7 +50,6 @@ public class SysUser extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 用户昵称
|
* 用户昵称
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "用户昵称")
|
|
||||||
@Xss(message = "用户昵称不能包含脚本字符")
|
@Xss(message = "用户昵称不能包含脚本字符")
|
||||||
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
|
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
|
||||||
private String nickName;
|
private String nickName;
|
||||||
@ -66,14 +57,12 @@ public class SysUser extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 用户类型(sys_user系统用户)
|
* 用户类型(sys_user系统用户)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "用户类型")
|
|
||||||
private String userType;
|
private String userType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户邮箱
|
* 用户邮箱
|
||||||
*/
|
*/
|
||||||
@Sensitive(strategy = SensitiveStrategy.EMAIL)
|
@Sensitive(strategy = SensitiveStrategy.EMAIL)
|
||||||
@ApiModelProperty(value = "用户邮箱")
|
|
||||||
@Email(message = "邮箱格式不正确")
|
@Email(message = "邮箱格式不正确")
|
||||||
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
||||||
private String email;
|
private String email;
|
||||||
@ -82,25 +71,21 @@ public class SysUser extends BaseEntity {
|
|||||||
* 手机号码
|
* 手机号码
|
||||||
*/
|
*/
|
||||||
@Sensitive(strategy = SensitiveStrategy.PHONE)
|
@Sensitive(strategy = SensitiveStrategy.PHONE)
|
||||||
@ApiModelProperty(value = "手机号码")
|
|
||||||
private String phonenumber;
|
private String phonenumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户性别
|
* 用户性别
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "用户性别")
|
|
||||||
private String sex;
|
private String sex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户头像
|
* 用户头像
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "用户头像")
|
|
||||||
private String avatar;
|
private String avatar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 密码
|
* 密码
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "密码")
|
|
||||||
@TableField(
|
@TableField(
|
||||||
insertStrategy = FieldStrategy.NOT_EMPTY,
|
insertStrategy = FieldStrategy.NOT_EMPTY,
|
||||||
updateStrategy = FieldStrategy.NOT_EMPTY,
|
updateStrategy = FieldStrategy.NOT_EMPTY,
|
||||||
@ -111,66 +96,56 @@ public class SysUser extends BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* 帐号状态(0正常 1停用)
|
* 帐号状态(0正常 1停用)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "帐号状态(0正常 1停用)")
|
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除标志(0代表存在 2代表删除)
|
* 删除标志(0代表存在 2代表删除)
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "删除标志(0代表存在 2代表删除)")
|
|
||||||
@TableLogic
|
@TableLogic
|
||||||
private String delFlag;
|
private String delFlag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最后登录IP
|
* 最后登录IP
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "最后登录IP")
|
|
||||||
private String loginIp;
|
private String loginIp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最后登录时间
|
* 最后登录时间
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "最后登录时间")
|
|
||||||
private Date loginDate;
|
private Date loginDate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "备注")
|
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门对象
|
* 部门对象
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "部门对象")
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private SysDept dept;
|
private SysDept dept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色对象
|
* 角色对象
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "角色对象")
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private List<SysRole> roles;
|
private List<SysRole> roles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色组
|
* 角色组
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "角色组")
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private Long[] roleIds;
|
private Long[] roleIds;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 岗位组
|
* 岗位组
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "岗位组")
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private Long[] postIds;
|
private Long[] postIds;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据权限 当前角色ID
|
* 数据权限 当前角色ID
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "角色ID")
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private Long roleId;
|
private Long roleId;
|
||||||
|
|
||||||
@ -178,7 +153,6 @@ public class SysUser extends BaseEntity {
|
|||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiModelProperty(value = "是否管理员")
|
|
||||||
public boolean isAdmin() {
|
public boolean isAdmin() {
|
||||||
return UserConstants.ADMIN_ID.equals(this.userId);
|
return UserConstants.ADMIN_ID.equals(this.userId);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package com.ruoyi.common.core.domain.model;
|
package com.ruoyi.common.core.domain.model;
|
||||||
|
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
@ -15,7 +13,6 @@ import javax.validation.constraints.NotBlank;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ApiModel("用户登录对象")
|
|
||||||
public class LoginBody {
|
public class LoginBody {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,7 +20,6 @@ public class LoginBody {
|
|||||||
*/
|
*/
|
||||||
@NotBlank(message = "{user.username.not.blank}")
|
@NotBlank(message = "{user.username.not.blank}")
|
||||||
@Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
|
@Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
|
||||||
@ApiModelProperty(value = "用户名")
|
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,19 +27,16 @@ public class LoginBody {
|
|||||||
*/
|
*/
|
||||||
@NotBlank(message = "{user.password.not.blank}")
|
@NotBlank(message = "{user.password.not.blank}")
|
||||||
@Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
|
@Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
|
||||||
@ApiModelProperty(value = "用户密码")
|
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码
|
* 验证码
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "验证码")
|
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 唯一标识
|
* 唯一标识
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty(value = "唯一标识")
|
|
||||||
private String uuid;
|
private String uuid;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,12 @@ public class LoginUser implements Serializable {
|
|||||||
* 获取登录id
|
* 获取登录id
|
||||||
*/
|
*/
|
||||||
public String getLoginId() {
|
public String getLoginId() {
|
||||||
|
if (userType == null) {
|
||||||
|
throw new IllegalArgumentException("用户类型不能为空");
|
||||||
|
}
|
||||||
|
if (userId == null) {
|
||||||
|
throw new IllegalArgumentException("用户ID不能为空");
|
||||||
|
}
|
||||||
return userType + LoginHelper.JOIN_CODE + userId;
|
return userType + LoginHelper.JOIN_CODE + userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.ruoyi.common.core.domain.model;
|
package com.ruoyi.common.core.domain.model;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
@ -12,10 +10,8 @@ import lombok.EqualsAndHashCode;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ApiModel("用户注册对象")
|
|
||||||
public class RegisterBody extends LoginBody {
|
public class RegisterBody extends LoginBody {
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户类型")
|
|
||||||
private String userType;
|
private String userType;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.ruoyi.common.core.domain.model;
|
package com.ruoyi.common.core.domain.model;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
@ -13,21 +11,18 @@ import javax.validation.constraints.NotBlank;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ApiModel("短信登录对象")
|
|
||||||
public class SmsLoginBody {
|
public class SmsLoginBody {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户名
|
* 用户名
|
||||||
*/
|
*/
|
||||||
@NotBlank(message = "{user.phonenumber.not.blank}")
|
@NotBlank(message = "{user.phonenumber.not.blank}")
|
||||||
@ApiModelProperty(value = "用户手机号")
|
|
||||||
private String phonenumber;
|
private String phonenumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户密码
|
* 用户密码
|
||||||
*/
|
*/
|
||||||
@NotBlank(message = "{sms.code.not.blank}")
|
@NotBlank(message = "{sms.code.not.blank}")
|
||||||
@ApiModelProperty(value = "短信验证码")
|
|
||||||
private String smsCode;
|
private String smsCode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ public interface BaseMapperPlus<M, T, V> extends BaseMapper<T> {
|
|||||||
return BeanCopyUtils.copy(obj, voClass);
|
return BeanCopyUtils.copy(obj, voClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<V> selectVoById(Collection<? extends Serializable> idList) {
|
default List<V> selectVoBatchIds(Collection<? extends Serializable> idList) {
|
||||||
return selectVoBatchIds(idList, this.currentVoClass());
|
return selectVoBatchIds(idList, this.currentVoClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,8 @@ package com.ruoyi.common.core.page;
|
|||||||
|
|
||||||
import cn.hutool.http.HttpStatus;
|
import cn.hutool.http.HttpStatus;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -19,32 +16,27 @@ import java.util.List;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ApiModel("分页响应对象")
|
|
||||||
public class TableDataInfo<T> implements Serializable {
|
public class TableDataInfo<T> implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 总记录数
|
* 总记录数
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty("总记录数")
|
|
||||||
private long total;
|
private long total;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 列表数据
|
* 列表数据
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty("列表数据")
|
|
||||||
private List<T> rows;
|
private List<T> rows;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息状态码
|
* 消息状态码
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty("消息状态码")
|
|
||||||
private int code;
|
private int code;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息内容
|
* 消息内容
|
||||||
*/
|
*/
|
||||||
@ApiModelProperty("消息内容")
|
|
||||||
private String msg;
|
private String msg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,6 +6,7 @@ import com.alibaba.excel.event.AnalysisEventListener;
|
|||||||
import com.alibaba.excel.exception.ExcelAnalysisException;
|
import com.alibaba.excel.exception.ExcelAnalysisException;
|
||||||
import com.alibaba.excel.exception.ExcelDataConvertException;
|
import com.alibaba.excel.exception.ExcelDataConvertException;
|
||||||
import com.ruoyi.common.utils.JsonUtils;
|
import com.ruoyi.common.utils.JsonUtils;
|
||||||
|
import com.ruoyi.common.utils.StreamUtils;
|
||||||
import com.ruoyi.common.utils.ValidatorUtils;
|
import com.ruoyi.common.utils.ValidatorUtils;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -14,7 +15,6 @@ import javax.validation.ConstraintViolation;
|
|||||||
import javax.validation.ConstraintViolationException;
|
import javax.validation.ConstraintViolationException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Excel 导入监听
|
* Excel 导入监听
|
||||||
@ -69,9 +69,7 @@ public class DefaultExcelListener<T> extends AnalysisEventListener<T> implements
|
|||||||
if (exception instanceof ConstraintViolationException) {
|
if (exception instanceof ConstraintViolationException) {
|
||||||
ConstraintViolationException constraintViolationException = (ConstraintViolationException) exception;
|
ConstraintViolationException constraintViolationException = (ConstraintViolationException) exception;
|
||||||
Set<ConstraintViolation<?>> constraintViolations = constraintViolationException.getConstraintViolations();
|
Set<ConstraintViolation<?>> constraintViolations = constraintViolationException.getConstraintViolations();
|
||||||
String constraintViolationsMsg = constraintViolations.stream()
|
String constraintViolationsMsg = StreamUtils.join(constraintViolations, ConstraintViolation::getMessage, ", ");
|
||||||
.map(ConstraintViolation::getMessage)
|
|
||||||
.collect(Collectors.joining(", "));
|
|
||||||
errMsg = StrUtil.format("第{}行数据校验异常: {}", context.readRowHolder().getRowIndex() + 1, constraintViolationsMsg);
|
errMsg = StrUtil.format("第{}行数据校验异常: {}", context.readRowHolder().getRowIndex() + 1, constraintViolationsMsg);
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.error(errMsg);
|
log.error(errMsg);
|
||||||
|
@ -49,4 +49,4 @@ public class GlobalException extends RuntimeException {
|
|||||||
this.message = message;
|
this.message = message;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,4 +62,4 @@ public final class ServiceException extends RuntimeException {
|
|||||||
this.detailMessage = detailMessage;
|
this.detailMessage = detailMessage;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.ruoyi.common.exception.user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户错误最大次数异常类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class UserPasswordRetryLimitExceedException extends UserException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime) {
|
||||||
|
super("user.password.retry.limit.exceed", retryLimitCount, lockTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package com.ruoyi.common.filter;
|
package com.ruoyi.common.filter;
|
||||||
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
|
|
||||||
import javax.servlet.ReadListener;
|
import javax.servlet.ReadListener;
|
||||||
import javax.servlet.ServletInputStream;
|
import javax.servlet.ServletInputStream;
|
||||||
@ -23,8 +24,8 @@ public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
|
|||||||
|
|
||||||
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {
|
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {
|
||||||
super(request);
|
super(request);
|
||||||
request.setCharacterEncoding("UTF-8");
|
request.setCharacterEncoding(Constants.UTF8);
|
||||||
response.setCharacterEncoding("UTF-8");
|
response.setCharacterEncoding(Constants.UTF8);
|
||||||
|
|
||||||
body = IoUtil.readUtf8(request.getInputStream()).getBytes(StandardCharsets.UTF_8);
|
body = IoUtil.readUtf8(request.getInputStream()).getBytes(StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.common.filter;
|
package com.ruoyi.common.filter;
|
||||||
|
|
||||||
|
import com.ruoyi.common.enums.HttpMethod;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.*;
|
||||||
@ -48,7 +49,7 @@ public class XssFilter implements Filter {
|
|||||||
String url = request.getServletPath();
|
String url = request.getServletPath();
|
||||||
String method = request.getMethod();
|
String method = request.getMethod();
|
||||||
// GET DELETE 不过滤
|
// GET DELETE 不过滤
|
||||||
if (method == null || method.matches("GET") || method.matches("DELETE")) {
|
if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return StringUtils.matches(url, excludes);
|
return StringUtils.matches(url, excludes);
|
||||||
|
@ -89,10 +89,9 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
|||||||
/**
|
/**
|
||||||
* 是否是Json请求
|
* 是否是Json请求
|
||||||
*
|
*
|
||||||
* @param request
|
|
||||||
*/
|
*/
|
||||||
public boolean isJsonRequest() {
|
public boolean isJsonRequest() {
|
||||||
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
|
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
|
||||||
return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
|
return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.common.jackson;
|
package com.ruoyi.common.jackson;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
import com.fasterxml.jackson.databind.BeanProperty;
|
import com.fasterxml.jackson.databind.BeanProperty;
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
@ -10,6 +11,8 @@ import com.ruoyi.common.annotation.Sensitive;
|
|||||||
import com.ruoyi.common.core.service.SensitiveService;
|
import com.ruoyi.common.core.service.SensitiveService;
|
||||||
import com.ruoyi.common.enums.SensitiveStrategy;
|
import com.ruoyi.common.enums.SensitiveStrategy;
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -19,19 +22,24 @@ import java.util.Objects;
|
|||||||
*
|
*
|
||||||
* @author Yjoioooo
|
* @author Yjoioooo
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
|
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
|
||||||
|
|
||||||
private SensitiveStrategy strategy;
|
private SensitiveStrategy strategy;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||||
SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class);
|
try {
|
||||||
if (sensitiveService.isSensitive()) {
|
SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class);
|
||||||
gen.writeString(strategy.desensitizer().apply(value));
|
if (ObjectUtil.isNotNull(sensitiveService) && sensitiveService.isSensitive()) {
|
||||||
} else {
|
gen.writeString(strategy.desensitizer().apply(value));
|
||||||
|
} else {
|
||||||
|
gen.writeString(value);
|
||||||
|
}
|
||||||
|
} catch (BeansException e) {
|
||||||
|
log.error("脱敏实现不存在, 采用默认处理 => {}", e.getMessage());
|
||||||
gen.writeString(value);
|
gen.writeString(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -14,7 +14,6 @@ import org.springframework.cglib.core.Converter;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bean深拷贝工具(基于 cglib 性能优异)
|
* bean深拷贝工具(基于 cglib 性能优异)
|
||||||
@ -79,11 +78,11 @@ public class BeanCopyUtils {
|
|||||||
if (CollUtil.isEmpty(sourceList)) {
|
if (CollUtil.isEmpty(sourceList)) {
|
||||||
return CollUtil.newArrayList();
|
return CollUtil.newArrayList();
|
||||||
}
|
}
|
||||||
return sourceList.stream().map(source -> {
|
return StreamUtils.toList(sourceList, source -> {
|
||||||
V target = ReflectUtil.newInstanceIfPossible(desc);
|
V target = ReflectUtil.newInstanceIfPossible(desc);
|
||||||
copy(source, target);
|
copy(source, target);
|
||||||
return target;
|
return target;
|
||||||
}).collect(Collectors.toList());
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,6 +3,7 @@ package com.ruoyi.common.utils;
|
|||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.extra.servlet.ServletUtil;
|
import cn.hutool.extra.servlet.ServletUtil;
|
||||||
import cn.hutool.http.HttpStatus;
|
import cn.hutool.http.HttpStatus;
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
@ -14,6 +15,9 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,7 +121,7 @@ public class ServletUtils extends ServletUtil {
|
|||||||
public static boolean isAjaxRequest(HttpServletRequest request) {
|
public static boolean isAjaxRequest(HttpServletRequest request) {
|
||||||
|
|
||||||
String accept = request.getHeader("accept");
|
String accept = request.getHeader("accept");
|
||||||
if (accept != null && accept.contains("application/json")) {
|
if (accept != null && accept.contains(MediaType.APPLICATION_JSON_VALUE)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,4 +143,32 @@ public class ServletUtils extends ServletUtil {
|
|||||||
return getClientIP(getRequest());
|
return getClientIP(getRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容编码
|
||||||
|
*
|
||||||
|
* @param str 内容
|
||||||
|
* @return 编码后的内容
|
||||||
|
*/
|
||||||
|
public static String urlEncode(String str) {
|
||||||
|
try {
|
||||||
|
return URLEncoder.encode(str, Constants.UTF8);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容解码
|
||||||
|
*
|
||||||
|
* @param str 内容
|
||||||
|
* @return 解码后的内容
|
||||||
|
*/
|
||||||
|
public static String urlDecode(String str) {
|
||||||
|
try {
|
||||||
|
return URLDecoder.decode(str, Constants.UTF8);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
251
ruoyi/src/main/java/com/ruoyi/common/utils/StreamUtils.java
Normal file
251
ruoyi/src/main/java/com/ruoyi/common/utils/StreamUtils.java
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
package com.ruoyi.common.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream 流工具类
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class StreamUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将collection过滤
|
||||||
|
*
|
||||||
|
* @param collection 需要转化的集合
|
||||||
|
* @param function 过滤方法
|
||||||
|
* @return 过滤后的list
|
||||||
|
*/
|
||||||
|
public static <E> List<E> filter(Collection<E> collection, Predicate<E> function) {
|
||||||
|
if (CollUtil.isEmpty(collection)) {
|
||||||
|
return CollUtil.newArrayList();
|
||||||
|
}
|
||||||
|
return collection.stream().filter(function).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将collection拼接
|
||||||
|
*
|
||||||
|
* @param collection 需要转化的集合
|
||||||
|
* @param function 拼接方法
|
||||||
|
* @return 拼接后的list
|
||||||
|
*/
|
||||||
|
public static <E> String join(Collection<E> collection, Function<E, String> function) {
|
||||||
|
return join(collection, function, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将collection拼接
|
||||||
|
*
|
||||||
|
* @param collection 需要转化的集合
|
||||||
|
* @param function 拼接方法
|
||||||
|
* @param delimiter 拼接符
|
||||||
|
* @return 拼接后的list
|
||||||
|
*/
|
||||||
|
public static <E> String join(Collection<E> collection, Function<E, String> function, CharSequence delimiter) {
|
||||||
|
if (CollUtil.isEmpty(collection)) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将collection排序
|
||||||
|
*
|
||||||
|
* @param collection 需要转化的集合
|
||||||
|
* @param comparing 排序方法
|
||||||
|
* @return 排序后的list
|
||||||
|
*/
|
||||||
|
public static <E> List<E> sorted(Collection<E> collection, Comparator<E> comparing) {
|
||||||
|
if (CollUtil.isEmpty(collection)) {
|
||||||
|
return CollUtil.newArrayList();
|
||||||
|
}
|
||||||
|
return collection.stream().sorted(comparing).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将collection转化为类型不变的map<br>
|
||||||
|
* <B>{@code Collection<V> ----> Map<K,V>}</B>
|
||||||
|
*
|
||||||
|
* @param collection 需要转化的集合
|
||||||
|
* @param key V类型转化为K类型的lambda方法
|
||||||
|
* @param <V> collection中的泛型
|
||||||
|
* @param <K> map中的key类型
|
||||||
|
* @return 转化后的map
|
||||||
|
*/
|
||||||
|
public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key) {
|
||||||
|
if (CollUtil.isEmpty(collection)) {
|
||||||
|
return MapUtil.newHashMap();
|
||||||
|
}
|
||||||
|
return collection.stream().collect(Collectors.toMap(key, Function.identity(), (l, r) -> l));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将Collection转化为map(value类型与collection的泛型不同)<br>
|
||||||
|
* <B>{@code Collection<E> -----> Map<K,V> }</B>
|
||||||
|
*
|
||||||
|
* @param collection 需要转化的集合
|
||||||
|
* @param key E类型转化为K类型的lambda方法
|
||||||
|
* @param value E类型转化为V类型的lambda方法
|
||||||
|
* @param <E> collection中的泛型
|
||||||
|
* @param <K> map中的key类型
|
||||||
|
* @param <V> map中的value类型
|
||||||
|
* @return 转化后的map
|
||||||
|
*/
|
||||||
|
public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value) {
|
||||||
|
if (CollUtil.isEmpty(collection)) {
|
||||||
|
return MapUtil.newHashMap();
|
||||||
|
}
|
||||||
|
return collection.stream().collect(Collectors.toMap(key, value, (l, r) -> l));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将collection按照规则(比如有相同的班级id)分类成map<br>
|
||||||
|
* <B>{@code Collection<E> -------> Map<K,List<E>> } </B>
|
||||||
|
*
|
||||||
|
* @param collection 需要分类的集合
|
||||||
|
* @param key 分类的规则
|
||||||
|
* @param <E> collection中的泛型
|
||||||
|
* @param <K> map中的key类型
|
||||||
|
* @return 分类后的map
|
||||||
|
*/
|
||||||
|
public static <E, K> Map<K, List<E>> groupByKey(Collection<E> collection, Function<E, K> key) {
|
||||||
|
if (CollUtil.isEmpty(collection)) {
|
||||||
|
return MapUtil.newHashMap();
|
||||||
|
}
|
||||||
|
return collection
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map<br>
|
||||||
|
* <B>{@code Collection<E> ---> Map<T,Map<U,List<E>>> } </B>
|
||||||
|
*
|
||||||
|
* @param collection 需要分类的集合
|
||||||
|
* @param key1 第一个分类的规则
|
||||||
|
* @param key2 第二个分类的规则
|
||||||
|
* @param <E> 集合元素类型
|
||||||
|
* @param <K> 第一个map中的key类型
|
||||||
|
* @param <U> 第二个map中的key类型
|
||||||
|
* @return 分类后的map
|
||||||
|
*/
|
||||||
|
public static <E, K, U> Map<K, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, K> key1, Function<E, U> key2) {
|
||||||
|
if (CollUtil.isEmpty(collection)) {
|
||||||
|
return MapUtil.newHashMap();
|
||||||
|
}
|
||||||
|
return collection
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList())));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map<br>
|
||||||
|
* <B>{@code Collection<E> ---> Map<T,Map<U,E>> } </B>
|
||||||
|
*
|
||||||
|
* @param collection 需要分类的集合
|
||||||
|
* @param key1 第一个分类的规则
|
||||||
|
* @param key2 第二个分类的规则
|
||||||
|
* @param <T> 第一个map中的key类型
|
||||||
|
* @param <U> 第二个map中的key类型
|
||||||
|
* @param <E> collection中的泛型
|
||||||
|
* @return 分类后的map
|
||||||
|
*/
|
||||||
|
public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1, Function<E, U> key2) {
|
||||||
|
if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) {
|
||||||
|
return MapUtil.newHashMap();
|
||||||
|
}
|
||||||
|
return collection
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将collection转化为List集合,但是两者的泛型不同<br>
|
||||||
|
* <B>{@code Collection<E> ------> List<T> } </B>
|
||||||
|
*
|
||||||
|
* @param collection 需要转化的集合
|
||||||
|
* @param function collection中的泛型转化为list泛型的lambda表达式
|
||||||
|
* @param <E> collection中的泛型
|
||||||
|
* @param <T> List中的泛型
|
||||||
|
* @return 转化后的list
|
||||||
|
*/
|
||||||
|
public static <E, T> List<T> toList(Collection<E> collection, Function<E, T> function) {
|
||||||
|
if (CollUtil.isEmpty(collection)) {
|
||||||
|
return CollUtil.newArrayList();
|
||||||
|
}
|
||||||
|
return collection
|
||||||
|
.stream()
|
||||||
|
.map(function)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将collection转化为Set集合,但是两者的泛型不同<br>
|
||||||
|
* <B>{@code Collection<E> ------> Set<T> } </B>
|
||||||
|
*
|
||||||
|
* @param collection 需要转化的集合
|
||||||
|
* @param function collection中的泛型转化为set泛型的lambda表达式
|
||||||
|
* @param <E> collection中的泛型
|
||||||
|
* @param <T> Set中的泛型
|
||||||
|
* @return 转化后的Set
|
||||||
|
*/
|
||||||
|
public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) {
|
||||||
|
if (CollUtil.isEmpty(collection) || function == null) {
|
||||||
|
return CollUtil.newHashSet();
|
||||||
|
}
|
||||||
|
return collection
|
||||||
|
.stream()
|
||||||
|
.map(function)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合并两个相同key类型的map
|
||||||
|
*
|
||||||
|
* @param map1 第一个需要合并的 map
|
||||||
|
* @param map2 第二个需要合并的 map
|
||||||
|
* @param merge 合并的lambda,将key value1 value2合并成最终的类型,注意value可能为空的情况
|
||||||
|
* @param <K> map中的key类型
|
||||||
|
* @param <X> 第一个 map的value类型
|
||||||
|
* @param <Y> 第二个 map的value类型
|
||||||
|
* @param <V> 最终map的value类型
|
||||||
|
* @return 合并后的map
|
||||||
|
*/
|
||||||
|
public static <K, X, Y, V> Map<K, V> merge(Map<K, X> map1, Map<K, Y> map2, BiFunction<X, Y, V> merge) {
|
||||||
|
if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) {
|
||||||
|
return MapUtil.newHashMap();
|
||||||
|
} else if (MapUtil.isEmpty(map1)) {
|
||||||
|
map1 = MapUtil.newHashMap();
|
||||||
|
} else if (MapUtil.isEmpty(map2)) {
|
||||||
|
map2 = MapUtil.newHashMap();
|
||||||
|
}
|
||||||
|
Set<K> key = new HashSet<>();
|
||||||
|
key.addAll(map1.keySet());
|
||||||
|
key.addAll(map2.keySet());
|
||||||
|
Map<K, V> map = new HashMap<>();
|
||||||
|
for (K t : key) {
|
||||||
|
X x = map1.get(t);
|
||||||
|
Y y = map2.get(t);
|
||||||
|
V z = merge.apply(x, y);
|
||||||
|
if (z != null) {
|
||||||
|
map.put(t, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package com.ruoyi.common.utils.redis;
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.redisson.api.RMap;
|
||||||
|
import org.springframework.cache.Cache;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存操作工具类 {@link }
|
||||||
|
*
|
||||||
|
* @author Michelle.Chung
|
||||||
|
* @date 2022/8/13
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
@SuppressWarnings(value = {"unchecked"})
|
||||||
|
public class CacheUtils {
|
||||||
|
|
||||||
|
private static final CacheManager CACHE_MANAGER = SpringUtils.getBean(CacheManager.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存组内所有的KEY
|
||||||
|
*
|
||||||
|
* @param cacheNames 缓存组名称
|
||||||
|
*/
|
||||||
|
public static Set<Object> keys(String cacheNames) {
|
||||||
|
RMap<Object, Object> rmap = (RMap<Object, Object>) CACHE_MANAGER.getCache(cacheNames).getNativeCache();
|
||||||
|
return rmap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存值
|
||||||
|
*
|
||||||
|
* @param cacheNames 缓存组名称
|
||||||
|
* @param key 缓存key
|
||||||
|
*/
|
||||||
|
public static <T> T get(String cacheNames, Object key) {
|
||||||
|
Cache.ValueWrapper wrapper = CACHE_MANAGER.getCache(cacheNames).get(key);
|
||||||
|
return wrapper != null ? (T) wrapper.get() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存缓存值
|
||||||
|
*
|
||||||
|
* @param cacheNames 缓存组名称
|
||||||
|
* @param key 缓存key
|
||||||
|
* @param value 缓存值
|
||||||
|
*/
|
||||||
|
public static void put(String cacheNames, Object key, Object value) {
|
||||||
|
CACHE_MANAGER.getCache(cacheNames).put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除缓存值
|
||||||
|
*
|
||||||
|
* @param cacheNames 缓存组名称
|
||||||
|
* @param key 缓存key
|
||||||
|
*/
|
||||||
|
public static void evict(String cacheNames, Object key) {
|
||||||
|
CACHE_MANAGER.getCache(cacheNames).evict(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空缓存值
|
||||||
|
*
|
||||||
|
* @param cacheNames 缓存组名称
|
||||||
|
*/
|
||||||
|
public static void clear(String cacheNames) {
|
||||||
|
CACHE_MANAGER.getCache(cacheNames).clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,7 +5,6 @@ import lombok.AccessLevel;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.redisson.api.*;
|
import org.redisson.api.*;
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@ -30,6 +29,43 @@ public class QueueUtils {
|
|||||||
return CLIENT;
|
return CLIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加普通队列数据
|
||||||
|
*
|
||||||
|
* @param queueName 队列名
|
||||||
|
* @param data 数据
|
||||||
|
*/
|
||||||
|
public static <T> boolean addQueueObject(String queueName, T data) {
|
||||||
|
RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
|
||||||
|
return queue.offer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用获取一个队列数据 没有数据返回 null(不支持延迟队列)
|
||||||
|
*
|
||||||
|
* @param queueName 队列名
|
||||||
|
*/
|
||||||
|
public static <T> T getQueueObject(String queueName) {
|
||||||
|
RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
|
||||||
|
return queue.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用删除队列数据(不支持延迟队列)
|
||||||
|
*/
|
||||||
|
public static <T> boolean removeQueueObject(String queueName, T data) {
|
||||||
|
RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
|
||||||
|
return queue.remove(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用销毁队列 所有阻塞监听 报错(不支持延迟队列)
|
||||||
|
*/
|
||||||
|
public static <T> boolean destroyQueue(String queueName) {
|
||||||
|
RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
|
||||||
|
return queue.delete();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加延迟队列数据 默认毫秒
|
* 添加延迟队列数据 默认毫秒
|
||||||
*
|
*
|
||||||
@ -84,32 +120,6 @@ public class QueueUtils {
|
|||||||
delayedQueue.destroy();
|
delayedQueue.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 尝试设置 优先队列比较器 用于排序优先级
|
|
||||||
*
|
|
||||||
* @param queueName 队列名
|
|
||||||
* @param comparator 比较器
|
|
||||||
*/
|
|
||||||
public static <T> boolean trySetPriorityQueueComparator(String queueName, Comparator<T> comparator) {
|
|
||||||
RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
|
|
||||||
return priorityBlockingQueue.trySetComparator(comparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 尝试设置 优先队列比较器 用于排序优先级
|
|
||||||
*
|
|
||||||
* @param queueName 队列名
|
|
||||||
* @param comparator 比较器
|
|
||||||
* @param destroy 已存在是否销毁
|
|
||||||
*/
|
|
||||||
public static <T> boolean trySetPriorityQueueComparator(String queueName, Comparator<T> comparator, boolean destroy) {
|
|
||||||
RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
|
|
||||||
if (priorityBlockingQueue.isExists() && destroy) {
|
|
||||||
destroyPriorityQueueObject(queueName);
|
|
||||||
}
|
|
||||||
return priorityBlockingQueue.trySetComparator(comparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加优先队列数据
|
* 添加优先队列数据
|
||||||
*
|
*
|
||||||
@ -121,32 +131,6 @@ public class QueueUtils {
|
|||||||
return priorityBlockingQueue.offer(data);
|
return priorityBlockingQueue.offer(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取一个优先队列数据 没有数据返回 null
|
|
||||||
*
|
|
||||||
* @param queueName 队列名
|
|
||||||
*/
|
|
||||||
public static <T> T getPriorityQueueObject(String queueName) {
|
|
||||||
RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
|
|
||||||
return priorityBlockingQueue.poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除优先队列数据
|
|
||||||
*/
|
|
||||||
public static <T> boolean removePriorityQueueObject(String queueName, T data) {
|
|
||||||
RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
|
|
||||||
return priorityBlockingQueue.remove(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 销毁优先队列
|
|
||||||
*/
|
|
||||||
public static boolean destroyPriorityQueueObject(String queueName) {
|
|
||||||
RPriorityBlockingQueue<?> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
|
|
||||||
return priorityBlockingQueue.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 尝试设置 有界队列 容量 用于限制数量
|
* 尝试设置 有界队列 容量 用于限制数量
|
||||||
*
|
*
|
||||||
@ -168,7 +152,7 @@ public class QueueUtils {
|
|||||||
public static <T> boolean trySetBoundedQueueCapacity(String queueName, int capacity, boolean destroy) {
|
public static <T> boolean trySetBoundedQueueCapacity(String queueName, int capacity, boolean destroy) {
|
||||||
RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
|
RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
|
||||||
if (boundedBlockingQueue.isExists() && destroy) {
|
if (boundedBlockingQueue.isExists() && destroy) {
|
||||||
destroyBoundedQueueObject(queueName);
|
destroyQueue(queueName);
|
||||||
}
|
}
|
||||||
return boundedBlockingQueue.trySetCapacity(capacity);
|
return boundedBlockingQueue.trySetCapacity(capacity);
|
||||||
}
|
}
|
||||||
@ -185,32 +169,6 @@ public class QueueUtils {
|
|||||||
return boundedBlockingQueue.offer(data);
|
return boundedBlockingQueue.offer(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取一个有界队列数据 没有数据返回 null
|
|
||||||
*
|
|
||||||
* @param queueName 队列名
|
|
||||||
*/
|
|
||||||
public static <T> T getBoundedQueueObject(String queueName) {
|
|
||||||
RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
|
|
||||||
return boundedBlockingQueue.poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除有界队列数据
|
|
||||||
*/
|
|
||||||
public static <T> boolean removeBoundedQueueObject(String queueName, T data) {
|
|
||||||
RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
|
|
||||||
return boundedBlockingQueue.remove(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 销毁有界队列
|
|
||||||
*/
|
|
||||||
public static boolean destroyBoundedQueueObject(String queueName) {
|
|
||||||
RBoundedBlockingQueue<?> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
|
|
||||||
return boundedBlockingQueue.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订阅阻塞队列(可订阅所有实现类 例如: 延迟 优先 有界 等)
|
* 订阅阻塞队列(可订阅所有实现类 例如: 延迟 优先 有界 等)
|
||||||
*/
|
*/
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.ruoyi.common.utils.redis;
|
package com.ruoyi.common.utils.redis;
|
||||||
|
|
||||||
import cn.hutool.core.collection.IterUtil;
|
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.redisson.api.*;
|
import org.redisson.api.*;
|
||||||
|
import org.redisson.config.Config;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -12,6 +12,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* redis 工具类
|
* redis 工具类
|
||||||
@ -25,6 +27,14 @@ public class RedisUtils {
|
|||||||
|
|
||||||
private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);
|
private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);
|
||||||
|
|
||||||
|
public static NameMapper getNameMapper() {
|
||||||
|
Config config = CLIENT.getConfig();
|
||||||
|
if (config.isClusterConfig()) {
|
||||||
|
return config.useClusterServers().getNameMapper();
|
||||||
|
}
|
||||||
|
return config.useSingleServer().getNameMapper();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 限流
|
* 限流
|
||||||
*
|
*
|
||||||
@ -100,14 +110,13 @@ public class RedisUtils {
|
|||||||
* @since Redis 6.X 以上使用 setAndKeepTTL 兼容 5.X 方案
|
* @since Redis 6.X 以上使用 setAndKeepTTL 兼容 5.X 方案
|
||||||
*/
|
*/
|
||||||
public static <T> void setCacheObject(final String key, final T value, final boolean isSaveTtl) {
|
public static <T> void setCacheObject(final String key, final T value, final boolean isSaveTtl) {
|
||||||
RBucket<Object> bucket = CLIENT.getBucket(key);
|
RBucket<T> bucket = CLIENT.getBucket(key);
|
||||||
if (isSaveTtl) {
|
if (isSaveTtl) {
|
||||||
try {
|
try {
|
||||||
bucket.setAndKeepTTL(value);
|
bucket.setAndKeepTTL(value);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
long timeToLive = bucket.remainTimeToLive();
|
long timeToLive = bucket.remainTimeToLive();
|
||||||
bucket.set(value);
|
setCacheObject(key, value, Duration.ofMillis(timeToLive));
|
||||||
bucket.expire(Duration.ofMillis(timeToLive));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bucket.set(value);
|
bucket.set(value);
|
||||||
@ -122,9 +131,11 @@ public class RedisUtils {
|
|||||||
* @param duration 时间
|
* @param duration 时间
|
||||||
*/
|
*/
|
||||||
public static <T> void setCacheObject(final String key, final T value, final Duration duration) {
|
public static <T> void setCacheObject(final String key, final T value, final Duration duration) {
|
||||||
RBucket<T> result = CLIENT.getBucket(key);
|
RBatch batch = CLIENT.createBatch();
|
||||||
result.set(value);
|
RBucketAsync<T> bucket = batch.getBucket(key);
|
||||||
result.expire(duration);
|
bucket.setAsync(value);
|
||||||
|
bucket.expireAsync(duration);
|
||||||
|
batch.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -415,8 +426,17 @@ public class RedisUtils {
|
|||||||
* @return 对象列表
|
* @return 对象列表
|
||||||
*/
|
*/
|
||||||
public static Collection<String> keys(final String pattern) {
|
public static Collection<String> keys(final String pattern) {
|
||||||
Iterable<String> iterable = CLIENT.getKeys().getKeysByPattern(pattern);
|
Stream<String> stream = CLIENT.getKeys().getKeysStreamByPattern(getNameMapper().map(pattern));
|
||||||
return IterUtil.toList(iterable);
|
return stream.map(key -> getNameMapper().unmap(key)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除缓存的基本对象列表
|
||||||
|
*
|
||||||
|
* @param pattern 字符串前缀
|
||||||
|
*/
|
||||||
|
public static void deleteKeys(final String pattern) {
|
||||||
|
CLIENT.getKeys().deleteByPattern(getNameMapper().map(pattern));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -426,6 +446,6 @@ public class RedisUtils {
|
|||||||
*/
|
*/
|
||||||
public static Boolean hasKey(String key) {
|
public static Boolean hasKey(String key) {
|
||||||
RKeys rKeys = CLIENT.getKeys();
|
RKeys rKeys = CLIENT.getKeys();
|
||||||
return rKeys.countExists(key) > 0;
|
return rKeys.countExists(getNameMapper().map(key)) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,6 @@ package com.ruoyi.demo.controller;
|
|||||||
|
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.common.utils.email.MailUtils;
|
import com.ruoyi.common.utils.email.MailUtils;
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import io.swagger.annotations.ApiParam;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -20,27 +17,34 @@ import java.io.File;
|
|||||||
* @author Michelle.Chung
|
* @author Michelle.Chung
|
||||||
*/
|
*/
|
||||||
@Validated
|
@Validated
|
||||||
@Api(value = "邮件发送案例", tags = {"邮件发送案例"})
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/mail")
|
@RequestMapping("/demo/mail")
|
||||||
public class MailController {
|
public class MailController {
|
||||||
|
|
||||||
@ApiOperation("发送邮件")
|
/**
|
||||||
|
* 发送邮件
|
||||||
|
*
|
||||||
|
* @param to 接收人
|
||||||
|
* @param subject 标题
|
||||||
|
* @param text 内容
|
||||||
|
*/
|
||||||
@GetMapping("/sendSimpleMessage")
|
@GetMapping("/sendSimpleMessage")
|
||||||
public R<Void> sendSimpleMessage(@ApiParam("接收人") String to,
|
public R<Void> sendSimpleMessage(String to, String subject, String text) {
|
||||||
@ApiParam("标题") String subject,
|
|
||||||
@ApiParam("内容") String text) {
|
|
||||||
MailUtils.sendText(to, subject, text);
|
MailUtils.sendText(to, subject, text);
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("发送邮件(带附件)")
|
/**
|
||||||
|
* 发送邮件(带附件)
|
||||||
|
*
|
||||||
|
* @param to 接收人
|
||||||
|
* @param subject 标题
|
||||||
|
* @param text 内容
|
||||||
|
* @param filePath 附件路径
|
||||||
|
*/
|
||||||
@GetMapping("/sendMessageWithAttachment")
|
@GetMapping("/sendMessageWithAttachment")
|
||||||
public R<Void> sendMessageWithAttachment(@ApiParam("接收人") String to,
|
public R<Void> sendMessageWithAttachment(String to, String subject, String text, String filePath) {
|
||||||
@ApiParam("标题") String subject,
|
|
||||||
@ApiParam("内容") String text,
|
|
||||||
@ApiParam("附件路径") String filePath) {
|
|
||||||
MailUtils.sendText(to, subject, text, new File(filePath));
|
MailUtils.sendText(to, subject, text, new File(filePath));
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package com.ruoyi.demo.controller;
|
package com.ruoyi.demo.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.common.constant.CacheNames;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.common.utils.redis.RedisUtils;
|
import com.ruoyi.common.utils.redis.RedisUtils;
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.cache.annotation.CachePut;
|
import org.springframework.cache.annotation.CachePut;
|
||||||
@ -20,8 +19,7 @@ import java.time.Duration;
|
|||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
// 类级别 缓存统一配置
|
// 类级别 缓存统一配置
|
||||||
//@CacheConfig(cacheNames = "redissonCacheMap")
|
//@CacheConfig(cacheNames = CacheNames.DEMO_CACHE)
|
||||||
@Api(value = "spring-cache 演示案例", tags = {"spring-cache 演示案例"})
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/cache")
|
@RequestMapping("/demo/cache")
|
||||||
@ -39,10 +37,9 @@ public class RedisCacheController {
|
|||||||
* 重点说明: 缓存注解严谨与其他筛选数据功能一起使用
|
* 重点说明: 缓存注解严谨与其他筛选数据功能一起使用
|
||||||
* 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题
|
* 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题
|
||||||
* <p>
|
* <p>
|
||||||
* cacheNames 为配置文件内 groupId
|
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试 @Cacheable")
|
@Cacheable(cacheNames = "demo:cache#60s#10m#20", key = "#key", condition = "#key != null")
|
||||||
@Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
|
||||||
@GetMapping("/test1")
|
@GetMapping("/test1")
|
||||||
public R<String> test1(String key, String value) {
|
public R<String> test1(String key, String value) {
|
||||||
return R.ok("操作成功", value);
|
return R.ok("操作成功", value);
|
||||||
@ -52,12 +49,11 @@ public class RedisCacheController {
|
|||||||
* 测试 @CachePut
|
* 测试 @CachePut
|
||||||
* <p>
|
* <p>
|
||||||
* 加了@CachePut注解的方法,会把方法的返回值put到缓存里面缓存起来,供其它地方使用
|
* 加了@CachePut注解的方法,会把方法的返回值put到缓存里面缓存起来,供其它地方使用
|
||||||
* 它「通常用在新增方法上」
|
* 它「通常用在新增或者实时更新方法上」
|
||||||
* <p>
|
* <p>
|
||||||
* cacheNames 为 配置文件内 groupId
|
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试 @CachePut")
|
@CachePut(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null")
|
||||||
@CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
|
||||||
@GetMapping("/test2")
|
@GetMapping("/test2")
|
||||||
public R<String> test2(String key, String value) {
|
public R<String> test2(String key, String value) {
|
||||||
return R.ok("操作成功", value);
|
return R.ok("操作成功", value);
|
||||||
@ -67,12 +63,11 @@ public class RedisCacheController {
|
|||||||
* 测试 @CacheEvict
|
* 测试 @CacheEvict
|
||||||
* <p>
|
* <p>
|
||||||
* 使用了CacheEvict注解的方法,会清空指定缓存
|
* 使用了CacheEvict注解的方法,会清空指定缓存
|
||||||
* 「一般用在更新或者删除的方法上」
|
* 「一般用在删除的方法上」
|
||||||
* <p>
|
* <p>
|
||||||
* cacheNames 为 配置文件内 groupId
|
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试 @CacheEvict")
|
@CacheEvict(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null")
|
||||||
@CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
|
||||||
@GetMapping("/test3")
|
@GetMapping("/test3")
|
||||||
public R<String> test3(String key, String value) {
|
public R<String> test3(String key, String value) {
|
||||||
return R.ok("操作成功", value);
|
return R.ok("操作成功", value);
|
||||||
@ -83,7 +78,6 @@ public class RedisCacheController {
|
|||||||
* 手动设置过期时间10秒
|
* 手动设置过期时间10秒
|
||||||
* 11秒后获取 判断是否相等
|
* 11秒后获取 判断是否相等
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试设置过期时间")
|
|
||||||
@GetMapping("/test6")
|
@GetMapping("/test6")
|
||||||
public R<Boolean> test6(String key, String value) {
|
public R<Boolean> test6(String key, String value) {
|
||||||
RedisUtils.setCacheObject(key, value);
|
RedisUtils.setCacheObject(key, value);
|
||||||
|
@ -5,8 +5,6 @@ import com.baomidou.lock.LockTemplate;
|
|||||||
import com.baomidou.lock.annotation.Lock4j;
|
import com.baomidou.lock.annotation.Lock4j;
|
||||||
import com.baomidou.lock.executor.RedissonLockExecutor;
|
import com.baomidou.lock.executor.RedissonLockExecutor;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -21,7 +19,6 @@ import java.time.LocalTime;
|
|||||||
*
|
*
|
||||||
* @author shenxinquan
|
* @author shenxinquan
|
||||||
*/
|
*/
|
||||||
@Api(value = "测试分布式锁的样例", tags = {"测试分布式锁的样例"})
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/redisLock")
|
@RequestMapping("/demo/redisLock")
|
||||||
@ -33,7 +30,6 @@ public class RedisLockController {
|
|||||||
/**
|
/**
|
||||||
* 测试lock4j 注解
|
* 测试lock4j 注解
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试lock4j 注解")
|
|
||||||
@Lock4j(keys = {"#key"})
|
@Lock4j(keys = {"#key"})
|
||||||
@GetMapping("/testLock4j")
|
@GetMapping("/testLock4j")
|
||||||
public R<String> testLock4j(String key, String value) {
|
public R<String> testLock4j(String key, String value) {
|
||||||
@ -50,7 +46,6 @@ public class RedisLockController {
|
|||||||
/**
|
/**
|
||||||
* 测试lock4j 工具
|
* 测试lock4j 工具
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试lock4j 工具")
|
|
||||||
@GetMapping("/testLock4jLockTemplate")
|
@GetMapping("/testLock4jLockTemplate")
|
||||||
public R<String> testLock4jLockTemplate(String key, String value) {
|
public R<String> testLock4jLockTemplate(String key, String value) {
|
||||||
final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
|
final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
|
||||||
|
@ -2,9 +2,6 @@ package com.ruoyi.demo.controller;
|
|||||||
|
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.common.utils.redis.RedisUtils;
|
import com.ruoyi.common.utils.redis.RedisUtils;
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import io.swagger.annotations.ApiParam;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@ -15,24 +12,32 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Api(value = "Redis发布订阅 演示案例", tags = {"Redis发布订阅"})
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/redis/pubsub")
|
@RequestMapping("/demo/redis/pubsub")
|
||||||
public class RedisPubSubController {
|
public class RedisPubSubController {
|
||||||
|
|
||||||
@ApiOperation("发布消息")
|
/**
|
||||||
|
* 发布消息
|
||||||
|
*
|
||||||
|
* @param key 通道Key
|
||||||
|
* @param value 发送内容
|
||||||
|
*/
|
||||||
@GetMapping("/pub")
|
@GetMapping("/pub")
|
||||||
public R<Void> pub(@ApiParam("通道Key") String key, @ApiParam("发送内容") String value) {
|
public R<Void> pub(String key, String value) {
|
||||||
RedisUtils.publish(key, value, consumer -> {
|
RedisUtils.publish(key, value, consumer -> {
|
||||||
System.out.println("发布通道 => " + key + ", 发送值 => " + value);
|
System.out.println("发布通道 => " + key + ", 发送值 => " + value);
|
||||||
});
|
});
|
||||||
return R.ok("操作成功");
|
return R.ok("操作成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("订阅消息")
|
/**
|
||||||
|
* 订阅消息
|
||||||
|
*
|
||||||
|
* @param key 通道Key
|
||||||
|
*/
|
||||||
@GetMapping("/sub")
|
@GetMapping("/sub")
|
||||||
public R<Void> sub(@ApiParam("通道Key") String key) {
|
public R<Void> sub(String key) {
|
||||||
RedisUtils.subscribe(key, String.class, msg -> {
|
RedisUtils.subscribe(key, String.class, msg -> {
|
||||||
System.out.println("订阅通道 => " + key + ", 接收值 => " + msg);
|
System.out.println("订阅通道 => " + key + ", 接收值 => " + msg);
|
||||||
});
|
});
|
||||||
|
@ -3,8 +3,6 @@ package com.ruoyi.demo.controller;
|
|||||||
import com.ruoyi.common.annotation.RateLimiter;
|
import com.ruoyi.common.annotation.RateLimiter;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.common.enums.LimitType;
|
import com.ruoyi.common.enums.LimitType;
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@ -16,7 +14,6 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Api(value = "测试分布式限流样例", tags = {"测试分布式限流样例"})
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/rateLimiter")
|
@RequestMapping("/demo/rateLimiter")
|
||||||
@ -26,7 +23,6 @@ public class RedisRateLimiterController {
|
|||||||
* 测试全局限流
|
* 测试全局限流
|
||||||
* 全局影响
|
* 全局影响
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试全局限流")
|
|
||||||
@RateLimiter(count = 2, time = 10)
|
@RateLimiter(count = 2, time = 10)
|
||||||
@GetMapping("/test")
|
@GetMapping("/test")
|
||||||
public R<String> test(String value) {
|
public R<String> test(String value) {
|
||||||
@ -37,7 +33,6 @@ public class RedisRateLimiterController {
|
|||||||
* 测试请求IP限流
|
* 测试请求IP限流
|
||||||
* 同一IP请求受影响
|
* 同一IP请求受影响
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试请求IP限流")
|
|
||||||
@RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
|
@RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
|
||||||
@GetMapping("/testip")
|
@GetMapping("/testip")
|
||||||
public R<String> testip(String value) {
|
public R<String> testip(String value) {
|
||||||
@ -48,7 +43,6 @@ public class RedisRateLimiterController {
|
|||||||
* 测试集群实例限流
|
* 测试集群实例限流
|
||||||
* 启动两个后端服务互不影响
|
* 启动两个后端服务互不影响
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试集群实例限流")
|
|
||||||
@RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
|
@RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
|
||||||
@GetMapping("/testcluster")
|
@GetMapping("/testcluster")
|
||||||
public R<String> testcluster(String value) {
|
public R<String> testcluster(String value) {
|
||||||
|
@ -4,9 +4,6 @@ import com.ruoyi.common.core.domain.R;
|
|||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import com.ruoyi.sms.config.properties.SmsProperties;
|
import com.ruoyi.sms.config.properties.SmsProperties;
|
||||||
import com.ruoyi.sms.core.SmsTemplate;
|
import com.ruoyi.sms.core.SmsTemplate;
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import io.swagger.annotations.ApiParam;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -24,7 +21,6 @@ import java.util.Map;
|
|||||||
* @version 4.2.0
|
* @version 4.2.0
|
||||||
*/
|
*/
|
||||||
@Validated
|
@Validated
|
||||||
@Api(value = "短信演示案例", tags = {"短信演示案例"})
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/sms")
|
@RequestMapping("/demo/sms")
|
||||||
@ -34,10 +30,14 @@ public class SmsController {
|
|||||||
// private final SmsTemplate smsTemplate; // 可以使用spring注入
|
// private final SmsTemplate smsTemplate; // 可以使用spring注入
|
||||||
// private final AliyunSmsTemplate smsTemplate; // 也可以注入某个厂家的模板工具
|
// private final AliyunSmsTemplate smsTemplate; // 也可以注入某个厂家的模板工具
|
||||||
|
|
||||||
@ApiOperation("发送短信Aliyun")
|
/**
|
||||||
|
* 发送短信Aliyun
|
||||||
|
*
|
||||||
|
* @param phones 电话号
|
||||||
|
* @param templateId 模板ID
|
||||||
|
*/
|
||||||
@GetMapping("/sendAliyun")
|
@GetMapping("/sendAliyun")
|
||||||
public R<Object> sendAliyun(@ApiParam("电话号") String phones,
|
public R<Object> sendAliyun(String phones, String templateId) {
|
||||||
@ApiParam("模板ID") String templateId) {
|
|
||||||
if (!smsProperties.getEnabled()) {
|
if (!smsProperties.getEnabled()) {
|
||||||
return R.fail("当前系统没有开启短信功能!");
|
return R.fail("当前系统没有开启短信功能!");
|
||||||
}
|
}
|
||||||
@ -51,10 +51,14 @@ public class SmsController {
|
|||||||
return R.ok(send);
|
return R.ok(send);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("发送短信Tencent")
|
/**
|
||||||
|
* 发送短信Tencent
|
||||||
|
*
|
||||||
|
* @param phones 电话号
|
||||||
|
* @param templateId 模板ID
|
||||||
|
*/
|
||||||
@GetMapping("/sendTencent")
|
@GetMapping("/sendTencent")
|
||||||
public R<Object> sendTencent(@ApiParam("电话号") String phones,
|
public R<Object> sendTencent(String phones, String templateId) {
|
||||||
@ApiParam("模板ID") String templateId) {
|
|
||||||
if (!smsProperties.getEnabled()) {
|
if (!smsProperties.getEnabled()) {
|
||||||
return R.fail("当前系统没有开启短信功能!");
|
return R.fail("当前系统没有开启短信功能!");
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,18 @@
|
|||||||
package com.ruoyi.demo.controller;
|
package com.ruoyi.demo.controller;
|
||||||
|
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import io.swagger.annotations.Api;
|
import org.springframework.http.MediaType;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
|
||||||
import io.swagger.annotations.ApiImplicitParams;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestPart;
|
import org.springframework.web.bind.annotation.RequestPart;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* swagger3 用法示例
|
* swagger3 用法示例
|
||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Api(value = "演示swagger3控制器", tags = {"演示swagger3接口"})
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/swagger/demo")
|
@RequestMapping("/swagger/demo")
|
||||||
public class Swagger3DemoController {
|
public class Swagger3DemoController {
|
||||||
@ -26,12 +20,10 @@ public class Swagger3DemoController {
|
|||||||
/**
|
/**
|
||||||
* 上传请求
|
* 上传请求
|
||||||
* 必须使用 @RequestPart 注解标注为文件
|
* 必须使用 @RequestPart 注解标注为文件
|
||||||
|
*
|
||||||
|
* @param file 文件
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "通用上传请求")
|
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
@ApiImplicitParams({
|
|
||||||
@ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataTypeClass = File.class, required = true)
|
|
||||||
})
|
|
||||||
@PostMapping(value = "/upload")
|
|
||||||
public R<String> upload(@RequestPart("file") MultipartFile file) {
|
public R<String> upload(@RequestPart("file") MultipartFile file) {
|
||||||
return R.ok("操作成功", file.getOriginalFilename());
|
return R.ok("操作成功", file.getOriginalFilename());
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ import com.ruoyi.common.core.controller.BaseController;
|
|||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.demo.domain.TestDemo;
|
import com.ruoyi.demo.domain.TestDemo;
|
||||||
import com.ruoyi.demo.mapper.TestDemoMapper;
|
import com.ruoyi.demo.mapper.TestDemoMapper;
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@ -22,7 +20,6 @@ import java.util.List;
|
|||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
* @date 2021-05-30
|
* @date 2021-05-30
|
||||||
*/
|
*/
|
||||||
@Api(value = "测试批量方法", tags = {"测试批量方法"})
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/batch")
|
@RequestMapping("/demo/batch")
|
||||||
@ -38,7 +35,6 @@ public class TestBatchController extends BaseController {
|
|||||||
* <p>
|
* <p>
|
||||||
* 3.5.0 版本 增加 rewriteBatchedStatements=true 批处理参数 使 MP 原生批处理可以达到同样的速度
|
* 3.5.0 版本 增加 rewriteBatchedStatements=true 批处理参数 使 MP 原生批处理可以达到同样的速度
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "新增批量方法")
|
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
// @DS("slave")
|
// @DS("slave")
|
||||||
public R<Void> add() {
|
public R<Void> add() {
|
||||||
@ -58,7 +54,6 @@ public class TestBatchController extends BaseController {
|
|||||||
* <p>
|
* <p>
|
||||||
* 3.5.0 版本 增加 rewriteBatchedStatements=true 批处理参数 使 MP 原生批处理可以达到同样的速度
|
* 3.5.0 版本 增加 rewriteBatchedStatements=true 批处理参数 使 MP 原生批处理可以达到同样的速度
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "新增或更新批量方法")
|
|
||||||
@PostMapping("/addOrUpdate")
|
@PostMapping("/addOrUpdate")
|
||||||
// @DS("slave")
|
// @DS("slave")
|
||||||
public R<Void> addOrUpdate() {
|
public R<Void> addOrUpdate() {
|
||||||
@ -68,7 +63,8 @@ public class TestBatchController extends BaseController {
|
|||||||
testDemo.setOrderNum(-1);
|
testDemo.setOrderNum(-1);
|
||||||
testDemo.setTestKey("批量新增");
|
testDemo.setTestKey("批量新增");
|
||||||
testDemo.setValue("测试新增");
|
testDemo.setValue("测试新增");
|
||||||
list.add(testDemo); }
|
list.add(testDemo);
|
||||||
|
}
|
||||||
testDemoMapper.insertBatch(list);
|
testDemoMapper.insertBatch(list);
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
TestDemo testDemo = list.get(i);
|
TestDemo testDemo = list.get(i);
|
||||||
@ -84,7 +80,6 @@ public class TestBatchController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 删除批量方法
|
* 删除批量方法
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "删除批量方法")
|
|
||||||
@DeleteMapping()
|
@DeleteMapping()
|
||||||
// @DS("slave")
|
// @DS("slave")
|
||||||
public R<Void> remove() {
|
public R<Void> remove() {
|
||||||
|
@ -5,8 +5,8 @@ import cn.hutool.core.bean.BeanUtil;
|
|||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.annotation.RepeatSubmit;
|
import com.ruoyi.common.annotation.RepeatSubmit;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.R;
|
|
||||||
import com.ruoyi.common.core.domain.PageQuery;
|
import com.ruoyi.common.core.domain.PageQuery;
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.core.validate.AddGroup;
|
import com.ruoyi.common.core.validate.AddGroup;
|
||||||
import com.ruoyi.common.core.validate.EditGroup;
|
import com.ruoyi.common.core.validate.EditGroup;
|
||||||
@ -20,8 +20,8 @@ import com.ruoyi.demo.domain.bo.TestDemoBo;
|
|||||||
import com.ruoyi.demo.domain.bo.TestDemoImportVo;
|
import com.ruoyi.demo.domain.bo.TestDemoImportVo;
|
||||||
import com.ruoyi.demo.domain.vo.TestDemoVo;
|
import com.ruoyi.demo.domain.vo.TestDemoVo;
|
||||||
import com.ruoyi.demo.service.ITestDemoService;
|
import com.ruoyi.demo.service.ITestDemoService;
|
||||||
import io.swagger.annotations.*;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@ -29,7 +29,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.io.File;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -41,7 +40,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* @date 2021-07-26
|
* @date 2021-07-26
|
||||||
*/
|
*/
|
||||||
@Validated
|
@Validated
|
||||||
@Api(value = "测试单表控制器", tags = {"测试单表管理"})
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/demo")
|
@RequestMapping("/demo/demo")
|
||||||
@ -52,7 +50,6 @@ public class TestDemoController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 查询测试单表列表
|
* 查询测试单表列表
|
||||||
*/
|
*/
|
||||||
@ApiOperation("查询测试单表列表")
|
|
||||||
@SaCheckPermission("demo:demo:list")
|
@SaCheckPermission("demo:demo:list")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo<TestDemoVo> list(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) {
|
public TableDataInfo<TestDemoVo> list(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) {
|
||||||
@ -62,20 +59,20 @@ public class TestDemoController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 自定义分页查询
|
* 自定义分页查询
|
||||||
*/
|
*/
|
||||||
@ApiOperation("自定义分页查询")
|
|
||||||
@SaCheckPermission("demo:demo:list")
|
@SaCheckPermission("demo:demo:list")
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
public TableDataInfo<TestDemoVo> page(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) {
|
public TableDataInfo<TestDemoVo> page(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) {
|
||||||
return iTestDemoService.customPageList(bo, pageQuery);
|
return iTestDemoService.customPageList(bo, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("导入测试-校验")
|
/**
|
||||||
@ApiImplicitParams({
|
* 导入数据
|
||||||
@ApiImplicitParam(name = "file", value = "导入文件", paramType = "query", dataTypeClass = File.class, required = true),
|
*
|
||||||
})
|
* @param file 导入文件
|
||||||
|
*/
|
||||||
@Log(title = "测试单表", businessType = BusinessType.IMPORT)
|
@Log(title = "测试单表", businessType = BusinessType.IMPORT)
|
||||||
@SaCheckPermission("demo:demo:import")
|
@SaCheckPermission("demo:demo:import")
|
||||||
@PostMapping("/importData")
|
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
|
public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
|
||||||
ExcelResult<TestDemoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true);
|
ExcelResult<TestDemoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true);
|
||||||
List<TestDemoImportVo> volist = excelResult.getList();
|
List<TestDemoImportVo> volist = excelResult.getList();
|
||||||
@ -87,7 +84,6 @@ public class TestDemoController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 导出测试单表列表
|
* 导出测试单表列表
|
||||||
*/
|
*/
|
||||||
@ApiOperation("导出测试单表列表")
|
|
||||||
@SaCheckPermission("demo:demo:export")
|
@SaCheckPermission("demo:demo:export")
|
||||||
@Log(title = "测试单表", businessType = BusinessType.EXPORT)
|
@Log(title = "测试单表", businessType = BusinessType.EXPORT)
|
||||||
@PostMapping("/export")
|
@PostMapping("/export")
|
||||||
@ -102,20 +98,19 @@ public class TestDemoController extends BaseController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取测试单表详细信息
|
* 获取测试单表详细信息
|
||||||
|
*
|
||||||
|
* @param id 测试ID
|
||||||
*/
|
*/
|
||||||
@ApiOperation("获取测试单表详细信息")
|
|
||||||
@SaCheckPermission("demo:demo:query")
|
@SaCheckPermission("demo:demo:query")
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public R<TestDemoVo> getInfo(@ApiParam("测试ID")
|
public R<TestDemoVo> getInfo(@NotNull(message = "主键不能为空")
|
||||||
@NotNull(message = "主键不能为空")
|
@PathVariable("id") Long id) {
|
||||||
@PathVariable("id") Long id) {
|
|
||||||
return R.ok(iTestDemoService.queryById(id));
|
return R.ok(iTestDemoService.queryById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增测试单表
|
* 新增测试单表
|
||||||
*/
|
*/
|
||||||
@ApiOperation("新增测试单表")
|
|
||||||
@SaCheckPermission("demo:demo:add")
|
@SaCheckPermission("demo:demo:add")
|
||||||
@Log(title = "测试单表", businessType = BusinessType.INSERT)
|
@Log(title = "测试单表", businessType = BusinessType.INSERT)
|
||||||
@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "{repeat.submit.message}")
|
@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "{repeat.submit.message}")
|
||||||
@ -130,7 +125,6 @@ public class TestDemoController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 修改测试单表
|
* 修改测试单表
|
||||||
*/
|
*/
|
||||||
@ApiOperation("修改测试单表")
|
|
||||||
@SaCheckPermission("demo:demo:edit")
|
@SaCheckPermission("demo:demo:edit")
|
||||||
@Log(title = "测试单表", businessType = BusinessType.UPDATE)
|
@Log(title = "测试单表", businessType = BusinessType.UPDATE)
|
||||||
@RepeatSubmit
|
@RepeatSubmit
|
||||||
@ -141,14 +135,14 @@ public class TestDemoController extends BaseController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除测试单表
|
* 删除测试单表
|
||||||
|
*
|
||||||
|
* @param ids 测试ID串
|
||||||
*/
|
*/
|
||||||
@ApiOperation("删除测试单表")
|
|
||||||
@SaCheckPermission("demo:demo:remove")
|
@SaCheckPermission("demo:demo:remove")
|
||||||
@Log(title = "测试单表", businessType = BusinessType.DELETE)
|
@Log(title = "测试单表", businessType = BusinessType.DELETE)
|
||||||
@DeleteMapping("/{ids}")
|
@DeleteMapping("/{ids}")
|
||||||
public R<Void> remove(@ApiParam("测试ID串")
|
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||||
@NotEmpty(message = "主键不能为空")
|
@PathVariable Long[] ids) {
|
||||||
@PathVariable Long[] ids) {
|
|
||||||
return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
|
return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ package com.ruoyi.demo.controller;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -21,7 +19,6 @@ import java.util.Map;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Api(value = "测试Excel功能", tags = {"测试Excel功能"})
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/excel")
|
@RequestMapping("/demo/excel")
|
||||||
public class TestExcelController {
|
public class TestExcelController {
|
||||||
@ -29,35 +26,33 @@ public class TestExcelController {
|
|||||||
/**
|
/**
|
||||||
* 单列表多数据
|
* 单列表多数据
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "单列表多数据")
|
|
||||||
@GetMapping("/exportTemplateOne")
|
@GetMapping("/exportTemplateOne")
|
||||||
public void exportTemplateOne(HttpServletResponse response) {
|
public void exportTemplateOne(HttpServletResponse response) {
|
||||||
Map<String,String> map = new HashMap<>();
|
Map<String, String> map = new HashMap<>();
|
||||||
map.put("title","单列表多数据");
|
map.put("title", "单列表多数据");
|
||||||
map.put("test1","数据测试1");
|
map.put("test1", "数据测试1");
|
||||||
map.put("test2","数据测试2");
|
map.put("test2", "数据测试2");
|
||||||
map.put("test3","数据测试3");
|
map.put("test3", "数据测试3");
|
||||||
map.put("test4","数据测试4");
|
map.put("test4", "数据测试4");
|
||||||
map.put("testTest","666");
|
map.put("testTest", "666");
|
||||||
List<TestObj> list = new ArrayList<>();
|
List<TestObj> list = new ArrayList<>();
|
||||||
list.add(new TestObj("单列表测试1", "列表测试1", "列表测试2", "列表测试3", "列表测试4"));
|
list.add(new TestObj("单列表测试1", "列表测试1", "列表测试2", "列表测试3", "列表测试4"));
|
||||||
list.add(new TestObj("单列表测试2", "列表测试5", "列表测试6", "列表测试7", "列表测试8"));
|
list.add(new TestObj("单列表测试2", "列表测试5", "列表测试6", "列表测试7", "列表测试8"));
|
||||||
list.add(new TestObj("单列表测试3", "列表测试9", "列表测试10", "列表测试11", "列表测试12"));
|
list.add(new TestObj("单列表测试3", "列表测试9", "列表测试10", "列表测试11", "列表测试12"));
|
||||||
ExcelUtil.exportTemplate(CollUtil.newArrayList(map,list),"单列表.xlsx", "excel/单列表.xlsx", response);
|
ExcelUtil.exportTemplate(CollUtil.newArrayList(map, list), "单列表.xlsx", "excel/单列表.xlsx", response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多列表多数据
|
* 多列表多数据
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "多列表多数据")
|
|
||||||
@GetMapping("/exportTemplateMuliti")
|
@GetMapping("/exportTemplateMuliti")
|
||||||
public void exportTemplateMuliti(HttpServletResponse response) {
|
public void exportTemplateMuliti(HttpServletResponse response) {
|
||||||
Map<String,String> map = new HashMap<>();
|
Map<String, String> map = new HashMap<>();
|
||||||
map.put("title1","标题1");
|
map.put("title1", "标题1");
|
||||||
map.put("title2","标题2");
|
map.put("title2", "标题2");
|
||||||
map.put("title3","标题3");
|
map.put("title3", "标题3");
|
||||||
map.put("title4","标题4");
|
map.put("title4", "标题4");
|
||||||
map.put("author","Lion Li");
|
map.put("author", "Lion Li");
|
||||||
List<TestObj1> list1 = new ArrayList<>();
|
List<TestObj1> list1 = new ArrayList<>();
|
||||||
list1.add(new TestObj1("list1测试1", "list1测试2", "list1测试3"));
|
list1.add(new TestObj1("list1测试1", "list1测试2", "list1测试3"));
|
||||||
list1.add(new TestObj1("list1测试4", "list1测试5", "list1测试6"));
|
list1.add(new TestObj1("list1测试4", "list1测试5", "list1测试6"));
|
||||||
@ -72,12 +67,12 @@ public class TestExcelController {
|
|||||||
list4.add(new TestObj1("list4测试4", "list4测试5", "list4测试6"));
|
list4.add(new TestObj1("list4测试4", "list4测试5", "list4测试6"));
|
||||||
list4.add(new TestObj1("list4测试7", "list4测试8", "list4测试9"));
|
list4.add(new TestObj1("list4测试7", "list4测试8", "list4测试9"));
|
||||||
list4.add(new TestObj1("list4测试10", "list4测试11", "list4测试12"));
|
list4.add(new TestObj1("list4测试10", "list4测试11", "list4测试12"));
|
||||||
Map<String,Object> multiListMap = new HashMap<>();
|
Map<String, Object> multiListMap = new HashMap<>();
|
||||||
multiListMap.put("map",map);
|
multiListMap.put("map", map);
|
||||||
multiListMap.put("data1",list1);
|
multiListMap.put("data1", list1);
|
||||||
multiListMap.put("data2",list2);
|
multiListMap.put("data2", list2);
|
||||||
multiListMap.put("data3",list3);
|
multiListMap.put("data3", list3);
|
||||||
multiListMap.put("data4",list4);
|
multiListMap.put("data4", list4);
|
||||||
ExcelUtil.exportTemplateMultiList(multiListMap, "多列表.xlsx", "excel/多列表.xlsx", response);
|
ExcelUtil.exportTemplateMultiList(multiListMap, "多列表.xlsx", "excel/多列表.xlsx", response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user