mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2025-09-19 17:56:41 +08:00
发布 v3.4.0
This commit is contained in:
parent
d81377a2ed
commit
c76ab64e8a
16
README.md
16
README.md
@ -4,18 +4,20 @@
|
|||||||
[](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 针对 `分布式集群` 场景升级(不兼容原框架)
|
||||||
|
|
||||||
|
> 系统演示: [传送门](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/系统演示?sort_id=4836388)
|
||||||
|
|
||||||
| 功能介绍 | 使用技术 | 文档地址 | 特性注意事项 |
|
| 功能介绍 | 使用技术 | 文档地址 | 特性注意事项 |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| 当前框架 | RuoYi-Vue-Plus | [RuoYi-Vue-Plus文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages) | 重写RuoYi-Vue全方位升级(不兼容原框架) |
|
| 当前框架 | RuoYi-Vue-Plus | [RuoYi-Vue-Plus文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages) | 重写RuoYi-Vue全方位升级(不兼容原框架) |
|
||||||
| satoken分支 | RuoYi-Vue-Plus-satoken | [satoken分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/) | 使用satoken重构权限鉴权(仅供学习不推荐上生产) |
|
| satoken分支 | RuoYi-Vue-Plus-satoken | [satoken分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/) | 使用satoken重构权限鉴权(公测 可尝试上生产) |
|
||||||
| 单体分支 | RuoYi-Vue-Plus-fast | [fast分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) | 单体应用结构 |
|
| 单体分支 | RuoYi-Vue-Plus-fast | [fast分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) | 单体应用结构 |
|
||||||
| 原框架 | RuoYi-Vue | [RuoYi-Vue官网](http://ruoyi.vip/) | 定期同步需要的功能 |
|
| 原框架 | RuoYi-Vue | [RuoYi-Vue官网](http://ruoyi.vip/) | 定期同步需要的功能 |
|
||||||
| 前端开发框架 | Vue、Element UI | [Element UI官网](https://element.eleme.cn/#/zh-CN) | |
|
| 前端开发框架 | Vue、Element UI | [Element UI官网](https://element.eleme.cn/#/zh-CN) | |
|
||||||
@ -28,17 +30,16 @@ RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级(不兼
|
|||||||
| 数据库框架 | p6spy | [p6spy官网](https://p6spy.readthedocs.io/) | 更强劲的 SQL 分析 |
|
| 数据库框架 | p6spy | [p6spy官网](https://p6spy.readthedocs.io/) | 更强劲的 SQL 分析 |
|
||||||
| 多数据源框架 | dynamic-datasource | [dynamic-ds文档](https://www.kancloud.cn/tracy5546/dynamic-datasource/content) | 支持主从与多种类数据库异构 |
|
| 多数据源框架 | dynamic-datasource | [dynamic-ds文档](https://www.kancloud.cn/tracy5546/dynamic-datasource/content) | 支持主从与多种类数据库异构 |
|
||||||
| 序列化框架 | Jackson | [Jackson官网](https://github.com/FasterXML/jackson) | 统一使用 jackson 高效可靠 |
|
| 序列化框架 | Jackson | [Jackson官网](https://github.com/FasterXML/jackson) | 统一使用 jackson 高效可靠 |
|
||||||
| 网络框架 | Feign、OkHttp3 | [Feign官网](https://github.com/OpenFeign/feign) | 接口化管理 HTTP 请求 |
|
|
||||||
| Redis客户端 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 支持单机、集群配置 |
|
| Redis客户端 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 支持单机、集群配置 |
|
||||||
| 分布式限流 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 全局、请求IP、集群ID 多种限流 |
|
| 分布式限流 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 全局、请求IP、集群ID 多种限流 |
|
||||||
| 分布式锁 | Lock4j | [Lock4j官网](https://gitee.com/baomidou/lock4j) | 注解锁、工具锁 多种多样 |
|
| 分布式锁 | Lock4j | [Lock4j官网](https://gitee.com/baomidou/lock4j) | 注解锁、工具锁 多种多样 |
|
||||||
| 分布式幂等 | Lock4j | [Lock4j文档](https://gitee.com/baomidou/lock4j) | 基于分布式锁实现 |
|
| 分布式幂等 | Redisson | [Lock4j文档](https://gitee.com/baomidou/lock4j) | 拦截重复提交 |
|
||||||
| 分布式日志 | TLog | [TLog文档](https://yomahub.com/tlog/docs) | 支持跟踪链路日志记录、性能分析、链路排查 |
|
| 分布式日志 | TLog | [TLog文档](https://yomahub.com/tlog/docs) | 支持跟踪链路日志记录、性能分析、链路排查 |
|
||||||
| 分布式任务调度 | Xxl-Job | [Xxl-Job官网](https://www.xuxueli.com/xxl-job/) | 高性能 高可靠 易扩展 |
|
| 分布式任务调度 | Xxl-Job | [Xxl-Job官网](https://www.xuxueli.com/xxl-job/) | 高性能 高可靠 易扩展 |
|
||||||
| 文件存储 | Minio | [Minio文档](https://docs.min.io/) | 本地存储 |
|
| 文件存储 | Minio | [Minio文档](https://docs.min.io/) | 本地存储 |
|
||||||
| 文件存储 | 七牛、阿里、腾讯 | [OSS使用文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4359146&doc_id=1469725) | 云存储 |
|
| 文件存储 | 七牛、阿里、腾讯 | [OSS使用文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4359146&doc_id=1469725) | 云存储 |
|
||||||
| 监控框架 | 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/) | 美化接口文档 |
|
| 文档框架 | Knife4j | [Knife4j文档](https://doc.xiaominfo.com/knife4j/documentation/) | 美化接口文档 |
|
||||||
| 工具类框架 | Hutool、Lombok | [Hutool文档](https://www.hutool.cn/docs/) | 减少代码冗余 增加安全性 |
|
| 工具类框架 | Hutool、Lombok | [Hutool文档](https://www.hutool.cn/docs/) | 减少代码冗余 增加安全性 |
|
||||||
@ -61,8 +62,7 @@ RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级(不兼
|
|||||||
|
|
||||||
## 软件架构图
|
## 软件架构图
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 贡献代码
|
## 贡献代码
|
||||||
|
|
||||||
欢迎各路英雄豪杰 `PR` 代码 请提交到 `dev` 开发分支 统一测试发版
|
欢迎各路英雄豪杰 `PR` 代码 请提交到 `dev` 开发分支 统一测试发版
|
||||||
|
50
pom.xml
50
pom.xml
@ -6,15 +6,15 @@
|
|||||||
|
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<version>3.3.0</version>
|
<version>3.4.0</version>
|
||||||
|
|
||||||
<name>RuoYi-Vue-Plus</name>
|
<name>RuoYi-Vue-Plus</name>
|
||||||
<url>https://gitee.com/JavaLionLi/RuoYi-Vue-Plus</url>
|
<url>https://gitee.com/JavaLionLi/RuoYi-Vue-Plus</url>
|
||||||
<description>RuoYi-Vue-Plus后台管理系统</description>
|
<description>RuoYi-Vue-Plus后台管理系统</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<ruoyi-vue-plus.version>3.3.0</ruoyi-vue-plus.version>
|
<ruoyi-vue-plus.version>3.4.0</ruoyi-vue-plus.version>
|
||||||
<spring-boot.version>2.5.6</spring-boot.version>
|
<spring-boot.version>2.5.7</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>
|
||||||
@ -24,19 +24,17 @@
|
|||||||
<swagger-annotations.version>1.5.22</swagger-annotations.version>
|
<swagger-annotations.version>1.5.22</swagger-annotations.version>
|
||||||
<poi.version>4.1.2</poi.version>
|
<poi.version>4.1.2</poi.version>
|
||||||
<easyexcel.version>2.2.11</easyexcel.version>
|
<easyexcel.version>2.2.11</easyexcel.version>
|
||||||
<velocity.version>1.7</velocity.version>
|
<velocity.version>2.3</velocity.version>
|
||||||
<jwt.version>0.9.1</jwt.version>
|
<jwt.version>0.9.1</jwt.version>
|
||||||
<mybatis-plus.version>3.4.3.4</mybatis-plus.version>
|
<mybatis-plus.version>3.4.3.4</mybatis-plus.version>
|
||||||
<p6spy.version>3.9.1</p6spy.version>
|
<p6spy.version>3.9.1</p6spy.version>
|
||||||
<hutool.version>5.7.15</hutool.version>
|
<hutool.version>5.7.16</hutool.version>
|
||||||
<feign.version>3.0.3</feign.version>
|
<okhttp.version>4.9.2</okhttp.version>
|
||||||
<feign-okhttp.version>11.6</feign-okhttp.version>
|
<spring-boot-admin.version>2.5.4</spring-boot-admin.version>
|
||||||
<okhttp.version>4.9.1</okhttp.version>
|
<redisson.version>3.16.4</redisson.version>
|
||||||
<spring-boot-admin.version>2.5.2</spring-boot-admin.version>
|
|
||||||
<redisson.version>3.16.3</redisson.version>
|
|
||||||
<lock4j.version>2.2.1</lock4j.version>
|
<lock4j.version>2.2.1</lock4j.version>
|
||||||
<dynamic-ds.version>3.4.1</dynamic-ds.version>
|
<dynamic-ds.version>3.4.1</dynamic-ds.version>
|
||||||
<tlog.version>1.3.3</tlog.version>
|
<tlog.version>1.3.4</tlog.version>
|
||||||
<xxl-job.version>2.3.0</xxl-job.version>
|
<xxl-job.version>2.3.0</xxl-job.version>
|
||||||
|
|
||||||
<!-- jdk11 缺失依赖 jaxb-->
|
<!-- jdk11 缺失依赖 jaxb-->
|
||||||
@ -120,7 +118,7 @@
|
|||||||
<!-- velocity代码生成使用模板 -->
|
<!-- velocity代码生成使用模板 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.velocity</groupId>
|
<groupId>org.apache.velocity</groupId>
|
||||||
<artifactId>velocity</artifactId>
|
<artifactId>velocity-engine-core</artifactId>
|
||||||
<version>${velocity.version}</version>
|
<version>${velocity.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@ -168,25 +166,6 @@
|
|||||||
<version>${hutool.version}</version>
|
<version>${hutool.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- @deprecated 由于使用人数较少 决定与 3.4.0 版本移除 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
|
||||||
<version>${feign.version}</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>feign-core</artifactId>
|
|
||||||
<groupId>io.github.openfeign</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<!-- @deprecated 由于使用人数较少 决定与 3.4.0 版本移除 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.github.openfeign</groupId>
|
|
||||||
<artifactId>feign-okhttp</artifactId>
|
|
||||||
<version>${feign-okhttp.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup.okhttp3</groupId>
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
<artifactId>okhttp</artifactId>
|
<artifactId>okhttp</artifactId>
|
||||||
@ -245,12 +224,6 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.yomahub</groupId>
|
|
||||||
<artifactId>tlog-feign</artifactId>
|
|
||||||
<version>${tlog.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.yomahub</groupId>
|
<groupId>com.yomahub</groupId>
|
||||||
<artifactId>tlog-xxl-job</artifactId>
|
<artifactId>tlog-xxl-job</artifactId>
|
||||||
@ -321,6 +294,7 @@
|
|||||||
<!-- 环境标识,需要与配置文件的名称相对应 -->
|
<!-- 环境标识,需要与配置文件的名称相对应 -->
|
||||||
<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>
|
<endpoints.include>'*'</endpoints.include>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
@ -330,6 +304,7 @@
|
|||||||
<!-- 环境标识,需要与配置文件的名称相对应 -->
|
<!-- 环境标识,需要与配置文件的名称相对应 -->
|
||||||
<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>
|
<endpoints.include>'*'</endpoints.include>
|
||||||
</properties>
|
</properties>
|
||||||
<activation>
|
<activation>
|
||||||
@ -342,6 +317,7 @@
|
|||||||
<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>
|
<endpoints.include>health, info, logfile</endpoints.include>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.3.0</version>
|
<version>3.4.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>3.3.0</version>
|
<version>3.4.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@ -28,6 +28,12 @@
|
|||||||
<groupId>de.codecentric</groupId>
|
<groupId>de.codecentric</groupId>
|
||||||
<artifactId>spring-boot-admin-starter-server</artifactId>
|
<artifactId>spring-boot-admin-starter-server</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.codecentric</groupId>
|
||||||
|
<artifactId>spring-boot-admin-starter-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -34,6 +34,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
//授予对所有静态资产和登录页面的公共访问权限。
|
//授予对所有静态资产和登录页面的公共访问权限。
|
||||||
.antMatchers(adminContextPath + "/assets/**").permitAll()
|
.antMatchers(adminContextPath + "/assets/**").permitAll()
|
||||||
.antMatchers(adminContextPath + "/login").permitAll()
|
.antMatchers(adminContextPath + "/login").permitAll()
|
||||||
|
.antMatchers("/actuator").anonymous()
|
||||||
|
.antMatchers("/actuator/**").anonymous()
|
||||||
//必须对每个其他请求进行身份验证
|
//必须对每个其他请求进行身份验证
|
||||||
.anyRequest().authenticated().and()
|
.anyRequest().authenticated().and()
|
||||||
//配置登录和注销
|
//配置登录和注销
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
server:
|
server:
|
||||||
port: 9090
|
port: 9090
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: ruoyi-monitor-admin
|
||||||
|
profiles:
|
||||||
|
active: @profiles.active@
|
||||||
|
|
||||||
|
--- # 监控中心服务端配置
|
||||||
spring:
|
spring:
|
||||||
security:
|
security:
|
||||||
user:
|
user:
|
||||||
@ -9,3 +15,17 @@ spring:
|
|||||||
boot:
|
boot:
|
||||||
admin:
|
admin:
|
||||||
context-path: /admin
|
context-path: /admin
|
||||||
|
|
||||||
|
--- # Actuator 监控端点的配置项
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
# Actuator 提供的 API 接口的根目录。默认为 /actuator
|
||||||
|
base-path: /actuator
|
||||||
|
exposure:
|
||||||
|
# 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
|
||||||
|
# 生产环境不建议放开所有 根据项目需求放开即可
|
||||||
|
include: @endpoints.include@
|
||||||
|
endpoint:
|
||||||
|
logfile:
|
||||||
|
external-file: ./logs/ruoyi-monitor-admin.log
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-extend</artifactId>
|
<artifactId>ruoyi-extend</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.3.0</version>
|
<version>3.4.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>ruoyi-xxl-job-admin</artifactId>
|
<artifactId>ruoyi-xxl-job-admin</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@ -71,6 +71,11 @@
|
|||||||
<version>${mysql-connector-java.version}</version>
|
<version>${mysql-connector-java.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.codecentric</groupId>
|
||||||
|
<artifactId>spring-boot-admin-starter-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- xxl-job-core -->
|
<!-- xxl-job-core -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.xuxueli</groupId>
|
<groupId>com.xuxueli</groupId>
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
--- # 监控配置
|
||||||
|
spring:
|
||||||
|
boot:
|
||||||
|
admin:
|
||||||
|
# Spring Boot Admin Client 客户端的相关配置
|
||||||
|
client:
|
||||||
|
# 增加客户端开关
|
||||||
|
enabled: true
|
||||||
|
# 设置 Spring Boot Admin Server 地址
|
||||||
|
url: http://localhost:9090/admin
|
||||||
|
instance:
|
||||||
|
prefer-ip: true # 注册实例时,优先使用 IP
|
||||||
|
username: ruoyi
|
||||||
|
password: 123456
|
||||||
|
|
||||||
--- # 数据库配置
|
--- # 数据库配置
|
||||||
spring:
|
spring:
|
||||||
datasource:
|
datasource:
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
--- # 监控配置
|
||||||
|
spring:
|
||||||
|
boot:
|
||||||
|
admin:
|
||||||
|
# Spring Boot Admin Client 客户端的相关配置
|
||||||
|
client:
|
||||||
|
# 增加客户端开关
|
||||||
|
enabled: true
|
||||||
|
# 设置 Spring Boot Admin Server 地址
|
||||||
|
url: http://172.30.0.90:9090/admin
|
||||||
|
instance:
|
||||||
|
prefer-ip: true # 注册实例时,优先使用 IP
|
||||||
|
username: ruoyi
|
||||||
|
password: 123456
|
||||||
|
|
||||||
--- # 数据库配置
|
--- # 数据库配置
|
||||||
spring:
|
spring:
|
||||||
datasource:
|
datasource:
|
||||||
|
@ -4,6 +4,8 @@ server:
|
|||||||
servlet:
|
servlet:
|
||||||
context-path: /xxl-job-admin
|
context-path: /xxl-job-admin
|
||||||
spring:
|
spring:
|
||||||
|
application:
|
||||||
|
name: ruoyi-xxl-job-admin
|
||||||
profiles:
|
profiles:
|
||||||
active: @profiles.active@
|
active: @profiles.active@
|
||||||
mvc:
|
mvc:
|
||||||
@ -28,13 +30,22 @@ spring:
|
|||||||
suffix: .ftl
|
suffix: .ftl
|
||||||
templateLoaderPath: classpath:/templates/
|
templateLoaderPath: classpath:/templates/
|
||||||
|
|
||||||
--- # 监控配置
|
--- # Actuator 监控端点的配置项
|
||||||
management:
|
management:
|
||||||
health:
|
health:
|
||||||
mail:
|
mail:
|
||||||
enabled: false
|
enabled: false
|
||||||
server:
|
endpoints:
|
||||||
base-path: /actuator
|
web:
|
||||||
|
# Actuator 提供的 API 接口的根目录。默认为 /actuator
|
||||||
|
base-path: /actuator
|
||||||
|
exposure:
|
||||||
|
# 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
|
||||||
|
# 生产环境不建议放开所有 根据项目需求放开即可
|
||||||
|
include: @endpoints.include@
|
||||||
|
endpoint:
|
||||||
|
logfile:
|
||||||
|
external-file: ./logs/ruoyi-xxl-job-admin.log
|
||||||
|
|
||||||
--- # xxljob系统配置
|
--- # xxljob系统配置
|
||||||
xxl:
|
xxl:
|
||||||
|
@ -7,6 +7,9 @@ ENV = 'development'
|
|||||||
# 若依管理系统/开发环境
|
# 若依管理系统/开发环境
|
||||||
VUE_APP_BASE_API = '/dev-api'
|
VUE_APP_BASE_API = '/dev-api'
|
||||||
|
|
||||||
|
# 应用访问路径 例如使用前缀 /admin/
|
||||||
|
VUE_APP_CONTEXT_PATH = '/'
|
||||||
|
|
||||||
# 监控地址
|
# 监控地址
|
||||||
VUE_APP_MONITRO_ADMIN = 'http://localhost:9090/admin/login'
|
VUE_APP_MONITRO_ADMIN = 'http://localhost:9090/admin/login'
|
||||||
|
|
||||||
|
@ -4,6 +4,9 @@ VUE_APP_TITLE = RuoYi-Vue-Plus后台管理系统
|
|||||||
# 生产环境配置
|
# 生产环境配置
|
||||||
ENV = 'production'
|
ENV = 'production'
|
||||||
|
|
||||||
|
# 应用访问路径 例如使用前缀 /admin/
|
||||||
|
VUE_APP_CONTEXT_PATH = '/'
|
||||||
|
|
||||||
# 监控地址
|
# 监控地址
|
||||||
VUE_APP_MONITRO_ADMIN = '/admin/login'
|
VUE_APP_MONITRO_ADMIN = '/admin/login'
|
||||||
|
|
||||||
|
@ -6,6 +6,9 @@ NODE_ENV = production
|
|||||||
# 测试环境配置
|
# 测试环境配置
|
||||||
ENV = 'staging'
|
ENV = 'staging'
|
||||||
|
|
||||||
|
# 应用访问路径 例如使用前缀 /admin/
|
||||||
|
VUE_APP_CONTEXT_PATH = '/'
|
||||||
|
|
||||||
# 监控地址
|
# 监控地址
|
||||||
VUE_APP_MONITRO_ADMIN = '/admin/login'
|
VUE_APP_MONITRO_ADMIN = '/admin/login'
|
||||||
|
|
||||||
|
@ -37,17 +37,17 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@riophae/vue-treeselect": "0.4.0",
|
"@riophae/vue-treeselect": "0.4.0",
|
||||||
"axios": "0.21.0",
|
"axios": "0.24.0",
|
||||||
"clipboard": "2.0.6",
|
"clipboard": "2.0.6",
|
||||||
"core-js": "3.8.1",
|
"core-js": "3.19.1",
|
||||||
"echarts": "4.9.0",
|
"echarts": "4.9.0",
|
||||||
"element-ui": "2.15.6",
|
"element-ui": "2.15.6",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
"fuse.js": "6.4.3",
|
"fuse.js": "6.4.3",
|
||||||
"highlight.js": "9.18.5",
|
"highlight.js": "9.18.5",
|
||||||
"js-beautify": "1.13.0",
|
"js-beautify": "1.13.0",
|
||||||
"js-cookie": "2.2.1",
|
"js-cookie": "3.0.1",
|
||||||
"jsencrypt": "3.0.0-rc.1",
|
"jsencrypt": "3.2.1",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"quill": "1.3.7",
|
"quill": "1.3.7",
|
||||||
"screenfull": "5.0.2",
|
"screenfull": "5.0.2",
|
||||||
@ -55,7 +55,7 @@
|
|||||||
"vue": "2.6.12",
|
"vue": "2.6.12",
|
||||||
"vue-count-to": "1.0.13",
|
"vue-count-to": "1.0.13",
|
||||||
"vue-cropper": "0.5.5",
|
"vue-cropper": "0.5.5",
|
||||||
"vue-meta": "^2.4.0",
|
"vue-meta": "2.4.0",
|
||||||
"vue-router": "3.4.9",
|
"vue-router": "3.4.9",
|
||||||
"vuedraggable": "2.24.3",
|
"vuedraggable": "2.24.3",
|
||||||
"vuex": "3.6.0"
|
"vuex": "3.6.0"
|
||||||
|
@ -10,6 +10,9 @@ export function login(username, password, code, uuid) {
|
|||||||
}
|
}
|
||||||
return request({
|
return request({
|
||||||
url: '/login',
|
url: '/login',
|
||||||
|
headers: {
|
||||||
|
isToken: false
|
||||||
|
},
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
@ -47,6 +50,9 @@ export function logout() {
|
|||||||
export function getCodeImg() {
|
export function getCodeImg() {
|
||||||
return request({
|
return request({
|
||||||
url: '/captchaImage',
|
url: '/captchaImage',
|
||||||
|
headers: {
|
||||||
|
isToken: false
|
||||||
|
},
|
||||||
method: 'get',
|
method: 'get',
|
||||||
timeout: 20000
|
timeout: 20000
|
||||||
})
|
})
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询定时任务调度列表
|
|
||||||
export function listJob(query) {
|
|
||||||
return request({
|
|
||||||
url: '/monitor/job/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询定时任务调度详细
|
|
||||||
export function getJob(jobId) {
|
|
||||||
return request({
|
|
||||||
url: '/monitor/job/' + jobId,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增定时任务调度
|
|
||||||
export function addJob(data) {
|
|
||||||
return request({
|
|
||||||
url: '/monitor/job',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改定时任务调度
|
|
||||||
export function updateJob(data) {
|
|
||||||
return request({
|
|
||||||
url: '/monitor/job',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除定时任务调度
|
|
||||||
export function delJob(jobId) {
|
|
||||||
return request({
|
|
||||||
url: '/monitor/job/' + jobId,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出定时任务调度
|
|
||||||
export function exportJob(query) {
|
|
||||||
return request({
|
|
||||||
url: '/monitor/job/export',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 任务状态修改
|
|
||||||
export function changeJobStatus(jobId, status) {
|
|
||||||
const data = {
|
|
||||||
jobId,
|
|
||||||
status
|
|
||||||
}
|
|
||||||
return request({
|
|
||||||
url: '/monitor/job/changeStatus',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 定时任务立即执行一次
|
|
||||||
export function runJob(jobId, jobGroup) {
|
|
||||||
const data = {
|
|
||||||
jobId,
|
|
||||||
jobGroup
|
|
||||||
}
|
|
||||||
return request({
|
|
||||||
url: '/monitor/job/run',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询调度日志列表
|
|
||||||
export function listJobLog(query) {
|
|
||||||
return request({
|
|
||||||
url: '/monitor/jobLog/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除调度日志
|
|
||||||
export function delJobLog(jobLogId) {
|
|
||||||
return request({
|
|
||||||
url: '/monitor/jobLog/' + jobLogId,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清空调度日志
|
|
||||||
export function cleanJobLog() {
|
|
||||||
return request({
|
|
||||||
url: '/monitor/jobLog/clean',
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询服务器详细
|
|
||||||
export function getServer() {
|
|
||||||
return request({
|
|
||||||
url: '/monitor/server',
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
@ -42,12 +42,3 @@ export function delPost(postId) {
|
|||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出岗位
|
|
||||||
export function exportPost(query) {
|
|
||||||
return request({
|
|
||||||
url: '/system/post/export',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
@ -2,7 +2,7 @@
|
|||||||
<el-breadcrumb class="app-breadcrumb" separator="/">
|
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||||
<transition-group name="breadcrumb">
|
<transition-group name="breadcrumb">
|
||||||
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
|
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
|
||||||
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
|
<span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
|
||||||
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
|
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
|
||||||
</el-breadcrumb-item>
|
</el-breadcrumb-item>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
|
@ -62,7 +62,7 @@ export default {
|
|||||||
},
|
},
|
||||||
// 右侧列表元素变化
|
// 右侧列表元素变化
|
||||||
dataChange(data) {
|
dataChange(data) {
|
||||||
for (var item in this.columns) {
|
for (let item in this.columns) {
|
||||||
const key = this.columns[item].key;
|
const key = this.columns[item].key;
|
||||||
this.columns[item].visible = !data.includes(key);
|
this.columns[item].visible = !data.includes(key);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<svg-icon icon-class="question" @click="goto"/>
|
<svg-icon icon-class="question" @click="goto" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<svg-icon icon-class="github" @click="goto"/>
|
<svg-icon icon-class="github" @click="goto" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value">
|
<el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value">
|
||||||
{{
|
{{ item.label }}
|
||||||
item.label }}
|
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
|
@ -102,7 +102,7 @@ export default {
|
|||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$store.dispatch('LogOut').then(() => {
|
this.$store.dispatch('LogOut').then(() => {
|
||||||
location.href = this.$router.options.base + '/index';
|
location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
|
||||||
})
|
})
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ export default {
|
|||||||
variables() {
|
variables() {
|
||||||
return variables;
|
return variables;
|
||||||
},
|
},
|
||||||
sideTheme() {
|
sideTheme() {
|
||||||
return this.$store.state.settings.sideTheme
|
return this.$store.state.settings.sideTheme
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -152,31 +152,24 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
refreshSelectedTag(view) {
|
refreshSelectedTag(view) {
|
||||||
this.$store.dispatch('tagsView/delCachedView', view).then(() => {
|
this.$tab.refreshPage(view);
|
||||||
const { fullPath } = view
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$router.replace({
|
|
||||||
path: '/redirect' + fullPath
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
closeSelectedTag(view) {
|
closeSelectedTag(view) {
|
||||||
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
|
this.$tab.closePage(view).then(({ visitedViews }) => {
|
||||||
if (this.isActive(view)) {
|
if (this.isActive(view)) {
|
||||||
this.toLastView(visitedViews, view)
|
this.toLastView(visitedViews, view)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
closeRightTags() {
|
closeRightTags() {
|
||||||
this.$store.dispatch('tagsView/delRightTags', this.selectedTag).then(visitedViews => {
|
this.$tab.closeRightPage(this.selectedTag).then(visitedViews => {
|
||||||
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
|
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
|
||||||
this.toLastView(visitedViews)
|
this.toLastView(visitedViews)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
closeLeftTags() {
|
closeLeftTags() {
|
||||||
this.$store.dispatch('tagsView/delLeftTags', this.selectedTag).then(visitedViews => {
|
this.$tab.closeLeftPage(this.selectedTag).then(visitedViews => {
|
||||||
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
|
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
|
||||||
this.toLastView(visitedViews)
|
this.toLastView(visitedViews)
|
||||||
}
|
}
|
||||||
@ -184,12 +177,12 @@ export default {
|
|||||||
},
|
},
|
||||||
closeOthersTags() {
|
closeOthersTags() {
|
||||||
this.$router.push(this.selectedTag).catch(()=>{});
|
this.$router.push(this.selectedTag).catch(()=>{});
|
||||||
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
|
this.$tab.closeOtherPage(this.selectedTag).then(() => {
|
||||||
this.moveToCurrentTag()
|
this.moveToCurrentTag()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
closeAllTags(view) {
|
closeAllTags(view) {
|
||||||
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
|
this.$tab.closeAllPage().then(({ visitedViews }) => {
|
||||||
if (this.affixTags.some(tag => tag.path === this.$route.path)) {
|
if (this.affixTags.some(tag => tag.path === this.$route.path)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hideSidebar .fixed-header {
|
.hideSidebar .fixed-header {
|
||||||
width: calc(100% - 54px)
|
width: calc(100% - 54px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile .fixed-header {
|
.mobile .fixed-header {
|
||||||
|
@ -10,8 +10,9 @@ import '@/assets/styles/ruoyi.scss' // ruoyi css
|
|||||||
import App from './App'
|
import App from './App'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
import directive from './directive' //directive
|
import directive from './directive' // directive
|
||||||
import plugins from './plugins' // plugins
|
import plugins from './plugins' // plugins
|
||||||
|
import { download } from '@/utils/request'
|
||||||
|
|
||||||
import './assets/icons' // icon
|
import './assets/icons' // icon
|
||||||
import './permission' // permission control
|
import './permission' // permission control
|
||||||
@ -43,6 +44,7 @@ Vue.prototype.resetForm = resetForm
|
|||||||
Vue.prototype.addDateRange = addDateRange
|
Vue.prototype.addDateRange = addDateRange
|
||||||
Vue.prototype.selectDictLabel = selectDictLabel
|
Vue.prototype.selectDictLabel = selectDictLabel
|
||||||
Vue.prototype.selectDictLabels = selectDictLabels
|
Vue.prototype.selectDictLabels = selectDictLabels
|
||||||
|
Vue.prototype.download = download
|
||||||
Vue.prototype.handleTree = handleTree
|
Vue.prototype.handleTree = handleTree
|
||||||
|
|
||||||
// 全局组件挂载
|
// 全局组件挂载
|
||||||
|
@ -1,51 +1,12 @@
|
|||||||
import { saveAs } from 'file-saver'
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { getToken } from '@/utils/auth'
|
|
||||||
import { Message } from 'element-ui'
|
import { Message } from 'element-ui'
|
||||||
|
import { saveAs } from 'file-saver'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
import { blobValidate } from "@/utils/ruoyi";
|
||||||
|
|
||||||
const baseURL = process.env.VUE_APP_BASE_API
|
const baseURL = process.env.VUE_APP_BASE_API
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
excel(url, params) {
|
|
||||||
// get请求映射params参数
|
|
||||||
if (params) {
|
|
||||||
let urlparams = url + '?';
|
|
||||||
for (const propName of Object.keys(params)) {
|
|
||||||
const value = params[propName];
|
|
||||||
var part = encodeURIComponent(propName) + "=";
|
|
||||||
if (value !== null && typeof(value) !== "undefined") {
|
|
||||||
if (typeof value === 'object') {
|
|
||||||
for (const key of Object.keys(value)) {
|
|
||||||
if (value[key] !== null && typeof (value[key]) !== 'undefined') {
|
|
||||||
let params = propName + '[' + key + ']';
|
|
||||||
let subPart = encodeURIComponent(params) + '=';
|
|
||||||
urlparams += subPart + encodeURIComponent(value[key]) + '&';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
urlparams += part + encodeURIComponent(value) + "&";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
urlparams = urlparams.slice(0, -1);
|
|
||||||
url = urlparams;
|
|
||||||
}
|
|
||||||
url = baseURL + url
|
|
||||||
axios({
|
|
||||||
method: 'get',
|
|
||||||
url: url,
|
|
||||||
responseType: 'blob',
|
|
||||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
|
||||||
}).then(async (res) => {
|
|
||||||
const isLogin = await this.blobValidate(res.data);
|
|
||||||
if (isLogin) {
|
|
||||||
const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
|
||||||
this.saveAs(blob, decodeURI(res.headers['download-filename']))
|
|
||||||
} else {
|
|
||||||
Message.error('无效的会话,或者会话已过期,请重新登录。');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
oss(ossId) {
|
oss(ossId) {
|
||||||
var url = baseURL + '/system/oss/download/' + ossId
|
var url = baseURL + '/system/oss/download/' + ossId
|
||||||
axios({
|
axios({
|
||||||
@ -54,7 +15,7 @@ export default {
|
|||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
headers: { 'Authorization': 'Bearer ' + getToken() }
|
||||||
}).then(async (res) => {
|
}).then(async (res) => {
|
||||||
const isLogin = await this.blobValidate(res.data);
|
const isLogin = await blobValidate(res.data);
|
||||||
if (isLogin) {
|
if (isLogin) {
|
||||||
const blob = new Blob([res.data], { type: 'application/octet-stream' })
|
const blob = new Blob([res.data], { type: 'application/octet-stream' })
|
||||||
this.saveAs(blob, decodeURI(res.headers['download-filename']))
|
this.saveAs(blob, decodeURI(res.headers['download-filename']))
|
||||||
@ -71,7 +32,7 @@ export default {
|
|||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
headers: { 'Authorization': 'Bearer ' + getToken() }
|
||||||
}).then(async (res) => {
|
}).then(async (res) => {
|
||||||
const isLogin = await this.blobValidate(res.data);
|
const isLogin = await blobValidate(res.data);
|
||||||
if (isLogin) {
|
if (isLogin) {
|
||||||
const blob = new Blob([res.data], { type: 'application/zip' })
|
const blob = new Blob([res.data], { type: 'application/zip' })
|
||||||
this.saveAs(blob, name)
|
this.saveAs(blob, name)
|
||||||
@ -82,15 +43,6 @@ export default {
|
|||||||
},
|
},
|
||||||
saveAs(text, name, opts) {
|
saveAs(text, name, opts) {
|
||||||
saveAs(text, name, opts);
|
saveAs(text, name, opts);
|
||||||
},
|
}
|
||||||
async blobValidate(data) {
|
|
||||||
try {
|
|
||||||
const text = await data.text();
|
|
||||||
JSON.parse(text);
|
|
||||||
return false;
|
|
||||||
} catch (error) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import tab from './tab'
|
||||||
import auth from './auth'
|
import auth from './auth'
|
||||||
import cache from './cache'
|
import cache from './cache'
|
||||||
import modal from './modal'
|
import modal from './modal'
|
||||||
@ -5,6 +6,8 @@ import download from './download'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
install(Vue) {
|
install(Vue) {
|
||||||
|
// 页签操作
|
||||||
|
Vue.prototype.$tab = tab
|
||||||
// 认证对象
|
// 认证对象
|
||||||
Vue.prototype.$auth = auth
|
Vue.prototype.$auth = auth
|
||||||
// 缓存对象
|
// 缓存对象
|
||||||
|
@ -95,7 +95,7 @@ export const constantRoutes = [
|
|||||||
path: 'role/:userId(\\d+)',
|
path: 'role/:userId(\\d+)',
|
||||||
component: (resolve) => require(['@/views/system/user/authRole'], resolve),
|
component: (resolve) => require(['@/views/system/user/authRole'], resolve),
|
||||||
name: 'AuthRole',
|
name: 'AuthRole',
|
||||||
meta: { title: '分配角色', activeMenu: '/system/user'}
|
meta: { title: '分配角色', activeMenu: '/system/user' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -108,7 +108,7 @@ export const constantRoutes = [
|
|||||||
path: 'user/:roleId(\\d+)',
|
path: 'user/:roleId(\\d+)',
|
||||||
component: (resolve) => require(['@/views/system/role/authUser'], resolve),
|
component: (resolve) => require(['@/views/system/role/authUser'], resolve),
|
||||||
name: 'AuthUser',
|
name: 'AuthUser',
|
||||||
meta: { title: '分配用户', activeMenu: '/system/role'}
|
meta: { title: '分配用户', activeMenu: '/system/role' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -121,7 +121,7 @@ export const constantRoutes = [
|
|||||||
path: 'index/:dictId(\\d+)',
|
path: 'index/:dictId(\\d+)',
|
||||||
component: (resolve) => require(['@/views/system/dict/data'], resolve),
|
component: (resolve) => require(['@/views/system/dict/data'], resolve),
|
||||||
name: 'Data',
|
name: 'Data',
|
||||||
meta: { title: '字典数据', activeMenu: '/system/dict'}
|
meta: { title: '字典数据', activeMenu: '/system/dict' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -138,19 +138,6 @@ export const constantRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/monitor/job-log',
|
|
||||||
component: Layout,
|
|
||||||
hidden: true,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'index',
|
|
||||||
component: (resolve) => require(['@/views/monitor/job/log'], resolve),
|
|
||||||
name: 'JobLog',
|
|
||||||
meta: { title: '调度日志', activeMenu: '/monitor/job'}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/tool/gen-edit',
|
path: '/tool/gen-edit',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@ -160,14 +147,13 @@ export const constantRoutes = [
|
|||||||
path: 'index',
|
path: 'index',
|
||||||
component: (resolve) => require(['@/views/tool/gen/editTable'], resolve),
|
component: (resolve) => require(['@/views/tool/gen/editTable'], resolve),
|
||||||
name: 'GenEdit',
|
name: 'GenEdit',
|
||||||
meta: { title: '修改生成配置', activeMenu: '/tool/gen'}
|
meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
export default new Router({
|
export default new Router({
|
||||||
base: "", // 项目前缀 与 publicPath 同步 例如 /api
|
|
||||||
mode: 'history', // 去掉url中的#
|
mode: 'history', // 去掉url中的#
|
||||||
scrollBehavior: () => ({ y: 0 }),
|
scrollBehavior: () => ({ y: 0 }),
|
||||||
routes: constantRoutes
|
routes: constantRoutes
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { constantRoutes } from '@/router'
|
import { constantRoutes } from '@/router'
|
||||||
import { getRouters } from '@/api/menu'
|
import { getRouters } from '@/api/menu'
|
||||||
import Layout from '@/layout/index'
|
import Layout from '@/layout/index'
|
||||||
import ParentView from '@/components/ParentView';
|
import ParentView from '@/components/ParentView'
|
||||||
import InnerLink from '@/layout/components/InnerLink'
|
import InnerLink from '@/layout/components/InnerLink'
|
||||||
|
|
||||||
const permission = {
|
const permission = {
|
||||||
@ -24,7 +24,7 @@ const permission = {
|
|||||||
// 顶部导航菜单默认添加统计报表栏指向首页
|
// 顶部导航菜单默认添加统计报表栏指向首页
|
||||||
const index = [{
|
const index = [{
|
||||||
path: 'index',
|
path: 'index',
|
||||||
meta: { title: '统计报表', icon: 'dashboard'}
|
meta: { title: '统计报表', icon: 'dashboard' }
|
||||||
}]
|
}]
|
||||||
state.topbarRouters = routes.concat(index);
|
state.topbarRouters = routes.concat(index);
|
||||||
},
|
},
|
||||||
|
@ -8,7 +8,7 @@ const state = {
|
|||||||
theme: storageSetting.theme || '#409EFF',
|
theme: storageSetting.theme || '#409EFF',
|
||||||
sideTheme: storageSetting.sideTheme || sideTheme,
|
sideTheme: storageSetting.sideTheme || sideTheme,
|
||||||
showSettings: showSettings,
|
showSettings: showSettings,
|
||||||
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
|
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
|
||||||
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
|
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
|
||||||
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
|
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
|
||||||
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
|
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
|
||||||
|
@ -14,7 +14,7 @@ const mutations = {
|
|||||||
},
|
},
|
||||||
ADD_CACHED_VIEW: (state, view) => {
|
ADD_CACHED_VIEW: (state, view) => {
|
||||||
if (state.cachedViews.includes(view.name)) return
|
if (state.cachedViews.includes(view.name)) return
|
||||||
if (!view.meta.noCache) {
|
if (view.meta && !view.meta.noCache) {
|
||||||
state.cachedViews.push(view.name)
|
state.cachedViews.push(view.name)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -5,7 +5,7 @@ export default function(Vue, options) {
|
|||||||
mergeOptions(options)
|
mergeOptions(options)
|
||||||
Vue.mixin({
|
Vue.mixin({
|
||||||
data() {
|
data() {
|
||||||
if (this.$options.dicts === undefined || this.$options.dicts === null) {
|
if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
const dict = new Dict()
|
const dict = new Dict()
|
||||||
|
@ -381,7 +381,7 @@ export function titleCase(str) {
|
|||||||
|
|
||||||
// 下划转驼峰
|
// 下划转驼峰
|
||||||
export function camelCase(str) {
|
export function camelCase(str) {
|
||||||
return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase())
|
return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase())
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isNumberStr(str) {
|
export function isNumberStr(str) {
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { Notification, MessageBox, Message } from 'element-ui'
|
import { Notification, MessageBox, Message, Loading } from 'element-ui'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
import errorCode from '@/utils/errorCode'
|
import errorCode from '@/utils/errorCode'
|
||||||
|
import { tansParams, blobValidate } from "@/utils/ruoyi";
|
||||||
|
import { saveAs } from 'file-saver'
|
||||||
|
|
||||||
|
let downloadLoadingInstance;
|
||||||
|
|
||||||
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
|
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
|
||||||
// 对应国际化资源文件后缀
|
// 对应国际化资源文件后缀
|
||||||
@ -14,6 +18,7 @@ const service = axios.create({
|
|||||||
// 超时
|
// 超时
|
||||||
timeout: 10000
|
timeout: 10000
|
||||||
})
|
})
|
||||||
|
|
||||||
// request拦截器
|
// request拦截器
|
||||||
service.interceptors.request.use(config => {
|
service.interceptors.request.use(config => {
|
||||||
// 是否需要设置 token
|
// 是否需要设置 token
|
||||||
@ -23,24 +28,7 @@ service.interceptors.request.use(config => {
|
|||||||
}
|
}
|
||||||
// get请求映射params参数
|
// get请求映射params参数
|
||||||
if (config.method === 'get' && config.params) {
|
if (config.method === 'get' && config.params) {
|
||||||
let url = config.url + '?';
|
let url = config.url + '?' + tansParams(config.params);
|
||||||
for (const propName of Object.keys(config.params)) {
|
|
||||||
const value = config.params[propName];
|
|
||||||
var part = encodeURIComponent(propName) + "=";
|
|
||||||
if (value !== null && typeof(value) !== "undefined") {
|
|
||||||
if (typeof value === 'object') {
|
|
||||||
for (const key of Object.keys(value)) {
|
|
||||||
if (value[key] !== null && typeof (value[key]) !== 'undefined') {
|
|
||||||
let params = propName + '[' + key + ']';
|
|
||||||
let subPart = encodeURIComponent(params) + '=';
|
|
||||||
url += subPart + encodeURIComponent(value[key]) + '&';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
url += part + encodeURIComponent(value) + "&";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
url = url.slice(0, -1);
|
url = url.slice(0, -1);
|
||||||
config.params = {};
|
config.params = {};
|
||||||
config.url = url;
|
config.url = url;
|
||||||
@ -57,6 +45,10 @@ service.interceptors.response.use(res => {
|
|||||||
const code = res.data.code || 200;
|
const code = res.data.code || 200;
|
||||||
// 获取错误信息
|
// 获取错误信息
|
||||||
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
||||||
|
// 二进制数据则直接返回
|
||||||
|
if(res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer'){
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
if (code === 401) {
|
if (code === 401) {
|
||||||
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
|
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
|
||||||
confirmButtonText: '重新登录',
|
confirmButtonText: '重新登录',
|
||||||
@ -65,7 +57,7 @@ service.interceptors.response.use(res => {
|
|||||||
}
|
}
|
||||||
).then(() => {
|
).then(() => {
|
||||||
store.dispatch('LogOut').then(() => {
|
store.dispatch('LogOut').then(() => {
|
||||||
location.href = this.$router.options.base + '/index';
|
location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
|
||||||
})
|
})
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
||||||
@ -105,4 +97,27 @@ service.interceptors.response.use(res => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 通用下载方法
|
||||||
|
export function download(url, params, filename) {
|
||||||
|
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
|
||||||
|
return service.post(url, params, {
|
||||||
|
transformRequest: [(params) => { return tansParams(params) }],
|
||||||
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
|
responseType: 'blob'
|
||||||
|
}).then(async (data) => {
|
||||||
|
const isLogin = await blobValidate(data);
|
||||||
|
if (isLogin) {
|
||||||
|
const blob = new Blob([data])
|
||||||
|
saveAs(blob, filename)
|
||||||
|
} else {
|
||||||
|
Message.error('无效的会话,或者会话已过期,请重新登录。');
|
||||||
|
}
|
||||||
|
downloadLoadingInstance.close();
|
||||||
|
}).catch((r) => {
|
||||||
|
console.error(r)
|
||||||
|
Message.error('下载文件出现错误,请联系管理员!')
|
||||||
|
downloadLoadingInstance.close();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export default service
|
export default service
|
||||||
|
@ -85,8 +85,8 @@ export function selectDictLabels(datas, value, separator) {
|
|||||||
var temp = value.split(currentSeparator);
|
var temp = value.split(currentSeparator);
|
||||||
Object.keys(value.split(currentSeparator)).some((val) => {
|
Object.keys(value.split(currentSeparator)).some((val) => {
|
||||||
Object.keys(datas).some((key) => {
|
Object.keys(datas).some((key) => {
|
||||||
if (datas[key].dictValue == ('' + temp[val])) {
|
if (datas[key].value == ('' + temp[val])) {
|
||||||
actions.push(datas[key].dictLabel + currentSeparator);
|
actions.push(datas[key].label + currentSeparator);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -181,3 +181,40 @@ export function handleTree(data, id, parentId, children) {
|
|||||||
}
|
}
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数处理
|
||||||
|
* @param {*} params 参数
|
||||||
|
*/
|
||||||
|
export function tansParams(params) {
|
||||||
|
let result = ''
|
||||||
|
for (const propName of Object.keys(params)) {
|
||||||
|
const value = params[propName];
|
||||||
|
var part = encodeURIComponent(propName) + "=";
|
||||||
|
if (value !== null && typeof (value) !== "undefined") {
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
for (const key of Object.keys(value)) {
|
||||||
|
if (value[key] !== null && typeof (value[key]) !== 'undefined') {
|
||||||
|
let params = propName + '[' + key + ']';
|
||||||
|
var subPart = encodeURIComponent(params) + "=";
|
||||||
|
result += subPart + encodeURIComponent(value[key]) + "&";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result += part + encodeURIComponent(value) + "&";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证是否为blob格式
|
||||||
|
export async function blobValidate(data) {
|
||||||
|
try {
|
||||||
|
const text = await data.text();
|
||||||
|
JSON.parse(text);
|
||||||
|
return false;
|
||||||
|
} catch (error) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -71,13 +71,22 @@
|
|||||||
v-hasPermi="['demo:demo:remove']"
|
v-hasPermi="['demo:demo:remove']"
|
||||||
>删除</el-button>
|
>删除</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="info"
|
||||||
|
plain
|
||||||
|
icon="el-icon-upload2"
|
||||||
|
size="mini"
|
||||||
|
@click="handleImport"
|
||||||
|
v-hasPermi="['demo:demo:import']"
|
||||||
|
>导入(校验)</el-button>
|
||||||
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button
|
||||||
type="warning"
|
type="warning"
|
||||||
plain
|
plain
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['demo:demo:export']"
|
v-hasPermi="['demo:demo:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
@ -165,11 +174,34 @@
|
|||||||
<el-button @click="cancel">取 消</el-button>
|
<el-button @click="cancel">取 消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<!-- 用户导入对话框 -->
|
||||||
|
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
:limit="1"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
:headers="upload.headers"
|
||||||
|
:action="upload.url + '?updateSupport=' + upload.updateSupport"
|
||||||
|
:disabled="upload.isUploading"
|
||||||
|
:on-progress="handleFileUploadProgress"
|
||||||
|
:on-success="handleFileSuccess"
|
||||||
|
:auto-upload="false"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<i class="el-icon-upload"></i>
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
</el-upload>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitFileForm">确 定</el-button>
|
||||||
|
<el-button @click="upload.open = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listDemo, pageDemo, getDemo, delDemo, addDemo, updateDemo } from "@/api/demo/demo";
|
import { listDemo, pageDemo, getDemo, delDemo, addDemo, updateDemo } from "@/api/demo/demo";
|
||||||
|
import {getToken} from "@/utils/auth";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Demo",
|
name: "Demo",
|
||||||
@ -181,8 +213,6 @@ export default {
|
|||||||
buttonLoading: false,
|
buttonLoading: false,
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
@ -201,6 +231,19 @@ export default {
|
|||||||
open: false,
|
open: false,
|
||||||
// 创建时间时间范围
|
// 创建时间时间范围
|
||||||
daterangeCreateTime: [],
|
daterangeCreateTime: [],
|
||||||
|
// 用户导入参数
|
||||||
|
upload: {
|
||||||
|
// 是否显示弹出层(用户导入)
|
||||||
|
open: false,
|
||||||
|
// 弹出层标题(用户导入)
|
||||||
|
title: "",
|
||||||
|
// 是否禁用上传
|
||||||
|
isUploading: false,
|
||||||
|
// 设置上传的请求头部
|
||||||
|
headers: { Authorization: "Bearer " + getToken() },
|
||||||
|
// 上传的地址
|
||||||
|
url: process.env.VUE_APP_BASE_API + "/demo/demo/importData"
|
||||||
|
},
|
||||||
// 查询参数
|
// 查询参数
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
@ -356,9 +399,32 @@ export default {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/** 导入按钮操作 */
|
||||||
|
handleImport() {
|
||||||
|
this.upload.title = "用户导入";
|
||||||
|
this.upload.open = true;
|
||||||
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.$download.excel('/demo/demo/export', this.queryParams);
|
this.download('demo/demo/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `demo_${new Date().getTime()}.xlsx`)
|
||||||
|
},
|
||||||
|
// 文件上传中处理
|
||||||
|
handleFileUploadProgress(event, file, fileList) {
|
||||||
|
this.upload.isUploading = true;
|
||||||
|
},
|
||||||
|
// 文件上传成功处理
|
||||||
|
handleFileSuccess(response, file, fileList) {
|
||||||
|
this.upload.open = false;
|
||||||
|
this.upload.isUploading = false;
|
||||||
|
this.$refs.upload.clearFiles();
|
||||||
|
this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
// 提交上传文件
|
||||||
|
submitFileForm() {
|
||||||
|
this.$refs.upload.submit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -4,26 +4,34 @@
|
|||||||
<el-col :sm="24" :lg="12" style="padding-left: 20px">
|
<el-col :sm="24" :lg="12" style="padding-left: 20px">
|
||||||
<h2>RuoYi-Vue-Plus后台管理框架</h2>
|
<h2>RuoYi-Vue-Plus后台管理框架</h2>
|
||||||
<p>
|
<p>
|
||||||
基于 RuoYi-Vue 集成 Mybatis-Plus Lombok Hutool 等便捷开发工具 适配重写相关业务 便于开发 定期与 RuoYi-Vue 同步
|
RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 分布式集群 场景升级(不兼容原框架)
|
||||||
<br/>
|
<br/>
|
||||||
* 前端开发框架 Vue、Element UI<br/>
|
* 前端开发框架 Vue、Element UI<br/>
|
||||||
* 后端开发框架 Spring Boot、Redis<br/>
|
* 后端开发框架 Spring Boot<br/>
|
||||||
* 容器框架 Undertow 基于 Netty 的高性能容器<br/>
|
* 容器框架 Undertow 基于 Netty 的高性能容器<br/>
|
||||||
* 权限认证框架 Spring Security、Jwt,支持多终端认证系统<br/>
|
* 权限认证框架 Spring Security、Jwt 支持多终端认证系统<br/>
|
||||||
* 关系数据库 MySQL 适配 8.X<br/>
|
* 关系数据库 MySQL 适配 8.X 最低 5.7<br/>
|
||||||
* 缓存数据库 Redis 适配 6.X<br/>
|
* 缓存数据库 Redis 适配 6.X 最低 4.X<br/>
|
||||||
* 数据库开发框架 Mybatis-Plus 快速 CRUD 增加开发效率 插件化支持各类需求<br/>
|
* 数据库框架 Mybatis-Plus 快速 CRUD 增加开发效率<br/>
|
||||||
* 网络框架 Feign、OkHttp3 接口化管理 HTTP 请求<br/>
|
* 数据库框架 p6spy 更强劲的 SQL 分析<br/>
|
||||||
* 工具类框架 Hutool、Lombok 减少代码冗余 增加安全性<br/>
|
|
||||||
* 监控框架 spring-boot-admin 全方位服务监控<br/>
|
|
||||||
* 校验框架 validation 增强接口安全性 严谨性<br/>
|
|
||||||
* 文档框架 knife4j 美化接口文档<br/>
|
|
||||||
* 代码生成器 一键生成前后端代码<br/>
|
|
||||||
* 多数据源框架 dynamic-datasource 支持主从与多种类数据库异构<br/>
|
* 多数据源框架 dynamic-datasource 支持主从与多种类数据库异构<br/>
|
||||||
* Redis客户端 采用 Redisson 性能更强<br/>
|
* 序列化框架 Jackson 统一使用 jackson 高效可靠<br/>
|
||||||
|
* Redis客户端 Redisson 性能强劲、API丰富<br/>
|
||||||
|
* 分布式限流 Redisson 全局、请求IP、集群ID 多种限流<br/>
|
||||||
* 分布式锁 Lock4j 注解锁、工具锁 多种多样<br/>
|
* 分布式锁 Lock4j 注解锁、工具锁 多种多样<br/>
|
||||||
|
* 分布式幂等 Lock4j 基于分布式锁实现<br/>
|
||||||
|
* 分布式日志 TLog 支持跟踪链路日志记录、性能分析、链路排查<br/>
|
||||||
|
* 分布式任务调度 Xxl-Job 高性能 高可靠 易扩展<br/>
|
||||||
|
* 文件存储 Minio 本地存储<br/>
|
||||||
|
* 文件存储 七牛、阿里、腾讯 云存储<br/>
|
||||||
|
* 监控框架 SpringBoot-Admin 全方位服务监控<br/>
|
||||||
|
* 校验框架 Validation 增强接口安全性 严谨性<br/>
|
||||||
|
* Excel框架 Alibaba EasyExcel 性能优异 扩展性强<br/>
|
||||||
|
* 文档框架 knife4j 美化接口文档<br/>
|
||||||
|
* 工具类框架 Hutool、Lombok 减少代码冗余 增加安全性<br/>
|
||||||
|
* 代码生成器 适配MP、Knife4j规范化代码 一键生成前后端代码<br/>
|
||||||
* 部署方式 Docker 容器编排 一键部署业务集群<br/>
|
* 部署方式 Docker 容器编排 一键部署业务集群<br/>
|
||||||
* 文件存储 OSS 对象存储模块 支持(Minio、七牛、阿里、腾讯)<br/>
|
* 国际化 SpringMessage Spring标准国际化方案<br/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<b>当前版本:</b> <span>v{{ version }}</span>
|
<b>当前版本:</b> <span>v{{ version }}</span>
|
||||||
@ -93,6 +101,61 @@
|
|||||||
<span>更新日志</span>
|
<span>更新日志</span>
|
||||||
</div>
|
</div>
|
||||||
<el-collapse accordion>
|
<el-collapse accordion>
|
||||||
|
<el-collapse-item title="v3.4.0 - 2021-11-29">
|
||||||
|
<ol>
|
||||||
|
<li>update [重磅更新] 重构 Excel 导入 支持 Validator 校验 支持自定义监听器</li>
|
||||||
|
<li>update [重磅更新] Validator 校验框架支持国际化</li>
|
||||||
|
<li>update springboot 2.5.6 => 2.5.7</li>
|
||||||
|
<li>update hutool 5.7.15 => 5.7.16</li>
|
||||||
|
<li>update okhttp 4.9.1 => 4.9.2</li>
|
||||||
|
<li>update spring-boot-admin 2.5.2 => 2.5.4</li>
|
||||||
|
<li>update redisson 3.16.3 => 3.16.4</li>
|
||||||
|
<li>update tlog 1.3.3 => 1.3.4</li>
|
||||||
|
<li>update axios 0.21.0 => 0.24.0</li>
|
||||||
|
<li>update core-js 3.8.1 => 3.19.1</li>
|
||||||
|
<li>update js-cookie 2.2.1 => 3.0.1</li>
|
||||||
|
<li>update velocity 1.7 => 2.3</li>
|
||||||
|
<li>update 升级 docker 基础镜像</li>
|
||||||
|
<li>update 基于 hutool 封装树构建工具 重构部门与菜单树结构返回</li>
|
||||||
|
<li>update 减少使用特定数据库函数</li>
|
||||||
|
<li>update 配置应用前缀路径 改为配置文件统一配置</li>
|
||||||
|
<li>update 升级 swagger 配置 使用 knife4j 增强模式</li>
|
||||||
|
<li>update 监控中心 集成监控客户端 实现自监控</li>
|
||||||
|
<li>update 调度中心 集成监控客户端 注册到监控中心</li>
|
||||||
|
<li>update 优化 tab 对象简化页签操作</li>
|
||||||
|
<li>update 解耦 LoginUser 与 SysUser 强关联</li>
|
||||||
|
<li>update 更新 RepeatSubmit 注解 aop 处理 针对特殊参数进行过滤</li>
|
||||||
|
<li>update DictUtils 字典工具类 标记过期 3.5.0 版本移除 使用 DictService 代替</li>
|
||||||
|
<li>update 抽象 DictService 通用 字典服务</li>
|
||||||
|
<li>update 抽象 ConfigService 通用 参数配置服务</li>
|
||||||
|
<li>update 基于 DictService 重构 Excel 内字典查询功能</li>
|
||||||
|
<li>update OSS 模块 整体重命名 消除歧义</li>
|
||||||
|
<li>update 更新 redis.conf 存储策略 aof 与 rdb 配置参数</li>
|
||||||
|
<li>update 初始化数据转移到 ApplicationRunner 统一处理</li>
|
||||||
|
<li>update 优化时间查询语句</li>
|
||||||
|
<li>add 增加 框架缓存懒加载 开关</li>
|
||||||
|
<li>add 新增 监控中心 Bean 初始化 startup trace 监控插件</li>
|
||||||
|
<li>add 增加 ValidatorUtils 校验框架工具 用于在非 Controller 的地方校验对象</li>
|
||||||
|
<li>fix 修复 SysOss、SysOssConfig 未继承 BaseEntity 基础实体问题</li>
|
||||||
|
<li>fix 修复 xxl-job-admin 部署问题</li>
|
||||||
|
<li>fix 修复 回显数据字典键值修正</li>
|
||||||
|
<li>fix 修复 Linux 清除临时目录 导致上传找不到目录报错问题</li>
|
||||||
|
<li>fix 修复通用实体 传参无法接收问题</li>
|
||||||
|
<li>fix 修复 SysLoginController 接口文档书写错误问题</li>
|
||||||
|
<li>fix 修复 用户逻辑删除 差异问题</li>
|
||||||
|
<li>fix 修复 OSS 七牛云 token 过期未刷新问题</li>
|
||||||
|
<li>fix 修复 分页工具 排序字段 null 处理</li>
|
||||||
|
<li>fix 修复 用户导入字典使用错误</li>
|
||||||
|
<li>fix 修复 关闭 xss 功能导致可重复读 RepeatableFilter 失效</li>
|
||||||
|
<li>fix 修复 使用 this.$options.data 报错问题</li>
|
||||||
|
<li>fix 修复 代码生成复选框字典遗漏问题</li>
|
||||||
|
<li>fix 修复 重复提交不生效问题 由于概念不同 使用 RedisUtils 重构</li>
|
||||||
|
<li>fix 修复 OSS 工厂 未实例化服务更新加载问题</li>
|
||||||
|
<li>remove 移除 quartz 相关代码与依赖</li>
|
||||||
|
<li>remove 移除 feign 相关代码与依赖</li>
|
||||||
|
<li>remove 移除 MybatisPlusRedisCache 二级缓存</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
<el-collapse-item title="v3.3.0 - 2021-10-29">
|
<el-collapse-item title="v3.3.0 - 2021-10-29">
|
||||||
<ol>
|
<ol>
|
||||||
<li>add [重磅更新] 增加分布式日志框架 TLog</li>
|
<li>add [重磅更新] 增加分布式日志框架 TLog</li>
|
||||||
@ -525,7 +588,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 版本号
|
// 版本号
|
||||||
version: "3.3.0",
|
version: "3.4.0",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -3,7 +3,12 @@
|
|||||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
|
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
|
||||||
<h3 class="title">RuoYi-Vue-Plus后台管理系统</h3>
|
<h3 class="title">RuoYi-Vue-Plus后台管理系统</h3>
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
|
<el-input
|
||||||
|
v-model="loginForm.username"
|
||||||
|
type="text"
|
||||||
|
auto-complete="off"
|
||||||
|
placeholder="账号"
|
||||||
|
>
|
||||||
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
|
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -66,7 +71,6 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
codeUrl: "",
|
codeUrl: "",
|
||||||
cookiePassword: "",
|
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: "admin",
|
username: "admin",
|
||||||
password: "admin123",
|
password: "admin123",
|
||||||
|
@ -1,517 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
|
||||||
<el-form-item label="任务名称" prop="jobName">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.jobName"
|
|
||||||
placeholder="请输入任务名称"
|
|
||||||
clearable
|
|
||||||
size="small"
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="任务组名" prop="jobGroup">
|
|
||||||
<el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable size="small">
|
|
||||||
<el-option
|
|
||||||
v-for="dict in dict.type.sys_job_group"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="任务状态" prop="status">
|
|
||||||
<el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable size="small">
|
|
||||||
<el-option
|
|
||||||
v-for="dict in dict.type.sys_job_status"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
icon="el-icon-plus"
|
|
||||||
size="mini"
|
|
||||||
@click="handleAdd"
|
|
||||||
v-hasPermi="['monitor:job:add']"
|
|
||||||
>新增</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="success"
|
|
||||||
plain
|
|
||||||
icon="el-icon-edit"
|
|
||||||
size="mini"
|
|
||||||
:disabled="single"
|
|
||||||
@click="handleUpdate"
|
|
||||||
v-hasPermi="['monitor:job:edit']"
|
|
||||||
>修改</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
plain
|
|
||||||
icon="el-icon-delete"
|
|
||||||
size="mini"
|
|
||||||
:disabled="multiple"
|
|
||||||
@click="handleDelete"
|
|
||||||
v-hasPermi="['monitor:job:remove']"
|
|
||||||
>删除</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="warning"
|
|
||||||
plain
|
|
||||||
icon="el-icon-download"
|
|
||||||
size="mini"
|
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
|
||||||
v-hasPermi="['monitor:job:export']"
|
|
||||||
>导出</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="info"
|
|
||||||
plain
|
|
||||||
icon="el-icon-s-operation"
|
|
||||||
size="mini"
|
|
||||||
@click="handleJobLog"
|
|
||||||
v-hasPermi="['monitor:job:query']"
|
|
||||||
>日志</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange">
|
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
|
||||||
<el-table-column label="任务编号" width="100" align="center" prop="jobId" />
|
|
||||||
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
|
|
||||||
<el-table-column label="任务组名" align="center" prop="jobGroup">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
|
|
||||||
<el-table-column label="cron执行表达式" align="center" prop="cronExpression" :show-overflow-tooltip="true" />
|
|
||||||
<el-table-column label="状态" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-switch
|
|
||||||
v-model="scope.row.status"
|
|
||||||
active-value="0"
|
|
||||||
inactive-value="1"
|
|
||||||
@change="handleStatusChange(scope.row)"
|
|
||||||
></el-switch>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-edit"
|
|
||||||
@click="handleUpdate(scope.row)"
|
|
||||||
v-hasPermi="['monitor:job:edit']"
|
|
||||||
>修改</el-button>
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-delete"
|
|
||||||
@click="handleDelete(scope.row)"
|
|
||||||
v-hasPermi="['monitor:job:remove']"
|
|
||||||
>删除</el-button>
|
|
||||||
<el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['monitor:job:changeStatus', 'monitor:job:query']">
|
|
||||||
<span class="el-dropdown-link">
|
|
||||||
<i class="el-icon-d-arrow-right el-icon--right"></i>更多
|
|
||||||
</span>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item command="handleRun" icon="el-icon-caret-right"
|
|
||||||
v-hasPermi="['monitor:job:changeStatus']">执行一次</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="handleView" icon="el-icon-view"
|
|
||||||
v-hasPermi="['monitor:job:query']">任务详细</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="handleJobLog" icon="el-icon-s-operation"
|
|
||||||
v-hasPermi="['monitor:job:query']">调度日志</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination
|
|
||||||
v-show="total>0"
|
|
||||||
:total="total"
|
|
||||||
:page.sync="queryParams.pageNum"
|
|
||||||
:limit.sync="queryParams.pageSize"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 添加或修改定时任务对话框 -->
|
|
||||||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="任务名称" prop="jobName">
|
|
||||||
<el-input v-model="form.jobName" placeholder="请输入任务名称" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="任务分组" prop="jobGroup">
|
|
||||||
<el-select v-model="form.jobGroup" placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="dict in dict.type.sys_job_group"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item prop="invokeTarget">
|
|
||||||
<span slot="label">
|
|
||||||
调用方法
|
|
||||||
<el-tooltip placement="top">
|
|
||||||
<div slot="content">
|
|
||||||
Bean调用示例:ryTask.ryParams('ry')
|
|
||||||
<br />Class类调用示例:com.ruoyi.quartz.task.RyTask.ryParams('ry')
|
|
||||||
<br />参数说明:支持字符串,布尔类型,长整型,浮点型,整型
|
|
||||||
</div>
|
|
||||||
<i class="el-icon-question"></i>
|
|
||||||
</el-tooltip>
|
|
||||||
</span>
|
|
||||||
<el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="cron表达式" prop="cronExpression">
|
|
||||||
<el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式">
|
|
||||||
<template slot="append">
|
|
||||||
<el-button type="primary" @click="handleShowCron">
|
|
||||||
生成表达式
|
|
||||||
<i class="el-icon-time el-icon--right"></i>
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="错误策略" prop="misfirePolicy">
|
|
||||||
<el-radio-group v-model="form.misfirePolicy" size="small">
|
|
||||||
<el-radio-button label="1">立即执行</el-radio-button>
|
|
||||||
<el-radio-button label="2">执行一次</el-radio-button>
|
|
||||||
<el-radio-button label="3">放弃执行</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="是否并发" prop="concurrent">
|
|
||||||
<el-radio-group v-model="form.concurrent" size="small">
|
|
||||||
<el-radio-button label="0">允许</el-radio-button>
|
|
||||||
<el-radio-button label="1">禁止</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="状态">
|
|
||||||
<el-radio-group v-model="form.status">
|
|
||||||
<el-radio
|
|
||||||
v-for="dict in dict.type.sys_job_status"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.value"
|
|
||||||
>{{dict.label}}</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
|
||||||
<el-button @click="cancel">取 消</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body destroy-on-close class="scrollbar">
|
|
||||||
<crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 任务日志详细 -->
|
|
||||||
<el-dialog title="任务详细" :visible.sync="openView" width="700px" append-to-body>
|
|
||||||
<el-form ref="form" :model="form" label-width="120px" size="mini">
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="任务编号:">{{ form.jobId }}</el-form-item>
|
|
||||||
<el-form-item label="任务名称:">{{ form.jobName }}</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="任务分组:">{{ jobGroupFormat(form) }}</el-form-item>
|
|
||||||
<el-form-item label="创建时间:">{{ form.createTime }}</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="cron表达式:">{{ form.cronExpression }}</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="下次执行时间:">{{ parseTime(form.nextValidTime) }}</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="调用目标方法:">{{ form.invokeTarget }}</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="任务状态:">
|
|
||||||
<div v-if="form.status == 0">正常</div>
|
|
||||||
<div v-else-if="form.status == 1">失败</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="是否并发:">
|
|
||||||
<div v-if="form.concurrent == 0">允许</div>
|
|
||||||
<div v-else-if="form.concurrent == 1">禁止</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="执行策略:">
|
|
||||||
<div v-if="form.misfirePolicy == 0">默认策略</div>
|
|
||||||
<div v-else-if="form.misfirePolicy == 1">立即执行</div>
|
|
||||||
<div v-else-if="form.misfirePolicy == 2">执行一次</div>
|
|
||||||
<div v-else-if="form.misfirePolicy == 3">放弃执行</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="openView = false">关 闭</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from "@/api/monitor/job";
|
|
||||||
import Crontab from '@/components/Crontab'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: { Crontab },
|
|
||||||
name: "Job",
|
|
||||||
dicts: ['sys_job_group', 'sys_job_status'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 遮罩层
|
|
||||||
loading: true,
|
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
|
||||||
ids: [],
|
|
||||||
// 非单个禁用
|
|
||||||
single: true,
|
|
||||||
// 非多个禁用
|
|
||||||
multiple: true,
|
|
||||||
// 显示搜索条件
|
|
||||||
showSearch: true,
|
|
||||||
// 总条数
|
|
||||||
total: 0,
|
|
||||||
// 定时任务表格数据
|
|
||||||
jobList: [],
|
|
||||||
// 弹出层标题
|
|
||||||
title: "",
|
|
||||||
// 是否显示弹出层
|
|
||||||
open: false,
|
|
||||||
// 是否显示详细弹出层
|
|
||||||
openView: false,
|
|
||||||
// 是否显示Cron表达式弹出层
|
|
||||||
openCron: false,
|
|
||||||
// 传入的表达式
|
|
||||||
expression: "",
|
|
||||||
// 查询参数
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
jobName: undefined,
|
|
||||||
jobGroup: undefined,
|
|
||||||
status: undefined
|
|
||||||
},
|
|
||||||
// 表单参数
|
|
||||||
form: {},
|
|
||||||
// 表单校验
|
|
||||||
rules: {
|
|
||||||
jobName: [
|
|
||||||
{ required: true, message: "任务名称不能为空", trigger: "blur" }
|
|
||||||
],
|
|
||||||
invokeTarget: [
|
|
||||||
{ required: true, message: "调用目标字符串不能为空", trigger: "blur" }
|
|
||||||
],
|
|
||||||
cronExpression: [
|
|
||||||
{ required: true, message: "cron执行表达式不能为空", trigger: "blur" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** 查询定时任务列表 */
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listJob(this.queryParams).then(response => {
|
|
||||||
this.jobList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 任务组名字典翻译
|
|
||||||
jobGroupFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.dict.type.sys_job_group, row.jobGroup);
|
|
||||||
},
|
|
||||||
// 取消按钮
|
|
||||||
cancel() {
|
|
||||||
this.open = false;
|
|
||||||
this.reset();
|
|
||||||
},
|
|
||||||
// 表单重置
|
|
||||||
reset() {
|
|
||||||
this.form = {
|
|
||||||
jobId: undefined,
|
|
||||||
jobName: undefined,
|
|
||||||
jobGroup: undefined,
|
|
||||||
invokeTarget: undefined,
|
|
||||||
cronExpression: undefined,
|
|
||||||
misfirePolicy: 1,
|
|
||||||
concurrent: 1,
|
|
||||||
status: "0"
|
|
||||||
};
|
|
||||||
this.resetForm("form");
|
|
||||||
},
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
/** 重置按钮操作 */
|
|
||||||
resetQuery() {
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
// 多选框选中数据
|
|
||||||
handleSelectionChange(selection) {
|
|
||||||
this.ids = selection.map(item => item.jobId);
|
|
||||||
this.single = selection.length != 1;
|
|
||||||
this.multiple = !selection.length;
|
|
||||||
},
|
|
||||||
// 更多操作触发
|
|
||||||
handleCommand(command, row) {
|
|
||||||
switch (command) {
|
|
||||||
case "handleRun":
|
|
||||||
this.handleRun(row);
|
|
||||||
break;
|
|
||||||
case "handleView":
|
|
||||||
this.handleView(row);
|
|
||||||
break;
|
|
||||||
case "handleJobLog":
|
|
||||||
this.handleJobLog(row);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 任务状态修改
|
|
||||||
handleStatusChange(row) {
|
|
||||||
let text = row.status === "0" ? "启用" : "停用";
|
|
||||||
this.$modal.confirm('确认要"' + text + '""' + row.jobName + '"任务吗?').then(function() {
|
|
||||||
return changeJobStatus(row.jobId, row.status);
|
|
||||||
}).then(() => {
|
|
||||||
this.$modal.msgSuccess(text + "成功");
|
|
||||||
}).catch(function() {
|
|
||||||
row.status = row.status === "0" ? "1" : "0";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/* 立即执行一次 */
|
|
||||||
handleRun(row) {
|
|
||||||
this.$modal.confirm('确认要立即执行一次"' + row.jobName + '"任务吗?').then(function() {
|
|
||||||
return runJob(row.jobId, row.jobGroup);
|
|
||||||
}).then(() => {
|
|
||||||
this.$modal.msgSuccess("执行成功");
|
|
||||||
}).catch(() => {});
|
|
||||||
},
|
|
||||||
/** 任务详细信息 */
|
|
||||||
handleView(row) {
|
|
||||||
getJob(row.jobId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.openView = true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** cron表达式按钮操作 */
|
|
||||||
handleShowCron() {
|
|
||||||
this.expression = this.form.cronExpression;
|
|
||||||
this.openCron = true;
|
|
||||||
},
|
|
||||||
/** 确定后回传值 */
|
|
||||||
crontabFill(value) {
|
|
||||||
this.form.cronExpression = value;
|
|
||||||
},
|
|
||||||
/** 任务日志列表查询 */
|
|
||||||
handleJobLog(row) {
|
|
||||||
const jobId = row.jobId || 0;
|
|
||||||
this.$router.push({ path: '/monitor/job-log/index', query: { jobId: jobId } })
|
|
||||||
},
|
|
||||||
/** 新增按钮操作 */
|
|
||||||
handleAdd() {
|
|
||||||
this.reset();
|
|
||||||
this.open = true;
|
|
||||||
this.title = "添加任务";
|
|
||||||
},
|
|
||||||
/** 修改按钮操作 */
|
|
||||||
handleUpdate(row) {
|
|
||||||
this.reset();
|
|
||||||
const jobId = row.jobId || this.ids;
|
|
||||||
getJob(jobId).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
this.open = true;
|
|
||||||
this.title = "修改任务";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 提交按钮 */
|
|
||||||
submitForm: function() {
|
|
||||||
this.$refs["form"].validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
if (this.form.jobId != undefined) {
|
|
||||||
updateJob(this.form).then(response => {
|
|
||||||
this.$modal.msgSuccess("修改成功");
|
|
||||||
this.open = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
addJob(this.form).then(response => {
|
|
||||||
this.$modal.msgSuccess("新增成功");
|
|
||||||
this.open = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 删除按钮操作 */
|
|
||||||
handleDelete(row) {
|
|
||||||
const jobIds = row.jobId || this.ids;
|
|
||||||
this.$modal.confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项?').then(function() {
|
|
||||||
return delJob(jobIds);
|
|
||||||
}).then(() => {
|
|
||||||
this.getList();
|
|
||||||
this.$modal.msgSuccess("删除成功");
|
|
||||||
}).catch(() => {});
|
|
||||||
},
|
|
||||||
/** 导出按钮操作 */
|
|
||||||
handleExport() {
|
|
||||||
this.$download.excel('/monitor/job/export', this.queryParams);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
@ -1,300 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
|
||||||
<el-form-item label="任务名称" prop="jobName">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.jobName"
|
|
||||||
placeholder="请输入任务名称"
|
|
||||||
clearable
|
|
||||||
size="small"
|
|
||||||
style="width: 240px"
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="任务组名" prop="jobGroup">
|
|
||||||
<el-select
|
|
||||||
v-model="queryParams.jobGroup"
|
|
||||||
placeholder="请任务组名"
|
|
||||||
clearable
|
|
||||||
size="small"
|
|
||||||
style="width: 240px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="dict in dict.type.sys_job_group"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="执行状态" prop="status">
|
|
||||||
<el-select
|
|
||||||
v-model="queryParams.status"
|
|
||||||
placeholder="请选择执行状态"
|
|
||||||
clearable
|
|
||||||
size="small"
|
|
||||||
style="width: 240px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="dict in dict.type.sys_common_status"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="执行时间">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
size="small"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
plain
|
|
||||||
icon="el-icon-delete"
|
|
||||||
size="mini"
|
|
||||||
:disabled="multiple"
|
|
||||||
@click="handleDelete"
|
|
||||||
v-hasPermi="['monitor:job:remove']"
|
|
||||||
>删除</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
plain
|
|
||||||
icon="el-icon-delete"
|
|
||||||
size="mini"
|
|
||||||
@click="handleClean"
|
|
||||||
v-hasPermi="['monitor:job:remove']"
|
|
||||||
>清空</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="warning"
|
|
||||||
plain
|
|
||||||
icon="el-icon-download"
|
|
||||||
size="mini"
|
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
|
||||||
v-hasPermi="['monitor:job:export']"
|
|
||||||
>导出</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button
|
|
||||||
type="warning"
|
|
||||||
plain
|
|
||||||
icon="el-icon-close"
|
|
||||||
size="mini"
|
|
||||||
@click="handleClose"
|
|
||||||
>关闭</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange">
|
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
|
||||||
<el-table-column label="日志编号" width="80" align="center" prop="jobLogId" />
|
|
||||||
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
|
|
||||||
<el-table-column label="任务组名" align="center" prop="jobGroup" :show-overflow-tooltip="true">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
|
|
||||||
<el-table-column label="日志信息" align="center" prop="jobMessage" :show-overflow-tooltip="true" />
|
|
||||||
<el-table-column label="执行状态" align="center" prop="status">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="执行时间" align="center" prop="createTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-view"
|
|
||||||
@click="handleView(scope.row)"
|
|
||||||
v-hasPermi="['monitor:job:query']"
|
|
||||||
>详细</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<pagination
|
|
||||||
v-show="total>0"
|
|
||||||
:total="total"
|
|
||||||
:page.sync="queryParams.pageNum"
|
|
||||||
:limit.sync="queryParams.pageSize"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 调度日志详细 -->
|
|
||||||
<el-dialog title="调度日志详细" :visible.sync="open" width="700px" append-to-body>
|
|
||||||
<el-form ref="form" :model="form" label-width="100px" size="mini">
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="日志序号:">{{ form.jobLogId }}</el-form-item>
|
|
||||||
<el-form-item label="任务名称:">{{ form.jobName }}</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="任务分组:">{{ form.jobGroup }}</el-form-item>
|
|
||||||
<el-form-item label="执行时间:">{{ form.createTime }}</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="调用方法:">{{ form.invokeTarget }}</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="日志信息:">{{ form.jobMessage }}</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="执行状态:">
|
|
||||||
<div v-if="form.status == 0">正常</div>
|
|
||||||
<div v-else-if="form.status == 1">失败</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="异常信息:" v-if="form.status == 1">{{ form.exceptionInfo }}</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="open = false">关 闭</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getJob } from "@/api/monitor/job";
|
|
||||||
import { listJobLog, delJobLog, cleanJobLog } from "@/api/monitor/jobLog";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "JobLog",
|
|
||||||
dicts: ['sys_common_status', 'sys_job_group'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 遮罩层
|
|
||||||
loading: true,
|
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
|
||||||
ids: [],
|
|
||||||
// 非多个禁用
|
|
||||||
multiple: true,
|
|
||||||
// 显示搜索条件
|
|
||||||
showSearch: true,
|
|
||||||
// 总条数
|
|
||||||
total: 0,
|
|
||||||
// 调度日志表格数据
|
|
||||||
jobLogList: [],
|
|
||||||
// 是否显示弹出层
|
|
||||||
open: false,
|
|
||||||
// 日期范围
|
|
||||||
dateRange: [],
|
|
||||||
// 表单参数
|
|
||||||
form: {},
|
|
||||||
// 查询参数
|
|
||||||
queryParams: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
jobName: undefined,
|
|
||||||
jobGroup: undefined,
|
|
||||||
status: undefined
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
const jobId = this.$route.query.jobId;
|
|
||||||
if (jobId !== undefined && jobId != 0) {
|
|
||||||
getJob(jobId).then(response => {
|
|
||||||
this.queryParams.jobName = response.data.jobName;
|
|
||||||
this.queryParams.jobGroup = response.data.jobGroup;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.getList();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** 查询调度日志列表 */
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
listJobLog(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
|
|
||||||
this.jobLogList = response.rows;
|
|
||||||
this.total = response.total;
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
// 返回按钮
|
|
||||||
handleClose() {
|
|
||||||
this.$store.dispatch("tagsView/delView", this.$route);
|
|
||||||
this.$router.push({ path: "/monitor/job" });
|
|
||||||
},
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNum = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
/** 重置按钮操作 */
|
|
||||||
resetQuery() {
|
|
||||||
this.dateRange = [];
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
// 多选框选中数据
|
|
||||||
handleSelectionChange(selection) {
|
|
||||||
this.ids = selection.map(item => item.jobLogId);
|
|
||||||
this.multiple = !selection.length;
|
|
||||||
},
|
|
||||||
/** 详细按钮操作 */
|
|
||||||
handleView(row) {
|
|
||||||
this.open = true;
|
|
||||||
this.form = row;
|
|
||||||
},
|
|
||||||
/** 删除按钮操作 */
|
|
||||||
handleDelete(row) {
|
|
||||||
const jobLogIds = this.ids;
|
|
||||||
this.$modal.confirm('是否确认删除调度日志编号为"' + jobLogIds + '"的数据项?').then(function() {
|
|
||||||
return delJobLog(jobLogIds);
|
|
||||||
}).then(() => {
|
|
||||||
this.getList();
|
|
||||||
this.$modal.msgSuccess("删除成功");
|
|
||||||
}).catch(() => {});
|
|
||||||
},
|
|
||||||
/** 清空按钮操作 */
|
|
||||||
handleClean() {
|
|
||||||
this.$modal.confirm('是否确认清空所有调度日志数据项?').then(function() {
|
|
||||||
return cleanJobLog();
|
|
||||||
}).then(() => {
|
|
||||||
this.getList();
|
|
||||||
this.$modal.msgSuccess("清空成功");
|
|
||||||
}).catch(() => {});
|
|
||||||
},
|
|
||||||
/** 导出按钮操作 */
|
|
||||||
handleExport() {
|
|
||||||
this.$download.excel('/monitor/jobLog/export', this.queryParams);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
@ -6,8 +6,8 @@
|
|||||||
v-model="queryParams.ipaddr"
|
v-model="queryParams.ipaddr"
|
||||||
placeholder="请输入登录地址"
|
placeholder="请输入登录地址"
|
||||||
clearable
|
clearable
|
||||||
|
size="small"
|
||||||
style="width: 240px;"
|
style="width: 240px;"
|
||||||
size="small"
|
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -16,8 +16,8 @@
|
|||||||
v-model="queryParams.userName"
|
v-model="queryParams.userName"
|
||||||
placeholder="请输入用户名称"
|
placeholder="请输入用户名称"
|
||||||
clearable
|
clearable
|
||||||
|
size="small"
|
||||||
style="width: 240px;"
|
style="width: 240px;"
|
||||||
size="small"
|
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -83,7 +83,6 @@
|
|||||||
plain
|
plain
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['monitor:logininfor:export']"
|
v-hasPermi="['monitor:logininfor:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
@ -132,8 +131,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非多个禁用
|
// 非多个禁用
|
||||||
@ -216,7 +213,9 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.$download.excel('/monitor/logininfor/export', this.queryParams);
|
this.download('monitor/logininfor/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `logininfor_${new Date().getTime()}.xlsx`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
v-model="queryParams.title"
|
v-model="queryParams.title"
|
||||||
placeholder="请输入系统模块"
|
placeholder="请输入系统模块"
|
||||||
clearable
|
clearable
|
||||||
style="width: 240px;"
|
|
||||||
size="small"
|
size="small"
|
||||||
|
style="width: 240px;"
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -16,8 +16,8 @@
|
|||||||
v-model="queryParams.operName"
|
v-model="queryParams.operName"
|
||||||
placeholder="请输入操作人员"
|
placeholder="请输入操作人员"
|
||||||
clearable
|
clearable
|
||||||
style="width: 240px;"
|
|
||||||
size="small"
|
size="small"
|
||||||
|
style="width: 240px;"
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -99,7 +99,6 @@
|
|||||||
plain
|
plain
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['monitor:operlog:export']"
|
v-hasPermi="['monitor:operlog:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
@ -205,8 +204,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非多个禁用
|
// 非多个禁用
|
||||||
@ -303,7 +300,9 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.$download.excel('/monitor/operlog/export', this.queryParams);
|
this.download('monitor/operlog/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `operlog_${new Date().getTime()}.xlsx`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -127,7 +127,8 @@ export default {
|
|||||||
register(this.registerForm).then(res => {
|
register(this.registerForm).then(res => {
|
||||||
const username = this.registerForm.username;
|
const username = this.registerForm.username;
|
||||||
this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
|
this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
|
||||||
dangerouslyUseHTMLString: true
|
dangerouslyUseHTMLString: true,
|
||||||
|
type: 'success'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$router.push("/login");
|
this.$router.push("/login");
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
|
@ -88,7 +88,6 @@
|
|||||||
plain
|
plain
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['system:config:export']"
|
v-hasPermi="['system:config:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
@ -194,8 +193,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
@ -334,7 +331,9 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.$download.excel('/system/config/export', this.queryParams);
|
this.download('system/config/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `config_${new Date().getTime()}.xlsx`)
|
||||||
},
|
},
|
||||||
/** 刷新缓存按钮操作 */
|
/** 刷新缓存按钮操作 */
|
||||||
handleRefreshCache() {
|
handleRefreshCache() {
|
||||||
|
@ -179,8 +179,6 @@ export default {
|
|||||||
isExpandAll: true,
|
isExpandAll: true,
|
||||||
// 重新渲染表格状态
|
// 重新渲染表格状态
|
||||||
refreshTable: true,
|
refreshTable: true,
|
||||||
// 是否展开
|
|
||||||
expand: false,
|
|
||||||
// 查询参数
|
// 查询参数
|
||||||
queryParams: {
|
queryParams: {
|
||||||
deptName: undefined,
|
deptName: undefined,
|
||||||
@ -276,7 +274,7 @@ export default {
|
|||||||
this.open = true;
|
this.open = true;
|
||||||
this.title = "添加部门";
|
this.title = "添加部门";
|
||||||
listDept().then(response => {
|
listDept().then(response => {
|
||||||
this.deptOptions = this.handleTree(response.data, "deptId");
|
this.deptOptions = this.handleTree(response.data, "deptId");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/** 展开/折叠操作 */
|
/** 展开/折叠操作 */
|
||||||
@ -296,7 +294,7 @@ export default {
|
|||||||
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");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
|
@ -75,11 +75,19 @@
|
|||||||
plain
|
plain
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['system:dict:export']"
|
v-hasPermi="['system:dict:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-close"
|
||||||
|
size="mini"
|
||||||
|
@click="handleClose"
|
||||||
|
>关闭</el-button>
|
||||||
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
@ -193,8 +201,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
@ -319,6 +325,11 @@ export default {
|
|||||||
this.queryParams.pageNum = 1;
|
this.queryParams.pageNum = 1;
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
|
/** 返回按钮操作 */
|
||||||
|
handleClose() {
|
||||||
|
const obj = { path: "/system/dict" };
|
||||||
|
this.$tab.closeOpenPage(obj);
|
||||||
|
},
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
this.resetForm("queryForm");
|
this.resetForm("queryForm");
|
||||||
@ -380,7 +391,9 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.$download.excel('/system/dict/data/export', this.queryParams);
|
this.download('system/dict/data/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `data_${new Date().getTime()}.xlsx`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -94,7 +94,6 @@
|
|||||||
plain
|
plain
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['system:dict:export']"
|
v-hasPermi="['system:dict:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
@ -202,8 +201,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
@ -338,7 +335,9 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.$download.excel('/system/dict/type/export', this.queryParams);
|
this.download('system/dict/type/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `type_${new Date().getTime()}.xlsx`)
|
||||||
},
|
},
|
||||||
/** 刷新缓存按钮操作 */
|
/** 刷新缓存按钮操作 */
|
||||||
handleRefreshCache() {
|
handleRefreshCache() {
|
||||||
|
@ -78,7 +78,8 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button size="mini"
|
<el-button
|
||||||
|
size="mini"
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-edit"
|
icon="el-icon-edit"
|
||||||
@click="handleUpdate(scope.row)"
|
@click="handleUpdate(scope.row)"
|
||||||
@ -126,8 +127,8 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24" v-if="form.menuType != 'F'">
|
||||||
<el-form-item v-if="form.menuType != 'F'" label="菜单图标">
|
<el-form-item label="菜单图标">
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="bottom-start"
|
placement="bottom-start"
|
||||||
width="460"
|
width="460"
|
||||||
@ -158,8 +159,8 @@
|
|||||||
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
|
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12" v-if="form.menuType != 'F'">
|
||||||
<el-form-item v-if="form.menuType != 'F'">
|
<el-form-item>
|
||||||
<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>
|
||||||
@ -172,8 +173,8 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12" v-if="form.menuType != 'F'">
|
||||||
<el-form-item v-if="form.menuType != 'F'" prop="path">
|
<el-form-item prop="path">
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
<el-tooltip content="访问的路由地址,如:`user`,如外网地址需内链访问则以`http(s)://`开头" placement="top">
|
<el-tooltip content="访问的路由地址,如:`user`,如外网地址需内链访问则以`http(s)://`开头" placement="top">
|
||||||
<i class="el-icon-question"></i>
|
<i class="el-icon-question"></i>
|
||||||
@ -194,8 +195,8 @@
|
|||||||
<el-input v-model="form.component" placeholder="请输入组件路径" />
|
<el-input v-model="form.component" placeholder="请输入组件路径" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12" v-if="form.menuType != 'M'">
|
||||||
<el-form-item v-if="form.menuType != 'M'">
|
<el-form-item>
|
||||||
<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="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
|
<el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
|
||||||
@ -205,8 +206,8 @@
|
|||||||
</span>
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12" v-if="form.menuType == 'C'">
|
||||||
<el-form-item v-if="form.menuType == 'C'">
|
<el-form-item>
|
||||||
<el-input v-model="form.query" placeholder="请输入路由参数" maxlength="255" />
|
<el-input v-model="form.query" 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">
|
||||||
@ -216,8 +217,8 @@
|
|||||||
</span>
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12" v-if="form.menuType == 'C'">
|
||||||
<el-form-item v-if="form.menuType == 'C'">
|
<el-form-item>
|
||||||
<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>
|
||||||
@ -230,8 +231,8 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12" v-if="form.menuType != 'F'">
|
||||||
<el-form-item v-if="form.menuType != 'F'">
|
<el-form-item>
|
||||||
<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>
|
||||||
@ -247,8 +248,8 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12" v-if="form.menuType != 'F'">
|
||||||
<el-form-item v-if="form.menuType != 'F'">
|
<el-form-item>
|
||||||
<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>
|
||||||
|
@ -74,7 +74,6 @@
|
|||||||
plain
|
plain
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['system:post:export']"
|
v-hasPermi="['system:post:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
@ -169,8 +168,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
@ -305,7 +302,9 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.$download.excel('/system/post/export', this.queryParams);
|
this.download('system/post/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `post_${new Date().getTime()}.xlsx`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -153,8 +153,8 @@ export default {
|
|||||||
},
|
},
|
||||||
// 返回按钮
|
// 返回按钮
|
||||||
handleClose() {
|
handleClose() {
|
||||||
this.$store.dispatch("tagsView/delView", this.$route);
|
const obj = { path: "/system/role" };
|
||||||
this.$router.push({ path: "/system/role" });
|
this.$tab.closeOpenPage(obj);
|
||||||
},
|
},
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
|
@ -94,7 +94,6 @@
|
|||||||
plain
|
plain
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['system:role:export']"
|
v-hasPermi="['system:role:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
@ -270,8 +269,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
@ -358,8 +355,7 @@ export default {
|
|||||||
/** 查询角色列表 */
|
/** 查询角色列表 */
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
listRole(this.addDateRange(this.queryParams, this.dateRange)).then(
|
listRole(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
|
||||||
response => {
|
|
||||||
this.roleList = response.rows;
|
this.roleList = response.rows;
|
||||||
this.total = response.total;
|
this.total = response.total;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
@ -613,7 +609,9 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.$download.excel('/system/role/export', this.queryParams);
|
this.download('system/role/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `role_${new Date().getTime()}.xlsx`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -123,6 +123,10 @@ export default {
|
|||||||
handleSelectUser() {
|
handleSelectUser() {
|
||||||
const roleId = this.queryParams.roleId;
|
const roleId = this.queryParams.roleId;
|
||||||
const userIds = this.userIds.join(",");
|
const userIds = this.userIds.join(",");
|
||||||
|
if (userIds == "") {
|
||||||
|
this.$modal.msgError("请选择要分配的用户");
|
||||||
|
return;
|
||||||
|
}
|
||||||
authUserSelectAll({ roleId: roleId, userIds: userIds }).then(res => {
|
authUserSelectAll({ roleId: roleId, userIds: userIds }).then(res => {
|
||||||
this.$modal.msgSuccess(res.msg);
|
this.$modal.msgSuccess(res.msg);
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
|
@ -109,8 +109,8 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 关闭按钮 */
|
/** 关闭按钮 */
|
||||||
close() {
|
close() {
|
||||||
this.$store.dispatch("tagsView/delView", this.$route);
|
const obj = { path: "/system/user" };
|
||||||
this.$router.push({ path: "/system/user" });
|
this.$tab.closeOpenPage(obj);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -131,7 +131,6 @@
|
|||||||
plain
|
plain
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="exportLoading"
|
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['system:user:export']"
|
v-hasPermi="['system:user:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
@ -207,7 +206,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 添加或修改参数配置对话框 -->
|
<!-- 添加或修改用户配置对话框 -->
|
||||||
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
|
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||||
<el-row>
|
<el-row>
|
||||||
@ -360,8 +359,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
@ -643,7 +640,9 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.$download.excel('/system/user/export', this.queryParams);
|
this.download('system/user/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `user_${new Date().getTime()}.xlsx`)
|
||||||
},
|
},
|
||||||
/** 导入按钮操作 */
|
/** 导入按钮操作 */
|
||||||
handleImport() {
|
handleImport() {
|
||||||
@ -652,7 +651,8 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 下载模板操作 */
|
/** 下载模板操作 */
|
||||||
importTemplate() {
|
importTemplate() {
|
||||||
this.$download.excel('/system/user/importTemplate');
|
this.download('system/user/importTemplate', {
|
||||||
|
}, `user_template_${new Date().getTime()}.xlsx`)
|
||||||
},
|
},
|
||||||
// 文件上传中处理
|
// 文件上传中处理
|
||||||
handleFileUploadProgress(event, file, fileList) {
|
handleFileUploadProgress(event, file, fileList) {
|
||||||
|
@ -29,7 +29,6 @@ export default {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
test: "1test",
|
|
||||||
user: {
|
user: {
|
||||||
oldPassword: undefined,
|
oldPassword: undefined,
|
||||||
newPassword: undefined,
|
newPassword: undefined,
|
||||||
@ -55,17 +54,14 @@ export default {
|
|||||||
submit() {
|
submit() {
|
||||||
this.$refs["form"].validate(valid => {
|
this.$refs["form"].validate(valid => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(
|
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => {
|
||||||
response => {
|
this.$modal.msgSuccess("修改成功");
|
||||||
this.$modal.msgSuccess("修改成功");
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.$store.dispatch("tagsView/delView", this.$route);
|
this.$tab.closePage();
|
||||||
this.$router.push({ path: "/index" });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="user-info-head" @click="editCropper()"><img v-bind:src="options.img" title="点击上传头像" class="img-circle img-lg" /></div>
|
<div class="user-info-head" @click="editCropper()"><img v-bind:src="options.img" title="点击上传头像" class="img-circle img-lg" /></div>
|
||||||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog()">
|
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :xs="24" :md="12" :style="{height: '350px'}">
|
<el-col :xs="24" :md="12" :style="{height: '350px'}">
|
||||||
<vue-cropper
|
<vue-cropper
|
||||||
@ -143,7 +143,7 @@ export default {
|
|||||||
// 关闭窗口
|
// 关闭窗口
|
||||||
closeDialog() {
|
closeDialog() {
|
||||||
this.options.img = store.getters.avatar
|
this.options.img = store.getters.avatar
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -68,8 +68,7 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.$store.dispatch("tagsView/delView", this.$route);
|
this.$tab.closePage();
|
||||||
this.$router.push({ path: "/index" });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -211,8 +211,8 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 关闭按钮 */
|
/** 关闭按钮 */
|
||||||
close() {
|
close() {
|
||||||
this.$store.dispatch("tagsView/delView", this.$route);
|
const obj = { path: "/tool/gen", query: { t: Date.now(), pageNum: this.$route.query.pageNum } };
|
||||||
this.$router.push({ path: "/tool/gen", query: { t: Date.now(), pageNum: this.$route.query.pageNum } })
|
this.$tab.closeOpenPage(obj);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -16,8 +16,7 @@ module.exports = {
|
|||||||
// 部署生产环境和开发环境下的URL。
|
// 部署生产环境和开发环境下的URL。
|
||||||
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
|
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
|
||||||
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
||||||
// 设置基路径参考文档: http://doc.ruoyi.vip/ruoyi-vue/document/qdsc.html#应用路径
|
publicPath: process.env.VUE_APP_CONTEXT_PATH,
|
||||||
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
|
|
||||||
// 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
|
// 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
|
||||||
outputDir: 'dist',
|
outputDir: 'dist',
|
||||||
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
|
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
|
||||||
|
@ -4,6 +4,7 @@ MAINTAINER Lion Li
|
|||||||
|
|
||||||
RUN mkdir -p /ruoyi/server
|
RUN mkdir -p /ruoyi/server
|
||||||
RUN mkdir -p /ruoyi/server/logs
|
RUN mkdir -p /ruoyi/server/logs
|
||||||
|
RUN mkdir -p /ruoyi/server/temp
|
||||||
|
|
||||||
WORKDIR /ruoyi/server
|
WORKDIR /ruoyi/server
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.3.0</version>
|
<version>3.4.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@ -48,7 +48,7 @@
|
|||||||
<!--velocity代码生成使用模板 -->
|
<!--velocity代码生成使用模板 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.velocity</groupId>
|
<groupId>org.apache.velocity</groupId>
|
||||||
<artifactId>velocity</artifactId>
|
<artifactId>velocity-engine-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- spring-boot-devtools -->
|
<!-- spring-boot-devtools -->
|
||||||
@ -85,12 +85,6 @@
|
|||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 自定义验证注解 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.validation</groupId>
|
|
||||||
<artifactId>validation-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!--常用工具类 -->
|
<!--常用工具类 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
@ -126,18 +120,6 @@
|
|||||||
<artifactId>jaxb-impl</artifactId>
|
<artifactId>jaxb-impl</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- redis 缓存操作 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- pool 对象池 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-pool2</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- servlet包 -->
|
<!-- servlet包 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
@ -174,16 +156,6 @@
|
|||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.github.openfeign</groupId>
|
|
||||||
<artifactId>feign-okhttp</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>de.codecentric</groupId>
|
<groupId>de.codecentric</groupId>
|
||||||
<artifactId>spring-boot-admin-starter-client</artifactId>
|
<artifactId>spring-boot-admin-starter-client</artifactId>
|
||||||
@ -225,11 +197,6 @@
|
|||||||
<artifactId>tlog-webroot</artifactId>
|
<artifactId>tlog-webroot</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.yomahub</groupId>
|
|
||||||
<artifactId>tlog-feign</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.yomahub</groupId>
|
<groupId>com.yomahub</groupId>
|
||||||
<artifactId>tlog-xxl-job</artifactId>
|
<artifactId>tlog-xxl-job</artifactId>
|
||||||
|
@ -2,6 +2,7 @@ package com.ruoyi;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动程序
|
* 启动程序
|
||||||
@ -14,7 +15,9 @@ public class RuoYiApplication {
|
|||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.setProperty("spring.devtools.restart.enabled", "false");
|
System.setProperty("spring.devtools.restart.enabled", "false");
|
||||||
SpringApplication.run(RuoYiApplication.class, args);
|
SpringApplication application = new SpringApplication(RuoYiApplication.class);
|
||||||
|
application.setApplicationStartup(new BufferingApplicationStartup(2048));
|
||||||
|
application.run(args);
|
||||||
System.out.println("(♥◠‿◠)ノ゙ RuoYi-Vue-Plus启动成功 ლ(´ڡ`ლ)゙");
|
System.out.println("(♥◠‿◠)ノ゙ RuoYi-Vue-Plus启动成功 ლ(´ڡ`ლ)゙");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,11 @@ public class RuoYiConfig {
|
|||||||
*/
|
*/
|
||||||
private boolean demoEnabled;
|
private boolean demoEnabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存懒加载
|
||||||
|
*/
|
||||||
|
private boolean cacheLazy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取地址开关
|
* 获取地址开关
|
||||||
*/
|
*/
|
||||||
|
@ -133,13 +133,4 @@ public class Constants {
|
|||||||
*/
|
*/
|
||||||
public static final String SYS_DICT_KEY = "sys_dict:";
|
public static final String SYS_DICT_KEY = "sys_dict:";
|
||||||
|
|
||||||
/**
|
|
||||||
* RMI 远程方法调用
|
|
||||||
*/
|
|
||||||
public static final String LOOKUP_RMI = "rmi://";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* LDAP 远程方法调用
|
|
||||||
*/
|
|
||||||
public static final String LOOKUP_LDAP = "ldap://";
|
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ import com.alibaba.excel.metadata.CellData;
|
|||||||
import com.alibaba.excel.metadata.GlobalConfiguration;
|
import com.alibaba.excel.metadata.GlobalConfiguration;
|
||||||
import com.alibaba.excel.metadata.property.ExcelContentProperty;
|
import com.alibaba.excel.metadata.property.ExcelContentProperty;
|
||||||
import com.ruoyi.common.annotation.ExcelDictFormat;
|
import com.ruoyi.common.annotation.ExcelDictFormat;
|
||||||
|
import com.ruoyi.common.core.service.DictService;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@ -41,7 +43,7 @@ public class ExcelDictConvert implements Converter<Object> {
|
|||||||
if (StringUtils.isBlank(type)) {
|
if (StringUtils.isBlank(type)) {
|
||||||
value = ExcelUtil.reverseByExp(label, anno.readConverterExp(), anno.separator());
|
value = ExcelUtil.reverseByExp(label, anno.readConverterExp(), anno.separator());
|
||||||
} else {
|
} else {
|
||||||
value = ExcelUtil.reverseDictByExp(label, type, anno.separator());
|
value = SpringUtils.getBean(DictService.class).getDictValue(type, label, anno.separator());
|
||||||
}
|
}
|
||||||
return Convert.convert(contentProperty.getField().getType(), value);
|
return Convert.convert(contentProperty.getField().getType(), value);
|
||||||
}
|
}
|
||||||
@ -58,7 +60,7 @@ public class ExcelDictConvert implements Converter<Object> {
|
|||||||
if (StringUtils.isBlank(type)) {
|
if (StringUtils.isBlank(type)) {
|
||||||
label = ExcelUtil.convertByExp(value, anno.readConverterExp(), anno.separator());
|
label = ExcelUtil.convertByExp(value, anno.readConverterExp(), anno.separator());
|
||||||
} else {
|
} else {
|
||||||
label = ExcelUtil.convertDictByExp(value, type, anno.separator());
|
label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator());
|
||||||
}
|
}
|
||||||
return new CellData<>(label);
|
return new CellData<>(label);
|
||||||
}
|
}
|
||||||
|
@ -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 com.fasterxml.jackson.annotation.JsonIgnore;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
package com.ruoyi.common.core.domain;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysMenu;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Treeselect树结构实体类
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@Accessors(chain = true)
|
|
||||||
@ApiModel("树结构实体类")
|
|
||||||
public class TreeSelect implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 节点ID
|
|
||||||
*/
|
|
||||||
@ApiModelProperty(value = "节点ID")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 节点名称
|
|
||||||
*/
|
|
||||||
@ApiModelProperty(value = "节点名称")
|
|
||||||
private String label;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 子节点
|
|
||||||
*/
|
|
||||||
@ApiModelProperty(value = "子节点")
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
|
||||||
private List<TreeSelect> children;
|
|
||||||
|
|
||||||
public TreeSelect(SysDept dept) {
|
|
||||||
this.id = dept.getDeptId();
|
|
||||||
this.label = dept.getDeptName();
|
|
||||||
this.children = dept.getChildren()
|
|
||||||
.stream()
|
|
||||||
.map(d -> new TreeSelect((SysDept) d))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public TreeSelect(SysMenu menu) {
|
|
||||||
this.id = menu.getMenuId();
|
|
||||||
this.label = menu.getMenuName();
|
|
||||||
this.children = menu.getChildren()
|
|
||||||
.stream()
|
|
||||||
.map(d -> new TreeSelect((SysMenu) d))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
package com.ruoyi.common.core.domain.model;
|
package com.ruoyi.common.core.domain.model;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
@ -75,31 +74,38 @@ public class LoginUser implements UserDetails {
|
|||||||
private Set<String> permissions;
|
private Set<String> permissions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户信息
|
* 用户名
|
||||||
*/
|
*/
|
||||||
private SysUser user;
|
private String username;
|
||||||
|
|
||||||
public LoginUser(SysUser user, Set<String> permissions) {
|
/**
|
||||||
this.user = user;
|
* 密码
|
||||||
|
*/
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
public LoginUser(String username, String password, Set<String> permissions) {
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
this.permissions = permissions;
|
this.permissions = permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions) {
|
public LoginUser(Long userId, Long deptId, String username, String password, Set<String> permissions) {
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.deptId = deptId;
|
this.deptId = deptId;
|
||||||
this.user = user;
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
this.permissions = permissions;
|
this.permissions = permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
return user.getPassword();
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return user.getUserName();
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
package com.ruoyi.common.core.mybatisplus.cache;
|
|
||||||
|
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
|
||||||
import com.ruoyi.common.utils.RedisUtils;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.ibatis.cache.Cache;
|
|
||||||
import org.springframework.data.redis.connection.RedisServerCommands;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mybatis-redis 二级缓存
|
|
||||||
*
|
|
||||||
* 使用方法 配置文件开启 mybatis-plus 二级缓存
|
|
||||||
* 在 XxxMapper.java 类上添加注解 @CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
|
|
||||||
*
|
|
||||||
* @deprecated 3.4.0删除 推荐使用spirng-cache
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class MybatisPlusRedisCache implements Cache {
|
|
||||||
|
|
||||||
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
|
|
||||||
|
|
||||||
private String id;
|
|
||||||
|
|
||||||
public MybatisPlusRedisCache(final String id) {
|
|
||||||
if (id == null) {
|
|
||||||
throw new IllegalArgumentException("Cache instances require an ID");
|
|
||||||
}
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putObject(Object key, Object value) {
|
|
||||||
if (value != null) {
|
|
||||||
RedisUtils.setCacheObject(key.toString(), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getObject(Object key) {
|
|
||||||
try {
|
|
||||||
if (key != null) {
|
|
||||||
return RedisUtils.getCacheObject(key.toString());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
log.error("缓存出错");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object removeObject(Object key) {
|
|
||||||
if (key != null) {
|
|
||||||
RedisUtils.deleteObject(key.toString());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
log.debug("清空缓存");
|
|
||||||
Collection<String> keys = RedisUtils.keys("*:" + this.id + "*");
|
|
||||||
if (!CollectionUtils.isEmpty(keys)) {
|
|
||||||
RedisUtils.deleteObject(keys);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSize() {
|
|
||||||
RedisTemplate<String, Object> redisTemplate = SpringUtil.getBean("redisTemplate");
|
|
||||||
Long size = redisTemplate.execute(RedisServerCommands::dbSize);
|
|
||||||
return size.intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReadWriteLock getReadWriteLock() {
|
|
||||||
return this.readWriteLock;
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,6 +2,11 @@ package com.ruoyi.common.core.service;
|
|||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用 系统访问日志
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
public interface LogininforService {
|
public interface LogininforService {
|
||||||
|
|
||||||
void recordLogininfor(String username, String status, String message,
|
void recordLogininfor(String username, String status, String message,
|
||||||
|
@ -3,7 +3,13 @@ package com.ruoyi.common.core.service;
|
|||||||
import com.ruoyi.common.core.domain.dto.OperLogDTO;
|
import com.ruoyi.common.core.domain.dto.OperLogDTO;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用 操作日志
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
public interface OperLogService {
|
public interface OperLogService {
|
||||||
|
|
||||||
@Async
|
@Async
|
||||||
void recordOper(OperLogDTO operLogDTO);
|
void recordOper(OperLogDTO operLogDTO);
|
||||||
}
|
}
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
package com.ruoyi.common.exception.file;
|
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import org.apache.commons.fileupload.FileUploadException;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件上传 误异常类
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class InvalidExtensionException extends FileUploadException {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private String[] allowedExtension;
|
|
||||||
private String extension;
|
|
||||||
private String filename;
|
|
||||||
|
|
||||||
public InvalidExtensionException(String[] allowedExtension, String extension, String filename) {
|
|
||||||
super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
|
|
||||||
this.allowedExtension = allowedExtension;
|
|
||||||
this.extension = extension;
|
|
||||||
this.filename = filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InvalidImageExtensionException extends InvalidExtensionException {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) {
|
|
||||||
super(allowedExtension, extension, filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InvalidFlashExtensionException extends InvalidExtensionException {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) {
|
|
||||||
super(allowedExtension, extension, filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InvalidMediaExtensionException extends InvalidExtensionException {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) {
|
|
||||||
super(allowedExtension, extension, filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InvalidVideoExtensionException extends InvalidExtensionException {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) {
|
|
||||||
super(allowedExtension, extension, filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,7 +11,9 @@ import java.util.List;
|
|||||||
* 字典工具类
|
* 字典工具类
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
|
* @deprecated 3.5.0 版本删除 迁移至 {@link com.ruoyi.common.core.service.DictService}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class DictUtils {
|
public class DictUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,9 +38,8 @@ public class DictUtils {
|
|||||||
* @return dictDatas 字典数据列表
|
* @return dictDatas 字典数据列表
|
||||||
*/
|
*/
|
||||||
public static List<SysDictData> getDictCache(String key) {
|
public static List<SysDictData> getDictCache(String key) {
|
||||||
Object cacheObj = RedisUtils.getCacheObject(getCacheKey(key));
|
List<SysDictData> dictDatas = RedisUtils.getCacheObject(getCacheKey(key));
|
||||||
if (StringUtils.isNotNull(cacheObj)) {
|
if (StringUtils.isNotNull(dictDatas)) {
|
||||||
List<SysDictData> dictDatas = (List<SysDictData>) cacheObj;
|
|
||||||
return dictDatas;
|
return dictDatas;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.common.utils;
|
package com.ruoyi.common.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.http.HttpStatus;
|
import cn.hutool.http.HttpStatus;
|
||||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
@ -63,7 +64,9 @@ public class PageUtils {
|
|||||||
}
|
}
|
||||||
PagePlus<T, K> page = new PagePlus<>(pageNum, pageSize);
|
PagePlus<T, K> page = new PagePlus<>(pageNum, pageSize);
|
||||||
OrderItem orderItem = buildOrderItem(orderByColumn, isAsc);
|
OrderItem orderItem = buildOrderItem(orderByColumn, isAsc);
|
||||||
page.addOrder(orderItem);
|
if (ObjectUtil.isNotNull(orderItem)) {
|
||||||
|
page.addOrder(orderItem);
|
||||||
|
}
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +90,9 @@ public class PageUtils {
|
|||||||
}
|
}
|
||||||
Page<T> page = new Page<>(pageNum, pageSize);
|
Page<T> page = new Page<>(pageNum, pageSize);
|
||||||
OrderItem orderItem = buildOrderItem(orderByColumn, isAsc);
|
OrderItem orderItem = buildOrderItem(orderByColumn, isAsc);
|
||||||
page.addOrder(orderItem);
|
if (ObjectUtil.isNotNull(orderItem)) {
|
||||||
|
page.addOrder(orderItem);
|
||||||
|
}
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,30 @@ public class RedisUtils {
|
|||||||
* @param value 缓存的值
|
* @param value 缓存的值
|
||||||
*/
|
*/
|
||||||
public static <T> void setCacheObject(final String key, final T value) {
|
public static <T> void setCacheObject(final String key, final T value) {
|
||||||
client.getBucket(key).set(value);
|
setCacheObject(key, value, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存基本的对象,保留当前对象 TTL 有效期
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param value 缓存的值
|
||||||
|
* @param isSaveTtl 是否保留TTL有效期(例如: set之前ttl剩余90 set之后还是为90)
|
||||||
|
* @since Redis 6.X 以上使用 setAndKeepTTL 兼容 5.X 方案
|
||||||
|
*/
|
||||||
|
public static <T> void setCacheObject(final String key, final T value, final boolean isSaveTtl) {
|
||||||
|
RBucket<Object> bucket = client.getBucket(key);
|
||||||
|
if (isSaveTtl) {
|
||||||
|
try {
|
||||||
|
bucket.setAndKeepTTL(value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
long timeToLive = bucket.remainTimeToLive();
|
||||||
|
bucket.set(value);
|
||||||
|
bucket.expire(timeToLive, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bucket.set(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,7 +122,7 @@ public class RedisUtils {
|
|||||||
* @param timeout 时间
|
* @param timeout 时间
|
||||||
* @param timeUnit 时间颗粒度
|
* @param timeUnit 时间颗粒度
|
||||||
*/
|
*/
|
||||||
public static <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
|
public static <T> void setCacheObject(final String key, final T value, final long timeout, final TimeUnit timeUnit) {
|
||||||
RBucket<T> result = client.getBucket(key);
|
RBucket<T> result = client.getBucket(key);
|
||||||
result.set(value);
|
result.set(value);
|
||||||
result.expire(timeout, timeUnit);
|
result.expire(timeout, timeUnit);
|
||||||
@ -140,6 +163,17 @@ public class RedisUtils {
|
|||||||
return rBucket.get();
|
return rBucket.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得key剩余存活时间
|
||||||
|
*
|
||||||
|
* @param key 缓存键值
|
||||||
|
* @return 剩余存活时间
|
||||||
|
*/
|
||||||
|
public static <T> long getTimeToLive(final String key) {
|
||||||
|
RBucket<T> rBucket = client.getBucket(key);
|
||||||
|
return rBucket.remainTimeToLive();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除单个对象
|
* 删除单个对象
|
||||||
*
|
*
|
||||||
|
@ -4,7 +4,9 @@ import cn.hutool.core.util.IdUtil;
|
|||||||
import com.alibaba.excel.EasyExcel;
|
import com.alibaba.excel.EasyExcel;
|
||||||
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||||
import com.ruoyi.common.convert.ExcelBigNumberConvert;
|
import com.ruoyi.common.convert.ExcelBigNumberConvert;
|
||||||
import com.ruoyi.common.utils.DictUtils;
|
import com.ruoyi.common.excel.DefaultExcelListener;
|
||||||
|
import com.ruoyi.common.excel.ExcelListener;
|
||||||
|
import com.ruoyi.common.excel.ExcelResult;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.file.FileUtils;
|
import com.ruoyi.common.utils.file.FileUtils;
|
||||||
|
|
||||||
@ -21,129 +23,133 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class ExcelUtil {
|
public class ExcelUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对excel表单默认第一个索引名转换成list(EasyExcel)
|
* 同步导入(适用于小数据量)
|
||||||
*
|
*
|
||||||
* @param is 输入流
|
* @param is 输入流
|
||||||
* @return 转换后集合
|
* @return 转换后集合
|
||||||
*/
|
*/
|
||||||
public static <T> List<T> importExcel(InputStream is, Class<T> clazz) {
|
public static <T> List<T> importExcel(InputStream is, Class<T> clazz) {
|
||||||
return EasyExcel.read(is).head(clazz).autoCloseStream(false).sheet().doReadSync();
|
return EasyExcel.read(is).head(clazz).autoCloseStream(false).sheet().doReadSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 对list数据源将其里面的数据导入到excel表单(EasyExcel)
|
|
||||||
*
|
|
||||||
* @param list 导出数据集合
|
|
||||||
* @param sheetName 工作表的名称
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) {
|
|
||||||
try {
|
|
||||||
String filename = encodingFilename(sheetName);
|
|
||||||
response.reset();
|
|
||||||
FileUtils.setAttachmentResponseHeader(response, filename);
|
|
||||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
|
|
||||||
ServletOutputStream os = response.getOutputStream();
|
|
||||||
EasyExcel.write(os, clazz)
|
|
||||||
.autoCloseStream(false)
|
|
||||||
// 自动适配
|
|
||||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
|
||||||
// 大数值自动转换 防止失真
|
|
||||||
.registerConverter(new ExcelBigNumberConvert())
|
|
||||||
.sheet(sheetName).doWrite(list);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("导出Excel异常");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析导出值 0=男,1=女,2=未知
|
* 使用校验监听器 异步导入 同步返回
|
||||||
*
|
*
|
||||||
* @param propertyValue 参数值
|
* @param is 输入流
|
||||||
* @param converterExp 翻译注解
|
* @param clazz 对象类型
|
||||||
* @param separator 分隔符
|
* @param isValidate 是否 Validator 检验 默认为是
|
||||||
* @return 解析后值
|
* @return 转换后集合
|
||||||
*/
|
*/
|
||||||
public static String convertByExp(String propertyValue, String converterExp, String separator) {
|
public static <T> ExcelResult<T> importExcel(InputStream is, Class<T> clazz, boolean isValidate) {
|
||||||
StringBuilder propertyString = new StringBuilder();
|
DefaultExcelListener<T> listener = new DefaultExcelListener<>(isValidate);
|
||||||
String[] convertSource = converterExp.split(",");
|
EasyExcel.read(is, clazz, listener).sheet().doRead();
|
||||||
for (String item : convertSource) {
|
return listener.getExcelResult();
|
||||||
String[] itemArray = item.split("=");
|
}
|
||||||
if (StringUtils.containsAny(separator, propertyValue)) {
|
|
||||||
for (String value : propertyValue.split(separator)) {
|
|
||||||
if (itemArray[0].equals(value)) {
|
|
||||||
propertyString.append(itemArray[1] + separator);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (itemArray[0].equals(propertyValue)) {
|
|
||||||
return itemArray[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反向解析值 男=0,女=1,未知=2
|
* 使用自定义监听器 异步导入 自定义返回
|
||||||
*
|
*
|
||||||
* @param propertyValue 参数值
|
* @param is 输入流
|
||||||
* @param converterExp 翻译注解
|
* @param clazz 对象类型
|
||||||
* @param separator 分隔符
|
* @param listener 自定义监听器
|
||||||
* @return 解析后值
|
* @return 转换后集合
|
||||||
*/
|
*/
|
||||||
public static String reverseByExp(String propertyValue, String converterExp, String separator) {
|
public static <T> ExcelResult<T> importExcel(InputStream is, Class<T> clazz, ExcelListener<T> listener) {
|
||||||
StringBuilder propertyString = new StringBuilder();
|
EasyExcel.read(is, clazz, listener).sheet().doRead();
|
||||||
String[] convertSource = converterExp.split(",");
|
return listener.getExcelResult();
|
||||||
for (String item : convertSource) {
|
}
|
||||||
String[] itemArray = item.split("=");
|
|
||||||
if (StringUtils.containsAny(separator, propertyValue)) {
|
|
||||||
for (String value : propertyValue.split(separator)) {
|
|
||||||
if (itemArray[1].equals(value)) {
|
|
||||||
propertyString.append(itemArray[0] + separator);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (itemArray[1].equals(propertyValue)) {
|
|
||||||
return itemArray[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析字典值
|
* 导出excel
|
||||||
*
|
*
|
||||||
* @param dictValue 字典值
|
* @param list 导出数据集合
|
||||||
* @param dictType 字典类型
|
* @param sheetName 工作表的名称
|
||||||
* @param separator 分隔符
|
* @return 结果
|
||||||
* @return 字典标签
|
*/
|
||||||
*/
|
public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) {
|
||||||
public static String convertDictByExp(String dictValue, String dictType, String separator) {
|
try {
|
||||||
return DictUtils.getDictLabel(dictType, dictValue, separator);
|
String filename = encodingFilename(sheetName);
|
||||||
}
|
response.reset();
|
||||||
|
FileUtils.setAttachmentResponseHeader(response, filename);
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
|
||||||
|
ServletOutputStream os = response.getOutputStream();
|
||||||
|
EasyExcel.write(os, clazz)
|
||||||
|
.autoCloseStream(false)
|
||||||
|
// 自动适配
|
||||||
|
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||||
|
// 大数值自动转换 防止失真
|
||||||
|
.registerConverter(new ExcelBigNumberConvert())
|
||||||
|
.sheet(sheetName).doWrite(list);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("导出Excel异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反向解析值字典值
|
* 解析导出值 0=男,1=女,2=未知
|
||||||
*
|
*
|
||||||
* @param dictLabel 字典标签
|
* @param propertyValue 参数值
|
||||||
* @param dictType 字典类型
|
* @param converterExp 翻译注解
|
||||||
* @param separator 分隔符
|
* @param separator 分隔符
|
||||||
* @return 字典值
|
* @return 解析后值
|
||||||
*/
|
*/
|
||||||
public static String reverseDictByExp(String dictLabel, String dictType, String separator) {
|
public static String convertByExp(String propertyValue, String converterExp, String separator) {
|
||||||
return DictUtils.getDictValue(dictType, dictLabel, separator);
|
StringBuilder propertyString = new StringBuilder();
|
||||||
}
|
String[] convertSource = converterExp.split(",");
|
||||||
|
for (String item : convertSource) {
|
||||||
|
String[] itemArray = item.split("=");
|
||||||
|
if (StringUtils.containsAny(separator, propertyValue)) {
|
||||||
|
for (String value : propertyValue.split(separator)) {
|
||||||
|
if (itemArray[0].equals(value)) {
|
||||||
|
propertyString.append(itemArray[1] + separator);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (itemArray[0].equals(propertyValue)) {
|
||||||
|
return itemArray[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return StringUtils.stripEnd(propertyString.toString(), separator);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编码文件名
|
* 反向解析值 男=0,女=1,未知=2
|
||||||
*/
|
*
|
||||||
public static String encodingFilename(String filename) {
|
* @param propertyValue 参数值
|
||||||
return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
|
* @param converterExp 翻译注解
|
||||||
}
|
* @param separator 分隔符
|
||||||
|
* @return 解析后值
|
||||||
|
*/
|
||||||
|
public static String reverseByExp(String propertyValue, String converterExp, String separator) {
|
||||||
|
StringBuilder propertyString = new StringBuilder();
|
||||||
|
String[] convertSource = converterExp.split(",");
|
||||||
|
for (String item : convertSource) {
|
||||||
|
String[] itemArray = item.split("=");
|
||||||
|
if (StringUtils.containsAny(separator, propertyValue)) {
|
||||||
|
for (String value : propertyValue.split(separator)) {
|
||||||
|
if (itemArray[1].equals(value)) {
|
||||||
|
propertyString.append(itemArray[0] + separator);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (itemArray[1].equals(propertyValue)) {
|
||||||
|
return itemArray[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return StringUtils.stripEnd(propertyString.toString(), separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编码文件名
|
||||||
|
*/
|
||||||
|
public static String encodingFilename(String filename) {
|
||||||
|
return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
package com.ruoyi.demo.controller;
|
|
||||||
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.demo.feign.FeignTestService;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* feign测试controller
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
* @deprecated 由于使用人数较少 决定与 3.4.0 版本移除
|
|
||||||
*/
|
|
||||||
@Api(value = "feign测试", tags = {"feign测试"})
|
|
||||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/feign/test")
|
|
||||||
public class FeignTestController {
|
|
||||||
|
|
||||||
private final FeignTestService feignTestService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搜索数据
|
|
||||||
*/
|
|
||||||
@ApiOperation("测试使用feign请求数据")
|
|
||||||
@GetMapping("/search/{wd}")
|
|
||||||
public AjaxResult search(@PathVariable String wd) {
|
|
||||||
String search = feignTestService.search(wd);
|
|
||||||
return AjaxResult.success("操作成功",search);
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,75 +28,75 @@ import java.util.concurrent.TimeUnit;
|
|||||||
@RequestMapping("/demo/cache")
|
@RequestMapping("/demo/cache")
|
||||||
public class RedisCacheController {
|
public class RedisCacheController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试 @Cacheable
|
* 测试 @Cacheable
|
||||||
*
|
* <p>
|
||||||
* 表示这个方法有了缓存的功能,方法的返回值会被缓存下来
|
* 表示这个方法有了缓存的功能,方法的返回值会被缓存下来
|
||||||
* 下一次调用该方法前,会去检查是否缓存中已经有值
|
* 下一次调用该方法前,会去检查是否缓存中已经有值
|
||||||
* 如果有就直接返回,不调用方法
|
* 如果有就直接返回,不调用方法
|
||||||
* 如果没有,就调用方法,然后把结果缓存起来
|
* 如果没有,就调用方法,然后把结果缓存起来
|
||||||
* 这个注解「一般用在查询方法上」
|
* 这个注解「一般用在查询方法上」
|
||||||
*
|
* <p>
|
||||||
* 重点说明: 缓存注解严谨与其他筛选数据功能一起使用
|
* 重点说明: 缓存注解严谨与其他筛选数据功能一起使用
|
||||||
* 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题
|
* 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题
|
||||||
*
|
* <p>
|
||||||
* cacheNames 为配置文件内 groupId
|
* cacheNames 为配置文件内 groupId
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试 @Cacheable")
|
@ApiOperation("测试 @Cacheable")
|
||||||
@Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
@Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
||||||
@GetMapping("/test1")
|
@GetMapping("/test1")
|
||||||
public AjaxResult<String> test1(String key, String value){
|
public AjaxResult<String> test1(String key, String value) {
|
||||||
return AjaxResult.success("操作成功", value);
|
return AjaxResult.success("操作成功", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试 @CachePut
|
* 测试 @CachePut
|
||||||
*
|
* <p>
|
||||||
* 加了@CachePut注解的方法,会把方法的返回值put到缓存里面缓存起来,供其它地方使用
|
* 加了@CachePut注解的方法,会把方法的返回值put到缓存里面缓存起来,供其它地方使用
|
||||||
* 它「通常用在新增方法上」
|
* 它「通常用在新增方法上」
|
||||||
*
|
* <p>
|
||||||
* cacheNames 为 配置文件内 groupId
|
* cacheNames 为 配置文件内 groupId
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试 @CachePut")
|
@ApiOperation("测试 @CachePut")
|
||||||
@CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
@CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
||||||
@GetMapping("/test2")
|
@GetMapping("/test2")
|
||||||
public AjaxResult<String> test2(String key, String value){
|
public AjaxResult<String> test2(String key, String value) {
|
||||||
return AjaxResult.success("操作成功", value);
|
return AjaxResult.success("操作成功", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试 @CacheEvict
|
* 测试 @CacheEvict
|
||||||
*
|
* <p>
|
||||||
* 使用了CacheEvict注解的方法,会清空指定缓存
|
* 使用了CacheEvict注解的方法,会清空指定缓存
|
||||||
* 「一般用在更新或者删除的方法上」
|
* 「一般用在更新或者删除的方法上」
|
||||||
*
|
* <p>
|
||||||
* cacheNames 为 配置文件内 groupId
|
* cacheNames 为 配置文件内 groupId
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试 @CacheEvict")
|
@ApiOperation("测试 @CacheEvict")
|
||||||
@CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
@CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
||||||
@GetMapping("/test3")
|
@GetMapping("/test3")
|
||||||
public AjaxResult<String> test3(String key, String value){
|
public AjaxResult<String> test3(String key, String value) {
|
||||||
return AjaxResult.success("操作成功", value);
|
return AjaxResult.success("操作成功", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试设置过期时间
|
* 测试设置过期时间
|
||||||
* 手动设置过期时间10秒
|
* 手动设置过期时间10秒
|
||||||
* 11秒后获取 判断是否相等
|
* 11秒后获取 判断是否相等
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试设置过期时间")
|
@ApiOperation("测试设置过期时间")
|
||||||
@GetMapping("/test6")
|
@GetMapping("/test6")
|
||||||
public AjaxResult<Boolean> test6(String key, String value){
|
public AjaxResult<Boolean> test6(String key, String value) {
|
||||||
RedisUtils.setCacheObject(key, value);
|
RedisUtils.setCacheObject(key, value);
|
||||||
boolean flag = RedisUtils.expire(key, 10, TimeUnit.SECONDS);
|
boolean flag = RedisUtils.expire(key, 10, TimeUnit.SECONDS);
|
||||||
System.out.println("***********" + flag);
|
System.out.println("***********" + flag);
|
||||||
try {
|
try {
|
||||||
Thread.sleep(11 * 1000);
|
Thread.sleep(11 * 1000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
Object obj = RedisUtils.getCacheObject(key);
|
Object obj = RedisUtils.getCacheObject(key);
|
||||||
return AjaxResult.success("操作成功", value.equals(obj));
|
return AjaxResult.success("操作成功", value.equals(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import io.swagger.annotations.Api;
|
|||||||
import io.swagger.annotations.ApiOperation;
|
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.cache.annotation.Cacheable;
|
|
||||||
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;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@ -28,59 +27,50 @@ import java.time.LocalTime;
|
|||||||
@RequestMapping("/demo/redisLock")
|
@RequestMapping("/demo/redisLock")
|
||||||
public class RedisLockController {
|
public class RedisLockController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private LockTemplate lockTemplate;
|
private LockTemplate lockTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试lock4j 注解
|
* 测试lock4j 注解
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试lock4j 注解")
|
@ApiOperation("测试lock4j 注解")
|
||||||
@Lock4j(keys = {"#key"})
|
@Lock4j(keys = {"#key"})
|
||||||
@GetMapping("/testLock4j")
|
@GetMapping("/testLock4j")
|
||||||
public AjaxResult<String> testLock4j(String key,String value){
|
public AjaxResult<String> testLock4j(String key, String value) {
|
||||||
System.out.println("start:"+key+",time:"+ LocalTime.now().toString());
|
System.out.println("start:" + key + ",time:" + LocalTime.now().toString());
|
||||||
try {
|
try {
|
||||||
Thread.sleep(10000);
|
Thread.sleep(10000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
System.out.println("end :"+key+",time:"+LocalTime.now().toString());
|
System.out.println("end :" + key + ",time:" + LocalTime.now().toString());
|
||||||
return AjaxResult.success("操作成功",value);
|
return AjaxResult.success("操作成功", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试lock4j 工具
|
* 测试lock4j 工具
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试lock4j 工具")
|
@ApiOperation("测试lock4j 工具")
|
||||||
@GetMapping("/testLock4jLockTemaplate")
|
@GetMapping("/testLock4jLockTemaplate")
|
||||||
public AjaxResult<String> testLock4jLockTemaplate(String key,String value){
|
public AjaxResult<String> testLock4jLockTemaplate(String key, String value) {
|
||||||
final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
|
final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
|
||||||
if (null == lockInfo) {
|
if (null == lockInfo) {
|
||||||
throw new RuntimeException("业务处理中,请稍后再试");
|
throw new RuntimeException("业务处理中,请稍后再试");
|
||||||
}
|
}
|
||||||
// 获取锁成功,处理业务
|
// 获取锁成功,处理业务
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(8000);
|
Thread.sleep(8000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
System.out.println("执行简单方法1 , 当前线程:" + Thread.currentThread().getName());
|
System.out.println("执行简单方法1 , 当前线程:" + Thread.currentThread().getName());
|
||||||
} finally {
|
} finally {
|
||||||
//释放锁
|
//释放锁
|
||||||
lockTemplate.releaseLock(lockInfo);
|
lockTemplate.releaseLock(lockInfo);
|
||||||
}
|
}
|
||||||
//结束
|
//结束
|
||||||
return AjaxResult.success("操作成功",value);
|
return AjaxResult.success("操作成功", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 测试spring-cache注解
|
|
||||||
*/
|
|
||||||
@ApiOperation("测试spring-cache注解")
|
|
||||||
@Cacheable(value = "test", key = "#key")
|
|
||||||
@GetMapping("/testCache")
|
|
||||||
public AjaxResult<String> testCache(String key) {
|
|
||||||
return AjaxResult.success("操作成功", key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
|||||||
import com.ruoyi.common.utils.RedisUtils;
|
import com.ruoyi.common.utils.RedisUtils;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.annotations.ApiParam;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
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,22 +22,22 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RequestMapping("/demo/redis/pubsub")
|
@RequestMapping("/demo/redis/pubsub")
|
||||||
public class RedisPubSubController {
|
public class RedisPubSubController {
|
||||||
|
|
||||||
@ApiOperation("发布消息")
|
@ApiOperation("发布消息")
|
||||||
@GetMapping("/pub")
|
@GetMapping("/pub")
|
||||||
public AjaxResult<Void> pub(String key, String value){
|
public AjaxResult<Void> pub(@ApiParam("通道Key") String key, @ApiParam("发送内容") String value) {
|
||||||
RedisUtils.publish(key, value, consumer -> {
|
RedisUtils.publish(key, value, consumer -> {
|
||||||
System.out.println("发布通道 => " + key + ", 发送值 => " + value);
|
System.out.println("发布通道 => " + key + ", 发送值 => " + value);
|
||||||
});
|
});
|
||||||
return AjaxResult.success("操作成功");
|
return AjaxResult.success("操作成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("订阅消息")
|
@ApiOperation("订阅消息")
|
||||||
@GetMapping("/sub")
|
@GetMapping("/sub")
|
||||||
public AjaxResult<Void> sub(String key){
|
public AjaxResult<Void> sub(@ApiParam("通道Key") String key) {
|
||||||
RedisUtils.subscribe(key, String.class, msg -> {
|
RedisUtils.subscribe(key, String.class, msg -> {
|
||||||
System.out.println("订阅通道 => " + key + ", 接收值 => " + msg);
|
System.out.println("订阅通道 => " + key + ", 接收值 => " + msg);
|
||||||
});
|
});
|
||||||
return AjaxResult.success("操作成功");
|
return AjaxResult.success("操作成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,37 +22,37 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RequestMapping("/demo/rateLimiter")
|
@RequestMapping("/demo/rateLimiter")
|
||||||
public class RedisRateLimiterController {
|
public class RedisRateLimiterController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试全局限流
|
* 测试全局限流
|
||||||
* 全局影响
|
* 全局影响
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试全局限流")
|
@ApiOperation("测试全局限流")
|
||||||
@RateLimiter(count = 2, time = 10)
|
@RateLimiter(count = 2, time = 10)
|
||||||
@GetMapping("/test")
|
@GetMapping("/test")
|
||||||
public AjaxResult<String> test(String value){
|
public AjaxResult<String> test(String value) {
|
||||||
return AjaxResult.success("操作成功",value);
|
return AjaxResult.success("操作成功", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试请求IP限流
|
* 测试请求IP限流
|
||||||
* 同一IP请求受影响
|
* 同一IP请求受影响
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试请求IP限流")
|
@ApiOperation("测试请求IP限流")
|
||||||
@RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
|
@RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
|
||||||
@GetMapping("/testip")
|
@GetMapping("/testip")
|
||||||
public AjaxResult<String> testip(String value){
|
public AjaxResult<String> testip(String value) {
|
||||||
return AjaxResult.success("操作成功",value);
|
return AjaxResult.success("操作成功", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试集群实例限流
|
* 测试集群实例限流
|
||||||
* 启动两个后端服务互不影响
|
* 启动两个后端服务互不影响
|
||||||
*/
|
*/
|
||||||
@ApiOperation("测试集群实例限流")
|
@ApiOperation("测试集群实例限流")
|
||||||
@RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
|
@RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
|
||||||
@GetMapping("/testcluster")
|
@GetMapping("/testcluster")
|
||||||
public AjaxResult<String> testcluster(String value){
|
public AjaxResult<String> testcluster(String value) {
|
||||||
return AjaxResult.success("操作成功",value);
|
return AjaxResult.success("操作成功", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,18 +21,18 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
@RequestMapping("/swagger/demo")
|
@RequestMapping("/swagger/demo")
|
||||||
public class Swagger3DemoController {
|
public class Swagger3DemoController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传请求
|
* 上传请求
|
||||||
* 必须使用 @RequestPart 注解标注为文件
|
* 必须使用 @RequestPart 注解标注为文件
|
||||||
* dataType 必须为 "java.io.File"
|
* dataType 必须为 "java.io.File"
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "通用上传请求")
|
@ApiOperation(value = "通用上传请求")
|
||||||
@ApiImplicitParams({
|
@ApiImplicitParams({
|
||||||
@ApiImplicitParam(name = "file", value = "文件", dataType = "java.io.File", required = true),
|
@ApiImplicitParam(name = "file", value = "文件", dataType = "java.io.File", required = true),
|
||||||
})
|
})
|
||||||
@PostMapping(value = "/upload")
|
@PostMapping(value = "/upload")
|
||||||
public AjaxResult<String> upload(@RequestPart("file") MultipartFile file) {
|
public AjaxResult<String> upload(@RequestPart("file") MultipartFile file) {
|
||||||
return AjaxResult.success("操作成功", file.getOriginalFilename());
|
return AjaxResult.success("操作成功", file.getOriginalFilename());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,48 +34,48 @@ public class TestBatchController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 新增批量方法 可完美替代 saveBatch 秒级插入上万数据 (对mysql负荷较大)
|
* 新增批量方法 可完美替代 saveBatch 秒级插入上万数据 (对mysql负荷较大)
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "新增批量方法")
|
@ApiOperation(value = "新增批量方法")
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
// @DataSource(DataSourceType.SLAVE)
|
// @DataSource(DataSourceType.SLAVE)
|
||||||
public AjaxResult<Void> add() {
|
public AjaxResult<Void> add() {
|
||||||
List<TestDemo> list = new ArrayList<>();
|
List<TestDemo> list = new ArrayList<>();
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
list.add(new TestDemo().setOrderNum(-1L).setTestKey("批量新增").setValue("测试新增"));
|
list.add(new TestDemo().setOrderNum(-1L).setTestKey("批量新增").setValue("测试新增"));
|
||||||
}
|
}
|
||||||
return toAjax(iTestDemoService.saveAll(list) ? 1 : 0);
|
return toAjax(iTestDemoService.saveAll(list) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增或更新 可完美替代 saveOrUpdateBatch 高性能
|
* 新增或更新 可完美替代 saveOrUpdateBatch 高性能
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "新增或更新批量方法")
|
@ApiOperation(value = "新增或更新批量方法")
|
||||||
@PostMapping("/addOrUpdate")
|
@PostMapping("/addOrUpdate")
|
||||||
// @DataSource(DataSourceType.SLAVE)
|
// @DataSource(DataSourceType.SLAVE)
|
||||||
public AjaxResult<Void> addOrUpdate() {
|
public AjaxResult<Void> addOrUpdate() {
|
||||||
List<TestDemo> list = new ArrayList<>();
|
List<TestDemo> list = new ArrayList<>();
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
list.add(new TestDemo().setOrderNum(-1L).setTestKey("批量新增").setValue("测试新增"));
|
list.add(new TestDemo().setOrderNum(-1L).setTestKey("批量新增").setValue("测试新增"));
|
||||||
}
|
}
|
||||||
iTestDemoService.saveAll(list);
|
iTestDemoService.saveAll(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);
|
||||||
testDemo.setTestKey("批量新增或修改").setValue("批量新增或修改");
|
testDemo.setTestKey("批量新增或修改").setValue("批量新增或修改");
|
||||||
if (i % 2 == 0) {
|
if (i % 2 == 0) {
|
||||||
testDemo.setId(null);
|
testDemo.setId(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return toAjax(iTestDemoService.saveOrUpdateAll(list) ? 1 : 0);
|
return toAjax(iTestDemoService.saveOrUpdateAll(list) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除批量方法
|
* 删除批量方法
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "删除批量方法")
|
@ApiOperation(value = "删除批量方法")
|
||||||
@DeleteMapping()
|
@DeleteMapping()
|
||||||
// @DataSource(DataSourceType.SLAVE)
|
// @DataSource(DataSourceType.SLAVE)
|
||||||
public AjaxResult<Void> remove() {
|
public AjaxResult<Void> remove() {
|
||||||
return toAjax(iTestDemoService.remove(new LambdaQueryWrapper<TestDemo>()
|
return toAjax(iTestDemoService.remove(new LambdaQueryWrapper<TestDemo>()
|
||||||
.eq(TestDemo::getOrderNum, -1L)) ? 1 : 0);
|
.eq(TestDemo::getOrderNum, -1L)) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.demo.controller;
|
package com.ruoyi.demo.controller;
|
||||||
|
|
||||||
|
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;
|
||||||
@ -9,17 +10,21 @@ import com.ruoyi.common.core.validate.AddGroup;
|
|||||||
import com.ruoyi.common.core.validate.EditGroup;
|
import com.ruoyi.common.core.validate.EditGroup;
|
||||||
import com.ruoyi.common.core.validate.QueryGroup;
|
import com.ruoyi.common.core.validate.QueryGroup;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.common.utils.ValidatorUtils;
|
||||||
|
import com.ruoyi.common.excel.ExcelResult;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.demo.domain.TestDemo;
|
||||||
import com.ruoyi.demo.domain.bo.TestDemoBo;
|
import com.ruoyi.demo.domain.bo.TestDemoBo;
|
||||||
|
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.Api;
|
import io.swagger.annotations.*;
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
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 javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
@ -53,30 +58,45 @@ public class TestDemoController extends BaseController {
|
|||||||
return iTestDemoService.queryPageList(bo);
|
return iTestDemoService.queryPageList(bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义分页查询
|
* 自定义分页查询
|
||||||
*/
|
*/
|
||||||
@ApiOperation("自定义分页查询")
|
@ApiOperation("自定义分页查询")
|
||||||
@PreAuthorize("@ss.hasPermi('demo:demo:list')")
|
@PreAuthorize("@ss.hasPermi('demo:demo:list')")
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
public TableDataInfo<TestDemoVo> page(@Validated(QueryGroup.class) TestDemoBo bo) {
|
public TableDataInfo<TestDemoVo> page(@Validated(QueryGroup.class) TestDemoBo bo) {
|
||||||
return iTestDemoService.customPageList(bo);
|
return iTestDemoService.customPageList(bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@ApiOperation("导入测试-校验")
|
||||||
|
@ApiImplicitParams({
|
||||||
|
@ApiImplicitParam(name = "file", value = "导入文件", dataType = "java.io.File", required = true),
|
||||||
|
})
|
||||||
|
@Log(title = "测试单表", businessType = BusinessType.IMPORT)
|
||||||
|
@PreAuthorize("@ss.hasPermi('demo:demo:import')")
|
||||||
|
@PostMapping("/importData")
|
||||||
|
public AjaxResult<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
|
||||||
|
ExcelResult<TestDemoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true);
|
||||||
|
List<TestDemoImportVo> volist = excelResult.getList();
|
||||||
|
List<TestDemo> list = BeanUtil.copyToList(volist, TestDemo.class);
|
||||||
|
iTestDemoService.saveAll(list);
|
||||||
|
return AjaxResult.success(excelResult.getAnalysis());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* 导出测试单表列表
|
* 导出测试单表列表
|
||||||
*/
|
*/
|
||||||
@ApiOperation("导出测试单表列表")
|
@ApiOperation("导出测试单表列表")
|
||||||
@PreAuthorize("@ss.hasPermi('demo:demo:export')")
|
@PreAuthorize("@ss.hasPermi('demo:demo:export')")
|
||||||
@Log(title = "测试单表", businessType = BusinessType.EXPORT)
|
@Log(title = "测试单表", businessType = BusinessType.EXPORT)
|
||||||
@GetMapping("/export")
|
@PostMapping("/export")
|
||||||
public void export(@Validated TestDemoBo bo, HttpServletResponse response) {
|
public void export(@Validated TestDemoBo bo, HttpServletResponse response) {
|
||||||
List<TestDemoVo> list = iTestDemoService.queryList(bo);
|
List<TestDemoVo> list = iTestDemoService.queryList(bo);
|
||||||
// 测试雪花id导出
|
// 测试雪花id导出
|
||||||
// for (TestDemoVo vo : list) {
|
// for (TestDemoVo vo : list) {
|
||||||
// vo.setId(1234567891234567893L);
|
// vo.setId(1234567891234567893L);
|
||||||
// }
|
// }
|
||||||
ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response);
|
ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,8 +105,9 @@ public class TestDemoController extends BaseController {
|
|||||||
@ApiOperation("获取测试单表详细信息")
|
@ApiOperation("获取测试单表详细信息")
|
||||||
@PreAuthorize("@ss.hasPermi('demo:demo:query')")
|
@PreAuthorize("@ss.hasPermi('demo:demo:query')")
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public AjaxResult<TestDemoVo> getInfo(@NotNull(message = "主键不能为空")
|
public AjaxResult<TestDemoVo> getInfo(@ApiParam("测试ID")
|
||||||
@PathVariable("id") Long id) {
|
@NotNull(message = "主键不能为空")
|
||||||
|
@PathVariable("id") Long id) {
|
||||||
return AjaxResult.success(iTestDemoService.queryById(id));
|
return AjaxResult.success(iTestDemoService.queryById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +119,10 @@ public class TestDemoController extends BaseController {
|
|||||||
@Log(title = "测试单表", businessType = BusinessType.INSERT)
|
@Log(title = "测试单表", businessType = BusinessType.INSERT)
|
||||||
@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "不允许重复提交")
|
@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "不允许重复提交")
|
||||||
@PostMapping()
|
@PostMapping()
|
||||||
public AjaxResult<Void> add(@Validated(AddGroup.class) @RequestBody TestDemoBo bo) {
|
public AjaxResult<Void> add(@RequestBody TestDemoBo bo) {
|
||||||
|
// 使用校验工具对标 @Validated(AddGroup.class) 注解
|
||||||
|
// 用于在非 Controller 的地方校验对象
|
||||||
|
ValidatorUtils.validate(bo, AddGroup.class);
|
||||||
return toAjax(iTestDemoService.insertByBo(bo) ? 1 : 0);
|
return toAjax(iTestDemoService.insertByBo(bo) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,10 +143,11 @@ public class TestDemoController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@ApiOperation("删除测试单表")
|
@ApiOperation("删除测试单表")
|
||||||
@PreAuthorize("@ss.hasPermi('demo:demo:remove')")
|
@PreAuthorize("@ss.hasPermi('demo:demo:remove')")
|
||||||
@Log(title = "测试单表" , businessType = BusinessType.DELETE)
|
@Log(title = "测试单表", businessType = BusinessType.DELETE)
|
||||||
@DeleteMapping("/{ids}")
|
@DeleteMapping("/{ids}")
|
||||||
public AjaxResult<Void> remove(@NotEmpty(message = "主键不能为空")
|
public AjaxResult<Void> remove(@ApiParam("测试ID串")
|
||||||
@PathVariable Long[] ids) {
|
@NotEmpty(message = "主键不能为空")
|
||||||
|
@PathVariable Long[] ids) {
|
||||||
return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
|
return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,24 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
|||||||
import com.ruoyi.common.utils.MessageUtils;
|
import com.ruoyi.common.utils.MessageUtils;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.annotations.ApiParam;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.hibernate.validator.constraints.Range;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
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;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试国际化
|
* 测试国际化
|
||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
|
@Validated
|
||||||
@Api(value = "测试国际化控制器", tags = {"测试国际化管理"})
|
@Api(value = "测试国际化控制器", tags = {"测试国际化管理"})
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/i18n")
|
@RequestMapping("/demo/i18n")
|
||||||
@ -27,7 +35,42 @@ public class TestI18nController {
|
|||||||
*/
|
*/
|
||||||
@ApiOperation("通过code获取国际化内容")
|
@ApiOperation("通过code获取国际化内容")
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public AjaxResult<Void> get(String code) {
|
public AjaxResult<Void> get(@ApiParam("国际化code") String code) {
|
||||||
return AjaxResult.success(MessageUtils.message(code));
|
return AjaxResult.success(MessageUtils.message(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validator 校验国际化
|
||||||
|
* 不传值 分别查看异常返回
|
||||||
|
*
|
||||||
|
* 测试使用 not.null
|
||||||
|
*/
|
||||||
|
@ApiOperation("Validator 校验国际化")
|
||||||
|
@GetMapping("/test1")
|
||||||
|
public AjaxResult<Void> test1(@NotBlank(message = "{not.null}") String str) {
|
||||||
|
return AjaxResult.success(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean 校验国际化
|
||||||
|
* 不传值 分别查看异常返回
|
||||||
|
*
|
||||||
|
* 测试使用 not.null
|
||||||
|
*/
|
||||||
|
@ApiOperation("Bean 校验国际化")
|
||||||
|
@GetMapping("/test2")
|
||||||
|
public AjaxResult<TestI18nBo> test2(@Validated TestI18nBo bo) {
|
||||||
|
return AjaxResult.success(bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class TestI18nBo {
|
||||||
|
|
||||||
|
@NotBlank(message = "{not.null}")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@NotNull(message = "{not.null}")
|
||||||
|
@Range(min = 0, max = 100, message = "{length.not.valid}")
|
||||||
|
private Integer age;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import com.ruoyi.demo.domain.vo.TestTreeVo;
|
|||||||
import com.ruoyi.demo.service.ITestTreeService;
|
import com.ruoyi.demo.service.ITestTreeService;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.annotations.ApiParam;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
@ -61,7 +62,7 @@ public class TestTreeController extends BaseController {
|
|||||||
@GetMapping("/export")
|
@GetMapping("/export")
|
||||||
public void export(@Validated TestTreeBo bo, HttpServletResponse response) {
|
public void export(@Validated TestTreeBo bo, HttpServletResponse response) {
|
||||||
List<TestTreeVo> list = iTestTreeService.queryList(bo);
|
List<TestTreeVo> list = iTestTreeService.queryList(bo);
|
||||||
ExcelUtil.exportExcel(list, "测试树表", TestTreeVo.class, response);
|
ExcelUtil.exportExcel(list, "测试树表", TestTreeVo.class, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,8 +71,9 @@ public class TestTreeController extends BaseController {
|
|||||||
@ApiOperation("获取测试树表详细信息")
|
@ApiOperation("获取测试树表详细信息")
|
||||||
@PreAuthorize("@ss.hasPermi('demo:tree:query')")
|
@PreAuthorize("@ss.hasPermi('demo:tree:query')")
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public AjaxResult<TestTreeVo> getInfo(@NotNull(message = "主键不能为空")
|
public AjaxResult<TestTreeVo> getInfo(@ApiParam("测试树ID")
|
||||||
@PathVariable("id") Long id) {
|
@NotNull(message = "主键不能为空")
|
||||||
|
@PathVariable("id") Long id) {
|
||||||
return AjaxResult.success(iTestTreeService.queryById(id));
|
return AjaxResult.success(iTestTreeService.queryById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +106,11 @@ public class TestTreeController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@ApiOperation("删除测试树表")
|
@ApiOperation("删除测试树表")
|
||||||
@PreAuthorize("@ss.hasPermi('demo:tree:remove')")
|
@PreAuthorize("@ss.hasPermi('demo:tree:remove')")
|
||||||
@Log(title = "测试树表" , businessType = BusinessType.DELETE)
|
@Log(title = "测试树表", businessType = BusinessType.DELETE)
|
||||||
@DeleteMapping("/{ids}")
|
@DeleteMapping("/{ids}")
|
||||||
public AjaxResult<Void> remove(@NotEmpty(message = "主键不能为空")
|
public AjaxResult<Void> remove(@ApiParam("测试树ID串")
|
||||||
@PathVariable Long[] ids) {
|
@NotEmpty(message = "主键不能为空")
|
||||||
|
@PathVariable Long[] ids) {
|
||||||
return toAjax(iTestTreeService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
|
return toAjax(iTestTreeService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
package com.ruoyi.demo.feign;
|
|
||||||
|
|
||||||
import com.ruoyi.demo.feign.constant.FeignTestConstant;
|
|
||||||
import com.ruoyi.demo.feign.fallback.FeignTestFallback;
|
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* feign测试service
|
|
||||||
* 规范接口 Service 无感调用
|
|
||||||
* 常量管理请求路径 更加规范
|
|
||||||
* 自定义容错处理 安全可靠 (需自行配置熔断器)
|
|
||||||
* 增加 feign 的目的为使 http 请求接口化
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
* @deprecated 由于使用人数较少 决定与 3.4.0 版本移除
|
|
||||||
*/
|
|
||||||
@FeignClient(
|
|
||||||
name = FeignTestConstant.BAIDU_NAME,
|
|
||||||
url = FeignTestConstant.BAIDU_URL,
|
|
||||||
fallback = FeignTestFallback.class)
|
|
||||||
public interface FeignTestService {
|
|
||||||
|
|
||||||
@GetMapping("/s")
|
|
||||||
String search(@RequestParam("wd") String wd);
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package com.ruoyi.demo.feign.constant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated 由于使用人数较少 决定与 3.4.0 版本移除
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class FeignTestConstant {
|
|
||||||
|
|
||||||
public static final String BAIDU_NAME = "baidu";
|
|
||||||
|
|
||||||
public static final String BAIDU_URL = "http://www.baidu.com";
|
|
||||||
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package com.ruoyi.demo.feign.fallback;
|
|
||||||
|
|
||||||
|
|
||||||
import com.ruoyi.demo.feign.FeignTestService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* feign测试fallback
|
|
||||||
* 自定义封装结构体熔断
|
|
||||||
* 需重写解码器 根据自定义实体 自行解析熔断
|
|
||||||
*
|
|
||||||
* 熔断器需要自行添加配置
|
|
||||||
*
|
|
||||||
* @see {com.ruoyi.framework.config.FeignConfig#errorDecoder()}
|
|
||||||
* @author Lion Li
|
|
||||||
* @deprecated 由于使用人数较少 决定与 3.4.0 版本移除
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class FeignTestFallback implements FeignTestService {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String search(String wd) {
|
|
||||||
log.error("fallback");
|
|
||||||
return "报错啦";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
package com.ruoyi.demo.feign.fallback;
|
|
@ -1 +0,0 @@
|
|||||||
package com.ruoyi.demo.feign;
|
|
@ -2,11 +2,9 @@ package com.ruoyi.demo.mapper;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.common.core.mybatisplus.cache.MybatisPlusRedisCache;
|
|
||||||
import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
|
import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
|
||||||
import com.ruoyi.demo.domain.TestDemo;
|
import com.ruoyi.demo.domain.TestDemo;
|
||||||
import com.ruoyi.demo.domain.vo.TestDemoVo;
|
import com.ruoyi.demo.domain.vo.TestDemoVo;
|
||||||
import org.apache.ibatis.annotations.CacheNamespace;
|
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,8 +13,6 @@ import org.apache.ibatis.annotations.Param;
|
|||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
* @date 2021-07-26
|
* @date 2021-07-26
|
||||||
*/
|
*/
|
||||||
// 如使需切换数据源 请勿使用缓存 会造成数据不一致现象
|
|
||||||
@CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
|
|
||||||
public interface TestDemoMapper extends BaseMapperPlus<TestDemo> {
|
public interface TestDemoMapper extends BaseMapperPlus<TestDemo> {
|
||||||
|
|
||||||
Page<TestDemoVo> customPageList(@Param("page") Page<TestDemo> page, @Param("ew") Wrapper<TestDemo> wrapper);
|
Page<TestDemoVo> customPageList(@Param("page") Page<TestDemo> page, @Param("ew") Wrapper<TestDemo> wrapper);
|
||||||
|
@ -5,9 +5,11 @@ import com.ruoyi.common.core.domain.BaseEntity;
|
|||||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
|
import com.ruoyi.common.core.service.UserService;
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.reflect.ReflectUtils;
|
import com.ruoyi.common.utils.reflect.ReflectUtils;
|
||||||
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.JoinPoint;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
import org.aspectj.lang.annotation.Before;
|
import org.aspectj.lang.annotation.Before;
|
||||||
@ -64,8 +66,8 @@ public class DataScopeAspect {
|
|||||||
// 获取当前的用户
|
// 获取当前的用户
|
||||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||||
if (StringUtils.isNotNull(loginUser)) {
|
if (StringUtils.isNotNull(loginUser)) {
|
||||||
SysUser currentUser = loginUser.getUser();
|
SysUser currentUser = SpringUtils.getBean(UserService.class).selectUserById(loginUser.getUserId());
|
||||||
// 如果是超级管理员,则不过滤数据
|
// 如果是超级管理员,则不过滤数据
|
||||||
if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) {
|
if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) {
|
||||||
dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
|
dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
|
||||||
controllerDataScope.userAlias(), controllerDataScope.isUser());
|
controllerDataScope.userAlias(), controllerDataScope.isUser());
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package com.ruoyi.framework.aspectj;
|
package com.ruoyi.framework.aspectj;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.crypto.SecureUtil;
|
import cn.hutool.crypto.SecureUtil;
|
||||||
import com.baomidou.lock.LockInfo;
|
|
||||||
import com.baomidou.lock.LockTemplate;
|
|
||||||
import com.ruoyi.common.annotation.RepeatSubmit;
|
import com.ruoyi.common.annotation.RepeatSubmit;
|
||||||
import com.ruoyi.common.constant.Constants;
|
import com.ruoyi.common.constant.Constants;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.properties.TokenProperties;
|
import com.ruoyi.common.properties.TokenProperties;
|
||||||
|
import com.ruoyi.common.utils.JsonUtils;
|
||||||
|
import com.ruoyi.common.utils.RedisUtils;
|
||||||
import com.ruoyi.common.utils.ServletUtils;
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.framework.config.properties.RepeatSubmitProperties;
|
import com.ruoyi.framework.config.properties.RepeatSubmitProperties;
|
||||||
@ -18,8 +17,14 @@ import org.aspectj.lang.annotation.Aspect;
|
|||||||
import org.aspectj.lang.annotation.Before;
|
import org.aspectj.lang.annotation.Before;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 防止重复提交
|
* 防止重复提交
|
||||||
@ -34,7 +39,6 @@ public class RepeatSubmitAspect {
|
|||||||
|
|
||||||
private final TokenProperties tokenProperties;
|
private final TokenProperties tokenProperties;
|
||||||
private final RepeatSubmitProperties repeatSubmitProperties;
|
private final RepeatSubmitProperties repeatSubmitProperties;
|
||||||
private final LockTemplate lockTemplate;
|
|
||||||
|
|
||||||
@Before("@annotation(repeatSubmit)")
|
@Before("@annotation(repeatSubmit)")
|
||||||
public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable {
|
public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable {
|
||||||
@ -47,7 +51,7 @@ public class RepeatSubmitAspect {
|
|||||||
throw new ServiceException("重复提交间隔时间不能小于'1'秒");
|
throw new ServiceException("重复提交间隔时间不能小于'1'秒");
|
||||||
}
|
}
|
||||||
HttpServletRequest request = ServletUtils.getRequest();
|
HttpServletRequest request = ServletUtils.getRequest();
|
||||||
String nowParams = StrUtil.join(",", point.getArgs());
|
String nowParams = argsArrayToString(point.getArgs());
|
||||||
|
|
||||||
// 请求地址(作为存放cache的key值)
|
// 请求地址(作为存放cache的key值)
|
||||||
String url = request.getRequestURI();
|
String url = request.getRequestURI();
|
||||||
@ -60,10 +64,58 @@ public class RepeatSubmitAspect {
|
|||||||
submitKey = SecureUtil.md5(submitKey + ":" + nowParams);
|
submitKey = SecureUtil.md5(submitKey + ":" + nowParams);
|
||||||
// 唯一标识(指定key + 消息头)
|
// 唯一标识(指定key + 消息头)
|
||||||
String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey;
|
String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey;
|
||||||
LockInfo lock = lockTemplate.lock(cacheRepeatKey, interval, interval / 2);
|
String key = RedisUtils.getCacheObject(cacheRepeatKey);
|
||||||
if (lock == null) {
|
if (key == null) {
|
||||||
|
RedisUtils.setCacheObject(cacheRepeatKey, "", interval, TimeUnit.MILLISECONDS);
|
||||||
|
} else {
|
||||||
throw new ServiceException(repeatSubmit.message());
|
throw new ServiceException(repeatSubmit.message());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数拼装
|
||||||
|
*/
|
||||||
|
private String argsArrayToString(Object[] paramsArray) {
|
||||||
|
StringBuilder params = new StringBuilder();
|
||||||
|
if (paramsArray != null && paramsArray.length > 0) {
|
||||||
|
for (Object o : paramsArray) {
|
||||||
|
if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
|
||||||
|
try {
|
||||||
|
params.append(JsonUtils.toJsonString(o)).append(" ");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否需要过滤的对象。
|
||||||
|
*
|
||||||
|
* @param o 对象信息。
|
||||||
|
* @return 如果是需要过滤的对象,则返回true;否则返回false。
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public boolean isFilterObject(final Object o) {
|
||||||
|
Class<?> clazz = o.getClass();
|
||||||
|
if (clazz.isArray()) {
|
||||||
|
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
|
||||||
|
} else if (Collection.class.isAssignableFrom(clazz)) {
|
||||||
|
Collection collection = (Collection) o;
|
||||||
|
for (Object value : collection) {
|
||||||
|
return value instanceof MultipartFile;
|
||||||
|
}
|
||||||
|
} else if (Map.class.isAssignableFrom(clazz)) {
|
||||||
|
Map map = (Map) o;
|
||||||
|
for (Object value : map.entrySet()) {
|
||||||
|
Map.Entry entry = (Map.Entry) value;
|
||||||
|
return entry.getValue() instanceof MultipartFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
|
||||||
|
|| o instanceof BindingResult;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
package com.ruoyi.framework.config;
|
|
||||||
|
|
||||||
import feign.*;
|
|
||||||
import okhttp3.ConnectionPool;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
|
||||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
|
||||||
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
|
|
||||||
import org.springframework.cloud.openfeign.support.SpringMvcContract;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* openfeign配置类
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
* @deprecated 由于使用人数较少 决定与 3.4.0 版本移除
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@EnableFeignClients("${feign.package}")
|
|
||||||
@Configuration
|
|
||||||
@ConditionalOnClass(Feign.class)
|
|
||||||
@AutoConfigureBefore(FeignAutoConfiguration.class)
|
|
||||||
public class FeignConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public OkHttpClient okHttpClient(){
|
|
||||||
return new OkHttpClient.Builder()
|
|
||||||
.readTimeout(60, TimeUnit.SECONDS)
|
|
||||||
.connectTimeout(60, TimeUnit.SECONDS)
|
|
||||||
.writeTimeout(120, TimeUnit.SECONDS)
|
|
||||||
.connectionPool(new ConnectionPool())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Contract feignContract() {
|
|
||||||
return new SpringMvcContract();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Logger.Level feignLoggerLevel() {
|
|
||||||
return Logger.Level.BASIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Request.Options feignRequestOptions() {
|
|
||||||
return new Request.Options(10, TimeUnit.SECONDS, 60,TimeUnit.SECONDS,true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Retryer feignRetry() {
|
|
||||||
return new Retryer.Default();
|
|
||||||
}
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * 自定义异常解码器
|
|
||||||
// * 用于自定义返回体异常熔断
|
|
||||||
// */
|
|
||||||
// @Bean
|
|
||||||
// public ErrorDecoder errorDecoder() {
|
|
||||||
// return new CustomErrorDecoder();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 自定义返回体解码器
|
|
||||||
// */
|
|
||||||
// @Slf4j
|
|
||||||
// public static class CustomErrorDecoder implements ErrorDecoder {
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Exception decode(String methodKey, Response response) {
|
|
||||||
// Exception exception = null;
|
|
||||||
// try {
|
|
||||||
// // 获取原始的返回内容
|
|
||||||
// String json = JsonUtils.toJsonString(response.body().asReader(StandardCharsets.UTF_8));
|
|
||||||
// exception = new RuntimeException(json);
|
|
||||||
// // 将返回内容反序列化为Result,这里应根据自身项目作修改
|
|
||||||
// AjaxResult result = JsonUtils.parseObject(json, AjaxResult.class);
|
|
||||||
// // 业务异常抛出简单的 RuntimeException,保留原来错误信息
|
|
||||||
// if (result.getCode() != 200) {
|
|
||||||
// exception = new RuntimeException(result.getMsg());
|
|
||||||
// }
|
|
||||||
// } catch (IOException e) {
|
|
||||||
// log.error(e.getMessage(), e);
|
|
||||||
// }
|
|
||||||
// return exception;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
@ -20,7 +20,6 @@ import java.util.Map;
|
|||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
|
|
||||||
public class FilterConfig {
|
public class FilterConfig {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -28,6 +27,7 @@ public class FilterConfig {
|
|||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
@Bean
|
@Bean
|
||||||
|
@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
|
||||||
public FilterRegistrationBean xssFilterRegistration() {
|
public FilterRegistrationBean xssFilterRegistration() {
|
||||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||||
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user