发布 v3.2.0

This commit is contained in:
疯狂的狮子li 2021-09-28 10:09:53 +08:00
parent 242a74a8ae
commit 9351cc4426
163 changed files with 2849 additions and 3436 deletions

150
README.md
View File

@ -4,39 +4,45 @@
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE) [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
[![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
<br> <br>
[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-3.1.0-success.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus) [![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-3.2.0-success.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.5-blue.svg)]() [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.5-blue.svg)]()
[![JDK-8+](https://img.shields.io/badge/JDK-8+-green.svg)]() [![JDK-8+](https://img.shields.io/badge/JDK-8-green.svg)]()
[![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]() [![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]()
[![JDK-17](https://img.shields.io/badge/JDK-17-green.svg)]()
RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级 定期与 RuoYi-Vue 同步 RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级(不兼容原框架)
集成 Lock4j dynamic-datasource OSS存储 等分布式场景解决方案 | 功能介绍 | 使用技术 | 文档地址 | 特性注意事项 |
|---|---|---|---|
集成 Mybatis-Plus Lombok Hutool 等便捷开发工具 适配重写相关业务 便于开发 | 当前框架 | 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重构权限鉴权(仅供学习不推荐上生产) |
* 前端开发框架 Vue、Element UI | 单体分支 | RuoYi-Vue-Plus-fast | [fast分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) | 单体应用结构 |
* 后端开发框架 Spring Boot、Redis | 原框架 | RuoYi-Vue | [RuoYi-Vue官网](http://ruoyi.vip/) | 定期同步需要的功能 |
* 容器框架 Undertow 基于 Netty 的高性能容器 | 前端开发框架 | Vue、Element UI | [Element UI官网](https://element.eleme.cn/#/zh-CN) | |
* 权限认证框架 Spring Security、Jwt支持多终端认证系统 | 后端开发框架 | SpringBoot | [SpringBoot官网](https://spring.io/projects/spring-boot/#learn) | |
* 关系数据库 MySQL 适配 8.X | 容器框架 | Undertow | [Undertow官网](https://undertow.io/) | 基于 Netty 的高性能容器 |
* 缓存数据库 Redis 适配 6.X | 权限认证框架 | Spring Security、Jwt | [SpringSecurity官网](https://spring.io/projects/spring-security#learn) | 支持多终端认证系统 |
* 数据库框架 Mybatis-Plus 快速 CRUD 增加开发效率 插件化支持各类需求 | 关系数据库 | MySQL | [MySQL官网](https://dev.mysql.com/) | 适配 8.X 最低 5.7 |
* 数据库框架 多数据源框架 dynamic-datasource 支持主从与多种类数据库异构 | 缓存数据库 | Redis | [Redis官网](https://redis.io/) | 适配 6.X 最低 4.X |
* 数据库框架 Redis客户端 采用 Redisson 性能更强 | 数据库框架 | Mybatis-Plus | [Mybatis-Plus文档](https://baomidou.com/guide/) | 快速 CRUD 增加开发效率 |
* 数据库框架 性能分析插件 p6spy 更强劲的 SQL 分析 | 数据库框架 | p6spy | [p6spy官网](https://p6spy.readthedocs.io/) | 更强劲的 SQL 分析 |
* 序列化框架 统一使用 jackson 高效可靠 | 多数据源框架 | dynamic-datasource | [dynamic-ds文档](https://www.kancloud.cn/tracy5546/dynamic-datasource/content) | 支持主从与多种类数据库异构 |
* 网络框架 Feign、OkHttp3 接口化管理 HTTP 请求 | 序列化框架 | Jackson | [Jackson官网](https://github.com/FasterXML/jackson) | 统一使用 jackson 高效可靠 |
* 分布式锁 Lock4j 注解锁、工具锁 多种多样 | 网络框架 | Feign、OkHttp3 | [Feign官网](https://github.com/OpenFeign/feign) | 接口化管理 HTTP 请求 |
* 文件存储 OSS 对象存储模块 支持(Minio、七牛、阿里、腾讯) | Redis客户端 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 支持单机、集群配置 |
* 监控框架 spring-boot-admin 全方位服务监控 | 分布式限流 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 全局、请求IP、集群ID 多种限流 |
* 校验框架 validation 增强接口安全性 严谨性 | 分布式锁 | Lock4j | [Lock4j官网](https://gitee.com/baomidou/lock4j) | 注解锁、工具锁 多种多样 |
* Excel框架 Alibaba EasyExcel 性能优异 扩展性强 | 分布式幂等 | Lock4j | [Lock4j文档](https://gitee.com/baomidou/lock4j) | 基于分布式锁实现 |
* 文档框架 knife4j 美化接口文档 | 文件存储 | Minio | [Minio文档](https://docs.min.io/) | 本地存储 |
* 工具类框架 Hutool、Lombok 减少代码冗余 增加安全性 | 文件存储 | 七牛、阿里、腾讯 | [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/) | 全方位服务监控 |
* 部署方式 Docker 容器编排 一键部署业务集群 | 校验框架 | Validation | [Validation文档](https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/) | 增强接口安全性、严谨性 |
* 国际化 Spring 标准国际化方解决方案 | Excel框架 | Alibaba EasyExcel | [EasyExcel文档](https://www.yuque.com/easyexcel/doc/easyexcel) | 性能优异 扩展性强 |
| 文档框架 | Knife4j | [Knife4j文档](https://doc.xiaominfo.com/knife4j/documentation/) | 美化接口文档 |
| 工具类框架 | Hutool、Lombok | [Hutool文档](https://www.hutool.cn/docs/) | 减少代码冗余 增加安全性 |
| 代码生成器 | 适配MP、Knife4j规范化代码 | [Hutool文档](https://www.hutool.cn/docs/) | 一键生成前后端代码 |
| 部署方式 | Docker | [Docker文档](https://docs.docker.com/) | 容器编排 一键部署业务集群 |
| 国际化 | SpringMessage | [SpringMVC文档](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc) | Spring标准国际化方案 |
## 参考文档 ## 参考文档
@ -61,46 +67,13 @@ RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级 定期
框架定位为 `通用后台管理系统(分布式集群强化)` 原则上不接受业务 `PR` 框架定位为 `通用后台管理系统(分布式集群强化)` 原则上不接受业务 `PR`
## 修改RuoYi功能
### 依赖改动
* ORM框架 使用 Mybatis-Plus 简化CRUD (不支持主子表)
* Bean简化 使用 Lombok 简化 get set toString 等等
* 容器改动 Tomcat 改为 并发性能更好的 undertow
* 移除 pagehelper 改为 Mybatis-Plus 分页
* 集成 p6spy 更强劲的 SQL 分析
* 升级 swagger 为 knife4j
* 集成 Hutool 5.X 并重写RuoYi部分功能
* 集成 Feign 接口化管理 Http 请求(如三方请求 支付,短信,推送等)
* 移除 自带服务监控 改为 spring-boot-admin 全方位监控
* 增加 demo 模块示例(给不会增加模块的小伙伴做参考)
* 增加 redisson 高性能 Redis 客户端
* 移除 fastjson 统一使用 jackson 序列化
* 集成 dynamic-datasource 多数据源(默认支持MySQL,其他种类需自行适配)
* 集成 Lock4j 实现分布式 注解锁、工具锁 多种多样
* 增加 Docker 容器编排 打包插件与部署脚本
* 移除 通用上传下载 改为 OSS对象存储 支持(Minio、七牛、阿里、腾讯)
* 移除 RuoYi自带 Excel 工具 改为 EasyExcel 工具
### 代码改动
* 所有原生功能使用 Mybatis-Plus 与 Lombok 重写
* 增加 IServicePlus 与 BaseMapperPlus 可自定义通用方法
* 代码生成模板 改为适配 Mybatis-Plus 的代码
* 代码生成模板 根据 Alibaba 代码规约 拆分出 VO、BO 等领域对象
* 代码生成模板 增加 文档注解 与 校验注解 简化通用操作
* 项目修改为 maven多环境配置
* 项目配置修改为 application.yml 统一管理
* 数据权限修改为 适配支持单表、多表
* 使用 redisson 实现 spring-cache 整合
* 增加 mybatis-plus 二级缓存 redis 存储
### 其他 ### 其他
* 同步升级 RuoYi-Vue * 同步升级 RuoYi-Vue
* GitHub 地址 [RuoYi-Vue-Plus-github](https://github.com/JavaLionLi/RuoYi-Vue-Plus) * GitHub 地址 [RuoYi-Vue-Plus-github](https://github.com/JavaLionLi/RuoYi-Vue-Plus)
* 单模块 fast 分支 [RuoYi-Vue-Plus-fast](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) * 单模块 fast 分支 [RuoYi-Vue-Plus-fast](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/)
* Oracle 模块 oracle 分支 [RuoYi-Vue-Plus-oracle](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/oracle/) * satoken 分支 [RuoYi-Vue-Plus-satoken](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/)
* 用户扩展项目 [扩展项目列表](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4478302&doc_id=1469725)
## 加群与捐献 ## 加群与捐献
>[加群与捐献](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/加群与捐献?sort_id=4104598) >[加群与捐献](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/加群与捐献?sort_id=4104598)
@ -111,26 +84,29 @@ RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级 定期
<img src="https://images.gitee.com/uploads/images/2021/0525/101654_451e4523_1766278.jpeg" width="300px" height="450px" /> <img src="https://images.gitee.com/uploads/images/2021/0525/101654_451e4523_1766278.jpeg" width="300px" height="450px" />
<img src="https://images.gitee.com/uploads/images/2021/0525/101713_3d18b119_1766278.jpeg" width="300px" height="450px" /> <img src="https://images.gitee.com/uploads/images/2021/0525/101713_3d18b119_1766278.jpeg" width="300px" height="450px" />
## 内置功能 ## 业务功能
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 | 功能 | 介绍 |
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 |---|---|
3. 岗位管理:配置系统用户所属担任职务。 | 用户管理 | 用户是系统操作者,该功能主要完成系统用户配置。 |
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 | 部门管理 | 配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 |
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 | 岗位管理 | 配置系统用户所属担任职务。 |
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。 | 菜单管理 | 配置系统菜单,操作权限,按钮权限标识等。 |
7. 参数管理:对系统动态配置常用参数。 | 角色管理 | 角色菜单权限分配、设置角色按机构进行数据范围权限划分。 |
8. 通知公告:系统通知公告信息发布维护。 | 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护。 |
9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 | 参数管理 | 对系统动态配置常用参数。 |
10. 登录日志:系统登录日志记录查询包含登录异常。 | 通知公告 | 系统通知公告信息发布维护。 |
11. 在线用户:当前系统中活跃用户状态监控。 | 操作日志 | 系统正常操作日志记录和查询;系统异常信息日志记录和查询。 |
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 | 登录日志 | 系统登录日志记录查询包含登录异常。 |
13. 代码生成前后端代码的生成java、html、xml、sql支持CRUD下载 。 | 文件管理 | 系统文件上传、下载等管理。 |
14. 系统接口根据业务代码自动生成相关的api接口文档。 | 定时任务 | 在线(添加、修改、删除)任务调度包含执行结果日志。 |
15. 服务监控监视当前系统CPU、内存、磁盘、堆栈等相关信息。 | 代码生成 | 前后端代码的生成java、html、xml、sql支持CRUD下载 。 |
16. 缓存监控:对系统的缓存信息查询,命令统计等。 | 系统接口 | 根据业务代码自动生成相关的api接口文档。 |
17. 在线构建器拖动表单元素生成相应的HTML代码。 | 服务监控 | 监视集群系统CPU、内存、磁盘、堆栈、在线日志、Spring相关配置等。 |
18. 连接池监视监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。 | 缓存监控 | 对系统的缓存信息查询,命令统计等。 |
| 在线构建器 | 拖动表单元素生成相应的HTML代码。 |
| 连接池监视 | 监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。 |
| 使用案例 | 系统的一些功能案例 |
## 演示图例 ## 演示图例
@ -172,11 +148,3 @@ RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级 定期
</tr> </tr>
</tbody> </tbody>
</table> </table>
## 在线体验
- admin/admin123
- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
演示地址http://vue.ruoyi.vip
文档地址http://doc.ruoyi.vip

View File

@ -103,7 +103,7 @@ services:
ipv4_address: 172.30.0.54 ipv4_address: 172.30.0.54
ruoyi-server1: ruoyi-server1:
image: "ruoyi/ruoyi-server:3.1.0" image: "ruoyi/ruoyi-server:3.2.0"
container_name: ruoyi-server1 container_name: ruoyi-server1
environment: environment:
# 时区上海 # 时区上海
@ -118,7 +118,7 @@ services:
ipv4_address: 172.30.0.60 ipv4_address: 172.30.0.60
ruoyi-server2: ruoyi-server2:
image: "ruoyi/ruoyi-server:3.1.0" image: "ruoyi/ruoyi-server:3.2.0"
container_name: ruoyi-server2 container_name: ruoyi-server2
environment: environment:
# 时区上海 # 时区上海
@ -133,7 +133,7 @@ services:
ipv4_address: 172.30.0.61 ipv4_address: 172.30.0.61
ruoyi-monitor-admin: ruoyi-monitor-admin:
image: "ruoyi/ruoyi-monitor-admin:3.1.0" image: "ruoyi/ruoyi-monitor-admin:3.2.0"
container_name: ruoyi-monitor-admin container_name: ruoyi-monitor-admin
environment: environment:
# 时区上海 # 时区上海

96
pom.xml
View File

@ -6,40 +6,44 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<version>3.1.0</version> <version>3.2.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.1.0</ruoyi-vue-plus.version> <ruoyi-vue-plus.version>3.2.0</ruoyi-vue-plus.version>
<spring-boot.version>2.5.4</spring-boot.version> <spring-boot.version>2.5.5</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version> <maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
<druid.version>1.2.6</druid.version> <druid.version>1.2.6</druid.version>
<knife4j.version>3.0.3</knife4j.version> <knife4j.version>3.0.3</knife4j.version>
<swagger-annotations.version>1.5.22</swagger-annotations.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<easyexcel.version>2.2.10</easyexcel.version> <easyexcel.version>2.2.11</easyexcel.version>
<velocity.version>1.7</velocity.version> <velocity.version>1.7</velocity.version>
<jwt.version>0.9.1</jwt.version> <jwt.version>0.9.1</jwt.version>
<mybatis-plus.version>3.4.3.3</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.11</hutool.version> <hutool.version>5.7.13</hutool.version>
<feign.version>3.0.3</feign.version> <feign.version>3.0.3</feign.version>
<feign-okhttp.version>11.6</feign-okhttp.version> <feign-okhttp.version>11.6</feign-okhttp.version>
<okhttp.version>4.9.1</okhttp.version> <okhttp.version>4.9.1</okhttp.version>
<spring-boot-admin.version>2.5.1</spring-boot-admin.version> <spring-boot-admin.version>2.5.1</spring-boot-admin.version>
<redisson.version>3.16.2</redisson.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>
<!-- jdk11 缺失依赖 jaxb-->
<jaxb.version>3.0.1</jaxb.version>
<!-- OSS 配置 --> <!-- OSS 配置 -->
<qiniu.version>7.8.0</qiniu.version> <qiniu.version>7.8.0</qiniu.version>
<aliyun.oss.version>3.13.1</aliyun.oss.version> <aliyun.oss.version>3.13.1</aliyun.oss.version>
<qcloud.cos.version>5.6.51</qcloud.cos.version> <qcloud.cos.version>5.6.55</qcloud.cos.version>
<minio.version>8.3.0</minio.version> <minio.version>8.3.0</minio.version>
<!-- docker 配置 --> <!-- docker 配置 -->
@ -73,6 +77,18 @@
<groupId>com.github.xiaoymin</groupId> <groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId> <artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j.version}</version> <version>${knife4j.version}</version>
<exclusions>
<exclusion>
<artifactId>swagger-annotations</artifactId>
<groupId>io.swagger</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations.version}</version>
</dependency> </dependency>
<!-- excel工具 --> <!-- excel工具 -->
@ -86,6 +102,16 @@
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId> <artifactId>easyexcel</artifactId>
<version>${easyexcel.version}</version> <version>${easyexcel.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<!-- velocity代码生成使用模板 --> <!-- velocity代码生成使用模板 -->
@ -136,6 +162,12 @@
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId> <artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${feign.version}</version> <version>${feign.version}</version>
<exclusions>
<exclusion>
<artifactId>feign-core</artifactId>
<groupId>io.github.openfeign</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
@ -184,7 +216,12 @@
<dependencies> <dependencies>
<!-- jdk11 缺失依赖 jaxb-->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -263,48 +300,9 @@
<properties> <properties>
<profiles.active>prod</profiles.active> <profiles.active>prod</profiles.active>
<logging.level>warn</logging.level> <logging.level>warn</logging.level>
<endpoints.include>health,info</endpoints.include> <endpoints.include>health, info, logfile</endpoints.include>
</properties> </properties>
</profile> </profile>
<!-- jdk多版本配置 -->
<profile>
<id>jdk8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<java.version>1.8</java.version>
</properties>
</profile>
<profile>
<id>jdk11</id>
<activation>
<jdk>11</jdk>
</activation>
<properties>
<java.version>11</java.version>
<jaxb.version>3.0.1</jaxb.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- jdk11 缺失依赖 jaxb-->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--jaxb-->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
</dependency>
</dependencies>
</profile>
</profiles> </profiles>
</project> </project>

View File

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

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-extend</artifactId> <artifactId>ruoyi-extend</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.1.0</version> <version>3.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>

View File

@ -1,6 +1,6 @@
{ {
"name": "ruoyi-vue-plus", "name": "ruoyi-vue-plus",
"version": "3.1.0", "version": "3.2.0",
"description": "RuoYi-Vue-Plus后台管理系统", "description": "RuoYi-Vue-Plus后台管理系统",
"author": "LionLi", "author": "LionLi",
"license": "MIT", "license": "MIT",
@ -42,7 +42,7 @@
"core-js": "3.8.1", "core-js": "3.8.1",
"echarts": "4.9.0", "echarts": "4.9.0",
"element-ui": "2.15.5", "element-ui": "2.15.5",
"file-saver": "2.0.4", "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",
@ -71,8 +71,8 @@
"eslint-plugin-vue": "7.2.0", "eslint-plugin-vue": "7.2.0",
"lint-staged": "10.5.3", "lint-staged": "10.5.3",
"runjs": "4.4.2", "runjs": "4.4.2",
"sass": "1.32.0", "sass": "1.32.13",
"sass-loader": "10.1.0", "sass-loader": "10.1.1",
"script-ext-html-webpack-plugin": "2.1.5", "script-ext-html-webpack-plugin": "2.1.5",
"svg-sprite-loader": "5.1.1", "svg-sprite-loader": "5.1.1",
"vue-template-compiler": "2.6.12" "vue-template-compiler": "2.6.12"

View File

@ -1,6 +1,6 @@
import request from '@/utils/request' import request from '@/utils/request'
// 查询OSS存储列表 // 查询OSS对象存储列表
export function listOss(query) { export function listOss(query) {
return request({ return request({
url: '/system/oss/list', url: '/system/oss/list',
@ -9,7 +9,7 @@ export function listOss(query) {
}) })
} }
// 删除OSS存储 // 删除OSS对象存储
export function delOss(ossId) { export function delOss(ossId) {
return request({ return request({
url: '/system/oss/' + ossId, url: '/system/oss/' + ossId,

View File

@ -1,6 +1,6 @@
import request from '@/utils/request' import request from '@/utils/request'
// 查询存储配置列表 // 查询对象存储配置列表
export function listOssConfig(query) { export function listOssConfig(query) {
return request({ return request({
url: '/system/oss/config/list', url: '/system/oss/config/list',
@ -9,7 +9,7 @@ export function listOssConfig(query) {
}) })
} }
// 查询存储配置详细 // 查询对象存储配置详细
export function getOssConfig(ossConfigId) { export function getOssConfig(ossConfigId) {
return request({ return request({
url: '/system/oss/config/' + ossConfigId, url: '/system/oss/config/' + ossConfigId,
@ -17,7 +17,7 @@ export function getOssConfig(ossConfigId) {
}) })
} }
// 新增存储配置 // 新增对象存储配置
export function addOssConfig(data) { export function addOssConfig(data) {
return request({ return request({
url: '/system/oss/config', url: '/system/oss/config',
@ -26,7 +26,7 @@ export function addOssConfig(data) {
}) })
} }
// 修改存储配置 // 修改对象存储配置
export function updateOssConfig(data) { export function updateOssConfig(data) {
return request({ return request({
url: '/system/oss/config', url: '/system/oss/config',
@ -35,7 +35,7 @@ export function updateOssConfig(data) {
}) })
} }
// 删除存储配置 // 删除对象存储配置
export function delOssConfig(ossConfigId) { export function delOssConfig(ossConfigId) {
return request({ return request({
url: '/system/oss/config/' + ossConfigId, url: '/system/oss/config/' + ossConfigId,

View File

@ -75,7 +75,7 @@ export default {
if (this.radioValue === 1) { if (this.radioValue === 1) {
this.$emit('update', 'day', '*', 'day'); this.$emit('update', 'day', '*', 'day');
this.$emit('update', 'week', '?', 'day'); this.$emit('update', 'week', '?', 'day');
this.$emit('update', 'mouth', '*', 'day'); this.$emit('update', 'month', '*', 'day');
} else { } else {
if (this.cron.hour === '*') { if (this.cron.hour === '*') {
this.$emit('update', 'hour', '0', 'day'); this.$emit('update', 'hour', '0', 'day');

View File

@ -2,59 +2,59 @@
<div> <div>
<el-tabs type="border-card"> <el-tabs type="border-card">
<el-tab-pane label="秒" v-if="shouldHide('second')"> <el-tab-pane label="秒" v-if="shouldHide('second')">
<CrontabSecond @update="updateContabValue" :check="checkNumber" ref="cronsecond" /> <CrontabSecond @update="updateCrontabValue" :check="checkNumber" ref="cronsecond" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="分钟" v-if="shouldHide('min')"> <el-tab-pane label="分钟" v-if="shouldHide('min')">
<CrontabMin <CrontabMin
@update="updateContabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="contabValueObj" :cron="crontabValueObj"
ref="cronmin" ref="cronmin"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="小时" v-if="shouldHide('hour')"> <el-tab-pane label="小时" v-if="shouldHide('hour')">
<CrontabHour <CrontabHour
@update="updateContabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="contabValueObj" :cron="crontabValueObj"
ref="cronhour" ref="cronhour"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="日" v-if="shouldHide('day')"> <el-tab-pane label="日" v-if="shouldHide('day')">
<CrontabDay <CrontabDay
@update="updateContabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="contabValueObj" :cron="crontabValueObj"
ref="cronday" ref="cronday"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="月" v-if="shouldHide('mouth')"> <el-tab-pane label="月" v-if="shouldHide('month')">
<CrontabMouth <CrontabMonth
@update="updateContabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="contabValueObj" :cron="crontabValueObj"
ref="cronmouth" ref="cronmonth"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="周" v-if="shouldHide('week')"> <el-tab-pane label="周" v-if="shouldHide('week')">
<CrontabWeek <CrontabWeek
@update="updateContabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="contabValueObj" :cron="crontabValueObj"
ref="cronweek" ref="cronweek"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="年" v-if="shouldHide('year')"> <el-tab-pane label="年" v-if="shouldHide('year')">
<CrontabYear <CrontabYear
@update="updateContabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="contabValueObj" :cron="crontabValueObj"
ref="cronyear" ref="cronyear"
/> />
</el-tab-pane> </el-tab-pane>
@ -70,33 +70,33 @@
</thead> </thead>
<tbody> <tbody>
<td> <td>
<span>{{contabValueObj.second}}</span> <span>{{crontabValueObj.second}}</span>
</td> </td>
<td> <td>
<span>{{contabValueObj.min}}</span> <span>{{crontabValueObj.min}}</span>
</td> </td>
<td> <td>
<span>{{contabValueObj.hour}}</span> <span>{{crontabValueObj.hour}}</span>
</td> </td>
<td> <td>
<span>{{contabValueObj.day}}</span> <span>{{crontabValueObj.day}}</span>
</td> </td>
<td> <td>
<span>{{contabValueObj.mouth}}</span> <span>{{crontabValueObj.month}}</span>
</td> </td>
<td> <td>
<span>{{contabValueObj.week}}</span> <span>{{crontabValueObj.week}}</span>
</td> </td>
<td> <td>
<span>{{contabValueObj.year}}</span> <span>{{crontabValueObj.year}}</span>
</td> </td>
<td> <td>
<span>{{contabValueString}}</span> <span>{{crontabValueString}}</span>
</td> </td>
</tbody> </tbody>
</table> </table>
</div> </div>
<CrontabResult :ex="contabValueString"></CrontabResult> <CrontabResult :ex="crontabValueString"></CrontabResult>
<div class="pop_btn"> <div class="pop_btn">
<el-button size="small" type="primary" @click="submitFill">确定</el-button> <el-button size="small" type="primary" @click="submitFill">确定</el-button>
@ -112,7 +112,7 @@ import CrontabSecond from "./second.vue";
import CrontabMin from "./min.vue"; import CrontabMin from "./min.vue";
import CrontabHour from "./hour.vue"; import CrontabHour from "./hour.vue";
import CrontabDay from "./day.vue"; import CrontabDay from "./day.vue";
import CrontabMouth from "./mouth.vue"; import CrontabMonth from "./month.vue";
import CrontabWeek from "./week.vue"; import CrontabWeek from "./week.vue";
import CrontabYear from "./year.vue"; import CrontabYear from "./year.vue";
import CrontabResult from "./result.vue"; import CrontabResult from "./result.vue";
@ -123,12 +123,12 @@ export default {
tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"], tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
tabActive: 0, tabActive: 0,
myindex: 0, myindex: 0,
contabValueObj: { crontabValueObj: {
second: "*", second: "*",
min: "*", min: "*",
hour: "*", hour: "*",
day: "*", day: "*",
mouth: "*", month: "*",
week: "?", week: "?",
year: "", year: "",
}, },
@ -142,7 +142,7 @@ export default {
return true; return true;
}, },
resolveExp() { resolveExp() {
// //
if (this.expression) { if (this.expression) {
let arr = this.expression.split(" "); let arr = this.expression.split(" ");
if (arr.length >= 6) { if (arr.length >= 6) {
@ -152,11 +152,11 @@ export default {
min: arr[1], min: arr[1],
hour: arr[2], hour: arr[2],
day: arr[3], day: arr[3],
mouth: arr[4], month: arr[4],
week: arr[5], week: arr[5],
year: arr[6] ? arr[6] : "", year: arr[6] ? arr[6] : "",
}; };
this.contabValueObj = { this.crontabValueObj = {
...obj, ...obj,
}; };
for (let i in obj) { for (let i in obj) {
@ -164,7 +164,7 @@ export default {
} }
} }
} else { } else {
// //
this.clearCron(); this.clearCron();
} }
}, },
@ -173,122 +173,122 @@ export default {
this.tabActive = index; this.tabActive = index;
}, },
// //
updateContabValue(name, value, from) { updateCrontabValue(name, value, from) {
"updateContabValue", name, value, from; "updateCrontabValue", name, value, from;
this.contabValueObj[name] = value; this.crontabValueObj[name] = value;
if (from && from !== name) { if (from && from !== name) {
console.log(`来自组件 ${from} 改变了 ${name} ${value}`); console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
this.changeRadio(name, value); this.changeRadio(name, value);
} }
}, },
// //
changeRadio(name, value) { changeRadio(name, value) {
let arr = ["second", "min", "hour", "mouth"], let arr = ["second", "min", "hour", "month"],
refName = "cron" + name, refName = "cron" + name,
insVlaue; insValue;
if (!this.$refs[refName]) return; if (!this.$refs[refName]) return;
if (arr.includes(name)) { if (arr.includes(name)) {
if (value === "*") { if (value === "*") {
insVlaue = 1; insValue = 1;
} else if (value.indexOf("-") > -1) { } else if (value.indexOf("-") > -1) {
let indexArr = value.split("-"); let indexArr = value.split("-");
isNaN(indexArr[0]) isNaN(indexArr[0])
? (this.$refs[refName].cycle01 = 0) ? (this.$refs[refName].cycle01 = 0)
: (this.$refs[refName].cycle01 = indexArr[0]); : (this.$refs[refName].cycle01 = indexArr[0]);
this.$refs[refName].cycle02 = indexArr[1]; this.$refs[refName].cycle02 = indexArr[1];
insVlaue = 2; insValue = 2;
} else if (value.indexOf("/") > -1) { } else if (value.indexOf("/") > -1) {
let indexArr = value.split("/"); let indexArr = value.split("/");
isNaN(indexArr[0]) isNaN(indexArr[0])
? (this.$refs[refName].average01 = 0) ? (this.$refs[refName].average01 = 0)
: (this.$refs[refName].average01 = indexArr[0]); : (this.$refs[refName].average01 = indexArr[0]);
this.$refs[refName].average02 = indexArr[1]; this.$refs[refName].average02 = indexArr[1];
insVlaue = 3; insValue = 3;
} else { } else {
insVlaue = 4; insValue = 4;
this.$refs[refName].checkboxList = value.split(","); this.$refs[refName].checkboxList = value.split(",");
} }
} else if (name == "day") { } else if (name == "day") {
if (value === "*") { if (value === "*") {
insVlaue = 1; insValue = 1;
} else if (value == "?") { } else if (value == "?") {
insVlaue = 2; insValue = 2;
} else if (value.indexOf("-") > -1) { } else if (value.indexOf("-") > -1) {
let indexArr = value.split("-"); let indexArr = value.split("-");
isNaN(indexArr[0]) isNaN(indexArr[0])
? (this.$refs[refName].cycle01 = 0) ? (this.$refs[refName].cycle01 = 0)
: (this.$refs[refName].cycle01 = indexArr[0]); : (this.$refs[refName].cycle01 = indexArr[0]);
this.$refs[refName].cycle02 = indexArr[1]; this.$refs[refName].cycle02 = indexArr[1];
insVlaue = 3; insValue = 3;
} else if (value.indexOf("/") > -1) { } else if (value.indexOf("/") > -1) {
let indexArr = value.split("/"); let indexArr = value.split("/");
isNaN(indexArr[0]) isNaN(indexArr[0])
? (this.$refs[refName].average01 = 0) ? (this.$refs[refName].average01 = 0)
: (this.$refs[refName].average01 = indexArr[0]); : (this.$refs[refName].average01 = indexArr[0]);
this.$refs[refName].average02 = indexArr[1]; this.$refs[refName].average02 = indexArr[1];
insVlaue = 4; insValue = 4;
} else if (value.indexOf("W") > -1) { } else if (value.indexOf("W") > -1) {
let indexArr = value.split("W"); let indexArr = value.split("W");
isNaN(indexArr[0]) isNaN(indexArr[0])
? (this.$refs[refName].workday = 0) ? (this.$refs[refName].workday = 0)
: (this.$refs[refName].workday = indexArr[0]); : (this.$refs[refName].workday = indexArr[0]);
insVlaue = 5; insValue = 5;
} else if (value === "L") { } else if (value === "L") {
insVlaue = 6; insValue = 6;
} else { } else {
this.$refs[refName].checkboxList = value.split(","); this.$refs[refName].checkboxList = value.split(",");
insVlaue = 7; insValue = 7;
} }
} else if (name == "week") { } else if (name == "week") {
if (value === "*") { if (value === "*") {
insVlaue = 1; insValue = 1;
} else if (value == "?") { } else if (value == "?") {
insVlaue = 2; insValue = 2;
} else if (value.indexOf("-") > -1) { } else if (value.indexOf("-") > -1) {
let indexArr = value.split("-"); let indexArr = value.split("-");
isNaN(indexArr[0]) isNaN(indexArr[0])
? (this.$refs[refName].cycle01 = 0) ? (this.$refs[refName].cycle01 = 0)
: (this.$refs[refName].cycle01 = indexArr[0]); : (this.$refs[refName].cycle01 = indexArr[0]);
this.$refs[refName].cycle02 = indexArr[1]; this.$refs[refName].cycle02 = indexArr[1];
insVlaue = 3; insValue = 3;
} else if (value.indexOf("#") > -1) { } else if (value.indexOf("#") > -1) {
let indexArr = value.split("#"); let indexArr = value.split("#");
isNaN(indexArr[0]) isNaN(indexArr[0])
? (this.$refs[refName].average01 = 1) ? (this.$refs[refName].average01 = 1)
: (this.$refs[refName].average01 = indexArr[0]); : (this.$refs[refName].average01 = indexArr[0]);
this.$refs[refName].average02 = indexArr[1]; this.$refs[refName].average02 = indexArr[1];
insVlaue = 4; insValue = 4;
} else if (value.indexOf("L") > -1) { } else if (value.indexOf("L") > -1) {
let indexArr = value.split("L"); let indexArr = value.split("L");
isNaN(indexArr[0]) isNaN(indexArr[0])
? (this.$refs[refName].weekday = 1) ? (this.$refs[refName].weekday = 1)
: (this.$refs[refName].weekday = indexArr[0]); : (this.$refs[refName].weekday = indexArr[0]);
insVlaue = 5; insValue = 5;
} else { } else {
this.$refs[refName].checkboxList = value.split(","); this.$refs[refName].checkboxList = value.split(",");
insVlaue = 7; insValue = 7;
} }
} else if (name == "year") { } else if (name == "year") {
if (value == "") { if (value == "") {
insVlaue = 1; insValue = 1;
} else if (value == "*") { } else if (value == "*") {
insVlaue = 2; insValue = 2;
} else if (value.indexOf("-") > -1) { } else if (value.indexOf("-") > -1) {
insVlaue = 3; insValue = 3;
} else if (value.indexOf("/") > -1) { } else if (value.indexOf("/") > -1) {
insVlaue = 4; insValue = 4;
} else { } else {
this.$refs[refName].checkboxList = value.split(","); this.$refs[refName].checkboxList = value.split(",");
insVlaue = 5; insValue = 5;
} }
} }
this.$refs[refName].radioValue = insVlaue; this.$refs[refName].radioValue = insValue;
}, },
// -props // -props
checkNumber(value, minLimit, maxLimit) { checkNumber(value, minLimit, maxLimit) {
// //
value = Math.floor(value); value = Math.floor(value);
if (value < minLimit) { if (value < minLimit) {
value = minLimit; value = minLimit;
@ -303,29 +303,29 @@ export default {
}, },
// //
submitFill() { submitFill() {
this.$emit("fill", this.contabValueString); this.$emit("fill", this.crontabValueString);
this.hidePopup(); this.hidePopup();
}, },
clearCron() { clearCron() {
// //
("准备还原"); ("准备还原");
this.contabValueObj = { this.crontabValueObj = {
second: "*", second: "*",
min: "*", min: "*",
hour: "*", hour: "*",
day: "*", day: "*",
mouth: "*", month: "*",
week: "?", week: "?",
year: "", year: "",
}; };
for (let j in this.contabValueObj) { for (let j in this.crontabValueObj) {
this.changeRadio(j, this.contabValueObj[j]); this.changeRadio(j, this.crontabValueObj[j]);
} }
}, },
}, },
computed: { computed: {
contabValueString: function() { crontabValueString: function() {
let obj = this.contabValueObj; let obj = this.crontabValueObj;
let str = let str =
obj.second + obj.second +
" " + " " +
@ -335,7 +335,7 @@ export default {
" " + " " +
obj.day + obj.day +
" " + " " +
obj.mouth + obj.month +
" " + " " +
obj.week + obj.week +
(obj.year == "" ? "" : " " + obj.year); (obj.year == "" ? "" : " " + obj.year);
@ -347,7 +347,7 @@ export default {
CrontabMin, CrontabMin,
CrontabHour, CrontabHour,
CrontabDay, CrontabDay,
CrontabMouth, CrontabMonth,
CrontabWeek, CrontabWeek,
CrontabYear, CrontabYear,
CrontabResult, CrontabResult,

View File

@ -46,56 +46,56 @@ export default {
checkNum: this.check checkNum: this.check
} }
}, },
name: 'crontab-mouth', name: 'crontab-month',
props: ['check', 'cron'], props: ['check', 'cron'],
methods: { methods: {
// //
radioChange() { radioChange() {
if (this.radioValue === 1) { if (this.radioValue === 1) {
this.$emit('update', 'mouth', '*'); this.$emit('update', 'month', '*');
this.$emit('update', 'year', '*'); this.$emit('update', 'year', '*');
} else { } else {
if (this.cron.day === '*') { if (this.cron.day === '*') {
this.$emit('update', 'day', '0', 'mouth'); this.$emit('update', 'day', '0', 'month');
} }
if (this.cron.hour === '*') { if (this.cron.hour === '*') {
this.$emit('update', 'hour', '0', 'mouth'); this.$emit('update', 'hour', '0', 'month');
} }
if (this.cron.min === '*') { if (this.cron.min === '*') {
this.$emit('update', 'min', '0', 'mouth'); this.$emit('update', 'min', '0', 'month');
} }
if (this.cron.second === '*') { if (this.cron.second === '*') {
this.$emit('update', 'second', '0', 'mouth'); this.$emit('update', 'second', '0', 'month');
} }
} }
switch (this.radioValue) { switch (this.radioValue) {
case 2: case 2:
this.$emit('update', 'mouth', this.cycle01 + '-' + this.cycle02); this.$emit('update', 'month', this.cycle01 + '-' + this.cycle02);
break; break;
case 3: case 3:
this.$emit('update', 'mouth', this.average01 + '/' + this.average02); this.$emit('update', 'month', this.average01 + '/' + this.average02);
break; break;
case 4: case 4:
this.$emit('update', 'mouth', this.checkboxString); this.$emit('update', 'month', this.checkboxString);
break; break;
} }
}, },
// //
cycleChange() { cycleChange() {
if (this.radioValue == '2') { if (this.radioValue == '2') {
this.$emit('update', 'mouth', this.cycleTotal); this.$emit('update', 'month', this.cycleTotal);
} }
}, },
// //
averageChange() { averageChange() {
if (this.radioValue == '3') { if (this.radioValue == '3') {
this.$emit('update', 'mouth', this.averageTotal); this.$emit('update', 'month', this.averageTotal);
} }
}, },
// checkbox // checkbox
checkboxChange() { checkboxChange() {
if (this.radioValue == '4') { if (this.radioValue == '4') {
this.$emit('update', 'mouth', this.checkboxString); this.$emit('update', 'month', this.checkboxString);
} }
} }
}, },

View File

@ -37,7 +37,7 @@ export default {
// [] // []
let nTime = new Date(); let nTime = new Date();
let nYear = nTime.getFullYear(); let nYear = nTime.getFullYear();
let nMouth = nTime.getMonth() + 1; let nMonth = nTime.getMonth() + 1;
let nDay = nTime.getDate(); let nDay = nTime.getDate();
let nHour = nTime.getHours(); let nHour = nTime.getHours();
let nMin = nTime.getMinutes(); let nMin = nTime.getMinutes();
@ -47,7 +47,7 @@ export default {
this.getMinArr(ruleArr[1]); this.getMinArr(ruleArr[1]);
this.getHourArr(ruleArr[2]); this.getHourArr(ruleArr[2]);
this.getDayArr(ruleArr[3]); this.getDayArr(ruleArr[3]);
this.getMouthArr(ruleArr[4]); this.getMonthArr(ruleArr[4]);
this.getWeekArr(ruleArr[5]); this.getWeekArr(ruleArr[5]);
this.getYearArr(ruleArr[6], nYear); this.getYearArr(ruleArr[6], nYear);
// -便使 // -便使
@ -62,7 +62,7 @@ export default {
let mIdx = this.getIndex(mDate, nMin); let mIdx = this.getIndex(mDate, nMin);
let hIdx = this.getIndex(hDate, nHour); let hIdx = this.getIndex(hDate, nHour);
let DIdx = this.getIndex(DDate, nDay); let DIdx = this.getIndex(DDate, nDay);
let MIdx = this.getIndex(MDate, nMouth); let MIdx = this.getIndex(MDate, nMonth);
let YIdx = this.getIndex(YDate, nYear); let YIdx = this.getIndex(YDate, nYear);
// () // ()
const resetSecond = function () { const resetSecond = function () {
@ -84,17 +84,17 @@ export default {
nDay = DDate[DIdx] nDay = DDate[DIdx]
resetHour(); resetHour();
} }
const resetMouth = function () { const resetMonth = function () {
MIdx = 0; MIdx = 0;
nMouth = MDate[MIdx] nMonth = MDate[MIdx]
resetDay(); resetDay();
} }
// //
if (nYear !== YDate[YIdx]) { if (nYear !== YDate[YIdx]) {
resetMouth(); resetMonth();
} }
// //
if (nMouth !== MDate[MIdx]) { if (nMonth !== MDate[MIdx]) {
resetDay(); resetDay();
} }
// //
@ -114,12 +114,12 @@ export default {
goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) { goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
let YY = YDate[Yi]; let YY = YDate[Yi];
// //
if (nMouth > MDate[MDate.length - 1]) { if (nMonth > MDate[MDate.length - 1]) {
resetMouth(); resetMonth();
continue; continue;
} }
// //
goMouth: for (let Mi = MIdx; Mi < MDate.length; Mi++) { goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
// 便 // 便
let MM = MDate[Mi]; let MM = MDate[Mi];
MM = MM < 10 ? '0' + MM : MM; MM = MM < 10 ? '0' + MM : MM;
@ -127,7 +127,7 @@ export default {
if (nDay > DDate[DDate.length - 1]) { if (nDay > DDate[DDate.length - 1]) {
resetDay(); resetDay();
if (Mi == MDate.length - 1) { if (Mi == MDate.length - 1) {
resetMouth(); resetMonth();
continue goYear; continue goYear;
} }
continue; continue;
@ -144,10 +144,10 @@ export default {
if (Di == DDate.length - 1) { if (Di == DDate.length - 1) {
resetDay(); resetDay();
if (Mi == MDate.length - 1) { if (Mi == MDate.length - 1) {
resetMouth(); resetMonth();
continue goYear; continue goYear;
} }
continue goMouth; continue goMonth;
} }
continue; continue;
} }
@ -155,11 +155,11 @@ export default {
// //
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') { if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') {
resetDay(); resetDay();
continue goMouth; continue goMonth;
} }
// //
if (this.dayRule == 'lastDay') { if (this.dayRule == 'lastDay') {
// //
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
@ -169,7 +169,7 @@ export default {
} }
} }
} else if (this.dayRule == 'workDay') { } else if (this.dayRule == 'workDay') {
//230 // 230
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
DD--; DD--;
@ -180,15 +180,15 @@ export default {
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week'); let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
// //
if (thisWeek == 0) { if (thisWeek == 0) {
// //
DD++; DD++;
thisDD = DD < 10 ? '0' + DD : DD; thisDD = DD < 10 ? '0' + DD : DD;
// //
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
DD -= 3; DD -= 3;
} }
} else if (thisWeek == 6) { } else if (thisWeek == 6) {
//61 // 61
if (this.dayRuleSup !== 1) { if (this.dayRuleSup !== 1) {
DD--; DD--;
} else { } else {
@ -196,25 +196,25 @@ export default {
} }
} }
} else if (this.dayRule == 'weekDay') { } else if (this.dayRule == 'weekDay') {
// //
// //
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week'); let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
//dayRuleSup // dayRuleSup
if (Array.indexOf(this.dayRuleSup, thisWeek) < 0) { if (Array.indexOf(this.dayRuleSup, thisWeek) < 0) {
// //
if (Di == DDate.length - 1) { if (Di == DDate.length - 1) {
resetDay(); resetDay();
if (Mi == MDate.length - 1) { if (Mi == MDate.length - 1) {
resetMouth(); resetMonth();
continue goYear; continue goYear;
} }
continue goMouth; continue goMonth;
} }
continue; continue;
} }
} else if (this.dayRule == 'assWeek') { } else if (this.dayRule == 'assWeek') {
// //
//1 // 1
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week'); let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
if (this.dayRuleSup[1] >= thisWeek) { if (this.dayRuleSup[1] >= thisWeek) {
DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1; DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1;
@ -222,17 +222,17 @@ export default {
DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1; DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1;
} }
} else if (this.dayRule == 'lastWeek') { } else if (this.dayRule == 'lastWeek') {
// //
//230 // 230
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
DD--; DD--;
thisDD = DD < 10 ? '0' + DD : DD; thisDD = DD < 10 ? '0' + DD : DD;
} }
} }
// //
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week'); let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
// //
if (this.dayRuleSup < thisWeek) { if (this.dayRuleSup < thisWeek) {
DD -= thisWeek - this.dayRuleSup; DD -= thisWeek - this.dayRuleSup;
} else if (this.dayRuleSup > thisWeek) { } else if (this.dayRuleSup > thisWeek) {
@ -254,10 +254,10 @@ export default {
if (Di == DDate.length - 1) { if (Di == DDate.length - 1) {
resetDay(); resetDay();
if (Mi == MDate.length - 1) { if (Mi == MDate.length - 1) {
resetMouth(); resetMonth();
continue goYear; continue goYear;
} }
continue goMouth; continue goMonth;
} }
continue goDay; continue goDay;
} }
@ -277,10 +277,10 @@ export default {
if (Di == DDate.length - 1) { if (Di == DDate.length - 1) {
resetDay(); resetDay();
if (Mi == MDate.length - 1) { if (Mi == MDate.length - 1) {
resetMouth(); resetMonth();
continue goYear; continue goYear;
} }
continue goMouth; continue goMonth;
} }
continue goDay; continue goDay;
} }
@ -296,9 +296,9 @@ export default {
resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss) resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
nums++; nums++;
} }
//退 // 退
if (nums == 5) break goYear; if (nums == 5) break goYear;
// //
if (si == sDate.length - 1) { if (si == sDate.length - 1) {
resetSecond(); resetSecond();
if (mi == mDate.length - 1) { if (mi == mDate.length - 1) {
@ -308,10 +308,10 @@ export default {
if (Di == DDate.length - 1) { if (Di == DDate.length - 1) {
resetDay(); resetDay();
if (Mi == MDate.length - 1) { if (Mi == MDate.length - 1) {
resetMouth(); resetMonth();
continue goYear; continue goYear;
} }
continue goMouth; continue goMonth;
} }
continue goDay; continue goDay;
} }
@ -323,7 +323,7 @@ export default {
} //goMin } //goMin
}//goHour }//goHour
}//goDay }//goDay
}//goMouth }//goMonth
} }
// 100 // 100
if (resultArr.length == 0) { if (resultArr.length == 0) {
@ -339,7 +339,7 @@ export default {
}, },
// //
getIndex(arr, value) { getIndex(arr, value) {
if (value <= arr[0] || value > arr[arr.length - 1]) { if (value <= arr[0] || value > arr[arr.length - 1]) {
return 0; return 0;
@ -365,7 +365,7 @@ export default {
} }
}, },
// "" // ""
getMouthArr(rule) { getMonthArr(rule) {
this.dateArr[4] = this.getOrderArr(1, 12); this.dateArr[4] = this.getOrderArr(1, 12);
if (rule.indexOf('-') >= 0) { if (rule.indexOf('-') >= 0) {
this.dateArr[4] = this.getCycleArr(rule, 12, false) this.dateArr[4] = this.getCycleArr(rule, 12, false)
@ -377,7 +377,7 @@ export default {
}, },
// ""- // ""-
getWeekArr(rule) { getWeekArr(rule) {
// //
if (this.dayRule == '' && this.dayRuleSup == '') { if (this.dayRule == '' && this.dayRuleSup == '') {
if (rule.indexOf('-') >= 0) { if (rule.indexOf('-') >= 0) {
this.dayRule = 'weekDay'; this.dayRule = 'weekDay';
@ -401,7 +401,7 @@ export default {
this.dayRule = 'weekDay'; this.dayRule = 'weekDay';
this.dayRuleSup = this.getAssignArr(rule) this.dayRuleSup = this.getAssignArr(rule)
} }
//weekDay70week0 // weekDay70week0
if (this.dayRule == 'weekDay') { if (this.dayRule == 'weekDay') {
for (let i = 0; i < this.dayRuleSup.length; i++) { for (let i = 0; i < this.dayRuleSup.length; i++) {
if (this.dayRuleSup[i] == 7) { if (this.dayRuleSup[i] == 7) {
@ -502,7 +502,7 @@ export default {
}, },
// //
getCycleArr(rule, limit, status) { getCycleArr(rule, limit, status) {
//status--01 // status--01
let arr = []; let arr = [];
let cycleArr = rule.split('-'); let cycleArr = rule.split('-');
let min = Number(cycleArr[0]); let min = Number(cycleArr[0]);
@ -520,7 +520,7 @@ export default {
arr.sort(this.compare) arr.sort(this.compare)
return arr; return arr;
}, },
//Array.sort // Array.sort
compare(value1, value2) { compare(value1, value2) {
if (value2 - value1 > 0) { if (value2 - value1 > 0) {
return -1; return -1;

View File

@ -86,7 +86,7 @@ export default {
} }
}, },
othChange() { othChange() {
// //
let ins = this.cron.second let ins = this.cron.second
('反解析 second', ins); ('反解析 second', ins);
if (ins === '*') { if (ins === '*') {

View File

@ -71,8 +71,8 @@ export default {
this.$emit('update', 'week', '*'); this.$emit('update', 'week', '*');
this.$emit('update', 'year', '*'); this.$emit('update', 'year', '*');
} else { } else {
if (this.cron.mouth === '*') { if (this.cron.month === '*') {
this.$emit('update', 'mouth', '0', 'week'); this.$emit('update', 'month', '0', 'week');
} }
if (this.cron.day === '*') { if (this.cron.day === '*') {
this.$emit('update', 'day', '0', 'week'); this.$emit('update', 'day', '0', 'week');

View File

@ -55,12 +55,12 @@ export default {
} }
}, },
name: 'crontab-year', name: 'crontab-year',
props: ['check', 'mouth', 'cron'], props: ['check', 'month', 'cron'],
methods: { methods: {
// //
radioChange() { radioChange() {
if (this.cron.mouth === '*') { if (this.cron.month === '*') {
this.$emit('update', 'mouth', '0', 'year'); this.$emit('update', 'month', '0', 'year');
} }
if (this.cron.day === '*') { if (this.cron.day === '*') {
this.$emit('update', 'day', '0', 'year'); this.$emit('update', 'day', '0', 'year');

View File

@ -0,0 +1,21 @@
import Vue from 'vue'
import DataDict from '@/utils/dict'
import { getDicts as getDicts } from '@/api/system/dict/data'
function install() {
Vue.use(DataDict, {
metas: {
'*': {
labelField: 'dictLabel',
valueField: 'dictValue',
request(dictMeta) {
return getDicts(dictMeta.type).then(res => res.data)
},
},
},
})
}
export default {
install,
}

View File

@ -1,22 +1,23 @@
<template> <template>
<div> <div>
<template v-for="(item, index) in options"> <template v-for="(item, index) in options">
<template v-if="values.includes(item.dictValue)"> <template v-if="values.includes(item.value)">
<span <span
v-if="item.listClass == 'default' || item.listClass == ''" v-if="item.raw.listClass == 'default' || item.raw.listClass == ''"
:key="item.dictValue" :key="item.value"
:index="index" :index="index"
:class="item.cssClass" :class="item.raw.cssClass"
>{{ item.dictLabel }}</span >{{ item.label }}</span
> >
<el-tag <el-tag
v-else v-else
:key="item.dictValue" :disable-transitions="true"
:key="item.value"
:index="index" :index="index"
:type="item.listClass == 'primary' ? '' : item.listClass" :type="item.raw.listClass == 'primary' ? '' : item.raw.listClass"
:class="item.cssClass" :class="item.raw.cssClass"
> >
{{ item.dictLabel }} {{ item.label }}
</el-tag> </el-tag>
</template> </template>
</template> </template>

View File

@ -113,8 +113,10 @@ export default {
// //
handleRemove(file, fileList) { handleRemove(file, fileList) {
const findex = this.fileList.map(f => f.name).indexOf(file.name); const findex = this.fileList.map(f => f.name).indexOf(file.name);
this.fileList.splice(findex, 1); if(findex > -1) {
this.$emit("input", this.listToString(this.fileList)); this.fileList.splice(findex, 1);
this.$emit("input", this.listToString(this.fileList));
}
}, },
// //
handleUploadSuccess(res) { handleUploadSuccess(res) {
@ -187,24 +189,23 @@ export default {
for (let i in list) { for (let i in list) {
strs += list[i].url + separator; strs += list[i].url + separator;
} }
return strs != "" ? strs.substr(0, strs.length - 1) : ""; return strs != '' ? strs.substr(0, strs.length - 1) : '';
}, }
}, }
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
// .el-upload--picture-card // .el-upload--picture-card
::v-deep.hide .el-upload--picture-card { ::v-deep.hide .el-upload--picture-card {
display: none; display: none;
} }
// //
::v-deep .el-list-enter-active, ::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active { ::v-deep .el-list-leave-active {
transition: all 0s; transition: all 0s;
} }
::v-deep .el-list-enter, ::v-deep .el-list-enter, .el-list-leave-active {
.el-list-leave-active {
opacity: 0; opacity: 0;
transform: translateY(0); transform: translateY(0);
} }

View File

@ -47,14 +47,6 @@ export default {
const themeCluster = this.getThemeCluster(val.replace('#', '')) const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', '')) const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
const $message = this.$message({
message: ' 正在切换主题,请稍后...',
customClass: 'theme-message',
type: 'success',
duration: 0,
iconClass: 'el-icon-loading'
})
const getHandler = (variable, id) => { const getHandler = (variable, id) => {
return () => { return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', '')) const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
@ -91,9 +83,6 @@ export default {
}) })
this.$emit('change', val) this.$emit('change', val)
$message.close()
}, },
updateStyle(style, oldCluster, newCluster) { updateStyle(style, oldCluster, newCluster) {

View File

@ -1,15 +0,0 @@
import hasRole from './hasRole'
import hasPermi from './hasPermi'
const install = function(Vue) {
Vue.directive('hasRole', hasRole)
Vue.directive('hasPermi', hasPermi)
}
if (window.Vue) {
window['hasRole'] = hasRole
window['hasPermi'] = hasPermi
Vue.use(install); // eslint-disable-line
}
export default install

View File

@ -162,14 +162,8 @@ export default {
this.sideTheme = val; this.sideTheme = val;
}, },
saveSetting() { saveSetting() {
const loading = this.$loading({ this.$modal.loading("正在保存到本地,请稍后...");
lock: true, this.$cache.local.set(
fullscreen: false,
text: "正在保存到本地,请稍后...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)"
});
localStorage.setItem(
"layout-setting", "layout-setting",
`{ `{
"topNav":${this.topNav}, "topNav":${this.topNav},
@ -181,17 +175,11 @@ export default {
"theme":"${this.theme}" "theme":"${this.theme}"
}` }`
); );
setTimeout(loading.close(), 1000) setTimeout(this.$modal.closeLoading(), 1000)
}, },
resetSetting() { resetSetting() {
this.$loading({ this.$modal.loading("正在清除设置缓存并刷新,请稍后...");
lock: true, this.$cache.local.remove("layout-setting")
fullscreen: false,
text: "正在清除设置缓存并刷新,请稍后...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)"
});
localStorage.removeItem("layout-setting")
setTimeout("window.location.reload()", 1000) setTimeout("window.location.reload()", 1000)
} }
} }

View File

@ -10,7 +10,7 @@ import { isExternal } from '@/utils/validate'
export default { export default {
props: { props: {
to: { to: {
type: String, type: [String, Object],
required: true required: true
} }
}, },

View File

@ -1,7 +1,7 @@
<template> <template>
<div v-if="!item.hidden"> <div v-if="!item.hidden">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"> <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" /> <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
</el-menu-item> </el-menu-item>
@ -82,13 +82,17 @@ export default {
return false return false
}, },
resolvePath(routePath) { resolvePath(routePath, routeQuery) {
if (isExternal(routePath)) { if (isExternal(routePath)) {
return routePath return routePath
} }
if (isExternal(this.basePath)) { if (isExternal(this.basePath)) {
return this.basePath return this.basePath
} }
if (routeQuery) {
let query = JSON.parse(routeQuery);
return { path: path.resolve(this.basePath, routePath), query: query }
}
return path.resolve(this.basePath, routePath) return path.resolve(this.basePath, routePath)
} }
} }

View File

@ -11,13 +11,14 @@ 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 './assets/icons' // icon import './assets/icons' // icon
import './permission' // permission control import './permission' // permission control
import { getDicts } from "@/api/system/dict/data"; import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config"; import { getConfigKey } from "@/api/system/config";
import { downLoadExcel } from "@/utils/download";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"; import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
// 分页组件
import Pagination from "@/components/Pagination"; import Pagination from "@/components/Pagination";
// 自定义表格工具组件 // 自定义表格工具组件
import RightToolbar from "@/components/RightToolbar" import RightToolbar from "@/components/RightToolbar"
@ -31,6 +32,8 @@ import ImageUpload from "@/components/ImageUpload"
import DictTag from '@/components/DictTag' import DictTag from '@/components/DictTag'
// 头部标签组件 // 头部标签组件
import VueMeta from 'vue-meta' import VueMeta from 'vue-meta'
// 字典数据组件
import DictData from '@/components/DictData'
// 全局方法挂载 // 全局方法挂载
Vue.prototype.getDicts = getDicts Vue.prototype.getDicts = getDicts
@ -41,19 +44,6 @@ Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.handleTree = handleTree Vue.prototype.handleTree = handleTree
Vue.prototype.downLoadExcel = downLoadExcel
Vue.prototype.msgSuccess = function (msg) {
this.$message({ showClose: true, message: msg, type: "success" });
}
Vue.prototype.msgError = function (msg) {
this.$message({ showClose: true, message: msg, type: "error" });
}
Vue.prototype.msgInfo = function (msg) {
this.$message.info(msg);
}
// 全局组件挂载 // 全局组件挂载
Vue.component('DictTag', DictTag) Vue.component('DictTag', DictTag)
@ -64,7 +54,9 @@ Vue.component('FileUpload', FileUpload)
Vue.component('ImageUpload', ImageUpload) Vue.component('ImageUpload', ImageUpload)
Vue.use(directive) Vue.use(directive)
Vue.use(plugins)
Vue.use(VueMeta) Vue.use(VueMeta)
DictData.install()
/** /**
* If you don't want to use mock-server * If you don't want to use mock-server

View File

@ -0,0 +1,77 @@
const sessionCache = {
set (key, value) {
if (!sessionStorage) {
return
}
if (key != null && value != null) {
sessionStorage.setItem(key, value)
}
},
get (key) {
if (!sessionStorage) {
return null
}
if (key == null) {
return null
}
return sessionStorage.getItem(key)
},
setJSON (key, jsonValue) {
if (jsonValue != null) {
this.set(key, JSON.stringify(jsonValue))
}
},
getJSON (key) {
const value = this.get(key)
if (value != null) {
return JSON.parse(value)
}
},
remove (key) {
sessionStorage.removeItem(key);
}
}
const localCache = {
set (key, value) {
if (!localStorage) {
return
}
if (key != null && value != null) {
localStorage.setItem(key, value)
}
},
get (key) {
if (!localStorage) {
return null
}
if (key == null) {
return null
}
return localStorage.getItem(key)
},
setJSON (key, jsonValue) {
if (jsonValue != null) {
this.set(key, JSON.stringify(jsonValue))
}
},
getJSON (key) {
const value = this.get(key)
if (value != null) {
return JSON.parse(value)
}
},
remove (key) {
localStorage.removeItem(key);
}
}
export default {
/**
* 会话级缓存
*/
session: sessionCache,
/**
* 本地缓存
*/
local: localCache
}

View File

@ -0,0 +1,71 @@
import { saveAs } from 'file-saver'
import axios from 'axios'
import { getToken } from '@/utils/auth'
const baseURL = process.env.VUE_APP_BASE_API
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(res => {
const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
this.saveAs(blob, decodeURI(res.headers['download-filename']))
})
},
oss(ossId) {
var url = baseURL + '/system/oss/download/' + ossId
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => {
const blob = new Blob([res.data], { type: 'application/octet-stream' })
this.saveAs(blob, decodeURI(res.headers['download-filename']))
})
},
zip(url, name) {
var url = baseURL + url
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => {
const blob = new Blob([res.data], { type: 'application/zip' })
this.saveAs(blob, name)
})
},
saveAs(text, name, opts) {
saveAs(text, name, opts);
}
}

View File

@ -0,0 +1,14 @@
import cache from './cache'
import modal from './modal'
import download from './download'
export default {
install(Vue) {
// 缓存对象
Vue.prototype.$cache = cache
// 模态框对象
Vue.prototype.$modal = modal
// 下载文件
Vue.prototype.$download = download
}
}

View File

@ -0,0 +1,75 @@
import { Message, MessageBox, Notification, Loading } from 'element-ui'
let loadingInstance;
export default {
// 消息提示
msg(content) {
Message.info(content)
},
// 错误消息
msgError(content) {
Message.error(content)
},
// 成功消息
msgSuccess(content) {
Message.success(content)
},
// 警告消息
msgWarning(content) {
Message.warning(content)
},
// 弹出提示
alert(content) {
MessageBox.alert(content, "系统提示")
},
// 错误提示
alertError(content) {
MessageBox.alert(content, "系统提示", { type: 'error' })
},
// 成功提示
alertSuccess(content) {
MessageBox.alert(content, "系统提示", { type: 'success' })
},
// 警告提示
alertWarning(content) {
MessageBox.alert(content, "系统提示", { type: 'warning' })
},
// 通知提示
notify(content) {
Notification.info(content)
},
// 错误通知
notifyError(content) {
Notification.error(content);
},
// 成功通知
notifySuccess(content) {
Notification.success(content)
},
// 警告通知
notifyWarning(content) {
Notification.warning(content)
},
// 确认窗体
confirm(content) {
return MessageBox.confirm(content, "系统提示", {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: "warning",
})
},
// 打开遮罩层
loading(content) {
loadingInstance = Loading.service({
lock: true,
text: content,
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
})
},
// 关闭遮罩层
closeLoading() {
loadingInstance.close();
}
}

View File

@ -9,19 +9,20 @@ import Layout from '@/layout'
/** /**
* Note: 路由配置项 * Note: 路由配置项
* *
* hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401login等页面或者如一些编辑页面/edit/1 * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401login等页面或者如一些编辑页面/edit/1
* alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时自动会变成嵌套的模式--如组件页面 * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时自动会变成嵌套的模式--如组件页面
* // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
* // 若你想不管路由下面的 children 声明的个数都显示你的根路由 * // 若你想不管路由下面的 children 声明的个数都显示你的根路由
* // 你可以设置 alwaysShow: true这样它就会忽略之前定义的规则一直显示根路由 * // 你可以设置 alwaysShow: true这样它就会忽略之前定义的规则一直显示根路由
* redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
* name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题 * name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
* query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数
* meta : { * meta : {
noCache: true // 如果设置为true则不会被 <keep-alive> 缓存(默认 false) noCache: true // 如果设置为true则不会被 <keep-alive> 缓存(默认 false)
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
icon: 'svg-name' // 设置该路由的图标对应路径src/assets/icons/svg icon: 'svg-name' // 设置该路由的图标对应路径src/assets/icons/svg
breadcrumb: false // 如果设置为false则不会在breadcrumb面包屑中显示 breadcrumb: false // 如果设置为false则不会在breadcrumb面包屑中显示
activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。
} }
*/ */
@ -156,7 +157,7 @@ export const constantRoutes = [
hidden: true, hidden: true,
children: [ children: [
{ {
path: 'index/:tableId(\\d+)', 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'}

View File

@ -0,0 +1,82 @@
import Vue from 'vue'
import { mergeRecursive } from "@/utils/ruoyi";
import DictMeta from './DictMeta'
import DictData from './DictData'
const DEFAULT_DICT_OPTIONS = {
types: [],
}
/**
* @classdesc 字典
* @property {Object} label 标签对象内部属性名为字典类型名称
* @property {Object} dict 字段数组内部属性名为字典类型名称
* @property {Array.<DictMeta>} _dictMetas 字典元数据数组
*/
export default class Dict {
constructor() {
this.owner = null
this.label = {}
this.type = {}
}
init(options) {
if (options instanceof Array) {
options = { types: options }
}
const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options)
if (opts.types === undefined) {
throw new Error('need dict types')
}
const ps = []
this._dictMetas = opts.types.map(t => DictMeta.parse(t))
this._dictMetas.forEach(dictMeta => {
const type = dictMeta.type
Vue.set(this.label, type, {})
Vue.set(this.type, type, [])
if (dictMeta.lazy) {
return
}
ps.push(loadDict(this, dictMeta))
})
return Promise.all(ps)
}
/**
* 重新加载字典
* @param {String} type 字典类型
*/
reloadDict(type) {
const dictMeta = this._dictMetas.find(e => e.type === type)
if (dictMeta === undefined) {
return Promise.reject(`the dict meta of ${type} was not found`)
}
return loadDict(this, dictMeta)
}
}
/**
* 加载字典
* @param {Dict} dict 字典
* @param {DictMeta} dictMeta 字典元数据
* @returns {Promise}
*/
function loadDict(dict, dictMeta) {
return dictMeta.request(dictMeta)
.then(response => {
const type = dictMeta.type
let dicts = dictMeta.responseConverter(response, dictMeta)
if (!(dicts instanceof Array)) {
console.error('the return of responseConverter must be Array.<DictData>')
dicts = []
} else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
console.error('the type of elements in dicts must be DictData')
dicts = []
}
dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts)
dicts.forEach(d => {
Vue.set(dict.label[type], d.value, d.label)
})
return dicts
})
}

View File

@ -0,0 +1,17 @@
import DictOptions from './DictOptions'
import DictData from './DictData'
export default function(dict, dictMeta) {
const label = determineDictField(dict, dictMeta.labelField, ...DictOptions.DEFAULT_LABEL_FIELDS)
const value = determineDictField(dict, dictMeta.valueField, ...DictOptions.DEFAULT_VALUE_FIELDS)
return new DictData(dict[label], dict[value], dict)
}
/**
* 确定字典字段
* @param {DictData} dict
* @param {...String} fields
*/
function determineDictField(dict, ...fields) {
return fields.find(f => Object.prototype.hasOwnProperty.call(dict, f))
}

View File

@ -0,0 +1,13 @@
/**
* @classdesc 字典数据
* @property {String} label 标签
* @property {*} value 标签
* @property {Object} raw 原始数据
*/
export default class DictData {
constructor(label, value, raw) {
this.label = label
this.value = value
this.raw = raw
}
}

View File

@ -0,0 +1,38 @@
import { mergeRecursive } from "@/utils/ruoyi";
import DictOptions from './DictOptions'
/**
* @classdesc 字典元数据
* @property {String} type 类型
* @property {Function} request 请求
* @property {String} label 标签字段
* @property {String} value 值字段
*/
export default class DictMeta {
constructor(options) {
this.type = options.type
this.request = options.request,
this.responseConverter = options.responseConverter
this.labelField = options.labelField
this.valueField = options.valueField
this.lazy = options.lazy === true
}
}
/**
* 解析字典元数据
* @param {Object} options
* @returns {DictMeta}
*/
DictMeta.parse= function(options) {
let opts = null
if (typeof options === 'string') {
opts = DictOptions.metas[options] || {}
opts.type = options
} else if (typeof options === 'object') {
opts = options
}
opts = mergeRecursive(DictOptions.metas['*'], opts)
return new DictMeta(opts)
}

View File

@ -0,0 +1,51 @@
import { mergeRecursive } from "@/utils/ruoyi";
import dictConverter from './DictConverter'
export const options = {
metas: {
'*': {
/**
* 字典请求方法签名为function(dictMeta: DictMeta): Promise
*/
request: (dictMeta) => {
console.log(`load dict ${dictMeta.type}`)
return Promise.resolve([])
},
/**
* 字典响应数据转换器方法签名为function(response: Object, dictMeta: DictMeta): DictData
*/
responseConverter,
labelField: 'label',
valueField: 'value',
},
},
/**
* 默认标签字段
*/
DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'],
/**
* 默认值字段
*/
DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'],
}
/**
* 映射字典
* @param {Object} response 字典数据
* @param {DictMeta} dictMeta 字典元数据
* @returns {DictData}
*/
function responseConverter(response, dictMeta) {
const dicts = response.content instanceof Array ? response.content : response
if (dicts === undefined) {
console.warn(`no dict data of "${dictMeta.type}" found in the response`)
return []
}
return dicts.map(d => dictConverter(d, dictMeta))
}
export function mergeOptions(src) {
mergeRecursive(options, src)
}
export default options

View File

@ -0,0 +1,33 @@
import Dict from './Dict'
import { mergeOptions } from './DictOptions'
export default function(Vue, options) {
mergeOptions(options)
Vue.mixin({
data() {
if (this.$options.dicts === undefined || this.$options.dicts === null) {
return {}
}
const dict = new Dict()
dict.owner = this
return {
dict
}
},
created() {
if (!(this.dict instanceof Dict)) {
return
}
options.onCreated && options.onCreated(this.dict)
this.dict.init(this.$options.dicts).then(() => {
options.onReady && options.onReady(this.dict)
this.$nextTick(() => {
this.$emit('dictReady', this.dict)
if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) {
this.$options.methods.onDictReady.call(this, this.dict)
}
})
})
},
})
}

View File

@ -1,91 +0,0 @@
import axios from 'axios'
import { getToken } from '@/utils/auth'
const mimeMap = {
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
zip: 'application/zip',
oss: 'application/octet-stream'
}
const baseUrl = process.env.VUE_APP_BASE_API
export function downLoadZip(str, filename) {
var url = baseUrl + str
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => {
resolveBlob(res, mimeMap.zip)
})
}
export function downLoadOss(ossId) {
var url = baseUrl + '/system/oss/download/' + ossId
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => {
resolveBlob(res, mimeMap.oss)
})
}
export function downLoadExcel(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(res => {
resolveBlob(res, mimeMap.xlsx)
})
}
/**
* 解析blob响应内容并下载
* @param {*} res blob响应内容
* @param {String} mimeType MIME类型
*/
export function resolveBlob(res, mimeType) {
const aLink = document.createElement('a')
var blob = new Blob([res.data], { type: mimeType })
// //从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
var contentDisposition = decodeURI(res.headers['content-disposition'])
var result = patt.exec(contentDisposition)
var fileName = result[1]
fileName = fileName.replace(/\"/g, '')
aLink.style.display = 'none'
aLink.href = URL.createObjectURL(blob)
aLink.setAttribute('download', decodeURI(fileName)) // 设置下载文件名称
document.body.appendChild(aLink)
aLink.click()
URL.revokeObjectURL(aLink.href);//清除引用
document.body.removeChild(aLink);
}

View File

@ -1,39 +0,0 @@
import axios from 'axios'
import { getToken } from '@/utils/auth'
const mimeMap = {
oss: 'application/octet-stream'
}
const baseUrl = process.env.VUE_APP_BASE_API
export function downLoadOss(ossId) {
var url = baseUrl + '/system/oss/download/' + ossId
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => {
resolveBlob(res, mimeMap.oss)
})
}
/**
* 解析blob响应内容并下载
* @param {*} res blob响应内容
* @param {String} mimeType MIME类型
*/
export function resolveBlob(res, mimeType) {
const aLink = document.createElement('a')
var blob = new Blob([res.data], { type: mimeType })
// 从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
var contentDisposition = decodeURI(res.headers['content-disposition'])
var result = patt.exec(contentDisposition)
var fileName = result[1]
fileName = fileName.replace(/\"/g, '')
aLink.href = URL.createObjectURL(blob)
aLink.setAttribute('download', decodeURI(fileName)) // 设置下载文件名称
document.body.appendChild(aLink)
aLink.click()
document.body.removeChild(aLink);
}

View File

@ -66,7 +66,7 @@ service.interceptors.response.use(res => {
location.href = '/index'; location.href = '/index';
}) })
}).catch(() => {}); }).catch(() => {});
return Promise.reject('令牌验证失败') return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) { } else if (code === 500) {
Message({ Message({
message: msg, message: msg,

View File

@ -3,8 +3,6 @@
* Copyright (c) 2019 ruoyi * Copyright (c) 2019 ruoyi
*/ */
const baseURL = process.env.VUE_APP_BASE_API
// 日期格式化 // 日期格式化
export function parseTime(time, pattern) { export function parseTime(time, pattern) {
if (arguments.length === 0 || !time) { if (arguments.length === 0 || !time) {
@ -72,8 +70,8 @@ export function addDateRange(params, dateRange, propName) {
export function selectDictLabel(datas, value) { export function selectDictLabel(datas, value) {
var actions = []; var actions = [];
Object.keys(datas).some((key) => { Object.keys(datas).some((key) => {
if (datas[key].dictValue == ('' + value)) { if (datas[key].value == ('' + value)) {
actions.push(datas[key].dictLabel); actions.push(datas[key].label);
return true; return true;
} }
}) })
@ -117,6 +115,22 @@ export function praseStrEmpty(str) {
return str; return str;
} }
// 数据合并
export function mergeRecursive(source, target) {
for (var p in target) {
try {
if (target[p].constructor == Object) {
source[p] = mergeRecursive(source[p], target[p]);
} else {
source[p] = target[p];
}
} catch(e) {
source[p] = target[p];
}
}
return source;
};
/** /**
* 构造树型结构数据 * 构造树型结构数据
* @param {*} data 数据源 * @param {*} data 数据源

View File

@ -1,40 +0,0 @@
import axios from 'axios'
import { getToken } from '@/utils/auth'
const mimeMap = {
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
zip: 'application/zip'
}
const baseUrl = process.env.VUE_APP_BASE_API
export function downLoadZip(str, filename) {
var url = baseUrl + str
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => {
resolveBlob(res, mimeMap.zip)
})
}
/**
* 解析blob响应内容并下载
* @param {*} res blob响应内容
* @param {String} mimeType MIME类型
*/
export function resolveBlob(res, mimeType) {
const aLink = document.createElement('a')
var blob = new Blob([res.data], { type: mimeType })
// //从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
var contentDisposition = decodeURI(res.headers['content-disposition'])
var result = patt.exec(contentDisposition)
var fileName = result[1]
fileName = fileName.replace(/\"/g, '')
aLink.href = URL.createObjectURL(blob)
aLink.setAttribute('download', fileName) // 设置下载文件名称
document.body.appendChild(aLink)
aLink.click()
document.body.removeChild(aLink);
}

View File

@ -324,7 +324,7 @@ export default {
this.buttonLoading = true; this.buttonLoading = true;
if (this.form.id != null) { if (this.form.id != null) {
updateDemo(this.form).then(response => { updateDemo(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}).finally(() => { }).finally(() => {
@ -332,7 +332,7 @@ export default {
}); });
} else { } else {
addDemo(this.form).then(response => { addDemo(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}).finally(() => { }).finally(() => {
@ -345,22 +345,20 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ids = row.id || this.ids; const ids = row.id || this.ids;
this.$confirm('是否确认删除测试单表编号为"' + ids + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除测试单表编号为"' + ids + '"的数据项?').then(() => {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.loading = true; this.loading = true;
return delDemo(ids); return delDemo(ids);
}).then(() => { }).then(() => {
this.loading = false; this.loading = false;
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}) }).finally(() => {
this.loading = false;
});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/demo/demo/export', this.queryParams); this.$download.excel('/demo/demo/export', this.queryParams);
} }
} }
}; };

View File

@ -255,7 +255,7 @@ export default {
this.buttonLoading = true; this.buttonLoading = true;
if (this.form.id != null) { if (this.form.id != null) {
updateTree(this.form).then(response => { updateTree(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}).finally(() => { }).finally(() => {
@ -263,7 +263,7 @@ export default {
}); });
} else { } else {
addTree(this.form).then(response => { addTree(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}).finally(() => { }).finally(() => {
@ -275,18 +275,16 @@ export default {
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
this.$confirm('是否确认删除测试树表编号为"' + row.id + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除测试树表编号为"' + row.id + '"的数据项?').then(() => {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.loading = true; this.loading = true;
return delTree(row.id); return delTree(row.id);
}).then(() => { }).then(() => {
this.loading = false; this.loading = false;
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}) }).finally(() => {
this.loading = false;
});
} }
} }
}; };

View File

@ -93,6 +93,47 @@
<span>更新日志</span> <span>更新日志</span>
</div> </div>
<el-collapse accordion> <el-collapse accordion>
<el-collapse-item title="v3.2.0 - 2021-9-28">
<ol>
<li>update [重大改动]接口文档 支持分组配置</li>
<li>update [重大改动]security 路径配置抽取到配置文件</li>
<li>update [重大改动] framework system 模块 解耦 调整依赖结构 解决依赖冲突</li>
<li>update [重大改动]重写 防重提交实现 使用分布式锁 解决并发问题 压测通过</li>
<li>update springboot 2.5.4 => 2.5.5 bugfix版本</li>
<li>update mybatis-plus 3.4.3.3 => 3.4.3.4 bugfix版本</li>
<li>update redisson 3.16.2 => 3.16.3 bugfix版本</li>
<li>update easyexcel 2.2.10 => 2.2.11</li>
<li>update hutool 5.7.11 => 5.7.13</li>
<li>update file-saver 2.0.4 => 2.0.5</li>
<li>update dart-sass 1.32.0 => 1.32.13</li>
<li>update sass-loader 10.1.0 => 10.1.1</li>
<li>update 优化代码生成 根据MP生成特性 调整导入表结构默认值合理化</li>
<li>update 将所有 云存储字样 改为 对象存储 避免误解</li>
<li>update 更新 @Cacheable 错误用法 注意事项</li>
<li>update 优化 AddressUtils 空校验处理</li>
<li>update 菜单管理支持配置路由参数</li>
<li>update 优化aop语法 使用spring自动注入注解</li>
<li>update 使用 Redisson 限流工具 重写限流实现</li>
<li>update 使用 vue-data-dict 简化数据字典使用</li>
<li>update 增加日志注解新增是否保存响应参数开关</li>
<li>update 用户未登录日志改为 warn 级别</li>
<li>update OSS模块 关于下载403报错信息优化</li>
<li>update 更新 Actuator prod 默认暴漏端点 增加暴漏 logfile 日志端点</li>
<li>update 默认适配jdk11 测试 jdk17 无异常</li>
<li>update 封装通用下载方法简化下载使用</li>
<li>add 新增通用方法简化模态/缓存使用</li>
<li>add 增加 限流演示案例</li>
<li>add 增加 redis redisson 集群配置</li>
<li>fix Cron表达式生成器关闭时销毁避免再次打开时存在上一次修改的数据</li>
<li>fix 全局限流key会多出一个"-" 将其移动到IP后面 去除多余的空格</li>
<li>fix 修复多主键代码生成bug</li>
<li>fix 修复 @Cacheable @DataScope 冲突问题</li>
<li>fix 修复代码生成页面数据编辑保存之后总是跳转第一页的问题</li>
<li>remove 移除过期工具 RedisCache</li>
<li>remove 移除无用配置类 ServerConfig</li>
<li>remove 移除 SysUser 无用字段 salt</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.1.0 - 2021-9-7"> <el-collapse-item title="v3.1.0 - 2021-9-7">
<ol> <ol>
<li>add [重大改动] 过期 RedisCache 新增 RedisUtils 工具类 新增 发布订阅功能 更灵巧便于使用</li> <li>add [重大改动] 过期 RedisCache 新增 RedisUtils 工具类 新增 发布订阅功能 更灵巧便于使用</li>

View File

@ -74,8 +74,6 @@ export default {
name: "Server", name: "Server",
data() { data() {
return { return {
//
loading: [],
// //
commandstats: null, commandstats: null,
// 使 // 使
@ -93,7 +91,7 @@ export default {
getList() { getList() {
getCache().then((response) => { getCache().then((response) => {
this.cache = response.data; this.cache = response.data;
this.loading.close(); this.$modal.closeLoading();
this.commandstats = echarts.init(this.$refs.commandstats, "macarons"); this.commandstats = echarts.init(this.$refs.commandstats, "macarons");
this.commandstats.setOption({ this.commandstats.setOption({
@ -141,12 +139,7 @@ export default {
}, },
// //
openLoading() { openLoading() {
this.loading = this.$loading({ this.$modal.loading("正在加载缓存监控数据,请稍后!");
lock: true,
text: "拼命读取中",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
}, },
}, },
}; };

View File

@ -13,20 +13,20 @@
<el-form-item label="任务组名" prop="jobGroup"> <el-form-item label="任务组名" prop="jobGroup">
<el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable size="small"> <el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable size="small">
<el-option <el-option
v-for="dict in jobGroupOptions" v-for="dict in dict.type.sys_job_group"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="任务状态" prop="status"> <el-form-item label="任务状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable size="small">
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_job_status"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -99,7 +99,7 @@
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" /> <el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
<el-table-column label="任务组名" align="center" prop="jobGroup"> <el-table-column label="任务组名" align="center" prop="jobGroup">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="jobGroupOptions" :value="scope.row.jobGroup"/> <dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" /> <el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
@ -168,10 +168,10 @@
<el-form-item label="任务分组" prop="jobGroup"> <el-form-item label="任务分组" prop="jobGroup">
<el-select v-model="form.jobGroup" placeholder="请选择"> <el-select v-model="form.jobGroup" placeholder="请选择">
<el-option <el-option
v-for="dict in jobGroupOptions" v-for="dict in dict.type.sys_job_group"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -225,10 +225,10 @@
<el-form-item label="状态"> <el-form-item label="状态">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio <el-radio
v-for="dict in statusOptions" v-for="dict in dict.type.sys_job_status"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictValue" :label="dict.value"
>{{dict.dictLabel}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -240,7 +240,7 @@
</div> </div>
</el-dialog> </el-dialog>
<el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body class="scrollbar"> <el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body destroy-on-close class="scrollbar">
<crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab> <crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab>
</el-dialog> </el-dialog>
@ -301,6 +301,7 @@ import Crontab from '@/components/Crontab'
export default { export default {
components: { Crontab }, components: { Crontab },
name: "Job", name: "Job",
dicts: ['sys_job_group', 'sys_job_status'],
data() { data() {
return { return {
// //
@ -329,10 +330,6 @@ export default {
openCron: false, openCron: false,
// //
expression: "", expression: "",
//
jobGroupOptions: [],
//
statusOptions: [],
// //
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
@ -359,12 +356,6 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_job_group").then(response => {
this.jobGroupOptions = response.data;
});
this.getDicts("sys_job_status").then(response => {
this.statusOptions = response.data;
});
}, },
methods: { methods: {
/** 查询定时任务列表 */ /** 查询定时任务列表 */
@ -378,7 +369,7 @@ export default {
}, },
// //
jobGroupFormat(row, column) { jobGroupFormat(row, column) {
return this.selectDictLabel(this.jobGroupOptions, row.jobGroup); return this.selectDictLabel(this.dict.type.sys_job_group, row.jobGroup);
}, },
// //
cancel() { cancel() {
@ -434,29 +425,21 @@ export default {
// //
handleStatusChange(row) { handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用"; let text = row.status === "0" ? "启用" : "停用";
this.$confirm('确认要"' + text + '""' + row.jobName + '"任务吗?', "警告", { this.$modal.confirm('确认要"' + text + '""' + row.jobName + '"任务吗?').then(function() {
confirmButtonText: "确定", return changeJobStatus(row.jobId, row.status);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.$modal.msgSuccess(text + "成功");
}).then(function() { }).catch(function() {
return changeJobStatus(row.jobId, row.status); row.status = row.status === "0" ? "1" : "0";
}).then(() => { });
this.msgSuccess(text + "成功");
}).catch(function() {
row.status = row.status === "0" ? "1" : "0";
});
}, },
/* 立即执行一次 */ /* 立即执行一次 */
handleRun(row) { handleRun(row) {
this.$confirm('确认要立即执行一次"' + row.jobName + '"任务吗?', "警告", { this.$modal.confirm('确认要立即执行一次"' + row.jobName + '"任务吗?').then(function() {
confirmButtonText: "确定", return runJob(row.jobId, row.jobGroup);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.$modal.msgSuccess("执行成功");
}).then(function() { }).catch(() => {});
return runJob(row.jobId, row.jobGroup);
}).then(() => {
this.msgSuccess("执行成功");
}).catch(() => {});
}, },
/** 任务详细信息 */ /** 任务详细信息 */
handleView(row) { handleView(row) {
@ -501,13 +484,13 @@ export default {
if (valid) { if (valid) {
if (this.form.jobId != undefined) { if (this.form.jobId != undefined) {
updateJob(this.form).then(response => { updateJob(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addJob(this.form).then(response => { addJob(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
@ -518,20 +501,16 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const jobIds = row.jobId || this.ids; const jobIds = row.jobId || this.ids;
this.$confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项?').then(function() {
confirmButtonText: "确定", return delJob(jobIds);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delJob(jobIds); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/monitor/job/export', this.queryParams); this.$download.excel('/monitor/job/export', this.queryParams);
} }
} }
}; };

View File

@ -20,10 +20,10 @@
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
v-for="dict in jobGroupOptions" v-for="dict in dict.type.sys_job_group"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -36,10 +36,10 @@
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_common_status"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -112,14 +112,14 @@
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" /> <el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
<el-table-column label="任务组名" align="center" prop="jobGroup" :show-overflow-tooltip="true"> <el-table-column label="任务组名" align="center" prop="jobGroup" :show-overflow-tooltip="true">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="jobGroupOptions" :value="scope.row.jobGroup"/> <dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" /> <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="jobMessage" :show-overflow-tooltip="true" />
<el-table-column label="执行状态" align="center" prop="status"> <el-table-column label="执行状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="执行时间" align="center" prop="createTime" width="180"> <el-table-column label="执行时间" align="center" prop="createTime" width="180">
@ -190,6 +190,7 @@ import { listJobLog, delJobLog, cleanJobLog } from "@/api/monitor/jobLog";
export default { export default {
name: "JobLog", name: "JobLog",
dicts: ['sys_common_status', 'sys_job_group'],
data() { data() {
return { return {
// //
@ -212,10 +213,6 @@ export default {
dateRange: [], dateRange: [],
// //
form: {}, form: {},
//
statusOptions: [],
//
jobGroupOptions: [],
// //
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
@ -237,12 +234,6 @@ export default {
} else { } else {
this.getList(); this.getList();
} }
this.getDicts("sys_common_status").then(response => {
this.statusOptions = response.data;
});
this.getDicts("sys_job_group").then(response => {
this.jobGroupOptions = response.data;
});
}, },
methods: { methods: {
/** 查询调度日志列表 */ /** 查询调度日志列表 */
@ -284,33 +275,25 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const jobLogIds = this.ids; const jobLogIds = this.ids;
this.$confirm('是否确认删除调度日志编号为"' + jobLogIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除调度日志编号为"' + jobLogIds + '"的数据项?').then(function() {
confirmButtonText: "确定", return delJobLog(jobLogIds);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delJobLog(jobLogIds); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
}, },
/** 清空按钮操作 */ /** 清空按钮操作 */
handleClean() { handleClean() {
this.$confirm("是否确认清空所有调度日志数据项?", "警告", { this.$modal.confirm('是否确认清空所有调度日志数据项?').then(function() {
confirmButtonText: "确定", return cleanJobLog();
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("清空成功");
return cleanJobLog(); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("清空成功");
}).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/monitor/jobLog/export', this.queryParams); this.$download.excel('/monitor/jobLog/export', this.queryParams);
} }
} }
}; };

View File

@ -30,10 +30,10 @@
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_common_status"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -101,7 +101,7 @@
<el-table-column label="操作系统" align="center" prop="os" /> <el-table-column label="操作系统" align="center" prop="os" />
<el-table-column label="登录状态" align="center" prop="status"> <el-table-column label="登录状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作信息" align="center" prop="msg" /> <el-table-column label="操作信息" align="center" prop="msg" />
@ -127,6 +127,7 @@ import { list, delLogininfor, cleanLogininfor } from "@/api/monitor/logininfor";
export default { export default {
name: "Logininfor", name: "Logininfor",
dicts: ['sys_common_status'],
data() { data() {
return { return {
// //
@ -143,8 +144,6 @@ export default {
total: 0, total: 0,
// //
list: [], list: [],
//
statusOptions: [],
// //
dateRange: [], dateRange: [],
// //
@ -161,9 +160,6 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_common_status").then(response => {
this.statusOptions = response.data;
});
}, },
methods: { methods: {
/** 查询登录日志列表 */ /** 查询登录日志列表 */
@ -202,33 +198,25 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const infoIds = row.infoId || this.ids; const infoIds = row.infoId || this.ids;
this.$confirm('是否确认删除访问编号为"' + infoIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除访问编号为"' + infoIds + '"的数据项?').then(function() {
confirmButtonText: "确定", return delLogininfor(infoIds);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delLogininfor(infoIds); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
}, },
/** 清空按钮操作 */ /** 清空按钮操作 */
handleClean() { handleClean() {
this.$confirm('是否确认清空所有登录日志数据项?', "警告", { this.$modal.confirm('是否确认清空所有登录日志数据项?').then(function() {
confirmButtonText: "确定", return cleanLogininfor();
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("清空成功");
return cleanLogininfor(); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("清空成功");
}).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/monitor/logininfor/export', this.queryParams); this.$download.excel('/monitor/logininfor/export', this.queryParams);
} }
} }
}; };

View File

@ -111,16 +111,12 @@ export default {
}, },
/** 强退按钮操作 */ /** 强退按钮操作 */
handleForceLogout(row) { handleForceLogout(row) {
this.$confirm('是否确认强退名称为"' + row.userName + '"的数据项?', "警告", { this.$modal.confirm('是否确认强退名称为"' + row.userName + '"的数据项?').then(function() {
confirmButtonText: "确定", return forceLogout(row.tokenId);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("强退成功");
return forceLogout(row.tokenId); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("强退成功");
}).catch(() => {});
} }
} }
}; };

View File

@ -30,10 +30,10 @@
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
v-for="dict in typeOptions" v-for="dict in dict.type.sys_oper_type"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -46,10 +46,10 @@
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_common_status"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -113,7 +113,7 @@
<el-table-column label="系统模块" align="center" prop="title" /> <el-table-column label="系统模块" align="center" prop="title" />
<el-table-column label="操作类型" align="center" prop="businessType"> <el-table-column label="操作类型" align="center" prop="businessType">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="typeOptions" :value="scope.row.businessType"/> <dict-tag :options="dict.type.sys_oper_type" :value="scope.row.businessType"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="请求方式" align="center" prop="requestMethod" /> <el-table-column label="请求方式" align="center" prop="requestMethod" />
@ -122,7 +122,7 @@
<el-table-column label="操作地点" align="center" prop="operLocation" :show-overflow-tooltip="true" /> <el-table-column label="操作地点" align="center" prop="operLocation" :show-overflow-tooltip="true" />
<el-table-column label="操作状态" align="center" prop="status"> <el-table-column label="操作状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作日期" align="center" prop="operTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180"> <el-table-column label="操作日期" align="center" prop="operTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180">
@ -200,6 +200,7 @@ import { list, delOperlog, cleanOperlog } from "@/api/monitor/operlog";
export default { export default {
name: "Operlog", name: "Operlog",
dicts: ['sys_oper_type', 'sys_common_status'],
data() { data() {
return { return {
// //
@ -218,10 +219,6 @@ export default {
list: [], list: [],
// //
open: false, open: false,
//
typeOptions: [],
//
statusOptions: [],
// //
dateRange: [], dateRange: [],
// //
@ -241,12 +238,6 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_oper_type").then(response => {
this.typeOptions = response.data;
});
this.getDicts("sys_common_status").then(response => {
this.statusOptions = response.data;
});
}, },
methods: { methods: {
/** 查询登录日志 */ /** 查询登录日志 */
@ -261,7 +252,7 @@ export default {
}, },
// //
typeFormat(row, column) { typeFormat(row, column) {
return this.selectDictLabel(this.typeOptions, row.businessType); return this.selectDictLabel(this.dict.type.sys_oper_type, row.businessType);
}, },
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery() {
@ -294,33 +285,25 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const operIds = row.operId || this.ids; const operIds = row.operId || this.ids;
this.$confirm('是否确认删除日志编号为"' + operIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除日志编号为"' + operIds + '"的数据项?').then(function() {
confirmButtonText: "确定", return delOperlog(operIds);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delOperlog(operIds); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
}, },
/** 清空按钮操作 */ /** 清空按钮操作 */
handleClean() { handleClean() {
this.$confirm('是否确认清空所有操作日志数据项?', "警告", { this.$modal.confirm('是否确认清空所有操作日志数据项?').then(function() {
confirmButtonText: "确定", return cleanOperlog();
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("清空成功");
return cleanOperlog(); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("清空成功");
}).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/monitor/operlog/export', this.queryParams); this.$download.excel('/monitor/operlog/export', this.queryParams);
} }
} }
}; };

View File

@ -24,10 +24,10 @@
<el-form-item label="系统内置" prop="configType"> <el-form-item label="系统内置" prop="configType">
<el-select v-model="queryParams.configType" placeholder="系统内置" clearable size="small"> <el-select v-model="queryParams.configType" placeholder="系统内置" clearable size="small">
<el-option <el-option
v-for="dict in typeOptions" v-for="dict in dict.type.sys_yes_no"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -114,7 +114,7 @@
<el-table-column label="参数键值" align="center" prop="configValue" /> <el-table-column label="参数键值" align="center" prop="configValue" />
<el-table-column label="系统内置" align="center" prop="configType"> <el-table-column label="系统内置" align="center" prop="configType">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="typeOptions" :value="scope.row.configType"/> <dict-tag :options="dict.type.sys_yes_no" :value="scope.row.configType"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" /> <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
@ -166,10 +166,10 @@
<el-form-item label="系统内置" prop="configType"> <el-form-item label="系统内置" prop="configType">
<el-radio-group v-model="form.configType"> <el-radio-group v-model="form.configType">
<el-radio <el-radio
v-for="dict in typeOptions" v-for="dict in dict.type.sys_yes_no"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictValue" :label="dict.value"
>{{dict.dictLabel}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
@ -189,6 +189,7 @@ import { listConfig, getConfig, delConfig, addConfig, updateConfig, refreshCache
export default { export default {
name: "Config", name: "Config",
dicts: ['sys_yes_no'],
data() { data() {
return { return {
// //
@ -211,8 +212,6 @@ export default {
title: "", title: "",
// //
open: false, open: false,
//
typeOptions: [],
// //
dateRange: [], dateRange: [],
// //
@ -241,9 +240,6 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_yes_no").then(response => {
this.typeOptions = response.data;
});
}, },
methods: { methods: {
/** 查询参数列表 */ /** 查询参数列表 */
@ -312,13 +308,13 @@ export default {
if (valid) { if (valid) {
if (this.form.configId != undefined) { if (this.form.configId != undefined) {
updateConfig(this.form).then(response => { updateConfig(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addConfig(this.form).then(response => { addConfig(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
@ -329,25 +325,21 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const configIds = row.configId || this.ids; const configIds = row.configId || this.ids;
this.$confirm('是否确认删除参数编号为"' + configIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除参数编号为"' + configIds + '"的数据项?').then(function() {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return delConfig(configIds); return delConfig(configIds);
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).catch(() => {}); }).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/system/config/export', this.queryParams); this.$download.excel('/system/config/export', this.queryParams);
}, },
/** 刷新缓存按钮操作 */ /** 刷新缓存按钮操作 */
handleRefreshCache() { handleRefreshCache() {
refreshCache().then(() => { refreshCache().then(() => {
this.msgSuccess("刷新成功"); this.$modal.msgSuccess("刷新成功");
}); });
} }
} }

View File

@ -13,10 +13,10 @@
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="部门状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="部门状态" clearable size="small">
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -61,7 +61,7 @@
<el-table-column prop="orderNum" label="排序" width="200"></el-table-column> <el-table-column prop="orderNum" label="排序" width="200"></el-table-column>
<el-table-column prop="status" label="状态" width="100"> <el-table-column prop="status" label="状态" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="200"> <el-table-column label="创建时间" align="center" prop="createTime" width="200">
@ -135,10 +135,10 @@
<el-form-item label="部门状态"> <el-form-item label="部门状态">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio <el-radio
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictValue" :label="dict.value"
>{{dict.dictLabel}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -159,6 +159,7 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default { export default {
name: "Dept", name: "Dept",
dicts: ['sys_normal_disable'],
components: { Treeselect }, components: { Treeselect },
data() { data() {
return { return {
@ -180,8 +181,6 @@ export default {
refreshTable: true, refreshTable: true,
// //
expand: false, expand: false,
//
statusOptions: [],
// //
queryParams: { queryParams: {
deptName: undefined, deptName: undefined,
@ -219,9 +218,6 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
}, },
methods: { methods: {
/** 查询部门列表 */ /** 查询部门列表 */
@ -309,13 +305,13 @@ export default {
if (valid) { if (valid) {
if (this.form.deptId != undefined) { if (this.form.deptId != undefined) {
updateDept(this.form).then(response => { updateDept(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addDept(this.form).then(response => { addDept(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
@ -325,16 +321,12 @@ export default {
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
this.$confirm('是否确认删除名称为"' + row.deptName + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除名称为"' + row.deptName + '"的数据项?').then(function() {
confirmButtonText: "确定", return delDept(row.deptId);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delDept(row.deptId); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
} }
} }
}; };

View File

@ -23,10 +23,10 @@
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="数据状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="数据状态" clearable size="small">
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -96,7 +96,7 @@
<el-table-column label="字典排序" align="center" prop="dictSort" /> <el-table-column label="字典排序" align="center" prop="dictSort" />
<el-table-column label="状态" align="center" prop="status"> <el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" /> <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
@ -164,10 +164,10 @@
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio <el-radio
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictValue" :label="dict.value"
>{{dict.dictLabel}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
@ -188,6 +188,7 @@ import { listType, getType } from "@/api/system/dict/type";
export default { export default {
name: "Data", name: "Data",
dicts: ['sys_normal_disable'],
data() { data() {
return { return {
// //
@ -239,8 +240,6 @@ export default {
label: "危险" label: "危险"
} }
], ],
//
statusOptions: [],
// //
typeOptions: [], typeOptions: [],
// //
@ -271,9 +270,6 @@ export default {
const dictId = this.$route.params && this.$route.params.dictId; const dictId = this.$route.params && this.$route.params.dictId;
this.getType(dictId); this.getType(dictId);
this.getTypeList(); this.getTypeList();
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
}, },
methods: { methods: {
/** 查询字典类型详细 */ /** 查询字典类型详细 */
@ -358,13 +354,13 @@ export default {
if (valid) { if (valid) {
if (this.form.dictCode != undefined) { if (this.form.dictCode != undefined) {
updateData(this.form).then(response => { updateData(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addData(this.form).then(response => { addData(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
@ -375,20 +371,16 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const dictCodes = row.dictCode || this.ids; const dictCodes = row.dictCode || this.ids;
this.$confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?').then(function() {
confirmButtonText: "确定", return delData(dictCodes);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delData(dictCodes); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/system/dict/data/export', this.queryParams); this.$download.excel('/system/dict/data/export', this.queryParams);
} }
} }
}; };

View File

@ -30,10 +30,10 @@
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -125,7 +125,7 @@
</el-table-column> </el-table-column>
<el-table-column label="状态" align="center" prop="status"> <el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" /> <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
@ -174,10 +174,10 @@
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio <el-radio
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictValue" :label="dict.value"
>{{dict.dictLabel}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
@ -197,6 +197,7 @@ import { listType, getType, delType, addType, updateType, refreshCache } from "@
export default { export default {
name: "Dict", name: "Dict",
dicts: ['sys_normal_disable'],
data() { data() {
return { return {
// //
@ -219,8 +220,6 @@ export default {
title: "", title: "",
// //
open: false, open: false,
//
statusOptions: [],
// //
dateRange: [], dateRange: [],
// //
@ -246,9 +245,6 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
}, },
methods: { methods: {
/** 查询字典类型列表 */ /** 查询字典类型列表 */
@ -316,13 +312,13 @@ export default {
if (valid) { if (valid) {
if (this.form.dictId != undefined) { if (this.form.dictId != undefined) {
updateType(this.form).then(response => { updateType(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addType(this.form).then(response => { addType(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
@ -333,25 +329,21 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const dictIds = row.dictId || this.ids; const dictIds = row.dictId || this.ids;
this.$confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?').then(function() {
confirmButtonText: "确定", return delType(dictIds);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delType(dictIds); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/system/dict/type/export', this.queryParams); this.$download.excel('/system/dict/type/export', this.queryParams);
}, },
/** 刷新缓存按钮操作 */ /** 刷新缓存按钮操作 */
handleRefreshCache() { handleRefreshCache() {
refreshCache().then(() => { refreshCache().then(() => {
this.msgSuccess("刷新成功"); this.$modal.msgSuccess("刷新成功");
}); });
} }
} }

View File

@ -13,10 +13,10 @@
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="菜单状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="菜单状态" clearable size="small">
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -68,7 +68,7 @@
<el-table-column prop="component" label="组件路径" :show-overflow-tooltip="true"></el-table-column> <el-table-column prop="component" label="组件路径" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="status" label="状态" width="80"> <el-table-column prop="status" label="状态" width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime"> <el-table-column label="创建时间" align="center" prop="createTime">
@ -206,37 +206,14 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item v-if="form.menuType != 'F'"> <el-form-item v-if="form.menuType == 'C'">
<el-input v-model="form.query" placeholder="请输入路由参数" maxlength="255" />
<span slot="label"> <span slot="label">
<el-tooltip content="选择隐藏则路由将不会出现在侧边栏,但仍然可以访问" placement="top"> <el-tooltip content='访问路由的默认传递参数,如:`{"id": 1, "name": "ry"}`' placement="top">
<i class="el-icon-question"></i> <i class="el-icon-question"></i>
</el-tooltip> </el-tooltip>
显示状态 路由参数
</span> </span>
<el-radio-group v-model="form.visible">
<el-radio
v-for="dict in visibleOptions"
:key="dict.dictValue"
:label="dict.dictValue"
>{{dict.dictLabel}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.menuType != 'F'">
<span slot="label">
<el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
菜单状态
</span>
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictValue"
>{{dict.dictLabel}}</el-radio>
</el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -253,6 +230,40 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item v-if="form.menuType != 'F'">
<span slot="label">
<el-tooltip content="选择隐藏则路由将不会出现在侧边栏,但仍然可以访问" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
显示状态
</span>
<el-radio-group v-model="form.visible">
<el-radio
v-for="dict in dict.type.sys_show_hide"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.menuType != 'F'">
<span slot="label">
<el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
菜单状态
</span>
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row> </el-row>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
@ -271,6 +282,7 @@ import IconSelect from "@/components/IconSelect";
export default { export default {
name: "Menu", name: "Menu",
dicts: ['sys_show_hide', 'sys_normal_disable'],
components: { Treeselect, IconSelect }, components: { Treeselect, IconSelect },
data() { data() {
return { return {
@ -290,10 +302,6 @@ export default {
isExpandAll: false, isExpandAll: false,
// //
refreshTable: true, refreshTable: true,
//
visibleOptions: [],
//
statusOptions: [],
// //
queryParams: { queryParams: {
menuName: undefined, menuName: undefined,
@ -317,12 +325,6 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_show_hide").then(response => {
this.visibleOptions = response.data;
});
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
}, },
methods: { methods: {
// //
@ -423,13 +425,13 @@ export default {
if (valid) { if (valid) {
if (this.form.menuId != undefined) { if (this.form.menuId != undefined) {
updateMenu(this.form).then(response => { updateMenu(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addMenu(this.form).then(response => { addMenu(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
@ -439,16 +441,12 @@ export default {
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
this.$confirm('是否确认删除名称为"' + row.menuName + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除名称为"' + row.menuName + '"的数据项?').then(function() {
confirmButtonText: "确定", return delMenu(row.menuId);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delMenu(row.menuId); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
} }
} }
}; };

View File

@ -22,10 +22,10 @@
<el-form-item label="类型" prop="noticeType"> <el-form-item label="类型" prop="noticeType">
<el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable size="small"> <el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable size="small">
<el-option <el-option
v-for="dict in typeOptions" v-for="dict in dict.type.sys_notice_type"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -82,12 +82,12 @@
/> />
<el-table-column label="公告类型" align="center" prop="noticeType" width="100"> <el-table-column label="公告类型" align="center" prop="noticeType" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="typeOptions" :value="scope.row.noticeType"/> <dict-tag :options="dict.type.sys_notice_type" :value="scope.row.noticeType"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" align="center" prop="status" width="100"> <el-table-column label="状态" align="center" prop="status" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_notice_status" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建者" align="center" prop="createBy" width="100" /> <el-table-column label="创建者" align="center" prop="createBy" width="100" />
@ -137,10 +137,10 @@
<el-form-item label="公告类型" prop="noticeType"> <el-form-item label="公告类型" prop="noticeType">
<el-select v-model="form.noticeType" placeholder="请选择"> <el-select v-model="form.noticeType" placeholder="请选择">
<el-option <el-option
v-for="dict in typeOptions" v-for="dict in dict.type.sys_notice_type"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -149,10 +149,10 @@
<el-form-item label="状态"> <el-form-item label="状态">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio <el-radio
v-for="dict in statusOptions" v-for="dict in dict.type.sys_notice_status"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictValue" :label="dict.value"
>{{dict.dictLabel}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -176,6 +176,7 @@ import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api
export default { export default {
name: "Notice", name: "Notice",
dicts: ['sys_notice_status', 'sys_notice_type'],
data() { data() {
return { return {
// //
@ -196,10 +197,6 @@ export default {
title: "", title: "",
// //
open: false, open: false,
//
statusOptions: [],
//
typeOptions: [],
// //
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
@ -223,12 +220,6 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_notice_status").then(response => {
this.statusOptions = response.data;
});
this.getDicts("sys_notice_type").then(response => {
this.typeOptions = response.data;
});
}, },
methods: { methods: {
/** 查询公告列表 */ /** 查询公告列表 */
@ -294,13 +285,13 @@ export default {
if (valid) { if (valid) {
if (this.form.noticeId != undefined) { if (this.form.noticeId != undefined) {
updateNotice(this.form).then(response => { updateNotice(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addNotice(this.form).then(response => { addNotice(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
@ -311,16 +302,12 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const noticeIds = row.noticeId || this.ids const noticeIds = row.noticeId || this.ids
this.$confirm('是否确认删除公告编号为"' + noticeIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除公告编号为"' + noticeIds + '"的数据项?').then(function() {
confirmButtonText: "确定", return delNotice(noticeIds);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delNotice(noticeIds); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
} }
} }
}; };

View File

@ -23,10 +23,10 @@
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -118,7 +118,7 @@
@pagination="getList" @pagination="getList"
/> />
<!-- 添加或修改存储配置对话框 --> <!-- 添加或修改对象存储配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body> <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px"> <el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-form-item label="配置key" prop="configKey"> <el-form-item label="配置key" prop="configKey">
@ -149,10 +149,10 @@
<el-form-item label="是否HTTPS"> <el-form-item label="是否HTTPS">
<el-radio-group v-model="form.isHttps"> <el-radio-group v-model="form.isHttps">
<el-radio <el-radio
v-for="dict in isHttpsOptions" v-for="dict in dict.type.sys_yes_no"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictValue" :label="dict.value"
>{{dict.dictLabel}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="域" prop="region"> <el-form-item label="域" prop="region">
@ -183,6 +183,7 @@ import {
export default { export default {
name: "OssConfig", name: "OssConfig",
dicts: ['sys_yes_no', 'sys_normal_disable'],
data() { data() {
return { return {
// loading // loading
@ -201,7 +202,7 @@ export default {
showSearch: true, showSearch: true,
// //
total: 0, total: 0,
// //
ossConfigList: [], ossConfigList: [],
// configKeyOptions // configKeyOptions
configKeyOptions: [], configKeyOptions: [],
@ -275,16 +276,10 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_yes_no").then(response => {
this.isHttpsOptions = response.data;
});
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
this.configKeyOptions = this.configKeyDatas; this.configKeyOptions = this.configKeyDatas;
}, },
methods: { methods: {
/** 查询存储配置列表 */ /** 查询对象存储配置列表 */
getList() { getList() {
this.loading = true; this.loading = true;
listOssConfig(this.queryParams).then((response) => { listOssConfig(this.queryParams).then((response) => {
@ -335,7 +330,7 @@ export default {
handleAdd() { handleAdd() {
this.reset(); this.reset();
this.open = true; this.open = true;
this.title = "添加存储配置"; this.title = "添加对象存储配置";
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
@ -346,7 +341,7 @@ export default {
this.loading = false; this.loading = false;
this.form = response.data; this.form = response.data;
this.open = true; this.open = true;
this.title = "修改存储配置"; this.title = "修改对象存储配置";
}); });
}, },
/** 提交按钮 */ /** 提交按钮 */
@ -356,7 +351,7 @@ export default {
this.buttonLoading = true; this.buttonLoading = true;
if (this.form.ossConfigId != null) { if (this.form.ossConfigId != null) {
updateOssConfig(this.form).then(response => { updateOssConfig(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}).finally(() => { }).finally(() => {
@ -364,7 +359,7 @@ export default {
}); });
} else { } else {
addOssConfig(this.form).then(response => { addOssConfig(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}).finally(() => { }).finally(() => {
@ -377,34 +372,25 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ossConfigIds = row.ossConfigId || this.ids; const ossConfigIds = row.ossConfigId || this.ids;
this.$confirm('是否确认删除云存储配置编号为"' + ossConfigIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除对象存储配置编号为"' + ossConfigIds + '"的数据项?').then(() => {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.loading = true; this.loading = true;
return delOssConfig(ossConfigIds); return delOssConfig(ossConfigIds);
}).then(() => { }).then(() => {
this.loading = false; this.loading = false;
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).finally(() => { }).finally(() => {
this.loading = false; this.loading = false;
}); });
}, },
// //
handleStatusChange(row) { handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用"; let text = row.status === "0" ? "启用" : "停用";
this.$confirm( this.$modal.confirm('确认要"' + text + '""' + row.configKey + '"配置吗?').then(() => {
'确认要"' + text + '""' + row.configKey + '"配置吗?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
return changeOssConfigStatus(row.ossConfigId, row.status, row.configKey); return changeOssConfigStatus(row.ossConfigId, row.status, row.configKey);
}).then(() => { }).then(() => {
this.getList() this.getList()
this.msgSuccess(text + "成功"); this.$modal.msgSuccess(text + "成功");
}).catch(() => { }).catch(() => {
row.status = row.status === "0" ? "1" : "0"; row.status = row.status === "0" ? "1" : "0";
}) })

View File

@ -120,7 +120,7 @@
<el-table v-loading="loading" :data="ossList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="ossList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="存储主键" align="center" prop="ossId" v-if="false"/> <el-table-column label="对象存储主键" align="center" prop="ossId" v-if="false"/>
<el-table-column label="文件名" align="center" prop="fileName" /> <el-table-column label="文件名" align="center" prop="fileName" />
<el-table-column label="原名" align="center" prop="originalName" /> <el-table-column label="原名" align="center" prop="originalName" />
<el-table-column label="文件后缀" align="center" prop="fileSuffix" /> <el-table-column label="文件后缀" align="center" prop="fileSuffix" />
@ -170,7 +170,7 @@
@pagination="getList" @pagination="getList"
/> />
<!-- 添加或修改OSS存储对话框 --> <!-- 添加或修改OSS对象存储对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> <el-dialog :title="title" :visible.sync="open" width="500px" 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-form-item label="文件名"> <el-form-item label="文件名">
@ -188,7 +188,6 @@
<script> <script>
import { listOss, delOss, changePreviewListResource } from "@/api/system/oss"; import { listOss, delOss, changePreviewListResource } from "@/api/system/oss";
import { downLoadOss } from "@/utils/download";
export default { export default {
name: "Oss", name: "Oss",
@ -210,7 +209,7 @@ export default {
showSearch: true, showSearch: true,
// //
total: 0, total: 0,
// OSS // OSS
ossList: [], ossList: [],
// //
title: "", title: "",
@ -248,7 +247,7 @@ export default {
this.getList(); this.getList();
}, },
methods: { methods: {
/** 查询OSS存储列表 */ /** 查询OSS对象存储列表 */
getList() { getList() {
this.loading = true; this.loading = true;
this.queryParams.params = {}; this.queryParams.params = {};
@ -325,22 +324,18 @@ export default {
}, },
/** 下载按钮操作 */ /** 下载按钮操作 */
handleDownload(row) { handleDownload(row) {
downLoadOss(row.ossId) this.$download.oss(row.ossId)
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ossIds = row.ossId || this.ids; const ossIds = row.ossId || this.ids;
this.$confirm('是否确认删除OSS云存储编号为"' + ossIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除OSS对象存储编号为"' + ossIds + '"的数据项?').then(() => {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.loading = true; this.loading = true;
return delOss(ossIds); return delOss(ossIds);
}).then(() => { }).then(() => {
this.loading = false; this.loading = false;
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).finally(() => { }).finally(() => {
this.loading = false; this.loading = false;
}); });
@ -348,16 +343,11 @@ export default {
// //
handlePreviewListResource(previewListResource) { handlePreviewListResource(previewListResource) {
let text = previewListResource ? "启用" : "停用"; let text = previewListResource ? "启用" : "停用";
this.$confirm( this.$modal.confirm('确认要"' + text + '""预览列表图片"配置吗?').then(() => {
'确认要"' + text + '""预览列表图片"配置吗?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
return changePreviewListResource(previewListResource); return changePreviewListResource(previewListResource);
}).then(() => { }).then(() => {
this.getList() this.getList()
this.msgSuccess(text + "成功"); this.$modal.msgSuccess(text + "成功");
}).catch(() => { }).catch(() => {
this.previewListResource = previewListResource !== true; this.previewListResource = previewListResource !== true;
}) })

View File

@ -22,10 +22,10 @@
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="岗位状态" clearable size="small"> <el-select v-model="queryParams.status" placeholder="岗位状态" clearable size="small">
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -90,7 +90,7 @@
<el-table-column label="岗位排序" align="center" prop="postSort" /> <el-table-column label="岗位排序" align="center" prop="postSort" />
<el-table-column label="状态" align="center" prop="status"> <el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180"> <el-table-column label="创建时间" align="center" prop="createTime" width="180">
@ -141,10 +141,10 @@
<el-form-item label="岗位状态" prop="status"> <el-form-item label="岗位状态" prop="status">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio <el-radio
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictValue" :label="dict.value"
>{{dict.dictLabel}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
@ -164,6 +164,7 @@ import { listPost, getPost, delPost, addPost, updatePost } from "@/api/system/po
export default { export default {
name: "Post", name: "Post",
dicts: ['sys_normal_disable'],
data() { data() {
return { return {
// //
@ -186,8 +187,6 @@ export default {
title: "", title: "",
// //
open: false, open: false,
//
statusOptions: [],
// //
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
@ -214,9 +213,6 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
}, },
methods: { methods: {
/** 查询岗位列表 */ /** 查询岗位列表 */
@ -283,13 +279,13 @@ export default {
if (valid) { if (valid) {
if (this.form.postId != undefined) { if (this.form.postId != undefined) {
updatePost(this.form).then(response => { updatePost(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addPost(this.form).then(response => { addPost(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
@ -300,20 +296,16 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const postIds = row.postId || this.ids; const postIds = row.postId || this.ids;
this.$confirm('是否确认删除岗位编号为"' + postIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除岗位编号为"' + postIds + '"的数据项?').then(function() {
confirmButtonText: "确定", return delPost(postIds);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delPost(postIds); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/system/post/export', this.queryParams); this.$download.excel('/system/post/export', this.queryParams);
} }
} }
}; };

View File

@ -69,7 +69,7 @@
<el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" /> <el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" />
<el-table-column label="状态" align="center" prop="status"> <el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180"> <el-table-column label="创建时间" align="center" prop="createTime" width="180">
@ -107,6 +107,7 @@ import selectUser from "./selectUser";
export default { export default {
name: "AuthUser", name: "AuthUser",
dicts: ['sys_normal_disable'],
components: { selectUser }, components: { selectUser },
data() { data() {
return { return {
@ -122,8 +123,6 @@ export default {
total: 0, total: 0,
// //
userList: [], userList: [],
//
statusOptions: [],
// //
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
@ -139,9 +138,6 @@ export default {
if (roleId) { if (roleId) {
this.queryParams.roleId = roleId; this.queryParams.roleId = roleId;
this.getList(); this.getList();
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
} }
}, },
methods: { methods: {
@ -182,30 +178,22 @@ export default {
/** 取消授权按钮操作 */ /** 取消授权按钮操作 */
cancelAuthUser(row) { cancelAuthUser(row) {
const roleId = this.queryParams.roleId; const roleId = this.queryParams.roleId;
this.$confirm('确认要取消该用户"' + row.userName + '"角色吗?', "警告", { this.$modal.confirm('确认要取消该用户"' + row.userName + '"角色吗?').then(function() {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return authUserCancel({ userId: row.userId, roleId: roleId }); return authUserCancel({ userId: row.userId, roleId: roleId });
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("取消授权成功"); this.$modal.msgSuccess("取消授权成功");
}).catch(() => {}); }).catch(() => {});
}, },
/** 批量取消授权按钮操作 */ /** 批量取消授权按钮操作 */
cancelAuthUserAll(row) { cancelAuthUserAll(row) {
const roleId = this.queryParams.roleId; const roleId = this.queryParams.roleId;
const userIds = this.userIds.join(","); const userIds = this.userIds.join(",");
this.$confirm('是否取消选中用户授权数据项?', "警告", { this.$modal.confirm('是否取消选中用户授权数据项?').then(function() {
confirmButtonText: "确定", return authUserCancelAll({ roleId: roleId, userIds: userIds });
cancelButtonText: "取消",
type: "warning"
}).then(() => {
return authUserCancelAll({ roleId: roleId, userIds: userIds });
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("取消授权成功"); this.$modal.msgSuccess("取消授权成功");
}).catch(() => {}); }).catch(() => {});
} }
} }

View File

@ -30,10 +30,10 @@
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -183,10 +183,10 @@
<el-form-item label="状态"> <el-form-item label="状态">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio <el-radio
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictValue" :label="dict.value"
>{{dict.dictLabel}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="菜单权限"> <el-form-item label="菜单权限">
@ -265,6 +265,7 @@ import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/d
export default { export default {
name: "Role", name: "Role",
dicts: ['sys_normal_disable'],
data() { data() {
return { return {
// //
@ -295,8 +296,6 @@ export default {
deptNodeAll: false, deptNodeAll: false,
// //
dateRange: [], dateRange: [],
//
statusOptions: [],
// //
dataScopeOptions: [ dataScopeOptions: [
{ {
@ -354,9 +353,6 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
}, },
methods: { methods: {
/** 查询角色列表 */ /** 查询角色列表 */
@ -417,17 +413,13 @@ export default {
// //
handleStatusChange(row) { handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用"; let text = row.status === "0" ? "启用" : "停用";
this.$confirm('确认要"' + text + '""' + row.roleName + '"角色吗?', "警告", { this.$modal.confirm('确认要"' + text + '""' + row.roleName + '"角色吗?').then(function() {
confirmButtonText: "确定", return changeRoleStatus(row.roleId, row.status);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.$modal.msgSuccess(text + "成功");
}).then(function() { }).catch(function() {
return changeRoleStatus(row.roleId, row.status); row.status = row.status === "0" ? "1" : "0";
}).then(() => { });
this.msgSuccess(text + "成功");
}).catch(function() {
row.status = row.status === "0" ? "1" : "0";
});
}, },
// //
cancel() { cancel() {
@ -583,14 +575,14 @@ export default {
if (this.form.roleId != undefined) { if (this.form.roleId != undefined) {
this.form.menuIds = this.getMenuAllCheckedKeys(); this.form.menuIds = this.getMenuAllCheckedKeys();
updateRole(this.form).then(response => { updateRole(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
this.form.menuIds = this.getMenuAllCheckedKeys(); this.form.menuIds = this.getMenuAllCheckedKeys();
addRole(this.form).then(response => { addRole(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
@ -603,7 +595,7 @@ export default {
if (this.form.roleId != undefined) { if (this.form.roleId != undefined) {
this.form.deptIds = this.getDeptAllCheckedKeys(); this.form.deptIds = this.getDeptAllCheckedKeys();
dataScope(this.form).then(response => { dataScope(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.openDataScope = false; this.openDataScope = false;
this.getList(); this.getList();
}); });
@ -612,20 +604,16 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const roleIds = row.roleId || this.ids; const roleIds = row.roleId || this.ids;
this.$confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?').then(function() {
confirmButtonText: "确定", return delRole(roleIds);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delRole(roleIds); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/system/role/export', this.queryParams); this.$download.excel('/system/role/export', this.queryParams);
} }
} }
}; };

View File

@ -34,7 +34,7 @@
<el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" /> <el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" />
<el-table-column label="状态" align="center" prop="status"> <el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="statusOptions" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180"> <el-table-column label="创建时间" align="center" prop="createTime" width="180">
@ -61,6 +61,7 @@
<script> <script>
import { unallocatedUserList, authUserSelectAll } from "@/api/system/role"; import { unallocatedUserList, authUserSelectAll } from "@/api/system/role";
export default { export default {
dicts: ['sys_normal_disable'],
props: { props: {
// //
roleId: { roleId: {
@ -77,8 +78,6 @@ export default {
total: 0, total: 0,
// //
userList: [], userList: [],
//
statusOptions: [],
// //
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
@ -89,11 +88,6 @@ export default {
} }
}; };
}, },
created() {
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
},
methods: { methods: {
// //
show() { show() {
@ -130,7 +124,7 @@ export default {
const roleId = this.queryParams.roleId; const roleId = this.queryParams.roleId;
const userIds = this.userIds.join(","); const userIds = this.userIds.join(",");
authUserSelectAll({ roleId: roleId, userIds: userIds }).then(res => { authUserSelectAll({ roleId: roleId, userIds: userIds }).then(res => {
this.msgSuccess(res.msg); this.$modal.msgSuccess(res.msg);
if (res.code === 200) { if (res.code === 200) {
this.visible = false; this.visible = false;
this.$emit("ok"); this.$emit("ok");

View File

@ -103,7 +103,7 @@ export default {
const userId = this.form.userId; const userId = this.form.userId;
const roleIds = this.roleIds.join(","); const roleIds = this.roleIds.join(",");
updateAuthRole({ userId: userId, roleIds: roleIds }).then((response) => { updateAuthRole({ userId: userId, roleIds: roleIds }).then((response) => {
this.msgSuccess("授权成功"); this.$modal.msgSuccess("授权成功");
this.close(); this.close();
}); });
}, },

View File

@ -57,10 +57,10 @@
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -251,10 +251,10 @@
<el-form-item label="用户性别"> <el-form-item label="用户性别">
<el-select v-model="form.sex" placeholder="请选择"> <el-select v-model="form.sex" placeholder="请选择">
<el-option <el-option
v-for="dict in sexOptions" v-for="dict in dict.type.sys_user_sex"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="dict.value"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -263,10 +263,10 @@
<el-form-item label="状态"> <el-form-item label="状态">
<el-radio-group v-model="form.status"> <el-radio-group v-model="form.status">
<el-radio <el-radio
v-for="dict in statusOptions" v-for="dict in dict.type.sys_normal_disable"
:key="dict.dictValue" :key="dict.value"
:label="dict.dictValue" :label="dict.value"
>{{dict.dictLabel}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -354,6 +354,7 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default { export default {
name: "User", name: "User",
dicts: ['sys_normal_disable', 'sys_user_sex'],
components: { Treeselect }, components: { Treeselect },
data() { data() {
return { return {
@ -385,10 +386,6 @@ export default {
initPassword: undefined, initPassword: undefined,
// //
dateRange: [], dateRange: [],
//
statusOptions: [],
//
sexOptions: [],
// //
postOptions: [], postOptions: [],
// //
@ -472,12 +469,6 @@ export default {
created() { created() {
this.getList(); this.getList();
this.getTreeselect(); this.getTreeselect();
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
this.getDicts("sys_user_sex").then(response => {
this.sexOptions = response.data;
});
this.getConfigKey("sys.user.initPassword").then(response => { this.getConfigKey("sys.user.initPassword").then(response => {
this.initPassword = response.msg; this.initPassword = response.msg;
}); });
@ -512,17 +503,13 @@ export default {
// //
handleStatusChange(row) { handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用"; let text = row.status === "0" ? "启用" : "停用";
this.$confirm('确认要"' + text + '""' + row.userName + '"用户吗?', "警告", { this.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?').then(function() {
confirmButtonText: "确定", return changeUserStatus(row.userId, row.status);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.$modal.msgSuccess(text + "成功");
}).then(function() { }).catch(function() {
return changeUserStatus(row.userId, row.status); row.status = row.status === "0" ? "1" : "0";
}).then(() => { });
this.msgSuccess(text + "成功");
}).catch(function() {
row.status = row.status === "0" ? "1" : "0";
});
}, },
// //
cancel() { cancel() {
@ -615,7 +602,7 @@ export default {
inputErrorMessage: "用户密码长度必须介于 5 和 20 之间", inputErrorMessage: "用户密码长度必须介于 5 和 20 之间",
}).then(({ value }) => { }).then(({ value }) => {
resetUserPwd(row.userId, value).then(response => { resetUserPwd(row.userId, value).then(response => {
this.msgSuccess("修改成功,新密码是:" + value); this.$modal.msgSuccess("修改成功,新密码是:" + value);
}); });
}).catch(() => {}); }).catch(() => {});
}, },
@ -630,13 +617,13 @@ export default {
if (valid) { if (valid) {
if (this.form.userId != undefined) { if (this.form.userId != undefined) {
updateUser(this.form).then(response => { updateUser(this.form).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addUser(this.form).then(response => { addUser(this.form).then(response => {
this.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
@ -647,20 +634,16 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const userIds = row.userId || this.ids; const userIds = row.userId || this.ids;
this.$confirm('是否确认删除用户编号为"' + userIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?').then(function() {
confirmButtonText: "确定", return delUser(userIds);
cancelButtonText: "取消", }).then(() => {
type: "warning" this.getList();
}).then(function() { this.$modal.msgSuccess("删除成功");
return delUser(userIds); }).catch(() => {});
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.downLoadExcel('/system/user/export', this.queryParams); this.$download.excel('/system/user/export', this.queryParams);
}, },
/** 导入按钮操作 */ /** 导入按钮操作 */
handleImport() { handleImport() {
@ -669,7 +652,7 @@ export default {
}, },
/** 下载模板操作 */ /** 下载模板操作 */
importTemplate() { importTemplate() {
this.downLoadExcel('/system/user/importTemplate'); this.$download.excel('/system/user/importTemplate');
}, },
// //
handleFileUploadProgress(event, file, fileList) { handleFileUploadProgress(event, file, fileList) {

View File

@ -57,7 +57,7 @@ export default {
if (valid) { if (valid) {
updateUserPwd(this.user.oldPassword, this.user.newPassword).then( updateUserPwd(this.user.oldPassword, this.user.newPassword).then(
response => { response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
} }
); );
} }

View File

@ -111,7 +111,7 @@ export default {
// //
beforeUpload(file) { beforeUpload(file) {
if (file.type.indexOf("image/") == -1) { if (file.type.indexOf("image/") == -1) {
this.msgError("文件格式错误,请上传图片类型,如JPGPNG后缀的文件。"); this.$modal.msgError("文件格式错误,请上传图片类型,如JPGPNG后缀的文件。");
} else { } else {
const reader = new FileReader(); const reader = new FileReader();
reader.readAsDataURL(file); reader.readAsDataURL(file);
@ -131,7 +131,7 @@ export default {
this.open = false; this.open = false;
this.options.img = response.data.imgUrl; this.options.img = response.data.imgUrl;
store.commit('SET_AVATAR', this.options.img); store.commit('SET_AVATAR', this.options.img);
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.visible = false; this.visible = false;
}); });
}); });

View File

@ -62,7 +62,7 @@ export default {
this.$refs["form"].validate(valid => { this.$refs["form"].validate(valid => {
if (valid) { if (valid) {
updateUserProfile(this.user).then(response => { updateUserProfile(this.user).then(response => {
this.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
}); });
} }
}); });

View File

@ -137,23 +137,13 @@
<script> <script>
import draggable from 'vuedraggable' import draggable from 'vuedraggable'
import { saveAs } from 'file-saver'
import beautifier from 'js-beautify' import beautifier from 'js-beautify'
import ClipboardJS from 'clipboard' import ClipboardJS from 'clipboard'
import render from '@/utils/generator/render' import render from '@/utils/generator/render'
import RightPanel from './RightPanel' import RightPanel from './RightPanel'
import { import { inputComponents, selectComponents, layoutComponents, formConf } from '@/utils/generator/config'
inputComponents, import { beautifierConf, titleCase } from '@/utils/index'
selectComponents, import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html'
layoutComponents,
formConf
} from '@/utils/generator/config'
import {
exportDefault, beautifierConf, isNumberStr, titleCase
} from '@/utils/index'
import {
makeUpHtml, vueTemplate, vueScript, cssStyle
} from '@/utils/generator/html'
import { makeUpJs } from '@/utils/generator/js' import { makeUpJs } from '@/utils/generator/js'
import { makeUpCss } from '@/utils/generator/css' import { makeUpCss } from '@/utils/generator/css'
import drawingDefalut from '@/utils/generator/drawingDefalut' import drawingDefalut from '@/utils/generator/drawingDefalut'
@ -161,7 +151,6 @@ import logo from '@/assets/logo/logo.png'
import CodeTypeDialog from './CodeTypeDialog' import CodeTypeDialog from './CodeTypeDialog'
import DraggableItem from './DraggableItem' import DraggableItem from './DraggableItem'
const emptyActiveData = { style: {}, autosize: {} }
let oldActiveId let oldActiveId
let tempActiveData let tempActiveData
@ -287,7 +276,7 @@ export default {
execDownload(data) { execDownload(data) {
const codeStr = this.generateCode() const codeStr = this.generateCode()
const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' }) const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' })
saveAs(blob, data.fileName) this.$download.saveAs(blob, data.fileName)
}, },
execCopy(data) { execCopy(data) {
document.getElementById('copyNode').click() document.getElementById('copyNode').click()

View File

@ -4,8 +4,8 @@
<el-tab-pane label="基本信息" name="basic"> <el-tab-pane label="基本信息" name="basic">
<basic-info-form ref="basicInfo" :info="info" /> <basic-info-form ref="basicInfo" :info="info" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="字段信息" name="cloum"> <el-tab-pane label="字段信息" name="columnInfo">
<el-table ref="dragTable" :data="cloumns" row-key="columnId" :max-height="tableHeight"> <el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight">
<el-table-column label="序号" type="index" min-width="5%" class-name="allowDrag" /> <el-table-column label="序号" type="index" min-width="5%" class-name="allowDrag" />
<el-table-column <el-table-column
label="字段列名" label="字段列名"
@ -141,13 +141,13 @@ export default {
data() { data() {
return { return {
// name // name
activeName: "cloum", activeName: "columnInfo",
// //
tableHeight: document.documentElement.scrollHeight - 245 + "px", tableHeight: document.documentElement.scrollHeight - 245 + "px",
// //
tables: [], tables: [],
// //
cloumns: [], columns: [],
// //
dictOptions: [], dictOptions: [],
// //
@ -157,11 +157,11 @@ export default {
}; };
}, },
created() { created() {
const tableId = this.$route.params && this.$route.params.tableId; const tableId = this.$route.query && this.$route.query.tableId;
if (tableId) { if (tableId) {
// //
getGenTable(tableId).then(res => { getGenTable(tableId).then(res => {
this.cloumns = res.data.rows; this.columns = res.data.rows;
this.info = res.data.info; this.info = res.data.info;
this.tables = res.data.tables; this.tables = res.data.tables;
}); });
@ -184,7 +184,7 @@ export default {
const validateResult = res.every(item => !!item); const validateResult = res.every(item => !!item);
if (validateResult) { if (validateResult) {
const genTable = Object.assign({}, basicForm.model, genForm.model); const genTable = Object.assign({}, basicForm.model, genForm.model);
genTable.columns = this.cloumns; genTable.columns = this.columns;
genTable.params = { genTable.params = {
treeCode: genTable.treeCode, treeCode: genTable.treeCode,
treeName: genTable.treeName, treeName: genTable.treeName,
@ -192,13 +192,13 @@ export default {
parentMenuId: genTable.parentMenuId parentMenuId: genTable.parentMenuId
}; };
updateGenTable(genTable).then(res => { updateGenTable(genTable).then(res => {
this.msgSuccess(res.msg); this.$modal.msgSuccess(res.msg);
if (res.code === 200) { if (res.code === 200) {
this.close(); this.close();
} }
}); });
} else { } else {
this.msgError("表单校验未通过,请重新检查提交内容"); this.$modal.msgError("表单校验未通过,请重新检查提交内容");
} }
}); });
}, },
@ -212,7 +212,7 @@ export default {
/** 关闭按钮 */ /** 关闭按钮 */
close() { close() {
this.$store.dispatch("tagsView/delView", this.$route); this.$store.dispatch("tagsView/delView", this.$route);
this.$router.push({ path: "/tool/gen", query: { t: Date.now()}}) this.$router.push({ path: "/tool/gen", query: { t: Date.now(), pageNum: this.$route.query.pageNum } })
} }
}, },
mounted() { mounted() {
@ -220,10 +220,10 @@ export default {
const sortable = Sortable.create(el, { const sortable = Sortable.create(el, {
handle: ".allowDrag", handle: ".allowDrag",
onEnd: evt => { onEnd: evt => {
const targetRow = this.cloumns.splice(evt.oldIndex, 1)[0]; const targetRow = this.columns.splice(evt.oldIndex, 1)[0];
this.cloumns.splice(evt.newIndex, 0, targetRow); this.columns.splice(evt.newIndex, 0, targetRow);
for (let index in this.cloumns) { for (let index in this.columns) {
this.cloumns[index].sort = parseInt(index) + 1; this.columns[index].sort = parseInt(index) + 1;
} }
} }
}); });

View File

@ -104,8 +104,13 @@ export default {
}, },
/** 导入按钮操作 */ /** 导入按钮操作 */
handleImportTable() { handleImportTable() {
importTable({ tables: this.tables.join(",") }).then(res => { const tableNames = this.tables.join(",");
this.msgSuccess(res.msg); if (tableNames == "") {
this.$modal.msgError("请选择要导入的表");
return;
}
importTable({ tables: tableNames }).then(res => {
this.$modal.msgSuccess(res.msg);
if (res.code === 200) { if (res.code === 200) {
this.visible = false; this.visible = false;
this.$emit("ok"); this.$emit("ok");

View File

@ -180,7 +180,6 @@
<script> <script>
import { listTable, previewTable, delTable, genCode, synchDb } from "@/api/tool/gen"; import { listTable, previewTable, delTable, genCode, synchDb } from "@/api/tool/gen";
import importTable from "./importTable"; import importTable from "./importTable";
import { downLoadZip } from "@/utils/download";
import hljs from "highlight.js/lib/highlight"; import hljs from "highlight.js/lib/highlight";
import "highlight.js/styles/github-gist.css"; import "highlight.js/styles/github-gist.css";
hljs.registerLanguage("java", require("highlight.js/lib/languages/java")); hljs.registerLanguage("java", require("highlight.js/lib/languages/java"));
@ -238,7 +237,8 @@ export default {
const time = this.$route.query.t; const time = this.$route.query.t;
if (time != null && time != this.uniqueId) { if (time != null && time != this.uniqueId) {
this.uniqueId = time; this.uniqueId = time;
this.resetQuery(); this.queryParams.pageNum = Number(this.$route.query.pageNum);
this.getList();
} }
}, },
methods: { methods: {
@ -261,28 +261,24 @@ export default {
handleGenTable(row) { handleGenTable(row) {
const tableNames = row.tableName || this.tableNames; const tableNames = row.tableName || this.tableNames;
if (tableNames == "") { if (tableNames == "") {
this.msgError("请选择要生成的数据"); this.$modal.msgError("请选择要生成的数据");
return; return;
} }
if(row.genType === "1") { if(row.genType === "1") {
genCode(row.tableName).then(response => { genCode(row.tableName).then(response => {
this.msgSuccess("成功生成到自定义路径:" + row.genPath); this.$modal.msgSuccess("成功生成到自定义路径:" + row.genPath);
}); });
} else { } else {
downLoadZip("/tool/gen/batchGenCode?tables=" + tableNames, "ruoyi"); this.$download.zip("/tool/gen/batchGenCode?tables=" + tableNames, "ruoyi");
} }
}, },
/** 同步数据库操作 */ /** 同步数据库操作 */
handleSynchDb(row) { handleSynchDb(row) {
const tableName = row.tableName; const tableName = row.tableName;
this.$confirm('确认要强制同步"' + tableName + '"表结构吗?', "警告", { this.$modal.confirm('确认要强制同步"' + tableName + '"表结构吗?').then(function() {
confirmButtonText: "确定", return synchDb(tableName);
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return synchDb(tableName);
}).then(() => { }).then(() => {
this.msgSuccess("同步成功"); this.$modal.msgSuccess("同步成功");
}).catch(() => {}); }).catch(() => {});
}, },
/** 打开导入表弹窗 */ /** 打开导入表弹窗 */
@ -300,6 +296,7 @@ export default {
previewTable(row.tableId).then(response => { previewTable(row.tableId).then(response => {
this.preview.data = response.data; this.preview.data = response.data;
this.preview.open = true; this.preview.open = true;
this.preview.activeName = "domain.java";
}); });
}, },
/** 高亮显示 */ /** 高亮显示 */
@ -319,20 +316,16 @@ export default {
/** 修改按钮操作 */ /** 修改按钮操作 */
handleEditTable(row) { handleEditTable(row) {
const tableId = row.tableId || this.ids[0]; const tableId = row.tableId || this.ids[0];
this.$router.push("/tool/gen-edit/index/" + tableId); this.$router.push({ path: '/tool/gen-edit/index', query: { tableId: tableId, pageNum: this.queryParams.pageNum } });
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const tableIds = row.tableId || this.ids; const tableIds = row.tableId || this.ids;
this.$confirm('是否确认删除表编号为"' + tableIds + '"的数据项?', "警告", { this.$modal.confirm('是否确认删除表编号为"' + tableIds + '"的数据项?').then(function() {
confirmButtonText: "确定", return delTable(tableIds);
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return delTable(tableIds);
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).catch(() => {}); }).catch(() => {});
} }
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.1.0</version> <version>3.2.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -84,6 +84,11 @@
<artifactId>knife4j-spring-boot-starter</artifactId> <artifactId>knife4j-spring-boot-starter</artifactId>
</dependency> </dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<!-- Mysql驱动包 --> <!-- Mysql驱动包 -->
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>

View File

@ -38,4 +38,9 @@ public @interface Log
* 是否保存请求的参数 * 是否保存请求的参数
*/ */
public boolean isSaveRequestData() default true; public boolean isSaveRequestData() default true;
/**
* 是否保存响应的参数
*/
public boolean isSaveResponseData() default true;
} }

View File

@ -20,10 +20,15 @@ import java.util.concurrent.TimeUnit;
public @interface RepeatSubmit { public @interface RepeatSubmit {
/** /**
* 默认使用全局配置 * 间隔时间(ms)小于此时间视为重复提交
*/ */
int intervalTime() default 0; int interval() default 5000;
TimeUnit timeUnit() default TimeUnit.MILLISECONDS; TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
/**
* 提示消息
*/
String message() default "不允许重复提交,请稍后再试";
} }

View File

@ -44,16 +44,21 @@ public class GenConstants
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
"bit", "bigint", "float", "double", "decimal" }; "bit", "bigint", "float", "double", "decimal" };
/** 页面不需要添加字段 */
public static final String[] COLUMNNAME_NOT_ADD = { "create_by", "create_time", "del_flag", "update_by",
"update_time", "version" };
/** 页面不需要编辑字段 */ /** 页面不需要编辑字段 */
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" }; public static final String[] COLUMNNAME_NOT_EDIT = { "create_by", "create_time", "del_flag", "update_by",
"update_time", "version" };
/** 页面不需要显示的列表字段 */ /** 页面不需要显示的列表字段 */
public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by", public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
"update_time" }; "update_time", "version" };
/** 页面不需要查询字段 */ /** 页面不需要查询字段 */
public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by", public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
"update_time", "remark" }; "update_time", "remark", "version" };
/** Entity基类字段 */ /** Entity基类字段 */
public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" }; public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };

View File

@ -1,5 +1,6 @@
package com.ruoyi.common.core.domain; package com.ruoyi.common.core.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -62,6 +63,7 @@ public class BaseEntity implements Serializable {
/** /**
* 请求参数 * 请求参数
*/ */
@JsonIgnore
@ApiModelProperty(value = "请求参数") @ApiModelProperty(value = "请求参数")
private Map<String, Object> params = new HashMap<>(); private Map<String, Object> params = new HashMap<>();

View File

@ -0,0 +1,107 @@
package com.ruoyi.common.core.domain.dto;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 操作日志记录表 oper_log
*
* @author ruoyi
*/
@Data
@NoArgsConstructor
@Accessors(chain = true)
public class OperLogDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 日志主键
*/
private Long operId;
/**
* 操作模块
*/
private String title;
/**
* 业务类型0其它 1新增 2修改 3删除
*/
private Integer businessType;
/**
* 业务类型数组
*/
private Integer[] businessTypes;
/**
* 请求方法
*/
private String method;
/**
* 请求方式
*/
private String requestMethod;
/**
* 操作类别0其它 1后台用户 2手机端用户
*/
private Integer operatorType;
/**
* 操作人员
*/
private String operName;
/**
* 部门名称
*/
private String deptName;
/**
* 请求url
*/
private String operUrl;
/**
* 操作地址
*/
private String operIp;
/**
* 操作地点
*/
private String operLocation;
/**
* 请求参数
*/
private String operParam;
/**
* 返回参数
*/
private String jsonResult;
/**
* 操作状态0正常 1异常
*/
private Integer status;
/**
* 错误消息
*/
private String errorMsg;
/**
* 操作时间
*/
private Date operTime;
}

View File

@ -90,7 +90,7 @@ public class SysDictData implements Serializable {
* 状态0正常 1停用 * 状态0正常 1停用
*/ */
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class) @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_common_status") @ExcelDictFormat(dictType = "sys_normal_disable")
private String status; private String status;
/** /**

View File

@ -57,7 +57,7 @@ public class SysDictType implements Serializable {
* 状态0正常 1停用 * 状态0正常 1停用
*/ */
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class) @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_common_status") @ExcelDictFormat(dictType = "sys_normal_disable")
private String status; private String status;
/** /**

View File

@ -66,6 +66,11 @@ public class SysMenu implements Serializable {
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符") @Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
private String component; private String component;
/**
* 路由参数
*/
private String query;
/** /**
* 是否为外链0是 1否 * 是否为外链0是 1否
*/ */

View File

@ -91,11 +91,6 @@ public class SysUser implements Serializable {
return password; return password;
} }
/**
* 盐加密
*/
private String salt;
/** /**
* 帐号状态0正常 1停用 * 帐号状态0正常 1停用
*/ */

View File

@ -1,260 +0,0 @@
package com.ruoyi.common.core.redis;
import com.google.common.collect.Lists;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
/**
* spring redis 工具类
*
* @author shenxinquan
* @see com.ruoyi.common.utils.RedisUtils
* @deprecated 3.2.0 删除此类
**/
@SuppressWarnings(value = {"unchecked", "rawtypes"})
@Component
@Deprecated
public class RedisCache {
@Autowired
private RedissonClient redissonClient;
/**
* 发布通道消息
*
* @param channelKey 通道key
* @param msg 发送数据
* @param consumer 自定义处理
*/
public <T> void publish(String channelKey, T msg, Consumer<T> consumer) {
RTopic topic = redissonClient.getTopic(channelKey);
topic.publish(msg);
consumer.accept(msg);
}
public <T> void publish(String channelKey, T msg) {
RTopic topic = redissonClient.getTopic(channelKey);
topic.publish(msg);
}
/**
* 订阅通道接收消息
*
* @param channelKey 通道key
* @param clazz 消息类型
* @param consumer 自定义处理
*/
public <T> void subscribe(String channelKey, Class<T> clazz, Consumer<T> consumer) {
RTopic topic = redissonClient.getTopic(channelKey);
topic.addListener(clazz, (channel, msg) -> consumer.accept(msg));
}
/**
* 缓存基本的对象IntegerString实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
*/
public <T> void setCacheObject(final String key, final T value) {
redissonClient.getBucket(key).set(value);
}
/**
* 缓存基本的对象IntegerString实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
*/
public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
RBucket<T> result = redissonClient.getBucket(key);
result.set(value);
result.expire(timeout, timeUnit);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @return true=设置成功false=设置失败
*/
public boolean expire(final String key, final long timeout) {
return expire(key, timeout, TimeUnit.SECONDS);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功false=设置失败
*/
public boolean expire(final String key, final long timeout, final TimeUnit unit) {
RBucket rBucket = redissonClient.getBucket(key);
return rBucket.expire(timeout, unit);
}
/**
* 获得缓存的基本对象
*
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public <T> T getCacheObject(final String key) {
RBucket<T> rBucket = redissonClient.getBucket(key);
return rBucket.get();
}
/**
* 删除单个对象
*
* @param key
*/
public boolean deleteObject(final String key) {
return redissonClient.getBucket(key).delete();
}
/* */
/**
* 删除集合对象
*
* @param collection 多个对象
* @return
*/
public void deleteObject(final Collection collection) {
RBatch batch = redissonClient.createBatch();
collection.forEach(t->{
batch.getBucket(t.toString()).deleteAsync();
});
batch.execute();
}
/**
* 缓存List数据
*
* @param key 缓存的键值
* @param dataList 待缓存的List数据
* @return 缓存的对象
*/
public <T> boolean setCacheList(final String key, final List<T> dataList) {
RList<T> rList = redissonClient.getList(key);
return rList.addAll(dataList);
}
/**
* 获得缓存的list对象
*
* @param key 缓存的键值
* @return 缓存键值对应的数据
*/
public <T> List<T> getCacheList(final String key) {
RList<T> rList = redissonClient.getList(key);
return rList.readAll();
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param dataSet 缓存的数据
* @return 缓存数据的对象
*/
public <T> boolean setCacheSet(final String key, final Set<T> dataSet) {
RSet<T> rSet = redissonClient.getSet(key);
return rSet.addAll(dataSet);
}
/**
* 获得缓存的set
*
* @param key
* @return
*/
public <T> Set<T> getCacheSet(final String key) {
RSet<T> rSet = redissonClient.getSet(key);
return rSet.readAll();
}
/**
* 缓存Map
*
* @param key
* @param dataMap
*/
public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
if (dataMap != null) {
RMap<String, T> rMap = redissonClient.getMap(key);
rMap.putAll(dataMap);
}
}
/**
* 获得缓存的Map
*
* @param key
* @return
*/
public <T> Map<String, T> getCacheMap(final String key) {
RMap<String, T> rMap = redissonClient.getMap(key);
return rMap.getAll(rMap.keySet());
}
/**
* 往Hash中存入数据
*
* @param key Redis键
* @param hKey Hash键
* @param value
*/
public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
RMap<String, T> rMap = redissonClient.getMap(key);
rMap.put(hKey, value);
}
/**
* 获取Hash中的数据
*
* @param key Redis键
* @param hKey Hash键
* @return Hash中的对象
*/
public <T> T getCacheMapValue(final String key, final String hKey) {
RMap<String, T> rMap = redissonClient.getMap(key);
return rMap.get(hKey);
}
/**
* 获取多个Hash中的数据
*
* @param key Redis键
* @param hKeys Hash键集合
* @return Hash对象集合
*/
public <K,V> Map<K,V> getMultiCacheMapValue(final String key, final Set<K> hKeys) {
RMap<K,V> rMap = redissonClient.getMap(key);
return rMap.getAll(hKeys);
}
/**
* 获得缓存的基本对象列表
*
* @param pattern 字符串前缀
* @return 对象列表
*/
public Collection<String> keys(final String pattern) {
Iterable<String> iterable = redissonClient.getKeys().getKeysByPattern(pattern);
return Lists.newArrayList(iterable);
}
}

View File

@ -0,0 +1,9 @@
package com.ruoyi.common.core.service;
import javax.servlet.http.HttpServletRequest;
public interface LogininforService {
void recordLogininfor(String username, String status, String message,
HttpServletRequest request, Object... args);
}

View File

@ -0,0 +1,9 @@
package com.ruoyi.common.core.service;
import com.ruoyi.common.core.domain.dto.OperLogDTO;
import org.springframework.scheduling.annotation.Async;
public interface OperLogService {
@Async
void recordOper(OperLogDTO operLogDTO);
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.common.core.service;
import com.ruoyi.common.core.domain.model.LoginUser;
import javax.servlet.http.HttpServletRequest;
/**
* token验证处理
*
* @author Lion Li
*/
public interface TokenService {
/**
* 获取用户身份信息
*
* @return 用户信息
*/
LoginUser getLoginUser(HttpServletRequest request);
/**
* 设置用户身份信息
*/
void setLoginUser(LoginUser loginUser);
/**
* 删除用户身份信息
*/
void delLoginUser(String token);
/**
* 创建令牌
*
* @param loginUser 用户信息
* @return 令牌
*/
String createToken(LoginUser loginUser);
/**
* 验证令牌有效期相差不足20分钟自动刷新缓存
*
* @param loginUser
* @return 令牌
*/
void verifyToken(LoginUser loginUser);
/**
* 刷新令牌有效期
*
* @param loginUser 登录信息
*/
void refreshToken(LoginUser loginUser);
/**
* 设置用户代理信息
*
* @param loginUser 登录信息
*/
void setUserAgent(LoginUser loginUser);
/**
* 从令牌中获取用户名
*
* @param token 令牌
* @return 用户名
*/
String getUsernameFromToken(String token);
}

View File

@ -16,5 +16,10 @@ public enum LimitType
/** /**
* 根据请求者IP进行限流 * 根据请求者IP进行限流
*/ */
IP IP,
/**
* 实例限流(集群多后端实例)
*/
CLUSTER
} }

View File

@ -15,7 +15,7 @@ import java.util.concurrent.ThreadPoolExecutor;
@AllArgsConstructor @AllArgsConstructor
public enum ThreadPoolRejectedPolicy { public enum ThreadPoolRejectedPolicy {
CALLER_RUNS_POLICY("等待", ThreadPoolExecutor.CallerRunsPolicy.class), CALLER_RUNS_POLICY("调用方执行", ThreadPoolExecutor.CallerRunsPolicy.class),
DISCARD_OLDEST_POLICY("放弃最旧的", ThreadPoolExecutor.DiscardOldestPolicy.class), DISCARD_OLDEST_POLICY("放弃最旧的", ThreadPoolExecutor.DiscardOldestPolicy.class),
DISCARD_POLICY("丢弃", ThreadPoolExecutor.DiscardPolicy.class), DISCARD_POLICY("丢弃", ThreadPoolExecutor.DiscardPolicy.class),
ABORT_POLICY("中止", ThreadPoolExecutor.AbortPolicy.class); ABORT_POLICY("中止", ThreadPoolExecutor.AbortPolicy.class);

View File

@ -1,4 +1,4 @@
package com.ruoyi.framework.config.properties; package com.ruoyi.common.properties;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;

View File

@ -25,6 +25,32 @@ public class RedisUtils {
private static RedissonClient client = SpringUtils.getBean(RedissonClient.class); private static RedissonClient client = SpringUtils.getBean(RedissonClient.class);
/**
* 限流
*
* @param key 限流key
* @param rateType 限流类型
* @param rate 速率
* @param rateInterval 速率间隔
* @return -1 表示失败
*/
public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval) {
RRateLimiter rateLimiter = client.getRateLimiter(key);
rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS);
if (rateLimiter.tryAcquire()) {
return rateLimiter.availablePermits();
} else {
return -1L;
}
}
/**
* 获取实例id
*/
public static String getClientId() {
return client.getId();
}
/** /**
* 发布通道消息 * 发布通道消息
* *

View File

@ -35,6 +35,7 @@ public class FileUtils extends FileUtil
.append(percentEncodedFileName); .append(percentEncodedFileName);
response.setHeader("Content-disposition", contentDispositionValue.toString()); response.setHeader("Content-disposition", contentDispositionValue.toString());
response.setHeader("download-filename", percentEncodedFileName);
} }
/** /**

View File

@ -27,6 +27,9 @@ public class AddressUtils {
public static String getRealAddressByIP(String ip) { public static String getRealAddressByIP(String ip) {
String address = UNKNOWN; String address = UNKNOWN;
if (StringUtils.isBlank(ip)){
return address;
}
// 内网不查询 // 内网不查询
ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip); ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
if (NetUtil.isInnerIP(ip)) { if (NetUtil.isInnerIP(ip)) {

View File

@ -46,7 +46,7 @@ public class ExcelUtil {
response.reset(); response.reset();
response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
FileUtils.setAttachmentResponseHeader(response, URLEncoder.encode(filename, StandardCharsets.UTF_8.toString())); FileUtils.setAttachmentResponseHeader(response, filename);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
ServletOutputStream os = response.getOutputStream(); ServletOutputStream os = response.getOutputStream();
EasyExcel.write(os, clazz) EasyExcel.write(os, clazz)

View File

@ -34,6 +34,9 @@ public class RedisCacheController {
* 如果没有,就调用方法,然后把结果缓存起来 * 如果没有,就调用方法,然后把结果缓存起来
* 这个注解一般用在查询方法上 * 这个注解一般用在查询方法上
* *
* 重点说明: 缓存注解严谨与其他筛选数据功能一起使用
* 例如: 数据权限注解 会造成 缓存击穿 数据不一致问题
*
* cacheNames 为配置文件内 groupId * cacheNames 为配置文件内 groupId
*/ */
@ApiOperation("测试 @Cacheable") @ApiOperation("测试 @Cacheable")

View File

@ -0,0 +1,58 @@
package com.ruoyi.demo.controller;
import com.ruoyi.common.annotation.RateLimiter;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.LimitType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 测试分布式限流样例
*
* @author Lion Li
*/
@Api(value = "测试分布式限流样例", tags = {"测试分布式限流样例"})
@Slf4j
@RestController
@RequestMapping("/demo/rateLimiter")
public class RedisRateLimiterController {
/**
* 测试全局限流
* 全局影响
*/
@ApiOperation("测试全局限流")
@RateLimiter(count = 2, time = 10)
@GetMapping("/test")
public AjaxResult<String> test(String value){
return AjaxResult.success("操作成功",value);
}
/**
* 测试请求IP限流
* 同一IP请求受影响
*/
@ApiOperation("测试请求IP限流")
@RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
@GetMapping("/testip")
public AjaxResult<String> testip(String value){
return AjaxResult.success("操作成功",value);
}
/**
* 测试集群实例限流
* 启动两个后端服务互不影响
*/
@ApiOperation("测试集群实例限流")
@RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
@GetMapping("/testcluster")
public AjaxResult<String> testcluster(String value){
return AjaxResult.success("操作成功",value);
}
}

View File

@ -96,7 +96,7 @@ public class TestDemoController extends BaseController {
@ApiOperation("新增测试单表") @ApiOperation("新增测试单表")
@PreAuthorize("@ss.hasPermi('demo:demo:add')") @PreAuthorize("@ss.hasPermi('demo:demo:add')")
@Log(title = "测试单表", businessType = BusinessType.INSERT) @Log(title = "测试单表", businessType = BusinessType.INSERT)
@RepeatSubmit(intervalTime = 2, timeUnit = TimeUnit.SECONDS) @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "不允许重复提交")
@PostMapping() @PostMapping()
public AjaxResult<Void> add(@Validated(AddGroup.class) @RequestBody TestDemoBo bo) { public AjaxResult<Void> add(@Validated(AddGroup.class) @RequestBody TestDemoBo bo) {
return toAjax(iTestDemoService.insertByBo(bo) ? 1 : 0); return toAjax(iTestDemoService.insertByBo(bo) ? 1 : 0);

View File

@ -75,7 +75,11 @@ public class TestDemoServiceImpl extends ServicePlusImpl<TestDemoMapper, TestDem
public Boolean insertByBo(TestDemoBo bo) { public Boolean insertByBo(TestDemoBo bo) {
TestDemo add = BeanUtil.toBean(bo, TestDemo.class); TestDemo add = BeanUtil.toBean(bo, TestDemo.class);
validEntityBeforeSave(add); validEntityBeforeSave(add);
return save(add); boolean flag = save(add);
if (flag) {
bo.setId(add.getId());
}
return flag;
} }
@Override @Override

View File

@ -54,7 +54,11 @@ public class TestTreeServiceImpl extends ServicePlusImpl<TestTreeMapper, TestTre
public Boolean insertByBo(TestTreeBo bo) { public Boolean insertByBo(TestTreeBo bo) {
TestTree add = BeanUtil.toBean(bo, TestTree.class); TestTree add = BeanUtil.toBean(bo, TestTree.class);
validEntityBeforeSave(add); validEntityBeforeSave(add);
return save(add); boolean flag = save(add);
if (flag) {
bo.setId(add.getId());
}
return flag;
} }
@Override @Override

View File

@ -9,14 +9,10 @@ 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 org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
/** /**
@ -58,23 +54,13 @@ public class DataScopeAspect {
*/ */
public static final String DATA_SCOPE = "dataScope"; public static final String DATA_SCOPE = "dataScope";
// 配置织入点 @Before("@annotation(controllerDataScope)")
@Pointcut("@annotation(com.ruoyi.common.annotation.DataScope)") public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable {
public void dataScopePointCut() {
}
@Before("dataScopePointCut()")
public void doBefore(JoinPoint point) throws Throwable {
clearDataScope(point); clearDataScope(point);
handleDataScope(point); handleDataScope(point, controllerDataScope);
} }
protected void handleDataScope(final JoinPoint joinPoint) { protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) {
// 获得注解
DataScope controllerDataScope = getAnnotationLog(joinPoint);
if (controllerDataScope == null) {
return;
}
// 获取当前的用户 // 获取当前的用户
LoginUser loginUser = SecurityUtils.getLoginUser(); LoginUser loginUser = SecurityUtils.getLoginUser();
if (StringUtils.isNotNull(loginUser)) { if (StringUtils.isNotNull(loginUser)) {
@ -133,20 +119,6 @@ public class DataScopeAspect {
} }
} }
/**
* 是否存在注解如果存在就获取
*/
private DataScope getAnnotationLog(JoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
return method.getAnnotation(DataScope.class);
}
return null;
}
/** /**
* 拼接权限sql前先清空params.dataScope参数防止注入 * 拼接权限sql前先清空params.dataScope参数防止注入
*/ */

View File

@ -6,33 +6,21 @@ import com.ruoyi.common.utils.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Objects;
/** /**
* 多数据源处理 * 多数据源处理
* *
* @author ruoyi * @author Lion Li
*/ */
@Aspect @Aspect
@Order(-500) @Order(-500)
@Component @Component
public class DataSourceAspect { public class DataSourceAspect {
@Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)" @Around("@annotation(dataSource) || @within(dataSource)")
+ "|| @within(com.ruoyi.common.annotation.DataSource)") public Object around(ProceedingJoinPoint point, DataSource dataSource) throws Throwable {
public void dsPointCut() {
}
@Around("dsPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
DataSource dataSource = getDataSource(point);
if (StringUtils.isNotNull(dataSource)) { if (StringUtils.isNotNull(dataSource)) {
DynamicDataSourceContextHolder.poll(); DynamicDataSourceContextHolder.poll();
String source = dataSource.value().getSource(); String source = dataSource.value().getSource();
@ -47,16 +35,4 @@ public class DataSourceAspect {
} }
} }
/**
* 获取需要切换的数据源
*/
public DataSource getDataSource(ProceedingJoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
if (Objects.nonNull(dataSource)) {
return dataSource;
}
return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
}
} }

View File

@ -1,7 +1,9 @@
package com.ruoyi.framework.aspectj; package com.ruoyi.framework.aspectj;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.dto.OperLogDTO;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.service.OperLogService;
import com.ruoyi.common.enums.BusinessStatus; import com.ruoyi.common.enums.BusinessStatus;
import com.ruoyi.common.enums.HttpMethod; import com.ruoyi.common.enums.HttpMethod;
import com.ruoyi.common.utils.JsonUtils; import com.ruoyi.common.utils.JsonUtils;
@ -9,17 +11,11 @@ import com.ruoyi.common.utils.SecurityUtils;
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.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.web.service.AsyncService; import lombok.extern.slf4j.Slf4j;
import com.ruoyi.system.domain.SysOperLog;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -27,81 +23,58 @@ import org.springframework.web.servlet.HandlerMapping;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
/** /**
* 操作日志记录处理 * 操作日志记录处理
* *
* @author ruoyi * @author Lion Li
*/ */
@Slf4j
@Aspect @Aspect
@Component @Component
public class LogAspect public class LogAspect {
{
private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
// 配置织入点
@Pointcut("@annotation(com.ruoyi.common.annotation.Log)")
public void logPointCut()
{
}
/** /**
* 处理完请求后执行 * 处理完请求后执行
* *
* @param joinPoint 切点 * @param joinPoint 切点
*/ */
@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult") @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
{ handleLog(joinPoint, controllerLog, null, jsonResult);
handleLog(joinPoint, null, jsonResult);
} }
/** /**
* 拦截异常操作 * 拦截异常操作
* *
* @param joinPoint 切点 * @param joinPoint 切点
* @param e 异常 * @param e 异常
*/ */
@AfterThrowing(value = "logPointCut()", throwing = "e") @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
{ handleLog(joinPoint, controllerLog, e, null);
handleLog(joinPoint, e, null);
} }
protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
{ try {
try
{
// 获得注解
Log controllerLog = getAnnotationLog(joinPoint);
if (controllerLog == null)
{
return;
}
// 获取当前的用户 // 获取当前的用户
LoginUser loginUser = SecurityUtils.getLoginUser(); LoginUser loginUser = SecurityUtils.getLoginUser();
// *========数据库日志=========*// // *========数据库日志=========*//
SysOperLog operLog = new SysOperLog(); OperLogDTO operLog = new OperLogDTO();
operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
// 请求的地址 // 请求的地址
String ip = ServletUtils.getClientIP(); String ip = ServletUtils.getClientIP();
operLog.setOperIp(ip); operLog.setOperIp(ip);
// 返回参数
operLog.setJsonResult(JsonUtils.toJsonString(jsonResult));
operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
if (loginUser != null) if (loginUser != null) {
{
operLog.setOperName(loginUser.getUsername()); operLog.setOperName(loginUser.getUsername());
} }
if (e != null) if (e != null) {
{
operLog.setStatus(BusinessStatus.FAIL.ordinal()); operLog.setStatus(BusinessStatus.FAIL.ordinal());
operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
} }
@ -112,12 +85,10 @@ public class LogAspect
// 设置请求方式 // 设置请求方式
operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数 // 处理设置注解上的参数
getControllerMethodDescription(joinPoint, controllerLog, operLog); getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
// 保存数据库 // 保存数据库
SpringUtils.getBean(AsyncService.class).recordOper(operLog); SpringUtils.getBean(OperLogService.class).recordOper(operLog);
} } catch (Exception exp) {
catch (Exception exp)
{
// 记录本地异常日志 // 记录本地异常日志
log.error("==前置通知异常=="); log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage()); log.error("异常信息:{}", exp.getMessage());
@ -128,12 +99,11 @@ public class LogAspect
/** /**
* 获取注解中对方法的描述信息 用于Controller层注解 * 获取注解中对方法的描述信息 用于Controller层注解
* *
* @param log 日志 * @param log 日志
* @param operLog 操作日志 * @param operLog 操作日志
* @throws Exception * @throws Exception
*/ */
public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) throws Exception public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogDTO operLog, Object jsonResult) throws Exception {
{
// 设置action动作 // 设置action动作
operLog.setBusinessType(log.businessType().ordinal()); operLog.setBusinessType(log.businessType().ordinal());
// 设置标题 // 设置标题
@ -141,11 +111,14 @@ public class LogAspect
// 设置操作人类别 // 设置操作人类别
operLog.setOperatorType(log.operatorType().ordinal()); operLog.setOperatorType(log.operatorType().ordinal());
// 是否需要保存request参数和值 // 是否需要保存request参数和值
if (log.isSaveRequestData()) if (log.isSaveRequestData()) {
{
// 获取参数的信息传入到数据库中 // 获取参数的信息传入到数据库中
setRequestValue(joinPoint, operLog); setRequestValue(joinPoint, operLog);
} }
// 是否需要保存response参数和值
if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) {
operLog.setJsonResult(StringUtils.substring(JsonUtils.toJsonString(jsonResult), 0, 2000));
}
} }
/** /**
@ -154,50 +127,32 @@ public class LogAspect
* @param operLog 操作日志 * @param operLog 操作日志
* @throws Exception 异常 * @throws Exception 异常
*/ */
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception private void setRequestValue(JoinPoint joinPoint, OperLogDTO operLog) throws Exception {
{
String requestMethod = operLog.getRequestMethod(); String requestMethod = operLog.getRequestMethod();
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
{
String params = argsArrayToString(joinPoint.getArgs()); String params = argsArrayToString(joinPoint.getArgs());
operLog.setOperParam(StringUtils.substring(params, 0, 2000)); operLog.setOperParam(StringUtils.substring(params, 0, 2000));
} } else {
else
{
Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000)); operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));
} }
} }
/**
* 是否存在注解如果存在就获取
*/
private Log getAnnotationLog(JoinPoint joinPoint) throws Exception
{
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null)
{
return method.getAnnotation(Log.class);
}
return null;
}
/** /**
* 参数拼装 * 参数拼装
*/ */
private String argsArrayToString(Object[] paramsArray) private String argsArrayToString(Object[] paramsArray) {
{
StringBuilder params = new StringBuilder(); StringBuilder params = new StringBuilder();
if (paramsArray != null && paramsArray.length > 0) if (paramsArray != null && paramsArray.length > 0) {
{ for (Object o : paramsArray) {
for (Object o : paramsArray) { if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
if (StringUtils.isNotNull(o) && !isFilterObject(o)) { try {
params.append(JsonUtils.toJsonString(o)).append(" "); params.append(JsonUtils.toJsonString(o)).append(" ");
} } catch (Exception e) {
} e.printStackTrace();
}
}
}
} }
return params.toString().trim(); return params.toString().trim();
} }
@ -209,27 +164,21 @@ public class LogAspect
* @return 如果是需要过滤的对象则返回true否则返回false * @return 如果是需要过滤的对象则返回true否则返回false
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public boolean isFilterObject(final Object o) public boolean isFilterObject(final Object o) {
{
Class<?> clazz = o.getClass(); Class<?> clazz = o.getClass();
if (clazz.isArray()) if (clazz.isArray()) {
{
return clazz.getComponentType().isAssignableFrom(MultipartFile.class); return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
} } else if (Collection.class.isAssignableFrom(clazz)) {
else if (Collection.class.isAssignableFrom(clazz))
{
Collection collection = (Collection) o; Collection collection = (Collection) o;
for (Object value : collection) { for (Object value : collection) {
return value instanceof MultipartFile; return value instanceof MultipartFile;
} }
} } else if (Map.class.isAssignableFrom(clazz)) {
else if (Map.class.isAssignableFrom(clazz))
{
Map map = (Map) o; Map map = (Map) o;
for (Object value : map.entrySet()) { for (Object value : map.entrySet()) {
Map.Entry entry = (Map.Entry) value; Map.Entry entry = (Map.Entry) value;
return entry.getValue() instanceof MultipartFile; return entry.getValue() instanceof MultipartFile;
} }
} }
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
|| o instanceof BindingResult; || o instanceof BindingResult;

View File

@ -3,114 +3,63 @@ package com.ruoyi.framework.aspectj;
import com.ruoyi.common.annotation.RateLimiter; import com.ruoyi.common.annotation.RateLimiter;
import com.ruoyi.common.enums.LimitType; import com.ruoyi.common.enums.LimitType;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
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 lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature; import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger; import org.redisson.api.RateType;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
/** /**
* 限流处理 * 限流处理
* *
* @author ruoyi * @author Lion Li
*/ */
@Slf4j
@Aspect @Aspect
@Component @Component
public class RateLimiterAspect public class RateLimiterAspect {
{
private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class);
private RedisTemplate<Object, Object> redisTemplate; @Before("@annotation(rateLimiter)")
public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable {
private RedisScript<Long> limitScript;
@Autowired
public void setRedisTemplate1(RedisTemplate<Object, Object> redisTemplate)
{
this.redisTemplate = redisTemplate;
}
@Autowired
public void setLimitScript(RedisScript<Long> limitScript)
{
this.limitScript = limitScript;
}
// 配置织入点
@Pointcut("@annotation(com.ruoyi.common.annotation.RateLimiter)")
public void rateLimiterPointCut()
{
}
@Before("rateLimiterPointCut()")
public void doBefore(JoinPoint point) throws Throwable
{
RateLimiter rateLimiter = getAnnotationRateLimiter(point);
String key = rateLimiter.key();
int time = rateLimiter.time(); int time = rateLimiter.time();
int count = rateLimiter.count(); int count = rateLimiter.count();
String combineKey = getCombineKey(rateLimiter, point); String combineKey = getCombineKey(rateLimiter, point);
List<Object> keys = Collections.singletonList(combineKey); try {
try RateType rateType = RateType.OVERALL;
{ if (rateLimiter.limitType() == LimitType.CLUSTER) {
Long number = redisTemplate.execute(limitScript, keys, count, time); rateType = RateType.PER_CLIENT;
if (StringUtils.isNull(number) || number.intValue() > count) }
{ long number = RedisUtils.rateLimiter(combineKey, rateType, count, time);
if (number == -1) {
throw new ServiceException("访问过于频繁,请稍后再试"); throw new ServiceException("访问过于频繁,请稍后再试");
} }
log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), key); log.info("限制令牌 => {}, 剩余令牌 => {}, 缓存key => '{}'", count, number, combineKey);
} } catch (ServiceException e) {
catch (ServiceException e)
{
throw e; throw e;
} } catch (Exception e) {
catch (Exception e)
{
throw new RuntimeException("服务器限流异常,请稍后再试"); throw new RuntimeException("服务器限流异常,请稍后再试");
} }
} }
/** public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) {
* 是否存在注解如果存在就获取 StringBuilder stringBuffer = new StringBuilder(rateLimiter.key());
*/ if (rateLimiter.limitType() == LimitType.IP) {
private RateLimiter getAnnotationRateLimiter(JoinPoint joinPoint) // 获取请求ip
{ stringBuffer.append(ServletUtils.getClientIP()).append("-");
Signature signature = joinPoint.getSignature(); } else if (rateLimiter.limitType() == LimitType.CLUSTER){
MethodSignature methodSignature = (MethodSignature) signature; // 获取客户端实例id
Method method = methodSignature.getMethod(); stringBuffer.append(RedisUtils.getClientId()).append("-");
if (method != null)
{
return method.getAnnotation(RateLimiter.class);
}
return null;
}
public String getCombineKey(RateLimiter rateLimiter, JoinPoint point)
{
StringBuffer stringBuffer = new StringBuffer(rateLimiter.key());
if (rateLimiter.limitType() == LimitType.IP)
{
stringBuffer.append(ServletUtils.getClientIP());
} }
MethodSignature signature = (MethodSignature) point.getSignature(); MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod(); Method method = signature.getMethod();
Class<?> targetClass = method.getDeclaringClass(); Class<?> targetClass = method.getDeclaringClass();
stringBuffer.append("-").append(targetClass.getName()).append("- ").append(method.getName()); stringBuffer.append(targetClass.getName()).append("-").append(method.getName());
return stringBuffer.toString(); return stringBuffer.toString();
} }
} }

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