mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2025-09-18 01:06:40 +08:00
发布 v3.1.0
This commit is contained in:
parent
33033d7d78
commit
5a0136a655
@ -10,9 +10,6 @@ end_of_line = lf
|
|||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
||||||
[*.java]
|
|
||||||
indent_style = tab
|
|
||||||
|
|
||||||
[*.{json,yml}]
|
[*.{json,yml}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
|
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
|
||||||
[](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
|
[](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
|
||||||
<br>
|
<br>
|
||||||
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
|
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
|
@ -22,11 +22,16 @@ port(){
|
|||||||
|
|
||||||
##放置挂载文件
|
##放置挂载文件
|
||||||
mount(){
|
mount(){
|
||||||
#挂载配置文件
|
#挂载 nginx 配置文件
|
||||||
if test ! -f "/docker/nginx/conf/nginx.conf" ;then
|
if test ! -f "/docker/nginx/conf/nginx.conf" ;then
|
||||||
mkdir -p /docker/nginx/conf
|
mkdir -p /docker/nginx/conf
|
||||||
cp nginx/nginx.conf /docker/nginx/conf/nginx.conf
|
cp nginx/nginx.conf /docker/nginx/conf/nginx.conf
|
||||||
fi
|
fi
|
||||||
|
#挂载 redis 配置文件
|
||||||
|
if test ! -f "/docker/redis/conf/redis.conf" ;then
|
||||||
|
mkdir -p /docker/redis/conf
|
||||||
|
cp redis/redis.conf /docker/redis/conf/redis.conf
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#启动基础模块
|
#启动基础模块
|
||||||
|
@ -65,10 +65,10 @@ services:
|
|||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
volumes:
|
volumes:
|
||||||
# 配置文件
|
# 配置文件
|
||||||
- /docker/redis/conf/redis.conf:/redis.conf:rw
|
- /docker/redis/conf:/redis/config:rw
|
||||||
# 数据文件
|
# 数据文件
|
||||||
- /docker/redis/data:/data:rw
|
- /docker/redis/data:/redis/data:rw
|
||||||
command: "redis-server --appendonly yes"
|
command: "redis-server /redis/config/redis.conf --appendonly yes"
|
||||||
privileged: true
|
privileged: true
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
@ -77,7 +77,7 @@ services:
|
|||||||
|
|
||||||
minio:
|
minio:
|
||||||
image: minio/minio:RELEASE.2021-07-08T01-15-01Z
|
image: minio/minio:RELEASE.2021-07-08T01-15-01Z
|
||||||
hostname: "minio"
|
container_name: minio
|
||||||
ports:
|
ports:
|
||||||
# api 端口
|
# api 端口
|
||||||
- 9000:9000
|
- 9000:9000
|
||||||
@ -103,14 +103,14 @@ services:
|
|||||||
ipv4_address: 172.30.0.54
|
ipv4_address: 172.30.0.54
|
||||||
|
|
||||||
ruoyi-server1:
|
ruoyi-server1:
|
||||||
image: "ruoyi/ruoyi-server:3.0.0"
|
image: "ruoyi/ruoyi-server:3.1.0"
|
||||||
|
container_name: ruoyi-server1
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
volumes:
|
volumes:
|
||||||
# 配置文件
|
# 配置文件
|
||||||
- /docker/server1/logs/:/ruoyi/server/logs/
|
- /docker/server1/logs/:/ruoyi/server/logs/
|
||||||
- /docker/ruoyi/uploadPath/:/ruoyi/server/ruoyi/uploadPath/
|
|
||||||
privileged: true
|
privileged: true
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
@ -118,14 +118,14 @@ services:
|
|||||||
ipv4_address: 172.30.0.60
|
ipv4_address: 172.30.0.60
|
||||||
|
|
||||||
ruoyi-server2:
|
ruoyi-server2:
|
||||||
image: "ruoyi/ruoyi-server:3.0.0"
|
image: "ruoyi/ruoyi-server:3.1.0"
|
||||||
|
container_name: ruoyi-server2
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
volumes:
|
volumes:
|
||||||
# 配置文件
|
# 配置文件
|
||||||
- /docker/server2/logs/:/ruoyi/server/logs/
|
- /docker/server2/logs/:/ruoyi/server/logs/
|
||||||
- /docker/ruoyi/uploadPath/:/ruoyi/server/ruoyi/uploadPath/
|
|
||||||
privileged: true
|
privileged: true
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
@ -133,7 +133,8 @@ 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.0.0"
|
image: "ruoyi/ruoyi-monitor-admin:3.1.0"
|
||||||
|
container_name: ruoyi-monitor-admin
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
|
@ -22,6 +22,7 @@ http {
|
|||||||
access_log /var/log/nginx/access.log main;
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
upstream server {
|
upstream server {
|
||||||
|
ip_hash;
|
||||||
server 172.30.0.60:8080;
|
server 172.30.0.60:8080;
|
||||||
server 172.30.0.61:8080;
|
server 172.30.0.61:8080;
|
||||||
}
|
}
|
||||||
|
2
docker/redis/redis.conf
Normal file
2
docker/redis/redis.conf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# redis 密码
|
||||||
|
# requirepass 123456
|
22
pom.xml
22
pom.xml
@ -6,40 +6,40 @@
|
|||||||
|
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<version>3.0.0</version>
|
<version>3.1.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.0.0</ruoyi-vue-plus.version>
|
<ruoyi-vue-plus.version>3.1.0</ruoyi-vue-plus.version>
|
||||||
<spring-boot.version>2.5.3</spring-boot.version>
|
<spring-boot.version>2.5.4</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.1.1</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>
|
||||||
<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.10</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</mybatis-plus.version>
|
<mybatis-plus.version>3.4.3.3</mybatis-plus.version>
|
||||||
<p6spy.version>3.9.1</p6spy.version>
|
<p6spy.version>3.9.1</p6spy.version>
|
||||||
<hutool.version>5.7.7</hutool.version>
|
<hutool.version>5.7.11</hutool.version>
|
||||||
<feign.version>3.0.3</feign.version>
|
<feign.version>3.0.3</feign.version>
|
||||||
<feign-okhttp.version>11.2</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.0</spring-boot-admin.version>
|
<spring-boot-admin.version>2.5.1</spring-boot-admin.version>
|
||||||
<redisson.version>3.16.1</redisson.version>
|
<redisson.version>3.16.2</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>
|
||||||
|
|
||||||
<!-- OSS 配置 -->
|
<!-- OSS 配置 -->
|
||||||
<qiniu.version>7.8.0</qiniu.version>
|
<qiniu.version>7.8.0</qiniu.version>
|
||||||
<aliyun.oss.version>3.13.0</aliyun.oss.version>
|
<aliyun.oss.version>3.13.1</aliyun.oss.version>
|
||||||
<qcloud.cos.version>5.6.47</qcloud.cos.version>
|
<qcloud.cos.version>5.6.51</qcloud.cos.version>
|
||||||
<minio.version>8.3.0</minio.version>
|
<minio.version>8.3.0</minio.version>
|
||||||
|
|
||||||
<!-- docker 配置 -->
|
<!-- docker 配置 -->
|
||||||
|
@ -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.0.0</version>
|
<version>3.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>ruoyi-extend</artifactId>
|
<artifactId>ruoyi-extend</artifactId>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-extend</artifactId>
|
<artifactId>ruoyi-extend</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.0.0</version>
|
<version>3.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ruoyi-vue-plus",
|
"name": "ruoyi-vue-plus",
|
||||||
"version": "3.0.0",
|
"version": "3.1.0",
|
||||||
"description": "RuoYi-Vue-Plus后台管理系统",
|
"description": "RuoYi-Vue-Plus后台管理系统",
|
||||||
"author": "LionLi",
|
"author": "LionLi",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -47,6 +47,7 @@ export function logout() {
|
|||||||
export function getCodeImg() {
|
export function getCodeImg() {
|
||||||
return request({
|
return request({
|
||||||
url: '/captchaImage',
|
url: '/captchaImage',
|
||||||
method: 'get'
|
method: 'get',
|
||||||
|
timeout: 20000
|
||||||
})
|
})
|
||||||
}
|
}
|
@ -64,6 +64,13 @@
|
|||||||
margin-top: 6vh !important;
|
margin-top: 6vh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body {
|
||||||
|
overflow: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
max-height: 70vh;
|
||||||
|
padding: 10px 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
.el-table {
|
.el-table {
|
||||||
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
||||||
th {
|
th {
|
||||||
@ -130,7 +137,7 @@
|
|||||||
/** 表格更多操作下拉样式 */
|
/** 表格更多操作下拉样式 */
|
||||||
.el-table .el-dropdown-link {
|
.el-table .el-dropdown-link {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: #1890ff;
|
color: #409EFF;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
.main-container {
|
.main-container {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
transition: margin-left .28s;
|
transition: margin-left .28s;
|
||||||
margin-left: $sideBarWidth;
|
margin-left: $base-sidebar-width;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-container {
|
.sidebar-container {
|
||||||
-webkit-transition: width .28s;
|
-webkit-transition: width .28s;
|
||||||
transition: width 0.28s;
|
transition: width 0.28s;
|
||||||
width: $sideBarWidth !important;
|
width: $base-sidebar-width !important;
|
||||||
background-color: $menuBg;
|
background-color: $base-menu-background;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
font-size: 0px;
|
font-size: 0px;
|
||||||
@ -81,12 +81,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
& .theme-dark .is-active > .el-submenu__title {
|
& .theme-dark .is-active > .el-submenu__title {
|
||||||
color: $subMenuActiveText !important;
|
color: $base-menu-color-active !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .nest-menu .el-submenu>.el-submenu__title,
|
& .nest-menu .el-submenu>.el-submenu__title,
|
||||||
& .el-submenu .el-menu-item {
|
& .el-submenu .el-menu-item {
|
||||||
min-width: $sideBarWidth !important;
|
min-width: $base-sidebar-width !important;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(0, 0, 0, 0.06) !important;
|
background-color: rgba(0, 0, 0, 0.06) !important;
|
||||||
@ -95,10 +95,10 @@
|
|||||||
|
|
||||||
& .theme-dark .nest-menu .el-submenu>.el-submenu__title,
|
& .theme-dark .nest-menu .el-submenu>.el-submenu__title,
|
||||||
& .theme-dark .el-submenu .el-menu-item {
|
& .theme-dark .el-submenu .el-menu-item {
|
||||||
background-color: $subMenuBg !important;
|
background-color: $base-sub-menu-background !important;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $subMenuHover !important;
|
background-color: $base-sub-menu-hover !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,7 +154,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.el-menu--collapse .el-menu .el-submenu {
|
.el-menu--collapse .el-menu .el-submenu {
|
||||||
min-width: $sideBarWidth !important;
|
min-width: $base-sidebar-width !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mobile responsive
|
// mobile responsive
|
||||||
@ -165,14 +165,14 @@
|
|||||||
|
|
||||||
.sidebar-container {
|
.sidebar-container {
|
||||||
transition: transform .28s;
|
transition: transform .28s;
|
||||||
width: $sideBarWidth !important;
|
width: $base-sidebar-width !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.hideSidebar {
|
&.hideSidebar {
|
||||||
.sidebar-container {
|
.sidebar-container {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
transition-duration: 0.3s;
|
transition-duration: 0.3s;
|
||||||
transform: translate3d(-$sideBarWidth, 0, 0);
|
transform: translate3d(-$base-sidebar-width, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,37 +8,47 @@ $tiffany: #4AB7BD;
|
|||||||
$yellow:#FEC171;
|
$yellow:#FEC171;
|
||||||
$panGreen: #30B08F;
|
$panGreen: #30B08F;
|
||||||
|
|
||||||
// sidebar
|
// 默认菜单主题风格
|
||||||
$menuText:#bfcbd9;
|
$base-menu-color:#bfcbd9;
|
||||||
$menuActiveText:#409EFF;
|
$base-menu-color-active:#f4f4f5;
|
||||||
$subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951
|
$base-menu-background:#304156;
|
||||||
|
$base-logo-title-color: #ffffff;
|
||||||
|
|
||||||
$menuBg:#304156;
|
$base-menu-light-color:rgba(0,0,0,.70);
|
||||||
$menuHover:#263445;
|
$base-menu-light-background:#ffffff;
|
||||||
$sidebarTitle: #ffffff;
|
$base-logo-light-title-color: #001529;
|
||||||
|
|
||||||
$menuLightBg:#ffffff;
|
$base-sub-menu-background:#1f2d3d;
|
||||||
$menuLightHover:#f0f1f5;
|
$base-sub-menu-hover:#001528;
|
||||||
$sidebarLightTitle: #001529;
|
|
||||||
|
|
||||||
$subMenuBg:#1f2d3d;
|
// 自定义暗色菜单风格
|
||||||
$subMenuHover:#001528;
|
/**
|
||||||
|
$base-menu-color:hsla(0,0%,100%,.65);
|
||||||
|
$base-menu-color-active:#fff;
|
||||||
|
$base-menu-background:#001529;
|
||||||
|
$base-logo-title-color: #ffffff;
|
||||||
|
|
||||||
$sideBarWidth: 200px;
|
$base-menu-light-color:rgba(0,0,0,.70);
|
||||||
|
$base-menu-light-background:#ffffff;
|
||||||
|
$base-logo-light-title-color: #001529;
|
||||||
|
|
||||||
|
$base-sub-menu-background:#000c17;
|
||||||
|
$base-sub-menu-hover:#001528;
|
||||||
|
*/
|
||||||
|
|
||||||
|
$base-sidebar-width: 200px;
|
||||||
|
|
||||||
// the :export directive is the magic sauce for webpack
|
// the :export directive is the magic sauce for webpack
|
||||||
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
|
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
|
||||||
:export {
|
:export {
|
||||||
menuText: $menuText;
|
menuColor: $base-menu-color;
|
||||||
menuActiveText: $menuActiveText;
|
menuLightColor: $base-menu-light-color;
|
||||||
subMenuActiveText: $subMenuActiveText;
|
menuColorActive: $base-menu-color-active;
|
||||||
menuBg: $menuBg;
|
menuBackground: $base-menu-background;
|
||||||
menuHover: $menuHover;
|
menuLightBackground: $base-menu-light-background;
|
||||||
menuLightBg: $menuLightBg;
|
subMenuBackground: $base-sub-menu-background;
|
||||||
menuLightHover: $menuLightHover;
|
subMenuHover: $base-sub-menu-hover;
|
||||||
subMenuBg: $subMenuBg;
|
sideBarWidth: $base-sidebar-width;
|
||||||
subMenuHover: $subMenuHover;
|
logoTitleColor: $base-logo-title-color;
|
||||||
sideBarWidth: $sideBarWidth;
|
logoLightTitleColor: $base-logo-light-title-color
|
||||||
sidebarTitle: $sidebarTitle;
|
|
||||||
sidebarLightTitle: $sidebarLightTitle
|
|
||||||
}
|
}
|
||||||
|
179
ruoyi-ui/src/components/Crontab/day.vue
Normal file
179
ruoyi-ui/src/components/Crontab/day.vue
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
日,允许的通配符[, - * / L M]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
不指定
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min="0" :max="31" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="0" :max="31" /> 日
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min="0" :max="31" /> 号开始,每
|
||||||
|
<el-input-number v-model='average02' :min="0" :max="31" /> 日执行一次
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="5">
|
||||||
|
每月
|
||||||
|
<el-input-number v-model='workday' :min="0" :max="31" /> 号最近的那个工作日
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="6">
|
||||||
|
本月最后一天
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="7">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="item in 31" :key="item" :value="item">{{item}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 1,
|
||||||
|
workday: 1,
|
||||||
|
cycle01: 1,
|
||||||
|
cycle02: 2,
|
||||||
|
average01: 1,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'crontab-day',
|
||||||
|
props: ['check', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
('day rachange');
|
||||||
|
if (this.radioValue === 1) {
|
||||||
|
this.$emit('update', 'day', '*', 'day');
|
||||||
|
this.$emit('update', 'week', '?', 'day');
|
||||||
|
this.$emit('update', 'mouth', '*', 'day');
|
||||||
|
} else {
|
||||||
|
if (this.cron.hour === '*') {
|
||||||
|
this.$emit('update', 'hour', '0', 'day');
|
||||||
|
}
|
||||||
|
if (this.cron.min === '*') {
|
||||||
|
this.$emit('update', 'min', '0', 'day');
|
||||||
|
}
|
||||||
|
if (this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'day');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'day', '?');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'day', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'day', this.average01 + '/' + this.average02);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
this.$emit('update', 'day', this.workday + 'W');
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
this.$emit('update', 'day', 'L');
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
this.$emit('update', 'day', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
('day rachange end');
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'day', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'day', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 最近工作日值变化时
|
||||||
|
workdayChange() {
|
||||||
|
if (this.radioValue == '5') {
|
||||||
|
this.$emit('update', 'day', this.workday + 'W');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '7') {
|
||||||
|
this.$emit('update', 'day', this.checkboxString);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 父组件传递的week发生变化触发
|
||||||
|
weekChange() {
|
||||||
|
//判断week值与day不能同时为“?”
|
||||||
|
if (this.cron.week == '?' && this.radioValue == '2') {
|
||||||
|
this.radioValue = '1';
|
||||||
|
} else if (this.cron.week !== '?' && this.radioValue != '2') {
|
||||||
|
this.radioValue = '2';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'workdayCheck': 'workdayChange',
|
||||||
|
'checkboxString': 'checkboxChange',
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 1, 31)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 1, 31)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 1, 31)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 31)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算工作日格式
|
||||||
|
workdayCheck: function () {
|
||||||
|
this.workday = this.checkNum(this.workday, 1, 31)
|
||||||
|
return this.workday;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
122
ruoyi-ui/src/components/Crontab/hour.vue
Normal file
122
ruoyi-ui/src/components/Crontab/hour.vue
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
小时,允许的通配符[, - * /]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min="0" :max="60" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="0" :max="60" /> 小时
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min="0" :max="60" /> 小时开始,每
|
||||||
|
<el-input-number v-model='average02' :min="0" :max="60" /> 小时执行一次
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 1,
|
||||||
|
cycle01: 0,
|
||||||
|
cycle02: 1,
|
||||||
|
average01: 0,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'crontab-hour',
|
||||||
|
props: ['check', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
if (this.radioValue === 1) {
|
||||||
|
this.$emit('update', 'hour', '*', 'hour');
|
||||||
|
this.$emit('update', 'day', '*', 'hour');
|
||||||
|
} else {
|
||||||
|
if (this.cron.min === '*') {
|
||||||
|
this.$emit('update', 'min', '0', 'hour');
|
||||||
|
}
|
||||||
|
if (this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'hour');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'hour', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'hour', this.average01 + '/' + this.average02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'hour', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '2') {
|
||||||
|
this.$emit('update', 'hour', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'hour', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'hour', this.checkboxString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'checkboxString': 'checkboxChange'
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 0, 23)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 0, 23)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 0, 23)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 23)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
425
ruoyi-ui/src/components/Crontab/index.vue
Normal file
425
ruoyi-ui/src/components/Crontab/index.vue
Normal file
@ -0,0 +1,425 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-tabs type="border-card">
|
||||||
|
<el-tab-pane label="秒" v-if="shouldHide('second')">
|
||||||
|
<CrontabSecond @update="updateContabValue" :check="checkNumber" ref="cronsecond" />
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="分钟" v-if="shouldHide('min')">
|
||||||
|
<CrontabMin
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronmin"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="小时" v-if="shouldHide('hour')">
|
||||||
|
<CrontabHour
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronhour"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="日" v-if="shouldHide('day')">
|
||||||
|
<CrontabDay
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronday"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="月" v-if="shouldHide('mouth')">
|
||||||
|
<CrontabMouth
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronmouth"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="周" v-if="shouldHide('week')">
|
||||||
|
<CrontabWeek
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronweek"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="年" v-if="shouldHide('year')">
|
||||||
|
<CrontabYear
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronyear"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
|
<div class="popup-main">
|
||||||
|
<div class="popup-result">
|
||||||
|
<p class="title">时间表达式</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<th v-for="item of tabTitles" width="40" :key="item">{{item}}</th>
|
||||||
|
<th>Cron 表达式</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.second}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.min}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.hour}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.day}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.mouth}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.week}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.year}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueString}}</span>
|
||||||
|
</td>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<CrontabResult :ex="contabValueString"></CrontabResult>
|
||||||
|
|
||||||
|
<div class="pop_btn">
|
||||||
|
<el-button size="small" type="primary" @click="submitFill">确定</el-button>
|
||||||
|
<el-button size="small" type="warning" @click="clearCron">重置</el-button>
|
||||||
|
<el-button size="small" @click="hidePopup">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CrontabSecond from "./second.vue";
|
||||||
|
import CrontabMin from "./min.vue";
|
||||||
|
import CrontabHour from "./hour.vue";
|
||||||
|
import CrontabDay from "./day.vue";
|
||||||
|
import CrontabMouth from "./mouth.vue";
|
||||||
|
import CrontabWeek from "./week.vue";
|
||||||
|
import CrontabYear from "./year.vue";
|
||||||
|
import CrontabResult from "./result.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
|
||||||
|
tabActive: 0,
|
||||||
|
myindex: 0,
|
||||||
|
contabValueObj: {
|
||||||
|
second: "*",
|
||||||
|
min: "*",
|
||||||
|
hour: "*",
|
||||||
|
day: "*",
|
||||||
|
mouth: "*",
|
||||||
|
week: "?",
|
||||||
|
year: "",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
name: "vcrontab",
|
||||||
|
props: ["expression", "hideComponent"],
|
||||||
|
methods: {
|
||||||
|
shouldHide(key) {
|
||||||
|
if (this.hideComponent && this.hideComponent.includes(key)) return false;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
resolveExp() {
|
||||||
|
//反解析 表达式
|
||||||
|
if (this.expression) {
|
||||||
|
let arr = this.expression.split(" ");
|
||||||
|
if (arr.length >= 6) {
|
||||||
|
//6 位以上是合法表达式
|
||||||
|
let obj = {
|
||||||
|
second: arr[0],
|
||||||
|
min: arr[1],
|
||||||
|
hour: arr[2],
|
||||||
|
day: arr[3],
|
||||||
|
mouth: arr[4],
|
||||||
|
week: arr[5],
|
||||||
|
year: arr[6] ? arr[6] : "",
|
||||||
|
};
|
||||||
|
this.contabValueObj = {
|
||||||
|
...obj,
|
||||||
|
};
|
||||||
|
for (let i in obj) {
|
||||||
|
if (obj[i]) this.changeRadio(i, obj[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//没有传入的表达式 则还原
|
||||||
|
this.clearCron();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// tab切换值
|
||||||
|
tabCheck(index) {
|
||||||
|
this.tabActive = index;
|
||||||
|
},
|
||||||
|
// 由子组件触发,更改表达式组成的字段值
|
||||||
|
updateContabValue(name, value, from) {
|
||||||
|
"updateContabValue", name, value, from;
|
||||||
|
this.contabValueObj[name] = value;
|
||||||
|
if (from && from !== name) {
|
||||||
|
console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
|
||||||
|
this.changeRadio(name, value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//赋值到组件
|
||||||
|
changeRadio(name, value) {
|
||||||
|
let arr = ["second", "min", "hour", "mouth"],
|
||||||
|
refName = "cron" + name,
|
||||||
|
insVlaue;
|
||||||
|
|
||||||
|
if (!this.$refs[refName]) return;
|
||||||
|
|
||||||
|
if (arr.includes(name)) {
|
||||||
|
if (value === "*") {
|
||||||
|
insVlaue = 1;
|
||||||
|
} else if (value.indexOf("-") > -1) {
|
||||||
|
let indexArr = value.split("-");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].cycle01 = 0)
|
||||||
|
: (this.$refs[refName].cycle01 = indexArr[0]);
|
||||||
|
this.$refs[refName].cycle02 = indexArr[1];
|
||||||
|
insVlaue = 2;
|
||||||
|
} else if (value.indexOf("/") > -1) {
|
||||||
|
let indexArr = value.split("/");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].average01 = 0)
|
||||||
|
: (this.$refs[refName].average01 = indexArr[0]);
|
||||||
|
this.$refs[refName].average02 = indexArr[1];
|
||||||
|
insVlaue = 3;
|
||||||
|
} else {
|
||||||
|
insVlaue = 4;
|
||||||
|
this.$refs[refName].checkboxList = value.split(",");
|
||||||
|
}
|
||||||
|
} else if (name == "day") {
|
||||||
|
if (value === "*") {
|
||||||
|
insVlaue = 1;
|
||||||
|
} else if (value == "?") {
|
||||||
|
insVlaue = 2;
|
||||||
|
} else if (value.indexOf("-") > -1) {
|
||||||
|
let indexArr = value.split("-");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].cycle01 = 0)
|
||||||
|
: (this.$refs[refName].cycle01 = indexArr[0]);
|
||||||
|
this.$refs[refName].cycle02 = indexArr[1];
|
||||||
|
insVlaue = 3;
|
||||||
|
} else if (value.indexOf("/") > -1) {
|
||||||
|
let indexArr = value.split("/");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].average01 = 0)
|
||||||
|
: (this.$refs[refName].average01 = indexArr[0]);
|
||||||
|
this.$refs[refName].average02 = indexArr[1];
|
||||||
|
insVlaue = 4;
|
||||||
|
} else if (value.indexOf("W") > -1) {
|
||||||
|
let indexArr = value.split("W");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].workday = 0)
|
||||||
|
: (this.$refs[refName].workday = indexArr[0]);
|
||||||
|
insVlaue = 5;
|
||||||
|
} else if (value === "L") {
|
||||||
|
insVlaue = 6;
|
||||||
|
} else {
|
||||||
|
this.$refs[refName].checkboxList = value.split(",");
|
||||||
|
insVlaue = 7;
|
||||||
|
}
|
||||||
|
} else if (name == "week") {
|
||||||
|
if (value === "*") {
|
||||||
|
insVlaue = 1;
|
||||||
|
} else if (value == "?") {
|
||||||
|
insVlaue = 2;
|
||||||
|
} else if (value.indexOf("-") > -1) {
|
||||||
|
let indexArr = value.split("-");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].cycle01 = 0)
|
||||||
|
: (this.$refs[refName].cycle01 = indexArr[0]);
|
||||||
|
this.$refs[refName].cycle02 = indexArr[1];
|
||||||
|
insVlaue = 3;
|
||||||
|
} else if (value.indexOf("#") > -1) {
|
||||||
|
let indexArr = value.split("#");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].average01 = 1)
|
||||||
|
: (this.$refs[refName].average01 = indexArr[0]);
|
||||||
|
this.$refs[refName].average02 = indexArr[1];
|
||||||
|
insVlaue = 4;
|
||||||
|
} else if (value.indexOf("L") > -1) {
|
||||||
|
let indexArr = value.split("L");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].weekday = 1)
|
||||||
|
: (this.$refs[refName].weekday = indexArr[0]);
|
||||||
|
insVlaue = 5;
|
||||||
|
} else {
|
||||||
|
this.$refs[refName].checkboxList = value.split(",");
|
||||||
|
insVlaue = 7;
|
||||||
|
}
|
||||||
|
} else if (name == "year") {
|
||||||
|
if (value == "") {
|
||||||
|
insVlaue = 1;
|
||||||
|
} else if (value == "*") {
|
||||||
|
insVlaue = 2;
|
||||||
|
} else if (value.indexOf("-") > -1) {
|
||||||
|
insVlaue = 3;
|
||||||
|
} else if (value.indexOf("/") > -1) {
|
||||||
|
insVlaue = 4;
|
||||||
|
} else {
|
||||||
|
this.$refs[refName].checkboxList = value.split(",");
|
||||||
|
insVlaue = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$refs[refName].radioValue = insVlaue;
|
||||||
|
},
|
||||||
|
// 表单选项的子组件校验数字格式(通过-props传递)
|
||||||
|
checkNumber(value, minLimit, maxLimit) {
|
||||||
|
//检查必须为整数
|
||||||
|
value = Math.floor(value);
|
||||||
|
if (value < minLimit) {
|
||||||
|
value = minLimit;
|
||||||
|
} else if (value > maxLimit) {
|
||||||
|
value = maxLimit;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
// 隐藏弹窗
|
||||||
|
hidePopup() {
|
||||||
|
this.$emit("hide");
|
||||||
|
},
|
||||||
|
// 填充表达式
|
||||||
|
submitFill() {
|
||||||
|
this.$emit("fill", this.contabValueString);
|
||||||
|
this.hidePopup();
|
||||||
|
},
|
||||||
|
clearCron() {
|
||||||
|
// 还原选择项
|
||||||
|
("准备还原");
|
||||||
|
this.contabValueObj = {
|
||||||
|
second: "*",
|
||||||
|
min: "*",
|
||||||
|
hour: "*",
|
||||||
|
day: "*",
|
||||||
|
mouth: "*",
|
||||||
|
week: "?",
|
||||||
|
year: "",
|
||||||
|
};
|
||||||
|
for (let j in this.contabValueObj) {
|
||||||
|
this.changeRadio(j, this.contabValueObj[j]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
contabValueString: function() {
|
||||||
|
let obj = this.contabValueObj;
|
||||||
|
let str =
|
||||||
|
obj.second +
|
||||||
|
" " +
|
||||||
|
obj.min +
|
||||||
|
" " +
|
||||||
|
obj.hour +
|
||||||
|
" " +
|
||||||
|
obj.day +
|
||||||
|
" " +
|
||||||
|
obj.mouth +
|
||||||
|
" " +
|
||||||
|
obj.week +
|
||||||
|
(obj.year == "" ? "" : " " + obj.year);
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
CrontabSecond,
|
||||||
|
CrontabMin,
|
||||||
|
CrontabHour,
|
||||||
|
CrontabDay,
|
||||||
|
CrontabMouth,
|
||||||
|
CrontabWeek,
|
||||||
|
CrontabYear,
|
||||||
|
CrontabResult,
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
expression: "resolveExp",
|
||||||
|
hideComponent(value) {
|
||||||
|
// 隐藏部分组件
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted: function() {
|
||||||
|
this.resolveExp();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.pop_btn {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.popup-main {
|
||||||
|
position: relative;
|
||||||
|
margin: 10px auto;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.popup-title {
|
||||||
|
overflow: hidden;
|
||||||
|
line-height: 34px;
|
||||||
|
padding-top: 6px;
|
||||||
|
background: #f2f2f2;
|
||||||
|
}
|
||||||
|
.popup-result {
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 24px;
|
||||||
|
margin: 25px auto;
|
||||||
|
padding: 15px 10px 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.popup-result .title {
|
||||||
|
position: absolute;
|
||||||
|
top: -28px;
|
||||||
|
left: 50%;
|
||||||
|
width: 140px;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-left: -70px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.popup-result table {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.popup-result table span {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
font-family: arial;
|
||||||
|
line-height: 30px;
|
||||||
|
height: 30px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
.popup-result-scroll {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 24px;
|
||||||
|
height: 10em;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
</style>
|
120
ruoyi-ui/src/components/Crontab/min.vue
Normal file
120
ruoyi-ui/src/components/Crontab/min.vue
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
分钟,允许的通配符[, - * /]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min="0" :max="60" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="0" :max="60" /> 分钟
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min="0" :max="60" /> 分钟开始,每
|
||||||
|
<el-input-number v-model='average02' :min="0" :max="60" /> 分钟执行一次
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 1,
|
||||||
|
cycle01: 1,
|
||||||
|
cycle02: 2,
|
||||||
|
average01: 0,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'crontab-min',
|
||||||
|
props: ['check', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
if (this.radioValue !== 1 && this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'min');
|
||||||
|
}
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 1:
|
||||||
|
this.$emit('update', 'min', '*', 'min');
|
||||||
|
this.$emit('update', 'hour', '*', 'min');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'min', this.cycle01 + '-' + this.cycle02, 'min');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'min', this.average01 + '/' + this.average02, 'min');
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'min', this.checkboxString, 'min');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '2') {
|
||||||
|
this.$emit('update', 'min', this.cycleTotal, 'min');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'min', this.averageTotal, 'min');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'min', this.checkboxString, 'min');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'checkboxString': 'checkboxChange',
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 0, 59)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 0, 59)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 0, 59)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 59)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
128
ruoyi-ui/src/components/Crontab/mouth.vue
Normal file
128
ruoyi-ui/src/components/Crontab/mouth.vue
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size='small'>
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
月,允许的通配符[, - * /]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min="1" :max="12" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="1" :max="12" /> 月
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min="1" :max="12" /> 月开始,每
|
||||||
|
<el-input-number v-model='average02' :min="1" :max="12" /> 月月执行一次
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="item in 12" :key="item" :value="item">{{item}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 1,
|
||||||
|
cycle01: 1,
|
||||||
|
cycle02: 2,
|
||||||
|
average01: 1,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'crontab-mouth',
|
||||||
|
props: ['check', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
if (this.radioValue === 1) {
|
||||||
|
this.$emit('update', 'mouth', '*');
|
||||||
|
this.$emit('update', 'year', '*');
|
||||||
|
} else {
|
||||||
|
if (this.cron.day === '*') {
|
||||||
|
this.$emit('update', 'day', '0', 'mouth');
|
||||||
|
}
|
||||||
|
if (this.cron.hour === '*') {
|
||||||
|
this.$emit('update', 'hour', '0', 'mouth');
|
||||||
|
}
|
||||||
|
if (this.cron.min === '*') {
|
||||||
|
this.$emit('update', 'min', '0', 'mouth');
|
||||||
|
}
|
||||||
|
if (this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'mouth');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'mouth', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'mouth', this.average01 + '/' + this.average02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'mouth', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '2') {
|
||||||
|
this.$emit('update', 'mouth', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'mouth', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'mouth', this.checkboxString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'checkboxString': 'checkboxChange'
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 1, 12)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 1, 12)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 1, 12)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 12)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
566
ruoyi-ui/src/components/Crontab/result.vue
Normal file
566
ruoyi-ui/src/components/Crontab/result.vue
Normal file
@ -0,0 +1,566 @@
|
|||||||
|
<template>
|
||||||
|
<div class="popup-result">
|
||||||
|
<p class="title">最近5次运行时间</p>
|
||||||
|
<ul class="popup-result-scroll">
|
||||||
|
<template v-if='isShow'>
|
||||||
|
<li v-for='item in resultList' :key="item">{{item}}</li>
|
||||||
|
</template>
|
||||||
|
<li v-else>计算结果中...</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dayRule: '',
|
||||||
|
dayRuleSup: '',
|
||||||
|
dateArr: [],
|
||||||
|
resultList: [],
|
||||||
|
isShow: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'crontab-result',
|
||||||
|
methods: {
|
||||||
|
// 表达式值变化时,开始去计算结果
|
||||||
|
expressionChange() {
|
||||||
|
|
||||||
|
// 计算开始-隐藏结果
|
||||||
|
this.isShow = false;
|
||||||
|
// 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年]
|
||||||
|
let ruleArr = this.$options.propsData.ex.split(' ');
|
||||||
|
// 用于记录进入循环的次数
|
||||||
|
let nums = 0;
|
||||||
|
// 用于暂时存符号时间规则结果的数组
|
||||||
|
let resultArr = [];
|
||||||
|
// 获取当前时间精确至[年、月、日、时、分、秒]
|
||||||
|
let nTime = new Date();
|
||||||
|
let nYear = nTime.getFullYear();
|
||||||
|
let nMouth = nTime.getMonth() + 1;
|
||||||
|
let nDay = nTime.getDate();
|
||||||
|
let nHour = nTime.getHours();
|
||||||
|
let nMin = nTime.getMinutes();
|
||||||
|
let nSecond = nTime.getSeconds();
|
||||||
|
// 根据规则获取到近100年可能年数组、月数组等等
|
||||||
|
this.getSecondArr(ruleArr[0]);
|
||||||
|
this.getMinArr(ruleArr[1]);
|
||||||
|
this.getHourArr(ruleArr[2]);
|
||||||
|
this.getDayArr(ruleArr[3]);
|
||||||
|
this.getMouthArr(ruleArr[4]);
|
||||||
|
this.getWeekArr(ruleArr[5]);
|
||||||
|
this.getYearArr(ruleArr[6], nYear);
|
||||||
|
// 将获取到的数组赋值-方便使用
|
||||||
|
let sDate = this.dateArr[0];
|
||||||
|
let mDate = this.dateArr[1];
|
||||||
|
let hDate = this.dateArr[2];
|
||||||
|
let DDate = this.dateArr[3];
|
||||||
|
let MDate = this.dateArr[4];
|
||||||
|
let YDate = this.dateArr[5];
|
||||||
|
// 获取当前时间在数组中的索引
|
||||||
|
let sIdx = this.getIndex(sDate, nSecond);
|
||||||
|
let mIdx = this.getIndex(mDate, nMin);
|
||||||
|
let hIdx = this.getIndex(hDate, nHour);
|
||||||
|
let DIdx = this.getIndex(DDate, nDay);
|
||||||
|
let MIdx = this.getIndex(MDate, nMouth);
|
||||||
|
let YIdx = this.getIndex(YDate, nYear);
|
||||||
|
// 重置月日时分秒的函数(后面用的比较多)
|
||||||
|
const resetSecond = function () {
|
||||||
|
sIdx = 0;
|
||||||
|
nSecond = sDate[sIdx]
|
||||||
|
}
|
||||||
|
const resetMin = function () {
|
||||||
|
mIdx = 0;
|
||||||
|
nMin = mDate[mIdx]
|
||||||
|
resetSecond();
|
||||||
|
}
|
||||||
|
const resetHour = function () {
|
||||||
|
hIdx = 0;
|
||||||
|
nHour = hDate[hIdx]
|
||||||
|
resetMin();
|
||||||
|
}
|
||||||
|
const resetDay = function () {
|
||||||
|
DIdx = 0;
|
||||||
|
nDay = DDate[DIdx]
|
||||||
|
resetHour();
|
||||||
|
}
|
||||||
|
const resetMouth = function () {
|
||||||
|
MIdx = 0;
|
||||||
|
nMouth = MDate[MIdx]
|
||||||
|
resetDay();
|
||||||
|
}
|
||||||
|
// 如果当前年份不为数组中当前值
|
||||||
|
if (nYear !== YDate[YIdx]) {
|
||||||
|
resetMouth();
|
||||||
|
}
|
||||||
|
// 如果当前月份不为数组中当前值
|
||||||
|
if (nMouth !== MDate[MIdx]) {
|
||||||
|
resetDay();
|
||||||
|
}
|
||||||
|
// 如果当前“日”不为数组中当前值
|
||||||
|
if (nDay !== DDate[DIdx]) {
|
||||||
|
resetHour();
|
||||||
|
}
|
||||||
|
// 如果当前“时”不为数组中当前值
|
||||||
|
if (nHour !== hDate[hIdx]) {
|
||||||
|
resetMin();
|
||||||
|
}
|
||||||
|
// 如果当前“分”不为数组中当前值
|
||||||
|
if (nMin !== mDate[mIdx]) {
|
||||||
|
resetSecond();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 循环年份数组
|
||||||
|
goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
|
||||||
|
let YY = YDate[Yi];
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (nMouth > MDate[MDate.length - 1]) {
|
||||||
|
resetMouth();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 循环月份数组
|
||||||
|
goMouth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
|
||||||
|
// 赋值、方便后面运算
|
||||||
|
let MM = MDate[Mi];
|
||||||
|
MM = MM < 10 ? '0' + MM : MM;
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (nDay > DDate[DDate.length - 1]) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 循环日期数组
|
||||||
|
goDay: for (let Di = DIdx; Di < DDate.length; Di++) {
|
||||||
|
// 赋值、方便后面运算
|
||||||
|
let DD = DDate[Di];
|
||||||
|
let thisDD = DD < 10 ? '0' + DD : DD;
|
||||||
|
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (nHour > hDate[hDate.length - 1]) {
|
||||||
|
resetHour();
|
||||||
|
if (Di == DDate.length - 1) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断日期的合法性,不合法的话也是跳出当前循环
|
||||||
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') {
|
||||||
|
resetDay();
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
// 如果日期规则中有值时
|
||||||
|
if (this.dayRule == 'lastDay') {
|
||||||
|
//如果不是合法日期则需要将前将日期调到合法日期即月末最后一天
|
||||||
|
|
||||||
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
DD--;
|
||||||
|
|
||||||
|
thisDD = DD < 10 ? '0' + DD : DD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this.dayRule == 'workDay') {
|
||||||
|
//校验并调整如果是2月30号这种日期传进来时需调整至正常月底
|
||||||
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
DD--;
|
||||||
|
thisDD = DD < 10 ? '0' + DD : DD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取达到条件的日期是星期X
|
||||||
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
|
||||||
|
// 当星期日时
|
||||||
|
if (thisWeek == 0) {
|
||||||
|
//先找下一个日,并判断是否为月底
|
||||||
|
DD++;
|
||||||
|
thisDD = DD < 10 ? '0' + DD : DD;
|
||||||
|
//判断下一日已经不是合法日期
|
||||||
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
DD -= 3;
|
||||||
|
}
|
||||||
|
} else if (thisWeek == 6) {
|
||||||
|
//当星期6时只需判断不是1号就可进行操作
|
||||||
|
if (this.dayRuleSup !== 1) {
|
||||||
|
DD--;
|
||||||
|
} else {
|
||||||
|
DD += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this.dayRule == 'weekDay') {
|
||||||
|
//如果指定了是星期几
|
||||||
|
//获取当前日期是属于星期几
|
||||||
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
|
||||||
|
//校验当前星期是否在星期池(dayRuleSup)中
|
||||||
|
if (Array.indexOf(this.dayRuleSup, thisWeek) < 0) {
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (Di == DDate.length - 1) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (this.dayRule == 'assWeek') {
|
||||||
|
//如果指定了是第几周的星期几
|
||||||
|
//获取每月1号是属于星期几
|
||||||
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
|
||||||
|
if (this.dayRuleSup[1] >= thisWeek) {
|
||||||
|
DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1;
|
||||||
|
} else {
|
||||||
|
DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1;
|
||||||
|
}
|
||||||
|
} else if (this.dayRule == 'lastWeek') {
|
||||||
|
//如果指定了每月最后一个星期几
|
||||||
|
//校验并调整如果是2月30号这种日期传进来时需调整至正常月底
|
||||||
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
DD--;
|
||||||
|
thisDD = DD < 10 ? '0' + DD : DD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//获取月末最后一天是星期几
|
||||||
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
|
||||||
|
//找到要求中最近的那个星期几
|
||||||
|
if (this.dayRuleSup < thisWeek) {
|
||||||
|
DD -= thisWeek - this.dayRuleSup;
|
||||||
|
} else if (this.dayRuleSup > thisWeek) {
|
||||||
|
DD -= 7 - (this.dayRuleSup - thisWeek)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 判断时间值是否小于10置换成“05”这种格式
|
||||||
|
DD = DD < 10 ? '0' + DD : DD;
|
||||||
|
|
||||||
|
// 循环“时”数组
|
||||||
|
goHour: for (let hi = hIdx; hi < hDate.length; hi++) {
|
||||||
|
let hh = hDate[hi] < 10 ? '0' + hDate[hi] : hDate[hi]
|
||||||
|
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (nMin > mDate[mDate.length - 1]) {
|
||||||
|
resetMin();
|
||||||
|
if (hi == hDate.length - 1) {
|
||||||
|
resetHour();
|
||||||
|
if (Di == DDate.length - 1) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
continue goDay;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 循环"分"数组
|
||||||
|
goMin: for (let mi = mIdx; mi < mDate.length; mi++) {
|
||||||
|
let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi];
|
||||||
|
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (nSecond > sDate[sDate.length - 1]) {
|
||||||
|
resetSecond();
|
||||||
|
if (mi == mDate.length - 1) {
|
||||||
|
resetMin();
|
||||||
|
if (hi == hDate.length - 1) {
|
||||||
|
resetHour();
|
||||||
|
if (Di == DDate.length - 1) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
continue goDay;
|
||||||
|
}
|
||||||
|
continue goHour;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 循环"秒"数组
|
||||||
|
goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) {
|
||||||
|
let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si];
|
||||||
|
// 添加当前时间(时间合法性在日期循环时已经判断)
|
||||||
|
if (MM !== '00' && DD !== '00') {
|
||||||
|
resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
|
||||||
|
nums++;
|
||||||
|
}
|
||||||
|
//如果条数满了就退出循环
|
||||||
|
if (nums == 5) break goYear;
|
||||||
|
//如果到达最大值时
|
||||||
|
if (si == sDate.length - 1) {
|
||||||
|
resetSecond();
|
||||||
|
if (mi == mDate.length - 1) {
|
||||||
|
resetMin();
|
||||||
|
if (hi == hDate.length - 1) {
|
||||||
|
resetHour();
|
||||||
|
if (Di == DDate.length - 1) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
continue goDay;
|
||||||
|
}
|
||||||
|
continue goHour;
|
||||||
|
}
|
||||||
|
continue goMin;
|
||||||
|
}
|
||||||
|
} //goSecond
|
||||||
|
} //goMin
|
||||||
|
}//goHour
|
||||||
|
}//goDay
|
||||||
|
}//goMouth
|
||||||
|
}
|
||||||
|
// 判断100年内的结果条数
|
||||||
|
if (resultArr.length == 0) {
|
||||||
|
this.resultList = ['没有达到条件的结果!'];
|
||||||
|
} else {
|
||||||
|
this.resultList = resultArr;
|
||||||
|
if (resultArr.length !== 5) {
|
||||||
|
this.resultList.push('最近100年内只有上面' + resultArr.length + '条结果!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 计算完成-显示结果
|
||||||
|
this.isShow = true;
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
//用于计算某位数字在数组中的索引
|
||||||
|
getIndex(arr, value) {
|
||||||
|
if (value <= arr[0] || value > arr[arr.length - 1]) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < arr.length - 1; i++) {
|
||||||
|
if (value > arr[i] && value <= arr[i + 1]) {
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"年"数组
|
||||||
|
getYearArr(rule, year) {
|
||||||
|
this.dateArr[5] = this.getOrderArr(year, year + 100);
|
||||||
|
if (rule !== undefined) {
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[5] = this.getCycleArr(rule, year + 100, false)
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[5] = this.getAverageArr(rule, year + 100)
|
||||||
|
} else if (rule !== '*') {
|
||||||
|
this.dateArr[5] = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"月"数组
|
||||||
|
getMouthArr(rule) {
|
||||||
|
this.dateArr[4] = this.getOrderArr(1, 12);
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[4] = this.getCycleArr(rule, 12, false)
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[4] = this.getAverageArr(rule, 12)
|
||||||
|
} else if (rule !== '*') {
|
||||||
|
this.dateArr[4] = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"日"数组-主要为日期规则
|
||||||
|
getWeekArr(rule) {
|
||||||
|
//只有当日期规则的两个值均为“”时则表达日期是有选项的
|
||||||
|
if (this.dayRule == '' && this.dayRuleSup == '') {
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dayRule = 'weekDay';
|
||||||
|
this.dayRuleSup = this.getCycleArr(rule, 7, false)
|
||||||
|
} else if (rule.indexOf('#') >= 0) {
|
||||||
|
this.dayRule = 'assWeek';
|
||||||
|
let matchRule = rule.match(/[0-9]{1}/g);
|
||||||
|
this.dayRuleSup = [Number(matchRule[0]), Number(matchRule[1])];
|
||||||
|
this.dateArr[3] = [1];
|
||||||
|
if (this.dayRuleSup[1] == 7) {
|
||||||
|
this.dayRuleSup[1] = 0;
|
||||||
|
}
|
||||||
|
} else if (rule.indexOf('L') >= 0) {
|
||||||
|
this.dayRule = 'lastWeek';
|
||||||
|
this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
|
||||||
|
this.dateArr[3] = [31];
|
||||||
|
if (this.dayRuleSup == 7) {
|
||||||
|
this.dayRuleSup = 0;
|
||||||
|
}
|
||||||
|
} else if (rule !== '*' && rule !== '?') {
|
||||||
|
this.dayRule = 'weekDay';
|
||||||
|
this.dayRuleSup = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
//如果weekDay时将7调整为0【week值0即是星期日】
|
||||||
|
if (this.dayRule == 'weekDay') {
|
||||||
|
for (let i = 0; i < this.dayRuleSup.length; i++) {
|
||||||
|
if (this.dayRuleSup[i] == 7) {
|
||||||
|
this.dayRuleSup[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"日"数组-少量为日期规则
|
||||||
|
getDayArr(rule) {
|
||||||
|
this.dateArr[3] = this.getOrderArr(1, 31);
|
||||||
|
this.dayRule = '';
|
||||||
|
this.dayRuleSup = '';
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[3] = this.getCycleArr(rule, 31, false)
|
||||||
|
this.dayRuleSup = 'null';
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[3] = this.getAverageArr(rule, 31)
|
||||||
|
this.dayRuleSup = 'null';
|
||||||
|
} else if (rule.indexOf('W') >= 0) {
|
||||||
|
this.dayRule = 'workDay';
|
||||||
|
this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
|
||||||
|
this.dateArr[3] = [this.dayRuleSup];
|
||||||
|
} else if (rule.indexOf('L') >= 0) {
|
||||||
|
this.dayRule = 'lastDay';
|
||||||
|
this.dayRuleSup = 'null';
|
||||||
|
this.dateArr[3] = [31];
|
||||||
|
} else if (rule !== '*' && rule !== '?') {
|
||||||
|
this.dateArr[3] = this.getAssignArr(rule)
|
||||||
|
this.dayRuleSup = 'null';
|
||||||
|
} else if (rule == '*') {
|
||||||
|
this.dayRuleSup = 'null';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"时"数组
|
||||||
|
getHourArr(rule) {
|
||||||
|
this.dateArr[2] = this.getOrderArr(0, 23);
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[2] = this.getCycleArr(rule, 24, true)
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[2] = this.getAverageArr(rule, 23)
|
||||||
|
} else if (rule !== '*') {
|
||||||
|
this.dateArr[2] = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"分"数组
|
||||||
|
getMinArr(rule) {
|
||||||
|
this.dateArr[1] = this.getOrderArr(0, 59);
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[1] = this.getCycleArr(rule, 60, true)
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[1] = this.getAverageArr(rule, 59)
|
||||||
|
} else if (rule !== '*') {
|
||||||
|
this.dateArr[1] = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"秒"数组
|
||||||
|
getSecondArr(rule) {
|
||||||
|
this.dateArr[0] = this.getOrderArr(0, 59);
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[0] = this.getCycleArr(rule, 60, true)
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[0] = this.getAverageArr(rule, 59)
|
||||||
|
} else if (rule !== '*') {
|
||||||
|
this.dateArr[0] = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 根据传进来的min-max返回一个顺序的数组
|
||||||
|
getOrderArr(min, max) {
|
||||||
|
let arr = [];
|
||||||
|
for (let i = min; i <= max; i++) {
|
||||||
|
arr.push(i);
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
},
|
||||||
|
// 根据规则中指定的零散值返回一个数组
|
||||||
|
getAssignArr(rule) {
|
||||||
|
let arr = [];
|
||||||
|
let assiginArr = rule.split(',');
|
||||||
|
for (let i = 0; i < assiginArr.length; i++) {
|
||||||
|
arr[i] = Number(assiginArr[i])
|
||||||
|
}
|
||||||
|
arr.sort(this.compare)
|
||||||
|
return arr;
|
||||||
|
},
|
||||||
|
// 根据一定算术规则计算返回一个数组
|
||||||
|
getAverageArr(rule, limit) {
|
||||||
|
let arr = [];
|
||||||
|
let agArr = rule.split('/');
|
||||||
|
let min = Number(agArr[0]);
|
||||||
|
let step = Number(agArr[1]);
|
||||||
|
while (min <= limit) {
|
||||||
|
arr.push(min);
|
||||||
|
min += step;
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
},
|
||||||
|
// 根据规则返回一个具有周期性的数组
|
||||||
|
getCycleArr(rule, limit, status) {
|
||||||
|
//status--表示是否从0开始(则从1开始)
|
||||||
|
let arr = [];
|
||||||
|
let cycleArr = rule.split('-');
|
||||||
|
let min = Number(cycleArr[0]);
|
||||||
|
let max = Number(cycleArr[1]);
|
||||||
|
if (min > max) {
|
||||||
|
max += limit;
|
||||||
|
}
|
||||||
|
for (let i = min; i <= max; i++) {
|
||||||
|
let add = 0;
|
||||||
|
if (status == false && i % limit == 0) {
|
||||||
|
add = limit;
|
||||||
|
}
|
||||||
|
arr.push(Math.round(i % limit + add))
|
||||||
|
}
|
||||||
|
arr.sort(this.compare)
|
||||||
|
return arr;
|
||||||
|
},
|
||||||
|
//比较数字大小(用于Array.sort)
|
||||||
|
compare(value1, value2) {
|
||||||
|
if (value2 - value1 > 0) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 格式化日期格式如:2017-9-19 18:04:33
|
||||||
|
formatDate(value, type) {
|
||||||
|
// 计算日期相关值
|
||||||
|
let time = typeof value == 'number' ? new Date(value) : value;
|
||||||
|
let Y = time.getFullYear();
|
||||||
|
let M = time.getMonth() + 1;
|
||||||
|
let D = time.getDate();
|
||||||
|
let h = time.getHours();
|
||||||
|
let m = time.getMinutes();
|
||||||
|
let s = time.getSeconds();
|
||||||
|
let week = time.getDay();
|
||||||
|
// 如果传递了type的话
|
||||||
|
if (type == undefined) {
|
||||||
|
return Y + '-' + (M < 10 ? '0' + M : M) + '-' + (D < 10 ? '0' + D : D) + ' ' + (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
||||||
|
} else if (type == 'week') {
|
||||||
|
return week;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 检查日期是否存在
|
||||||
|
checkDate(value) {
|
||||||
|
let time = new Date(value);
|
||||||
|
let format = this.formatDate(time)
|
||||||
|
return value == format ? true : false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'ex': 'expressionChange'
|
||||||
|
},
|
||||||
|
props: ['ex'],
|
||||||
|
mounted: function () {
|
||||||
|
// 初始化 获取一次结果
|
||||||
|
this.expressionChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
133
ruoyi-ui/src/components/Crontab/second.vue
Normal file
133
ruoyi-ui/src/components/Crontab/second.vue
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
秒,允许的通配符[, - * /]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min="0" :max="60" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="0" :max="60" /> 秒
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min="0" :max="60" /> 秒开始,每
|
||||||
|
<el-input-number v-model='average02' :min="0" :max="60" /> 秒执行一次
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 1,
|
||||||
|
cycle01: 1,
|
||||||
|
cycle02: 2,
|
||||||
|
average01: 0,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'crontab-second',
|
||||||
|
props: ['check', 'radioParent'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 1:
|
||||||
|
this.$emit('update', 'second', '*', 'second');
|
||||||
|
this.$emit('update', 'min', '*', 'second');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'second', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'second', this.average01 + '/' + this.average02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'second', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '2') {
|
||||||
|
this.$emit('update', 'second', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'second', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'second', this.checkboxString);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
othChange() {
|
||||||
|
//反解析
|
||||||
|
let ins = this.cron.second
|
||||||
|
('反解析 second', ins);
|
||||||
|
if (ins === '*') {
|
||||||
|
this.radioValue = 1;
|
||||||
|
} else if (ins.indexOf('-') > -1) {
|
||||||
|
this.radioValue = 2
|
||||||
|
} else if (ins.indexOf('/') > -1) {
|
||||||
|
this.radioValue = 3
|
||||||
|
} else {
|
||||||
|
this.radioValue = 4
|
||||||
|
this.checkboxList = ins.split(',')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'checkboxString': 'checkboxChange',
|
||||||
|
radioParent() {
|
||||||
|
this.radioValue = this.radioParent
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 0, 59)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 0, 59)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 0, 59)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 59)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
167
ruoyi-ui/src/components/Crontab/week.vue
Normal file
167
ruoyi-ui/src/components/Crontab/week.vue
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size='small'>
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
周,允许的通配符[, - * / L #]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
不指定
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
周期从星期
|
||||||
|
<el-input-number v-model='cycle01' :min="1" :max="7" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="1" :max="7" />
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
第
|
||||||
|
<el-input-number v-model='average01' :min="1" :max="4" /> 周的星期
|
||||||
|
<el-input-number v-model='average02' :min="1" :max="7" />
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="5">
|
||||||
|
本月最后一个星期
|
||||||
|
<el-input-number v-model='weekday' :min="1" :max="7" />
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="6">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="(item,index) of weekList" :key="index" :value="index+1">{{item}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 2,
|
||||||
|
weekday: 1,
|
||||||
|
cycle01: 1,
|
||||||
|
cycle02: 2,
|
||||||
|
average01: 1,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
weekList: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'crontab-week',
|
||||||
|
props: ['check', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
if (this.radioValue === 1) {
|
||||||
|
this.$emit('update', 'week', '*');
|
||||||
|
this.$emit('update', 'year', '*');
|
||||||
|
} else {
|
||||||
|
if (this.cron.mouth === '*') {
|
||||||
|
this.$emit('update', 'mouth', '0', 'week');
|
||||||
|
}
|
||||||
|
if (this.cron.day === '*') {
|
||||||
|
this.$emit('update', 'day', '0', 'week');
|
||||||
|
}
|
||||||
|
if (this.cron.hour === '*') {
|
||||||
|
this.$emit('update', 'hour', '0', 'week');
|
||||||
|
}
|
||||||
|
if (this.cron.min === '*') {
|
||||||
|
this.$emit('update', 'min', '0', 'week');
|
||||||
|
}
|
||||||
|
if (this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'week');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'week', '?');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'week', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'week', this.average01 + '#' + this.average02);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
this.$emit('update', 'week', this.weekday + 'L');
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
this.$emit('update', 'week', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 根据互斥事件,更改radio的值
|
||||||
|
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'week', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'week', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 最近工作日值变化时
|
||||||
|
weekdayChange() {
|
||||||
|
if (this.radioValue == '5') {
|
||||||
|
this.$emit('update', 'week', this.weekday + 'L');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '6') {
|
||||||
|
this.$emit('update', 'week', this.checkboxString);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'weekdayCheck': 'weekdayChange',
|
||||||
|
'checkboxString': 'checkboxChange',
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 1, 7)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 1, 7)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 1, 4)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 7)
|
||||||
|
return this.average01 + '#' + this.average02;
|
||||||
|
},
|
||||||
|
// 最近的工作日(格式)
|
||||||
|
weekdayCheck: function () {
|
||||||
|
this.weekday = this.checkNum(this.weekday, 1, 7)
|
||||||
|
return this.weekday;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
144
ruoyi-ui/src/components/Crontab/year.vue
Normal file
144
ruoyi-ui/src/components/Crontab/year.vue
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<template>
|
||||||
|
<el-form size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio :label="1" v-model='radioValue'>
|
||||||
|
不填,允许的通配符[, - * /]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio :label="2" v-model='radioValue'>
|
||||||
|
每年
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio :label="3" v-model='radioValue'>
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min='fullYear' /> -
|
||||||
|
<el-input-number v-model='cycle02' :min='fullYear' />
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio :label="4" v-model='radioValue'>
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min='fullYear' /> 年开始,每
|
||||||
|
<el-input-number v-model='average02' :min='fullYear' /> 年执行一次
|
||||||
|
</el-radio>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio :label="5" v-model='radioValue'>
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple>
|
||||||
|
<el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" />
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
fullYear: 0,
|
||||||
|
radioValue: 1,
|
||||||
|
cycle01: 0,
|
||||||
|
cycle02: 0,
|
||||||
|
average01: 0,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'crontab-year',
|
||||||
|
props: ['check', 'mouth', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
if (this.cron.mouth === '*') {
|
||||||
|
this.$emit('update', 'mouth', '0', 'year');
|
||||||
|
}
|
||||||
|
if (this.cron.day === '*') {
|
||||||
|
this.$emit('update', 'day', '0', 'year');
|
||||||
|
}
|
||||||
|
if (this.cron.hour === '*') {
|
||||||
|
this.$emit('update', 'hour', '0', 'year');
|
||||||
|
}
|
||||||
|
if (this.cron.min === '*') {
|
||||||
|
this.$emit('update', 'min', '0', 'year');
|
||||||
|
}
|
||||||
|
if (this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'year');
|
||||||
|
}
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 1:
|
||||||
|
this.$emit('update', 'year', '');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'year', '*');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'year', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'year', this.average01 + '/' + this.average02);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
this.$emit('update', 'year', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'year', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'year', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '5') {
|
||||||
|
this.$emit('update', 'year', this.checkboxString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'checkboxString': 'checkboxChange'
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, this.fullYear, this.fullYear + 100)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, this.fullYear + 1, this.fullYear + 101)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, this.fullYear, this.fullYear + 100)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 10)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted: function () {
|
||||||
|
// 仅获取当前年份
|
||||||
|
this.fullYear = Number(new Date().getFullYear());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -31,12 +31,12 @@ export default {
|
|||||||
type: Array,
|
type: Array,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
value: [String, Array],
|
value: [Number, String, Array],
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
values() {
|
values() {
|
||||||
if (this.value) {
|
if (this.value !== null && typeof this.value !== 'undefined') {
|
||||||
return Array.isArray(this.value) ? this.value : [this.value];
|
return Array.isArray(this.value) ? this.value : [String(this.value)];
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -31,13 +31,24 @@ export default {
|
|||||||
immediate: true
|
immediate: true
|
||||||
},
|
},
|
||||||
async theme(val) {
|
async theme(val) {
|
||||||
|
await this.setTheme(val)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if(this.defaultTheme !== ORIGINAL_THEME) {
|
||||||
|
this.setTheme(this.defaultTheme)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
async setTheme(val) {
|
||||||
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
|
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
|
||||||
if (typeof val !== 'string') return
|
if (typeof val !== 'string') return
|
||||||
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({
|
const $message = this.$message({
|
||||||
message: ' Compiling the theme',
|
message: ' 正在切换主题,请稍后...',
|
||||||
customClass: 'theme-message',
|
customClass: 'theme-message',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
duration: 0,
|
duration: 0,
|
||||||
@ -82,10 +93,9 @@ export default {
|
|||||||
this.$emit('change', val)
|
this.$emit('change', val)
|
||||||
|
|
||||||
$message.close()
|
$message.close()
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
|
||||||
updateStyle(style, oldCluster, newCluster) {
|
updateStyle(style, oldCluster, newCluster) {
|
||||||
let newStyle = style
|
let newStyle = style
|
||||||
oldCluster.forEach((color, index) => {
|
oldCluster.forEach((color, index) => {
|
||||||
|
34
ruoyi-ui/src/directive/dialog/dragHeight.js
Normal file
34
ruoyi-ui/src/directive/dialog/dragHeight.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* v-dialogDragWidth 可拖动弹窗高度(右下角)
|
||||||
|
* Copyright (c) 2019 ruoyi
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
bind(el) {
|
||||||
|
const dragDom = el.querySelector('.el-dialog');
|
||||||
|
const lineEl = document.createElement('div');
|
||||||
|
lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
|
||||||
|
lineEl.addEventListener('mousedown',
|
||||||
|
function(e) {
|
||||||
|
// 鼠标按下,计算当前元素距离可视区的距离
|
||||||
|
const disX = e.clientX - el.offsetLeft;
|
||||||
|
const disY = e.clientY - el.offsetTop;
|
||||||
|
// 当前宽度 高度
|
||||||
|
const curWidth = dragDom.offsetWidth;
|
||||||
|
const curHeight = dragDom.offsetHeight;
|
||||||
|
document.onmousemove = function(e) {
|
||||||
|
e.preventDefault(); // 移动时禁用默认事件
|
||||||
|
// 通过事件委托,计算移动的距离
|
||||||
|
const xl = e.clientX - disX;
|
||||||
|
const yl = e.clientY - disY
|
||||||
|
dragDom.style.width = `${curWidth + xl}px`;
|
||||||
|
dragDom.style.height = `${curHeight + yl}px`;
|
||||||
|
};
|
||||||
|
document.onmouseup = function(e) {
|
||||||
|
document.onmousemove = null;
|
||||||
|
document.onmouseup = null;
|
||||||
|
};
|
||||||
|
}, false);
|
||||||
|
dragDom.appendChild(lineEl);
|
||||||
|
}
|
||||||
|
}
|
30
ruoyi-ui/src/directive/dialog/dragWidth.js
Normal file
30
ruoyi-ui/src/directive/dialog/dragWidth.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* v-dialogDragWidth 可拖动弹窗宽度(右侧边)
|
||||||
|
* Copyright (c) 2019 ruoyi
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
bind(el) {
|
||||||
|
const dragDom = el.querySelector('.el-dialog');
|
||||||
|
const lineEl = document.createElement('div');
|
||||||
|
lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
|
||||||
|
lineEl.addEventListener('mousedown',
|
||||||
|
function (e) {
|
||||||
|
// 鼠标按下,计算当前元素距离可视区的距离
|
||||||
|
const disX = e.clientX - el.offsetLeft;
|
||||||
|
// 当前宽度
|
||||||
|
const curWidth = dragDom.offsetWidth;
|
||||||
|
document.onmousemove = function (e) {
|
||||||
|
e.preventDefault(); // 移动时禁用默认事件
|
||||||
|
// 通过事件委托,计算移动的距离
|
||||||
|
const l = e.clientX - disX;
|
||||||
|
dragDom.style.width = `${curWidth + l}px`;
|
||||||
|
};
|
||||||
|
document.onmouseup = function (e) {
|
||||||
|
document.onmousemove = null;
|
||||||
|
document.onmouseup = null;
|
||||||
|
};
|
||||||
|
}, false);
|
||||||
|
dragDom.appendChild(lineEl);
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,20 @@
|
|||||||
import hasRole from './permission/hasRole'
|
import hasRole from './permission/hasRole'
|
||||||
import hasPermi from './permission/hasPermi'
|
import hasPermi from './permission/hasPermi'
|
||||||
import dialogDrag from './dialog/drag'
|
import dialogDrag from './dialog/drag'
|
||||||
|
import dialogDragWidth from './dialog/dragWidth'
|
||||||
|
import dialogDragHeight from './dialog/dragHeight'
|
||||||
|
|
||||||
const install = function(Vue) {
|
const install = function(Vue) {
|
||||||
Vue.directive('hasRole', hasRole)
|
Vue.directive('hasRole', hasRole)
|
||||||
Vue.directive('hasPermi', hasPermi)
|
Vue.directive('hasPermi', hasPermi)
|
||||||
Vue.directive('dialogDrag', dialogDrag)
|
Vue.directive('dialogDrag', dialogDrag)
|
||||||
|
Vue.directive('dialogDragWidth', dialogDragWidth)
|
||||||
|
Vue.directive('dialogDragHeight', dialogDragHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.Vue) {
|
if (window.Vue) {
|
||||||
window['hasRole'] = hasRole
|
window['hasRole'] = hasRole
|
||||||
window['hasPermi'] = hasPermi
|
window['hasPermi'] = hasPermi
|
||||||
window['dialogDrag'] = dialogDrag
|
|
||||||
Vue.use(install); // eslint-disable-line
|
Vue.use(install); // eslint-disable-line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ import SizeSelect from '@/components/SizeSelect'
|
|||||||
import Search from '@/components/HeaderSearch'
|
import Search from '@/components/HeaderSearch'
|
||||||
import RuoYiGit from '@/components/RuoYi/Git'
|
import RuoYiGit from '@/components/RuoYi/Git'
|
||||||
import RuoYiDoc from '@/components/RuoYi/Doc'
|
import RuoYiDoc from '@/components/RuoYi/Doc'
|
||||||
|
import config from '@/../vue.config'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -102,7 +103,7 @@ export default {
|
|||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$store.dispatch('LogOut').then(() => {
|
this.$store.dispatch('LogOut').then(() => {
|
||||||
location.href = '/index';
|
location.href = config.publicPath + 'index';
|
||||||
})
|
})
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }">
|
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
|
||||||
<transition name="sidebarLogoFade">
|
<transition name="sidebarLogoFade">
|
||||||
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
||||||
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
||||||
<h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.sidebarTitle : variables.sidebarLightTitle }">{{ title }} </h1>
|
<h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
||||||
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
||||||
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.sidebarTitle : variables.sidebarLightTitle }">{{ title }} </h1>
|
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
|
||||||
</router-link>
|
</router-link>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }">
|
<div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
|
||||||
<logo v-if="showLogo" :collapse="isCollapse" />
|
<logo v-if="showLogo" :collapse="isCollapse" />
|
||||||
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
|
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
|
||||||
<el-menu
|
<el-menu
|
||||||
:default-active="activeMenu"
|
:default-active="activeMenu"
|
||||||
:collapse="isCollapse"
|
:collapse="isCollapse"
|
||||||
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg"
|
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
|
||||||
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuText : 'rgba(0,0,0,.65)'"
|
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
|
||||||
:unique-opened="true"
|
:unique-opened="true"
|
||||||
:active-text-color="settings.theme"
|
:active-text-color="settings.theme"
|
||||||
:collapse-transition="false"
|
:collapse-transition="false"
|
||||||
|
@ -18,11 +18,12 @@
|
|||||||
</router-link>
|
</router-link>
|
||||||
</scroll-pane>
|
</scroll-pane>
|
||||||
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
||||||
<li @click="refreshSelectedTag(selectedTag)">刷新页面</li>
|
<li @click="refreshSelectedTag(selectedTag)"><i class="el-icon-refresh-right"></i> 刷新页面</li>
|
||||||
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">关闭当前</li>
|
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><i class="el-icon-close"></i> 关闭当前</li>
|
||||||
<li @click="closeOthersTags">关闭其他</li>
|
<li @click="closeOthersTags"><i class="el-icon-circle-close"></i> 关闭其他</li>
|
||||||
<li v-if="!isLastView()" @click="closeRightTags">关闭右侧</li>
|
<li v-if="!isFirstView()" @click="closeLeftTags"><i class="el-icon-back"></i> 关闭左侧</li>
|
||||||
<li @click="closeAllTags(selectedTag)">关闭所有</li>
|
<li v-if="!isLastView()" @click="closeRightTags"><i class="el-icon-right"></i> 关闭右侧</li>
|
||||||
|
<li @click="closeAllTags(selectedTag)"><i class="el-icon-circle-close"></i> 全部关闭</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -84,6 +85,13 @@ export default {
|
|||||||
isAffix(tag) {
|
isAffix(tag) {
|
||||||
return tag.meta && tag.meta.affix
|
return tag.meta && tag.meta.affix
|
||||||
},
|
},
|
||||||
|
isFirstView() {
|
||||||
|
try {
|
||||||
|
return this.selectedTag.fullPath === this.visitedViews[1].fullPath || this.selectedTag.fullPath === '/index'
|
||||||
|
} catch (err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
isLastView() {
|
isLastView() {
|
||||||
try {
|
try {
|
||||||
return this.selectedTag.fullPath === this.visitedViews[this.visitedViews.length - 1].fullPath
|
return this.selectedTag.fullPath === this.visitedViews[this.visitedViews.length - 1].fullPath
|
||||||
@ -167,6 +175,13 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
closeLeftTags() {
|
||||||
|
this.$store.dispatch('tagsView/delLeftTags', this.selectedTag).then(visitedViews => {
|
||||||
|
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
|
||||||
|
this.toLastView(visitedViews)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
closeOthersTags() {
|
closeOthersTags() {
|
||||||
this.$router.push(this.selectedTag).catch(()=>{});
|
this.$router.push(this.selectedTag).catch(()=>{});
|
||||||
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
|
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
|
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
|
||||||
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
||||||
<sidebar class="sidebar-container" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }" />
|
<sidebar class="sidebar-container"/>
|
||||||
<div :class="{hasTagsView:needTagsView}" class="main-container">
|
<div :class="{hasTagsView:needTagsView}" class="main-container">
|
||||||
<div :class="{'fixed-header':fixedHeader}">
|
<div :class="{'fixed-header':fixedHeader}">
|
||||||
<navbar />
|
<navbar />
|
||||||
<tags-view v-if="needTagsView" />
|
<tags-view v-if="needTagsView" />
|
||||||
</div>
|
</div>
|
||||||
<app-main />
|
<app-main />
|
||||||
<right-panel v-if="showSettings">
|
<right-panel>
|
||||||
<settings />
|
<settings />
|
||||||
</right-panel>
|
</right-panel>
|
||||||
</div>
|
</div>
|
||||||
@ -39,7 +39,6 @@ export default {
|
|||||||
sideTheme: state => state.settings.sideTheme,
|
sideTheme: state => state.settings.sideTheme,
|
||||||
sidebar: state => state.app.sidebar,
|
sidebar: state => state.app.sidebar,
|
||||||
device: state => state.app.device,
|
device: state => state.app.device,
|
||||||
showSettings: state => state.settings.showSettings,
|
|
||||||
needTagsView: state => state.settings.tagsView,
|
needTagsView: state => state.settings.tagsView,
|
||||||
fixedHeader: state => state.settings.fixedHeader
|
fixedHeader: state => state.settings.fixedHeader
|
||||||
}),
|
}),
|
||||||
@ -94,7 +93,7 @@ export default {
|
|||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
width: calc(100% - #{$sideBarWidth});
|
width: calc(100% - #{$base-sidebar-width});
|
||||||
transition: width 0.28s;
|
transition: width 0.28s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ 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";
|
||||||
// 自定义表格工具组件
|
// 自定义表格工具组件
|
||||||
@ -40,6 +41,7 @@ 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) {
|
Vue.prototype.msgSuccess = function (msg) {
|
||||||
this.$message({ showClose: true, message: msg, type: "success" });
|
this.$message({ showClose: true, message: msg, type: "success" });
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import variables from '@/assets/styles/element-variables.scss'
|
|
||||||
import defaultSettings from '@/settings'
|
import defaultSettings from '@/settings'
|
||||||
|
|
||||||
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
|
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
|
||||||
@ -6,7 +5,7 @@ const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dyn
|
|||||||
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
|
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
|
||||||
const state = {
|
const state = {
|
||||||
title: '',
|
title: '',
|
||||||
theme: storageSetting.theme || variables.theme,
|
theme: storageSetting.theme || '#409EFF',
|
||||||
sideTheme: storageSetting.sideTheme || sideTheme,
|
sideTheme: storageSetting.sideTheme || sideTheme,
|
||||||
showSettings: showSettings,
|
showSettings: showSettings,
|
||||||
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
|
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
|
||||||
|
@ -79,6 +79,23 @@ const mutations = {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
DEL_LEFT_VIEWS: (state, view) => {
|
||||||
|
const index = state.visitedViews.findIndex(v => v.path === view.path)
|
||||||
|
if (index === -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.visitedViews = state.visitedViews.filter((item, idx) => {
|
||||||
|
if (idx >= index || (item.meta && item.meta.affix)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
const i = state.cachedViews.indexOf(item.name)
|
||||||
|
if (i > -1) {
|
||||||
|
state.cachedViews.splice(i, 1)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +189,14 @@ const actions = {
|
|||||||
commit('DEL_RIGHT_VIEWS', view)
|
commit('DEL_RIGHT_VIEWS', view)
|
||||||
resolve([...state.visitedViews])
|
resolve([...state.visitedViews])
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
|
||||||
|
delLeftTags({ commit }, view) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
commit('DEL_LEFT_VIEWS', view)
|
||||||
|
resolve([...state.visitedViews])
|
||||||
|
})
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -18,7 +18,7 @@ export function parseTime(time, pattern) {
|
|||||||
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
|
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
|
||||||
time = parseInt(time)
|
time = parseInt(time)
|
||||||
} else if (typeof time === 'string') {
|
} else if (typeof time === 'string') {
|
||||||
time = time.replace(new RegExp(/-/gm), '/');
|
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm),'');
|
||||||
}
|
}
|
||||||
if ((typeof time === 'number') && (time.toString().length === 10)) {
|
if ((typeof time === 'number') && (time.toString().length === 10)) {
|
||||||
time = time * 1000
|
time = time * 1000
|
||||||
|
@ -170,7 +170,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listDemo, pageDemo, getDemo, delDemo, addDemo, updateDemo } from "@/api/demo/demo";
|
import { listDemo, pageDemo, getDemo, delDemo, addDemo, updateDemo } from "@/api/demo/demo";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Demo",
|
name: "Demo",
|
||||||
@ -361,7 +360,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/demo/demo/export', this.queryParams);
|
this.downLoadExcel('/demo/demo/export', this.queryParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -93,6 +93,62 @@
|
|||||||
<span>更新日志</span>
|
<span>更新日志</span>
|
||||||
</div>
|
</div>
|
||||||
<el-collapse accordion>
|
<el-collapse accordion>
|
||||||
|
<el-collapse-item title="v3.1.0 - 2021-9-7">
|
||||||
|
<ol>
|
||||||
|
<li>add [重大改动] 过期 RedisCache 新增 RedisUtils 工具类 新增 发布订阅功能 更灵巧便于使用</li>
|
||||||
|
<li>add [重大改动] 新增 saveOrUpdateAll 方法 可完美替代 saveOrUpdateBatch 高性能</li>
|
||||||
|
<li>update [重大改动] 重写 InsertAll 方法实现 可完美替代 saveBatch 秒级插入上万数据</li>
|
||||||
|
<li>update [重大改动] 更改OSS上传通用路径生成 按照年月日分三级目录</li>
|
||||||
|
<li>update [重大改动] MP字段验证策略更改为 NOT_NULL 个别特殊字段使用注解单独处理</li>
|
||||||
|
<li>update [重大改动] 所有业务适配 RedisUtils 新工具</li>
|
||||||
|
<li>update springboot 2.5.3 => 2.5.4</li>
|
||||||
|
<li>update spring-boot-admin 2.5.0 => 2.5.1</li>
|
||||||
|
<li>update mybatis-plus 3.4.3 => 3.4.3.3 适配升级 (包含不兼容升级)</li>
|
||||||
|
<li>update aliyun.oss 3.13.0 => 3.13.1</li>
|
||||||
|
<li>update qcloud.cos 5.6.47 => 5.6.51</li>
|
||||||
|
<li>update hutool 5.7.9 => 5.7.11</li>
|
||||||
|
<li>update maven-jar-plugin 3.1.1 => 3.2.0</li>
|
||||||
|
<li>update feign-okhttp 11.2 => 11.6</li>
|
||||||
|
<li>update redisson 3.16.1 => 3.16.2</li>
|
||||||
|
<li>add 优化 docker 增加 redis 配置文件</li>
|
||||||
|
<li>add 新增暗色菜单风格主题</li>
|
||||||
|
<li>add 菜单&部门新增展开/折叠功能</li>
|
||||||
|
<li>add 页签右键按钮添加图标 页签新增关闭左侧</li>
|
||||||
|
<li>update 优化 OSS 模块与上传组件 异常处理</li>
|
||||||
|
<li>update 更新 jackson 配置 支持 LocalDateTime 全局格式化</li>
|
||||||
|
<li>update 优化 使用权限工具 获取用户信息</li>
|
||||||
|
<li>update 自定义可拖动弹窗宽度指令</li>
|
||||||
|
<li>update 重构 将下载excel工具提取到全局</li>
|
||||||
|
<li>update 定时任务对检查异常进行事务回滚</li>
|
||||||
|
<li>update 优化spy配置文件为 UTF8编码 解决中文注释乱码问题</li>
|
||||||
|
<li>update 修改时检查用户数据权限范围</li>
|
||||||
|
<li>update 解决 logout 写死 无法扩展路径问题</li>
|
||||||
|
<li>update 优化代码生成 导入与同步 批处理效率</li>
|
||||||
|
<li>update 修改时检查用户数据权限范围</li>
|
||||||
|
<li>update 修改代码生成字典回显样式</li>
|
||||||
|
<li>update 修改数据字典回显</li>
|
||||||
|
<li>update 优化验证码配置 使用泛型 防止错误输入</li>
|
||||||
|
<li>update 优化全局线程池配置 使用泛型 防止错误输入</li>
|
||||||
|
<li>update 使用 MP 全局配置分页溢出</li>
|
||||||
|
<li>update 代码生成器 导入表时查询 新创建表的优先排序在前面</li>
|
||||||
|
<li>update 定时任务支持在线生成cron表达式</li>
|
||||||
|
<li>update 自定义弹层溢出滚动样式</li>
|
||||||
|
<li>update 优化分页工具排序处理</li>
|
||||||
|
<li>update 优化 oss配置 使用发布订阅工具 刷新配置</li>
|
||||||
|
<li>update 代码生成 查询数据库列表 按照时间倒序</li>
|
||||||
|
<li>update 使用MP自行判断数据库类型</li>
|
||||||
|
<li>fix 修复保存配置主题颜色失效问题</li>
|
||||||
|
<li>fix 修复 导出雪花id excel失真问题</li>
|
||||||
|
<li>fix 修复 druid 监控 集群模式下 无法路由到同一台服务器问题</li>
|
||||||
|
<li>fix 解决搜索校验不通过问题</li>
|
||||||
|
<li>fix 修复定时器工具编写错误问题</li>
|
||||||
|
<li>fix 修复 minio 无 perfix 问题</li>
|
||||||
|
<li>fix 修复 富文本图片路径错误问题</li>
|
||||||
|
<li>fix 修复 OSS配置清空被过滤问题</li>
|
||||||
|
<li>fix 修复 excel 导入与 class 未对应问题</li>
|
||||||
|
<li>fix 修复字典组件值为整形不显示问题</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
<el-collapse-item title="v3.0.0 - 2021-8-18">
|
<el-collapse-item title="v3.0.0 - 2021-8-18">
|
||||||
<ol>
|
<ol>
|
||||||
<li>add [重大更新]重写 OSS 模块相关实现 支持动态配置(页面配置)</li>
|
<li>add [重大更新]重写 OSS 模块相关实现 支持动态配置(页面配置)</li>
|
||||||
@ -381,7 +437,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import config from '../../package.json'
|
import config from '@/../package.json'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Index",
|
name: "Index",
|
||||||
|
@ -7,7 +7,6 @@ export default {
|
|||||||
name: "Admin",
|
name: "Admin",
|
||||||
components: { iFrame },
|
components: { iFrame },
|
||||||
data() {
|
data() {
|
||||||
console.log(process.env)
|
|
||||||
return {
|
return {
|
||||||
url: process.env.VUE_APP_MONITRO_ADMIN
|
url: process.env.VUE_APP_MONITRO_ADMIN
|
||||||
};
|
};
|
||||||
|
@ -95,9 +95,13 @@
|
|||||||
|
|
||||||
<el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="jobList" @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="jobId" />
|
<el-table-column label="任务编号" width="100" align="center" prop="jobId" />
|
||||||
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
|
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="任务组名" align="center" prop="jobGroup" :formatter="jobGroupFormat" />
|
<el-table-column label="任务组名" align="center" prop="jobGroup">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="jobGroupOptions" :value="scope.row.jobGroup"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
|
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="cron执行表达式" align="center" prop="cronExpression" :show-overflow-tooltip="true" />
|
<el-table-column label="cron执行表达式" align="center" prop="cronExpression" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="状态" align="center">
|
<el-table-column label="状态" align="center">
|
||||||
@ -152,7 +156,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 添加或修改定时任务对话框 -->
|
<!-- 添加或修改定时任务对话框 -->
|
||||||
<el-dialog :title="title" :visible.sync="open" width="700px" 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-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@ -188,17 +192,16 @@
|
|||||||
<el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
|
<el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="24">
|
||||||
<el-form-item label="cron表达式" prop="cronExpression">
|
<el-form-item label="cron表达式" prop="cronExpression">
|
||||||
<el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式" />
|
<el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式">
|
||||||
</el-form-item>
|
<template slot="append">
|
||||||
</el-col>
|
<el-button type="primary" @click="handleShowCron">
|
||||||
<el-col :span="12">
|
生成表达式
|
||||||
<el-form-item label="是否并发" prop="concurrent">
|
<i class="el-icon-time el-icon--right"></i>
|
||||||
<el-radio-group v-model="form.concurrent" size="small">
|
</el-button>
|
||||||
<el-radio-button label="0">允许</el-radio-button>
|
</template>
|
||||||
<el-radio-button label="1">禁止</el-radio-button>
|
</el-input>
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
@ -210,7 +213,15 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="12">
|
||||||
|
<el-form-item label="是否并发" prop="concurrent">
|
||||||
|
<el-radio-group v-model="form.concurrent" size="small">
|
||||||
|
<el-radio-button label="0">允许</el-radio-button>
|
||||||
|
<el-radio-button label="1">禁止</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
<el-form-item label="状态">
|
<el-form-item label="状态">
|
||||||
<el-radio-group v-model="form.status">
|
<el-radio-group v-model="form.status">
|
||||||
<el-radio
|
<el-radio
|
||||||
@ -229,6 +240,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body class="scrollbar">
|
||||||
|
<crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 任务日志详细 -->
|
<!-- 任务日志详细 -->
|
||||||
<el-dialog title="任务详细" :visible.sync="openView" width="700px" append-to-body>
|
<el-dialog title="任务详细" :visible.sync="openView" width="700px" append-to-body>
|
||||||
<el-form ref="form" :model="form" label-width="120px" size="mini">
|
<el-form ref="form" :model="form" label-width="120px" size="mini">
|
||||||
@ -281,9 +296,10 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from "@/api/monitor/job";
|
import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from "@/api/monitor/job";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
import Crontab from '@/components/Crontab'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: { Crontab },
|
||||||
name: "Job",
|
name: "Job",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -309,6 +325,10 @@ export default {
|
|||||||
open: false,
|
open: false,
|
||||||
// 是否显示详细弹出层
|
// 是否显示详细弹出层
|
||||||
openView: false,
|
openView: false,
|
||||||
|
// 是否显示Cron表达式弹出层
|
||||||
|
openCron: false,
|
||||||
|
// 传入的表达式
|
||||||
|
expression: "",
|
||||||
// 任务组名字典
|
// 任务组名字典
|
||||||
jobGroupOptions: [],
|
jobGroupOptions: [],
|
||||||
// 状态字典
|
// 状态字典
|
||||||
@ -360,10 +380,6 @@ export default {
|
|||||||
jobGroupFormat(row, column) {
|
jobGroupFormat(row, column) {
|
||||||
return this.selectDictLabel(this.jobGroupOptions, row.jobGroup);
|
return this.selectDictLabel(this.jobGroupOptions, row.jobGroup);
|
||||||
},
|
},
|
||||||
// 状态字典翻译
|
|
||||||
statusFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.statusOptions, row.status);
|
|
||||||
},
|
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
cancel() {
|
cancel() {
|
||||||
this.open = false;
|
this.open = false;
|
||||||
@ -449,6 +465,15 @@ export default {
|
|||||||
this.openView = true;
|
this.openView = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/** cron表达式按钮操作 */
|
||||||
|
handleShowCron() {
|
||||||
|
this.expression = this.form.cronExpression;
|
||||||
|
this.openCron = true;
|
||||||
|
},
|
||||||
|
/** 确定后回传值 */
|
||||||
|
crontabFill(value) {
|
||||||
|
this.form.cronExpression = value;
|
||||||
|
},
|
||||||
/** 任务日志列表查询 */
|
/** 任务日志列表查询 */
|
||||||
handleJobLog(row) {
|
handleJobLog(row) {
|
||||||
const jobId = row.jobId || 0;
|
const jobId = row.jobId || 0;
|
||||||
@ -506,7 +531,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/monitor/job/export', this.queryParams);
|
this.downLoadExcel('/monitor/job/export', this.queryParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -110,10 +110,18 @@
|
|||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="日志编号" width="80" align="center" prop="jobLogId" />
|
<el-table-column label="日志编号" width="80" align="center" prop="jobLogId" />
|
||||||
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
|
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="任务组名" align="center" prop="jobGroup" :formatter="jobGroupFormat" :show-overflow-tooltip="true" />
|
<el-table-column label="任务组名" align="center" prop="jobGroup" :show-overflow-tooltip="true">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="jobGroupOptions" :value="scope.row.jobGroup"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
|
<el-table-column label="调用目标字符串" align="center" prop="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" :formatter="statusFormat" />
|
<el-table-column label="执行状态" align="center" prop="status">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="statusOptions" :value="scope.row.status"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="执行时间" align="center" prop="createTime" width="180">
|
<el-table-column label="执行时间" align="center" prop="createTime" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
@ -179,7 +187,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getJob } from "@/api/monitor/job";
|
import { getJob } from "@/api/monitor/job";
|
||||||
import { listJobLog, delJobLog, cleanJobLog } from "@/api/monitor/jobLog";
|
import { listJobLog, delJobLog, cleanJobLog } from "@/api/monitor/jobLog";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "JobLog",
|
name: "JobLog",
|
||||||
@ -248,14 +255,6 @@ export default {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
// 执行状态字典翻译
|
|
||||||
statusFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.statusOptions, row.status);
|
|
||||||
},
|
|
||||||
// 任务组名字典翻译
|
|
||||||
jobGroupFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.jobGroupOptions, row.jobGroup);
|
|
||||||
},
|
|
||||||
// 返回按钮
|
// 返回按钮
|
||||||
handleClose() {
|
handleClose() {
|
||||||
this.$store.dispatch("tagsView/delView", this.$route);
|
this.$store.dispatch("tagsView/delView", this.$route);
|
||||||
@ -311,7 +310,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/monitor/jobLog/export', this.queryParams);
|
this.downLoadExcel('/monitor/jobLog/export', this.queryParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -99,7 +99,11 @@
|
|||||||
<el-table-column label="登录地点" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
|
<el-table-column label="登录地点" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="浏览器" align="center" prop="browser" :show-overflow-tooltip="true" />
|
<el-table-column label="浏览器" align="center" prop="browser" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="操作系统" align="center" prop="os" />
|
<el-table-column label="操作系统" align="center" prop="os" />
|
||||||
<el-table-column label="登录状态" align="center" prop="status" :formatter="statusFormat" />
|
<el-table-column label="登录状态" align="center" prop="status">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="statusOptions" :value="scope.row.status"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="操作信息" align="center" prop="msg" />
|
<el-table-column label="操作信息" align="center" prop="msg" />
|
||||||
<el-table-column label="登录日期" align="center" prop="loginTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180">
|
<el-table-column label="登录日期" align="center" prop="loginTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
@ -120,7 +124,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { list, delLogininfor, cleanLogininfor } from "@/api/monitor/logininfor";
|
import { list, delLogininfor, cleanLogininfor } from "@/api/monitor/logininfor";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Logininfor",
|
name: "Logininfor",
|
||||||
@ -173,10 +176,6 @@ export default {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
// 登录状态字典翻译
|
|
||||||
statusFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.statusOptions, row.status);
|
|
||||||
},
|
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
this.queryParams.pageNum = 1;
|
this.queryParams.pageNum = 1;
|
||||||
@ -229,7 +228,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/monitor/logininfor/export', this.queryParams);
|
this.downLoadExcel('/monitor/logininfor/export', this.queryParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -111,12 +111,20 @@
|
|||||||
<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="operId" />
|
<el-table-column label="日志编号" align="center" prop="operId" />
|
||||||
<el-table-column label="系统模块" align="center" prop="title" />
|
<el-table-column label="系统模块" align="center" prop="title" />
|
||||||
<el-table-column label="操作类型" align="center" prop="businessType" :formatter="typeFormat" />
|
<el-table-column label="操作类型" align="center" prop="businessType">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="typeOptions" :value="scope.row.businessType"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="请求方式" align="center" prop="requestMethod" />
|
<el-table-column label="请求方式" align="center" prop="requestMethod" />
|
||||||
<el-table-column label="操作人员" align="center" prop="operName" width="100" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
|
<el-table-column label="操作人员" align="center" prop="operName" width="100" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
|
||||||
<el-table-column label="操作地址" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" />
|
<el-table-column label="操作地址" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" />
|
||||||
<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" :formatter="statusFormat" />
|
<el-table-column label="操作状态" align="center" prop="status">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="statusOptions" :value="scope.row.status"/>
|
||||||
|
</template>
|
||||||
|
</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">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.operTime) }}</span>
|
<span>{{ parseTime(scope.row.operTime) }}</span>
|
||||||
@ -189,7 +197,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { list, delOperlog, cleanOperlog } from "@/api/monitor/operlog";
|
import { list, delOperlog, cleanOperlog } from "@/api/monitor/operlog";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Operlog",
|
name: "Operlog",
|
||||||
@ -252,10 +259,6 @@ export default {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
// 操作日志状态字典翻译
|
|
||||||
statusFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.statusOptions, row.status);
|
|
||||||
},
|
|
||||||
// 操作日志类型字典翻译
|
// 操作日志类型字典翻译
|
||||||
typeFormat(row, column) {
|
typeFormat(row, column) {
|
||||||
return this.selectDictLabel(this.typeOptions, row.businessType);
|
return this.selectDictLabel(this.typeOptions, row.businessType);
|
||||||
@ -317,7 +320,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/monitor/operlog/export', this.queryParams);
|
this.downLoadExcel('/monitor/operlog/export', this.queryParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="register">
|
<div class="register">
|
||||||
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
|
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
|
||||||
<h3 class="title">若依后台管理系统</h3>
|
<h3 class="title">RuoYi-Vue-Plus后台管理系统</h3>
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号">
|
<el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号">
|
||||||
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
|
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
|
||||||
|
@ -112,7 +112,11 @@
|
|||||||
<el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" />
|
<el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="参数键名" align="center" prop="configKey" :show-overflow-tooltip="true" />
|
<el-table-column label="参数键名" align="center" prop="configKey" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="参数键值" align="center" prop="configValue" />
|
<el-table-column label="参数键值" align="center" prop="configValue" />
|
||||||
<el-table-column label="系统内置" align="center" prop="configType" :formatter="typeFormat" />
|
<el-table-column label="系统内置" align="center" prop="configType">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="typeOptions" :value="scope.row.configType"/>
|
||||||
|
</template>
|
||||||
|
</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" />
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
@ -182,7 +186,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listConfig, getConfig, delConfig, addConfig, updateConfig, refreshCache } from "@/api/system/config";
|
import { listConfig, getConfig, delConfig, addConfig, updateConfig, refreshCache } from "@/api/system/config";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Config",
|
name: "Config",
|
||||||
@ -253,10 +256,6 @@ export default {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
// 参数系统内置字典翻译
|
|
||||||
typeFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.typeOptions, row.configType);
|
|
||||||
},
|
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
cancel() {
|
cancel() {
|
||||||
this.open = false;
|
this.open = false;
|
||||||
@ -343,7 +342,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/system/config/export', this.queryParams);
|
this.downLoadExcel('/system/config/export', this.queryParams);
|
||||||
},
|
},
|
||||||
/** 刷新缓存按钮操作 */
|
/** 刷新缓存按钮操作 */
|
||||||
handleRefreshCache() {
|
handleRefreshCache() {
|
||||||
|
@ -37,19 +37,33 @@
|
|||||||
v-hasPermi="['system:dept:add']"
|
v-hasPermi="['system:dept:add']"
|
||||||
>新增</el-button>
|
>新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="info"
|
||||||
|
plain
|
||||||
|
icon="el-icon-sort"
|
||||||
|
size="mini"
|
||||||
|
@click="toggleExpandAll"
|
||||||
|
>展开/折叠</el-button>
|
||||||
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-table
|
<el-table
|
||||||
|
v-if="refreshTable"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="deptList"
|
:data="deptList"
|
||||||
row-key="deptId"
|
row-key="deptId"
|
||||||
default-expand-all
|
:default-expand-all="isExpandAll"
|
||||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||||
>
|
>
|
||||||
<el-table-column prop="deptName" label="部门名称" width="260"></el-table-column>
|
<el-table-column prop="deptName" label="部门名称" width="260"></el-table-column>
|
||||||
<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="状态" :formatter="statusFormat" width="100"></el-table-column>
|
<el-table-column prop="status" label="状态" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="statusOptions" :value="scope.row.status"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime" width="200">
|
<el-table-column label="创建时间" align="center" prop="createTime" width="200">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
@ -160,6 +174,12 @@ export default {
|
|||||||
title: "",
|
title: "",
|
||||||
// 是否显示弹出层
|
// 是否显示弹出层
|
||||||
open: false,
|
open: false,
|
||||||
|
// 是否展开,默认全部展开
|
||||||
|
isExpandAll: true,
|
||||||
|
// 重新渲染表格状态
|
||||||
|
refreshTable: true,
|
||||||
|
// 是否展开
|
||||||
|
expand: false,
|
||||||
// 状态数据字典
|
// 状态数据字典
|
||||||
statusOptions: [],
|
statusOptions: [],
|
||||||
// 查询参数
|
// 查询参数
|
||||||
@ -223,10 +243,6 @@ export default {
|
|||||||
children: node.children
|
children: node.children
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
// 字典状态字典翻译
|
|
||||||
statusFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.statusOptions, row.status);
|
|
||||||
},
|
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
cancel() {
|
cancel() {
|
||||||
this.open = false;
|
this.open = false;
|
||||||
@ -267,6 +283,14 @@ export default {
|
|||||||
this.deptOptions = this.handleTree(response.data, "deptId");
|
this.deptOptions = this.handleTree(response.data, "deptId");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/** 展开/折叠操作 */
|
||||||
|
toggleExpandAll() {
|
||||||
|
this.refreshTable = false;
|
||||||
|
this.isExpandAll = !this.isExpandAll;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.refreshTable = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
handleUpdate(row) {
|
handleUpdate(row) {
|
||||||
this.reset();
|
this.reset();
|
||||||
|
@ -185,7 +185,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data";
|
import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data";
|
||||||
import { listType, getType } from "@/api/system/dict/type";
|
import { listType, getType } from "@/api/system/dict/type";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Data",
|
name: "Data",
|
||||||
@ -389,7 +388,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/system/dict/data/export', this.queryParams);
|
this.downLoadExcel('/system/dict/data/export', this.queryParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -194,7 +194,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type";
|
import { listType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Dict",
|
name: "Dict",
|
||||||
@ -347,7 +346,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/system/dict/type/export', this.queryParams);
|
this.downLoadExcel('/system/dict/type/export', this.queryParams);
|
||||||
},
|
},
|
||||||
/** 刷新缓存按钮操作 */
|
/** 刷新缓存按钮操作 */
|
||||||
handleRefreshCache() {
|
handleRefreshCache() {
|
||||||
|
@ -37,13 +37,24 @@
|
|||||||
v-hasPermi="['system:menu:add']"
|
v-hasPermi="['system:menu:add']"
|
||||||
>新增</el-button>
|
>新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="info"
|
||||||
|
plain
|
||||||
|
icon="el-icon-sort"
|
||||||
|
size="mini"
|
||||||
|
@click="toggleExpandAll"
|
||||||
|
>展开/折叠</el-button>
|
||||||
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-table
|
<el-table
|
||||||
|
v-if="refreshTable"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="menuList"
|
:data="menuList"
|
||||||
row-key="menuId"
|
row-key="menuId"
|
||||||
|
:default-expand-all="isExpandAll"
|
||||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||||
>
|
>
|
||||||
<el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="160"></el-table-column>
|
<el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="160"></el-table-column>
|
||||||
@ -55,7 +66,11 @@
|
|||||||
<el-table-column prop="orderNum" label="排序" width="60"></el-table-column>
|
<el-table-column prop="orderNum" label="排序" width="60"></el-table-column>
|
||||||
<el-table-column prop="perms" label="权限标识" :show-overflow-tooltip="true"></el-table-column>
|
<el-table-column prop="perms" 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="component" label="组件路径" :show-overflow-tooltip="true"></el-table-column>
|
||||||
<el-table-column prop="status" label="状态" :formatter="statusFormat" width="80"></el-table-column>
|
<el-table-column prop="status" label="状态" width="80">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="statusOptions" :value="scope.row.status"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime">
|
<el-table-column label="创建时间" align="center" prop="createTime">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
@ -271,6 +286,10 @@ export default {
|
|||||||
title: "",
|
title: "",
|
||||||
// 是否显示弹出层
|
// 是否显示弹出层
|
||||||
open: false,
|
open: false,
|
||||||
|
// 是否展开,默认全部折叠
|
||||||
|
isExpandAll: false,
|
||||||
|
// 重新渲染表格状态
|
||||||
|
refreshTable: true,
|
||||||
// 显示状态数据字典
|
// 显示状态数据字典
|
||||||
visibleOptions: [],
|
visibleOptions: [],
|
||||||
// 菜单状态数据字典
|
// 菜单状态数据字典
|
||||||
@ -338,20 +357,6 @@ export default {
|
|||||||
this.menuOptions.push(menu);
|
this.menuOptions.push(menu);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 显示状态字典翻译
|
|
||||||
visibleFormat(row, column) {
|
|
||||||
if (row.menuType == "F") {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return this.selectDictLabel(this.visibleOptions, row.visible);
|
|
||||||
},
|
|
||||||
// 菜单状态字典翻译
|
|
||||||
statusFormat(row, column) {
|
|
||||||
if (row.menuType == "F") {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return this.selectDictLabel(this.statusOptions, row.status);
|
|
||||||
},
|
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
cancel() {
|
cancel() {
|
||||||
this.open = false;
|
this.open = false;
|
||||||
@ -394,6 +399,14 @@ export default {
|
|||||||
this.open = true;
|
this.open = true;
|
||||||
this.title = "添加菜单";
|
this.title = "添加菜单";
|
||||||
},
|
},
|
||||||
|
/** 展开/折叠操作 */
|
||||||
|
toggleExpandAll() {
|
||||||
|
this.refreshTable = false;
|
||||||
|
this.isExpandAll = !this.isExpandAll;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.refreshTable = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
handleUpdate(row) {
|
handleUpdate(row) {
|
||||||
this.reset();
|
this.reset();
|
||||||
|
@ -80,20 +80,16 @@
|
|||||||
prop="noticeTitle"
|
prop="noticeTitle"
|
||||||
:show-overflow-tooltip="true"
|
:show-overflow-tooltip="true"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column label="公告类型" align="center" prop="noticeType" width="100">
|
||||||
label="公告类型"
|
<template slot-scope="scope">
|
||||||
align="center"
|
<dict-tag :options="typeOptions" :value="scope.row.noticeType"/>
|
||||||
prop="noticeType"
|
</template>
|
||||||
:formatter="typeFormat"
|
</el-table-column>
|
||||||
width="100"
|
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||||
/>
|
<template slot-scope="scope">
|
||||||
<el-table-column
|
<dict-tag :options="statusOptions" :value="scope.row.status"/>
|
||||||
label="状态"
|
</template>
|
||||||
align="center"
|
</el-table-column>
|
||||||
prop="status"
|
|
||||||
:formatter="statusFormat"
|
|
||||||
width="100"
|
|
||||||
/>
|
|
||||||
<el-table-column label="创建者" align="center" prop="createBy" width="100" />
|
<el-table-column label="创建者" align="center" prop="createBy" width="100" />
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime" width="100">
|
<el-table-column label="创建时间" align="center" prop="createTime" width="100">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
@ -244,14 +240,6 @@ export default {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 公告状态字典翻译
|
|
||||||
statusFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.statusOptions, row.status);
|
|
||||||
},
|
|
||||||
// 公告状态字典翻译
|
|
||||||
typeFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.typeOptions, row.noticeType);
|
|
||||||
},
|
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
cancel() {
|
cancel() {
|
||||||
this.open = false;
|
this.open = false;
|
||||||
|
@ -88,7 +88,11 @@
|
|||||||
<el-table-column label="岗位编码" align="center" prop="postCode" />
|
<el-table-column label="岗位编码" align="center" prop="postCode" />
|
||||||
<el-table-column label="岗位名称" align="center" prop="postName" />
|
<el-table-column label="岗位名称" align="center" prop="postName" />
|
||||||
<el-table-column label="岗位排序" align="center" prop="postSort" />
|
<el-table-column label="岗位排序" align="center" prop="postSort" />
|
||||||
<el-table-column label="状态" align="center" prop="status" :formatter="statusFormat" />
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="statusOptions" :value="scope.row.status"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
@ -157,7 +161,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listPost, getPost, delPost, addPost, updatePost } from "@/api/system/post";
|
import { listPost, getPost, delPost, addPost, updatePost } from "@/api/system/post";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Post",
|
name: "Post",
|
||||||
@ -225,10 +228,6 @@ export default {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 岗位状态字典翻译
|
|
||||||
statusFormat(row, column) {
|
|
||||||
return this.selectDictLabel(this.statusOptions, row.status);
|
|
||||||
},
|
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
cancel() {
|
cancel() {
|
||||||
this.open = false;
|
this.open = false;
|
||||||
@ -314,7 +313,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/system/post/export', this.queryParams);
|
this.downLoadExcel('/system/post/export', this.queryParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -262,7 +262,6 @@
|
|||||||
import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus } from "@/api/system/role";
|
import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus } from "@/api/system/role";
|
||||||
import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu";
|
import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu";
|
||||||
import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/dept";
|
import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/dept";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Role",
|
name: "Role",
|
||||||
@ -626,7 +625,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/system/role/export', this.queryParams);
|
this.downLoadExcel('/system/role/export', this.queryParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -351,7 +351,6 @@ import { getToken } from "@/utils/auth";
|
|||||||
import { treeselect } from "@/api/system/dept";
|
import { treeselect } from "@/api/system/dept";
|
||||||
import Treeselect from "@riophae/vue-treeselect";
|
import Treeselect from "@riophae/vue-treeselect";
|
||||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||||
import { downLoadExcel } from "@/utils/download";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "User",
|
name: "User",
|
||||||
@ -661,7 +660,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
downLoadExcel('/system/user/export', this.queryParams);
|
this.downLoadExcel('/system/user/export', this.queryParams);
|
||||||
},
|
},
|
||||||
/** 导入按钮操作 */
|
/** 导入按钮操作 */
|
||||||
handleImport() {
|
handleImport() {
|
||||||
@ -670,7 +669,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 下载模板操作 */
|
/** 下载模板操作 */
|
||||||
importTemplate() {
|
importTemplate() {
|
||||||
downLoadExcel('/system/user/importTemplate');
|
this.downLoadExcel('/system/user/importTemplate');
|
||||||
},
|
},
|
||||||
// 文件上传中处理
|
// 文件上传中处理
|
||||||
handleFileUploadProgress(event, file, fileList) {
|
handleFileUploadProgress(event, file, fileList) {
|
||||||
|
@ -161,7 +161,7 @@
|
|||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
<!-- 预览界面 -->
|
<!-- 预览界面 -->
|
||||||
<el-dialog :title="preview.title" :visible.sync="preview.open" width="80%" top="5vh" append-to-body>
|
<el-dialog :title="preview.title" :visible.sync="preview.open" width="80%" top="5vh" append-to-body class="scrollbar">
|
||||||
<el-tabs v-model="preview.activeName">
|
<el-tabs v-model="preview.activeName">
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
v-for="(value, key) in preview.data"
|
v-for="(value, key) in preview.data"
|
||||||
|
@ -4,7 +4,6 @@ MAINTAINER Lion Li
|
|||||||
|
|
||||||
RUN mkdir -p /ruoyi/server
|
RUN mkdir -p /ruoyi/server
|
||||||
RUN mkdir -p /ruoyi/server/logs
|
RUN mkdir -p /ruoyi/server/logs
|
||||||
RUN mkdir -p /ruoyi/server/ruoyi/uploadPath
|
|
||||||
|
|
||||||
WORKDIR /ruoyi/server
|
WORKDIR /ruoyi/server
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.0.0</version>
|
<version>3.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@ -241,10 +241,6 @@
|
|||||||
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
|
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.qiniu</groupId>
|
<groupId>com.qiniu</groupId>
|
||||||
<artifactId>qiniu-java-sdk</artifactId>
|
<artifactId>qiniu-java-sdk</artifactId>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.ruoyi.framework.captcha;
|
package com.ruoyi.common.captcha;
|
||||||
|
|
||||||
import cn.hutool.captcha.generator.CodeGenerator;
|
import cn.hutool.captcha.generator.CodeGenerator;
|
||||||
import cn.hutool.core.math.Calculator;
|
import cn.hutool.core.math.Calculator;
|
@ -139,4 +139,8 @@ public class Constants
|
|||||||
*/
|
*/
|
||||||
public static final String LOOKUP_RMI = "rmi://";
|
public static final String LOOKUP_RMI = "rmi://";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LDAP 远程方法调用
|
||||||
|
*/
|
||||||
|
public static final String LOOKUP_LDAP = "ldap://";
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.ruoyi.common.convert;
|
||||||
|
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.alibaba.excel.converters.Converter;
|
||||||
|
import com.alibaba.excel.enums.CellDataTypeEnum;
|
||||||
|
import com.alibaba.excel.metadata.CellData;
|
||||||
|
import com.alibaba.excel.metadata.GlobalConfiguration;
|
||||||
|
import com.alibaba.excel.metadata.property.ExcelContentProperty;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 大数值转换
|
||||||
|
* Excel 数值长度位15位 大于15位的数值转换位字符串
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class ExcelBigNumberConvert implements Converter<Long> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Long> supportJavaTypeKey() {
|
||||||
|
return Long.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CellDataTypeEnum supportExcelTypeKey() {
|
||||||
|
return CellDataTypeEnum.STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||||
|
return Convert.toLong(cellData.getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CellData<Object> convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||||
|
if (ObjectUtil.isNotNull(object)) {
|
||||||
|
String str = Convert.toStr(object);
|
||||||
|
if (str.length() > 15) {
|
||||||
|
return new CellData<>(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CellData<Object> cellData = new CellData<>(new BigDecimal(object));
|
||||||
|
cellData.setType(CellDataTypeEnum.NUMBER);
|
||||||
|
return cellData;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,28 +16,6 @@ public class BaseController
|
|||||||
{
|
{
|
||||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
/**
|
|
||||||
* 响应返回结果
|
|
||||||
*
|
|
||||||
* @param rows 影响行数
|
|
||||||
* @return 操作结果
|
|
||||||
*/
|
|
||||||
protected AjaxResult<Void> toAjax(int rows)
|
|
||||||
{
|
|
||||||
return rows > 0 ? AjaxResult.success() : AjaxResult.error();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 响应返回结果
|
|
||||||
*
|
|
||||||
* @param result 结果
|
|
||||||
* @return 操作结果
|
|
||||||
*/
|
|
||||||
protected AjaxResult<Void> toAjax(boolean result)
|
|
||||||
{
|
|
||||||
return result ? success() : error();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回成功
|
* 返回成功
|
||||||
*/
|
*/
|
||||||
@ -70,6 +48,28 @@ public class BaseController
|
|||||||
return AjaxResult.error(message);
|
return AjaxResult.error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应返回结果
|
||||||
|
*
|
||||||
|
* @param rows 影响行数
|
||||||
|
* @return 操作结果
|
||||||
|
*/
|
||||||
|
protected AjaxResult<Void> toAjax(int rows)
|
||||||
|
{
|
||||||
|
return rows > 0 ? AjaxResult.success() : AjaxResult.error();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应返回结果
|
||||||
|
*
|
||||||
|
* @param result 结果
|
||||||
|
* @return 操作结果
|
||||||
|
*/
|
||||||
|
protected AjaxResult<Void> toAjax(boolean result)
|
||||||
|
{
|
||||||
|
return result ? success() : error();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面跳转
|
* 页面跳转
|
||||||
*/
|
*/
|
||||||
|
@ -78,6 +78,11 @@ public class SysUser implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 密码
|
* 密码
|
||||||
*/
|
*/
|
||||||
|
@TableField(
|
||||||
|
insertStrategy = FieldStrategy.NOT_EMPTY,
|
||||||
|
updateStrategy = FieldStrategy.NOT_EMPTY,
|
||||||
|
whereStrategy = FieldStrategy.NOT_EMPTY
|
||||||
|
)
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.ruoyi.common.core.mybatisplus.cache;
|
package com.ruoyi.common.core.mybatisplus.cache;
|
||||||
|
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.utils.RedisUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.ibatis.cache.Cache;
|
import org.apache.ibatis.cache.Cache;
|
||||||
import org.springframework.data.redis.connection.RedisServerCommands;
|
import org.springframework.data.redis.connection.RedisServerCommands;
|
||||||
@ -25,8 +25,6 @@ public class MybatisPlusRedisCache implements Cache {
|
|||||||
|
|
||||||
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
|
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
|
||||||
|
|
||||||
private RedisCache redisCache;
|
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
public MybatisPlusRedisCache(final String id) {
|
public MybatisPlusRedisCache(final String id) {
|
||||||
@ -43,23 +41,16 @@ public class MybatisPlusRedisCache implements Cache {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putObject(Object key, Object value) {
|
public void putObject(Object key, Object value) {
|
||||||
if (redisCache == null) {
|
|
||||||
redisCache = SpringUtil.getBean(RedisCache.class);
|
|
||||||
}
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
redisCache.setCacheObject(key.toString(), value);
|
RedisUtils.setCacheObject(key.toString(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(Object key) {
|
public Object getObject(Object key) {
|
||||||
if (redisCache == null) {
|
|
||||||
//由于启动期间注入失败,只能运行期间注入,这段代码可以删除
|
|
||||||
redisCache = SpringUtil.getBean(RedisCache.class);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
return redisCache.getCacheObject(key.toString());
|
return RedisUtils.getCacheObject(key.toString());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -70,11 +61,8 @@ public class MybatisPlusRedisCache implements Cache {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object removeObject(Object key) {
|
public Object removeObject(Object key) {
|
||||||
if (redisCache == null) {
|
|
||||||
redisCache = SpringUtil.getBean(RedisCache.class);
|
|
||||||
}
|
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
redisCache.deleteObject(key.toString());
|
RedisUtils.deleteObject(key.toString());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -82,12 +70,9 @@ public class MybatisPlusRedisCache implements Cache {
|
|||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
log.debug("清空缓存");
|
log.debug("清空缓存");
|
||||||
if (redisCache == null) {
|
Collection<String> keys = RedisUtils.keys("*:" + this.id + "*");
|
||||||
redisCache = SpringUtil.getBean(RedisCache.class);
|
|
||||||
}
|
|
||||||
Collection<String> keys = redisCache.keys("*:" + this.id + "*");
|
|
||||||
if (!CollectionUtils.isEmpty(keys)) {
|
if (!CollectionUtils.isEmpty(keys)) {
|
||||||
redisCache.deleteObject(keys);
|
RedisUtils.deleteObject(keys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,7 @@ import java.util.Collection;
|
|||||||
public interface BaseMapperPlus<T> extends BaseMapper<T> {
|
public interface BaseMapperPlus<T> extends BaseMapper<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单sql批量插入( 全量填充 无视数据库默认值 )
|
* 单sql批量插入( 全量填充 )
|
||||||
* 适用于无脑插入
|
|
||||||
*/
|
*/
|
||||||
int insertAll(@Param("list") Collection<T> batchList);
|
int insertAll(@Param("list") Collection<T> batchList);
|
||||||
|
|
||||||
|
@ -15,45 +15,46 @@ import java.util.function.Function;
|
|||||||
/**
|
/**
|
||||||
* 自定义 Service 接口, 实现 数据库实体与 vo 对象转换返回
|
* 自定义 Service 接口, 实现 数据库实体与 vo 对象转换返回
|
||||||
*
|
*
|
||||||
|
* @param <T> 数据实体类
|
||||||
|
* @param <V> vo类
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
* @since 2021-05-13
|
|
||||||
*/
|
*/
|
||||||
public interface IServicePlus<T, K> extends IService<T> {
|
public interface IServicePlus<T, V> extends IService<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id 主键id
|
* @param id 主键id
|
||||||
* @param copyOptions copy条件
|
* @param copyOptions copy条件
|
||||||
* @return K对象
|
* @return V对象
|
||||||
*/
|
*/
|
||||||
K getVoById(Serializable id, CopyOptions copyOptions);
|
V getVoById(Serializable id, CopyOptions copyOptions);
|
||||||
|
|
||||||
default K getVoById(Serializable id) {
|
default V getVoById(Serializable id) {
|
||||||
return getVoById(id, new CopyOptions());
|
return getVoById(id, new CopyOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param convertor 自定义转换器
|
* @param convertor 自定义转换器
|
||||||
*/
|
*/
|
||||||
default K getVoById(Serializable id, Function<T, K> convertor) {
|
default V getVoById(Serializable id, Function<T, V> convertor) {
|
||||||
return convertor.apply(getById(id));
|
return convertor.apply(getById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param idList id列表
|
* @param idList id列表
|
||||||
* @param copyOptions copy条件
|
* @param copyOptions copy条件
|
||||||
* @return K对象
|
* @return V对象
|
||||||
*/
|
*/
|
||||||
List<K> listVoByIds(Collection<? extends Serializable> idList, CopyOptions copyOptions);
|
List<V> listVoByIds(Collection<? extends Serializable> idList, CopyOptions copyOptions);
|
||||||
|
|
||||||
default List<K> listVoByIds(Collection<? extends Serializable> idList) {
|
default List<V> listVoByIds(Collection<? extends Serializable> idList) {
|
||||||
return listVoByIds(idList, new CopyOptions());
|
return listVoByIds(idList, new CopyOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param convertor 自定义转换器
|
* @param convertor 自定义转换器
|
||||||
*/
|
*/
|
||||||
default List<K> listVoByIds(Collection<? extends Serializable> idList,
|
default List<V> listVoByIds(Collection<? extends Serializable> idList,
|
||||||
Function<Collection<T>, List<K>> convertor) {
|
Function<Collection<T>, List<V>> convertor) {
|
||||||
List<T> list = getBaseMapper().selectBatchIds(idList);
|
List<T> list = getBaseMapper().selectBatchIds(idList);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -64,19 +65,19 @@ public interface IServicePlus<T, K> extends IService<T> {
|
|||||||
/**
|
/**
|
||||||
* @param columnMap 表字段 map 对象
|
* @param columnMap 表字段 map 对象
|
||||||
* @param copyOptions copy条件
|
* @param copyOptions copy条件
|
||||||
* @return K对象
|
* @return V对象
|
||||||
*/
|
*/
|
||||||
List<K> listVoByMap(Map<String, Object> columnMap, CopyOptions copyOptions);
|
List<V> listVoByMap(Map<String, Object> columnMap, CopyOptions copyOptions);
|
||||||
|
|
||||||
default List<K> listVoByMap(Map<String, Object> columnMap) {
|
default List<V> listVoByMap(Map<String, Object> columnMap) {
|
||||||
return listVoByMap(columnMap, new CopyOptions());
|
return listVoByMap(columnMap, new CopyOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param convertor 自定义转换器
|
* @param convertor 自定义转换器
|
||||||
*/
|
*/
|
||||||
default List<K> listVoByMap(Map<String, Object> columnMap,
|
default List<V> listVoByMap(Map<String, Object> columnMap,
|
||||||
Function<Collection<T>, List<K>> convertor) {
|
Function<Collection<T>, List<V>> convertor) {
|
||||||
List<T> list = getBaseMapper().selectByMap(columnMap);
|
List<T> list = getBaseMapper().selectByMap(columnMap);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -87,36 +88,36 @@ public interface IServicePlus<T, K> extends IService<T> {
|
|||||||
/**
|
/**
|
||||||
* @param queryWrapper 查询条件
|
* @param queryWrapper 查询条件
|
||||||
* @param copyOptions copy条件
|
* @param copyOptions copy条件
|
||||||
* @return K对象
|
* @return V对象
|
||||||
*/
|
*/
|
||||||
K getVoOne(Wrapper<T> queryWrapper, CopyOptions copyOptions);
|
V getVoOne(Wrapper<T> queryWrapper, CopyOptions copyOptions);
|
||||||
|
|
||||||
default K getVoOne(Wrapper<T> queryWrapper) {
|
default V getVoOne(Wrapper<T> queryWrapper) {
|
||||||
return getVoOne(queryWrapper, new CopyOptions());
|
return getVoOne(queryWrapper, new CopyOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param convertor 自定义转换器
|
* @param convertor 自定义转换器
|
||||||
*/
|
*/
|
||||||
default K getVoOne(Wrapper<T> queryWrapper, Function<T, K> convertor) {
|
default V getVoOne(Wrapper<T> queryWrapper, Function<T, V> convertor) {
|
||||||
return convertor.apply(getOne(queryWrapper, true));
|
return convertor.apply(getOne(queryWrapper, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param queryWrapper 查询条件
|
* @param queryWrapper 查询条件
|
||||||
* @param copyOptions copy条件
|
* @param copyOptions copy条件
|
||||||
* @return K对象
|
* @return V对象
|
||||||
*/
|
*/
|
||||||
List<K> listVo(Wrapper<T> queryWrapper, CopyOptions copyOptions);
|
List<V> listVo(Wrapper<T> queryWrapper, CopyOptions copyOptions);
|
||||||
|
|
||||||
default List<K> listVo(Wrapper<T> queryWrapper) {
|
default List<V> listVo(Wrapper<T> queryWrapper) {
|
||||||
return listVo(queryWrapper, new CopyOptions());
|
return listVo(queryWrapper, new CopyOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param convertor 自定义转换器
|
* @param convertor 自定义转换器
|
||||||
*/
|
*/
|
||||||
default List<K> listVo(Wrapper<T> queryWrapper, Function<Collection<T>, List<K>> convertor) {
|
default List<V> listVo(Wrapper<T> queryWrapper, Function<Collection<T>, List<V>> convertor) {
|
||||||
List<T> list = getBaseMapper().selectList(queryWrapper);
|
List<T> list = getBaseMapper().selectList(queryWrapper);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -124,14 +125,14 @@ public interface IServicePlus<T, K> extends IService<T> {
|
|||||||
return convertor.apply(list);
|
return convertor.apply(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<K> listVo() {
|
default List<V> listVo() {
|
||||||
return listVo(Wrappers.emptyWrapper());
|
return listVo(Wrappers.emptyWrapper());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param convertor 自定义转换器
|
* @param convertor 自定义转换器
|
||||||
*/
|
*/
|
||||||
default List<K> listVo(Function<Collection<T>, List<K>> convertor) {
|
default List<V> listVo(Function<Collection<T>, List<V>> convertor) {
|
||||||
return listVo(Wrappers.emptyWrapper(), convertor);
|
return listVo(Wrappers.emptyWrapper(), convertor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,34 +140,36 @@ public interface IServicePlus<T, K> extends IService<T> {
|
|||||||
* @param page 分页对象
|
* @param page 分页对象
|
||||||
* @param queryWrapper 查询条件
|
* @param queryWrapper 查询条件
|
||||||
* @param copyOptions copy条件
|
* @param copyOptions copy条件
|
||||||
* @return K对象
|
* @return V对象
|
||||||
*/
|
*/
|
||||||
PagePlus<T, K> pageVo(PagePlus<T, K> page, Wrapper<T> queryWrapper, CopyOptions copyOptions);
|
PagePlus<T, V> pageVo(PagePlus<T, V> page, Wrapper<T> queryWrapper, CopyOptions copyOptions);
|
||||||
|
|
||||||
default PagePlus<T, K> pageVo(PagePlus<T, K> page, Wrapper<T> queryWrapper) {
|
default PagePlus<T, V> pageVo(PagePlus<T, V> page, Wrapper<T> queryWrapper) {
|
||||||
return pageVo(page, queryWrapper, new CopyOptions());
|
return pageVo(page, queryWrapper, new CopyOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param convertor 自定义转换器
|
* @param convertor 自定义转换器
|
||||||
*/
|
*/
|
||||||
default PagePlus<T, K> pageVo(PagePlus<T, K> page, Wrapper<T> queryWrapper,
|
default PagePlus<T, V> pageVo(PagePlus<T, V> page, Wrapper<T> queryWrapper,
|
||||||
Function<Collection<T>, List<K>> convertor) {
|
Function<Collection<T>, List<V>> convertor) {
|
||||||
PagePlus<T, K> result = getBaseMapper().selectPage(page, queryWrapper);
|
PagePlus<T, V> result = getBaseMapper().selectPage(page, queryWrapper);
|
||||||
return result.setRecordsVo(convertor.apply(result.getRecords()));
|
return result.setRecordsVo(convertor.apply(result.getRecords()));
|
||||||
}
|
}
|
||||||
|
|
||||||
default PagePlus<T, K> pageVo(PagePlus<T, K> page) {
|
default PagePlus<T, V> pageVo(PagePlus<T, V> page) {
|
||||||
return pageVo(page, Wrappers.emptyWrapper());
|
return pageVo(page, Wrappers.emptyWrapper());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param convertor 自定义转换器
|
* @param convertor 自定义转换器
|
||||||
*/
|
*/
|
||||||
default PagePlus<T, K> pageVo(PagePlus<T, K> page, Function<Collection<T>, List<K>> convertor) {
|
default PagePlus<T, V> pageVo(PagePlus<T, V> page, Function<Collection<T>, List<V>> convertor) {
|
||||||
return pageVo(page, Wrappers.emptyWrapper(), convertor);
|
return pageVo(page, Wrappers.emptyWrapper(), convertor);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean saveAll(Collection<T> entityList);
|
boolean saveAll(Collection<T> entityList);
|
||||||
|
|
||||||
|
boolean saveOrUpdateAll(Collection<T> entityList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
package com.ruoyi.common.core.mybatisplus.core;
|
package com.ruoyi.common.core.mybatisplus.core;
|
||||||
|
|
||||||
import cn.hutool.core.bean.copier.CopyOptions;
|
import cn.hutool.core.bean.copier.CopyOptions;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
|
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.ruoyi.common.core.page.PagePlus;
|
import com.ruoyi.common.core.page.PagePlus;
|
||||||
import com.ruoyi.common.utils.BeanCopyUtils;
|
import com.ruoyi.common.utils.BeanCopyUtils;
|
||||||
|
import com.ruoyi.common.utils.reflect.ReflectUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.ResolvableType;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -18,11 +24,14 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* IServicePlus 实现类
|
* IServicePlus 实现类
|
||||||
*
|
*
|
||||||
|
* @param <M> Mapper类
|
||||||
|
* @param <T> 数据实体类
|
||||||
|
* @param <V> vo类
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, K> extends ServiceImpl<M, T> implements IServicePlus<T, K> {
|
public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, V> extends ServiceImpl<M, T> implements IServicePlus<T, V> {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected M baseMapper;
|
protected M baseMapper;
|
||||||
@ -40,31 +49,26 @@ public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, K> extends ServiceI
|
|||||||
return entityClass;
|
return entityClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Class<T> mapperClass = currentMapperClass();
|
protected Class<M> mapperClass = currentMapperClass();
|
||||||
|
|
||||||
protected Class<K> voClass = currentVoClass();
|
protected Class<V> voClass = currentVoClass();
|
||||||
|
|
||||||
public Class<K> getVoClass() {
|
public Class<V> getVoClass() {
|
||||||
return voClass;
|
return voClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<T> currentMapperClass() {
|
protected Class<M> currentMapperClass() {
|
||||||
return (Class<T>) this.getResolvableType().as(ServicePlusImpl.class).getGeneric(0).getType();
|
return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<T> currentModelClass() {
|
protected Class<T> currentModelClass() {
|
||||||
return (Class<T>) this.getResolvableType().as(ServicePlusImpl.class).getGeneric(1).getType();
|
return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Class<K> currentVoClass() {
|
protected Class<V> currentVoClass() {
|
||||||
return (Class<K>) this.getResolvableType().as(ServicePlusImpl.class).getGeneric(2).getType();
|
return (Class<V>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 2);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ResolvableType getResolvableType() {
|
|
||||||
return ResolvableType.forClass(ClassUtils.getUserClass(getClass()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,21 +117,55 @@ public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, K> extends ServiceI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单sql批量插入( 全量填充 无视数据库默认值 )
|
* 单sql批量插入( 全量填充 )
|
||||||
* 适用于无脑插入
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean saveAll(Collection<T> entityList) {
|
public boolean saveAll(Collection<T> entityList) {
|
||||||
|
if (CollUtil.isEmpty(entityList)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return baseMapper.insertAll(entityList) == entityList.size();
|
return baseMapper.insertAll(entityList) == entityList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全量保存或更新 ( 按主键区分 )
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean saveOrUpdateAll(Collection<T> entityList) {
|
||||||
|
if (CollUtil.isEmpty(entityList)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
|
||||||
|
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
|
||||||
|
String keyProperty = tableInfo.getKeyProperty();
|
||||||
|
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
|
||||||
|
List<T> addList = new ArrayList<>();
|
||||||
|
List<T> updateList = new ArrayList<>();
|
||||||
|
int row = 0;
|
||||||
|
for (T entity : entityList) {
|
||||||
|
Object id = ReflectUtils.invokeGetter(entity, keyProperty);
|
||||||
|
if (ObjectUtil.isNull(id)) {
|
||||||
|
addList.add(entity);
|
||||||
|
} else {
|
||||||
|
updateList.add(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CollUtil.isNotEmpty(updateList) && updateBatchById(updateList)) {
|
||||||
|
row += updateList.size();
|
||||||
|
}
|
||||||
|
if (CollUtil.isNotEmpty(addList)) {
|
||||||
|
row += baseMapper.insertAll(addList);
|
||||||
|
}
|
||||||
|
return row == entityList.size();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据 ID 查询
|
* 根据 ID 查询
|
||||||
*
|
*
|
||||||
* @param id 主键ID
|
* @param id 主键ID
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public K getVoById(Serializable id, CopyOptions copyOptions) {
|
public V getVoById(Serializable id, CopyOptions copyOptions) {
|
||||||
T t = getBaseMapper().selectById(id);
|
T t = getBaseMapper().selectById(id);
|
||||||
return BeanCopyUtils.oneCopy(t, copyOptions, voClass);
|
return BeanCopyUtils.oneCopy(t, copyOptions, voClass);
|
||||||
}
|
}
|
||||||
@ -138,7 +176,7 @@ public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, K> extends ServiceI
|
|||||||
* @param idList 主键ID列表
|
* @param idList 主键ID列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<K> listVoByIds(Collection<? extends Serializable> idList, CopyOptions copyOptions) {
|
public List<V> listVoByIds(Collection<? extends Serializable> idList, CopyOptions copyOptions) {
|
||||||
List<T> list = getBaseMapper().selectBatchIds(idList);
|
List<T> list = getBaseMapper().selectBatchIds(idList);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -152,7 +190,7 @@ public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, K> extends ServiceI
|
|||||||
* @param columnMap 表字段 map 对象
|
* @param columnMap 表字段 map 对象
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<K> listVoByMap(Map<String, Object> columnMap, CopyOptions copyOptions) {
|
public List<V> listVoByMap(Map<String, Object> columnMap, CopyOptions copyOptions) {
|
||||||
List<T> list = getBaseMapper().selectByMap(columnMap);
|
List<T> list = getBaseMapper().selectByMap(columnMap);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -167,7 +205,7 @@ public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, K> extends ServiceI
|
|||||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public K getVoOne(Wrapper<T> queryWrapper, CopyOptions copyOptions) {
|
public V getVoOne(Wrapper<T> queryWrapper, CopyOptions copyOptions) {
|
||||||
T t = getOne(queryWrapper, true);
|
T t = getOne(queryWrapper, true);
|
||||||
return BeanCopyUtils.oneCopy(t, copyOptions, voClass);
|
return BeanCopyUtils.oneCopy(t, copyOptions, voClass);
|
||||||
}
|
}
|
||||||
@ -178,7 +216,7 @@ public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, K> extends ServiceI
|
|||||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<K> listVo(Wrapper<T> queryWrapper, CopyOptions copyOptions) {
|
public List<V> listVo(Wrapper<T> queryWrapper, CopyOptions copyOptions) {
|
||||||
List<T> list = getBaseMapper().selectList(queryWrapper);
|
List<T> list = getBaseMapper().selectList(queryWrapper);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -193,9 +231,9 @@ public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, K> extends ServiceI
|
|||||||
* @param queryWrapper 实体对象封装操作类
|
* @param queryWrapper 实体对象封装操作类
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public PagePlus<T, K> pageVo(PagePlus<T, K> page, Wrapper<T> queryWrapper, CopyOptions copyOptions) {
|
public PagePlus<T, V> pageVo(PagePlus<T, V> page, Wrapper<T> queryWrapper, CopyOptions copyOptions) {
|
||||||
PagePlus<T, K> result = getBaseMapper().selectPage(page, queryWrapper);
|
PagePlus<T, V> result = getBaseMapper().selectPage(page, queryWrapper);
|
||||||
List<K> volist = BeanCopyUtils.listCopy(result.getRecords(), copyOptions, voClass);
|
List<V> volist = BeanCopyUtils.listCopy(result.getRecords(), copyOptions, voClass);
|
||||||
result.setRecordsVo(volist);
|
result.setRecordsVo(volist);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.ruoyi.common.core.mybatisplus.methods;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
|
||||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
@ -11,13 +12,17 @@ import org.apache.ibatis.executor.keygen.NoKeyGenerator;
|
|||||||
import org.apache.ibatis.mapping.MappedStatement;
|
import org.apache.ibatis.mapping.MappedStatement;
|
||||||
import org.apache.ibatis.mapping.SqlSource;
|
import org.apache.ibatis.mapping.SqlSource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单sql批量插入( 全量填充 无视数据库默认值 )
|
* 单sql批量插入( 全量填充 )
|
||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
public class InsertAll extends AbstractMethod {
|
public class InsertAll extends AbstractMethod {
|
||||||
|
|
||||||
|
private final static String[] FILL_PROPERTY = {"createTime", "createBy", "updateTime", "updateBy"};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||||||
final String sql = "<script>insert into %s %s values %s</script>";
|
final String sql = "<script>insert into %s %s values %s</script>";
|
||||||
@ -63,10 +68,32 @@ public class InsertAll extends AbstractMethod {
|
|||||||
final StringBuilder valueSql = new StringBuilder();
|
final StringBuilder valueSql = new StringBuilder();
|
||||||
valueSql.append("<foreach collection=\"list\" item=\"item\" index=\"index\" open=\"(\" separator=\"),(\" close=\")\">");
|
valueSql.append("<foreach collection=\"list\" item=\"item\" index=\"index\" open=\"(\" separator=\"),(\" close=\")\">");
|
||||||
if (StringUtils.isNotBlank(tableInfo.getKeyColumn())) {
|
if (StringUtils.isNotBlank(tableInfo.getKeyColumn())) {
|
||||||
valueSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},");
|
valueSql.append("\n#{item.").append(tableInfo.getKeyProperty()).append("},\n");
|
||||||
|
}
|
||||||
|
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
|
||||||
|
int last = fieldList.size() - 1;
|
||||||
|
for (int i = 0; i < fieldList.size(); i++) {
|
||||||
|
String property = fieldList.get(i).getProperty();
|
||||||
|
if (!StringUtils.equalsAny(property, FILL_PROPERTY)) {
|
||||||
|
valueSql.append("<if test=\"item.").append(property).append(" != null\">");
|
||||||
|
valueSql.append("#{item.").append(property).append("}");
|
||||||
|
if (i != last) {
|
||||||
|
valueSql.append(",");
|
||||||
|
}
|
||||||
|
valueSql.append("</if>");
|
||||||
|
valueSql.append("<if test=\"item.").append(property).append(" == null\">");
|
||||||
|
valueSql.append("DEFAULT");
|
||||||
|
if (i != last) {
|
||||||
|
valueSql.append(",");
|
||||||
|
}
|
||||||
|
valueSql.append("</if>");
|
||||||
|
} else {
|
||||||
|
valueSql.append("#{item.").append(property).append("}");
|
||||||
|
if (i != last) {
|
||||||
|
valueSql.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tableInfo.getFieldList().forEach(x -> valueSql.append("#{item.").append(x.getProperty()).append("},"));
|
|
||||||
valueSql.delete(valueSql.length() - 1, valueSql.length());
|
|
||||||
valueSql.append("</foreach>");
|
valueSql.append("</foreach>");
|
||||||
return valueSql.toString();
|
return valueSql.toString();
|
||||||
}
|
}
|
||||||
|
@ -5,21 +5,58 @@ import org.redisson.api.*;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spring redis 工具类
|
* spring redis 工具类
|
||||||
*
|
*
|
||||||
* @author shenxinquan
|
* @author shenxinquan
|
||||||
|
* @see com.ruoyi.common.utils.RedisUtils
|
||||||
|
* @deprecated 3.2.0 删除此类
|
||||||
**/
|
**/
|
||||||
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
||||||
@Component
|
@Component
|
||||||
|
@Deprecated
|
||||||
public class RedisCache {
|
public class RedisCache {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedissonClient redissonClient;
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存基本的对象,Integer、String、实体类等
|
* 缓存基本的对象,Integer、String、实体类等
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.ruoyi.common.core.validate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验分组 query
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
|
public interface QueryGroup {
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.ruoyi.common.enums;
|
||||||
|
|
||||||
|
import cn.hutool.captcha.AbstractCaptcha;
|
||||||
|
import cn.hutool.captcha.CircleCaptcha;
|
||||||
|
import cn.hutool.captcha.LineCaptcha;
|
||||||
|
import cn.hutool.captcha.ShearCaptcha;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码类别
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum CaptchaCategory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线段干扰
|
||||||
|
*/
|
||||||
|
LINE(LineCaptcha.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 圆圈干扰
|
||||||
|
*/
|
||||||
|
CIRCLE(CircleCaptcha.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扭曲干扰
|
||||||
|
*/
|
||||||
|
SHEAR(ShearCaptcha.class);
|
||||||
|
|
||||||
|
private final Class<? extends AbstractCaptcha> clazz;
|
||||||
|
}
|
29
ruoyi/src/main/java/com/ruoyi/common/enums/CaptchaType.java
Normal file
29
ruoyi/src/main/java/com/ruoyi/common/enums/CaptchaType.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.ruoyi.common.enums;
|
||||||
|
|
||||||
|
import cn.hutool.captcha.generator.CodeGenerator;
|
||||||
|
import cn.hutool.captcha.generator.RandomGenerator;
|
||||||
|
import com.ruoyi.common.captcha.UnsignedMathGenerator;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码类型
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum CaptchaType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数字
|
||||||
|
*/
|
||||||
|
MATH(UnsignedMathGenerator.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符
|
||||||
|
*/
|
||||||
|
CHAR(RandomGenerator.class);
|
||||||
|
|
||||||
|
private final Class<? extends CodeGenerator> clazz;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.ruoyi.common.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.concurrent.RejectedExecutionHandler;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线程池 拒绝策略 泛型
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum ThreadPoolRejectedPolicy {
|
||||||
|
|
||||||
|
CALLER_RUNS_POLICY("等待", ThreadPoolExecutor.CallerRunsPolicy.class),
|
||||||
|
DISCARD_OLDEST_POLICY("放弃最旧的", ThreadPoolExecutor.DiscardOldestPolicy.class),
|
||||||
|
DISCARD_POLICY("丢弃", ThreadPoolExecutor.DiscardPolicy.class),
|
||||||
|
ABORT_POLICY("中止", ThreadPoolExecutor.AbortPolicy.class);
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final Class<? extends RejectedExecutionHandler> clazz;
|
||||||
|
|
||||||
|
}
|
@ -65,8 +65,8 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
|
|||||||
|
|
||||||
// xss过滤
|
// xss过滤
|
||||||
json = HtmlUtil.cleanHtmlTag(json).trim();
|
json = HtmlUtil.cleanHtmlTag(json).trim();
|
||||||
|
byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8);
|
||||||
final ByteArrayInputStream bis = IoUtil.toStream(json, StandardCharsets.UTF_8);
|
final ByteArrayInputStream bis = IoUtil.toStream(jsonBytes);
|
||||||
return new ServletInputStream()
|
return new ServletInputStream()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
@ -81,6 +81,12 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() throws IOException
|
||||||
|
{
|
||||||
|
return jsonBytes.length;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setReadListener(ReadListener readListener)
|
public void setReadListener(ReadListener readListener)
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,8 @@ package com.ruoyi.common.utils;
|
|||||||
|
|
||||||
import cn.hutool.core.bean.copier.BeanCopier;
|
import cn.hutool.core.bean.copier.BeanCopier;
|
||||||
import cn.hutool.core.bean.copier.CopyOptions;
|
import cn.hutool.core.bean.copier.CopyOptions;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -36,6 +38,9 @@ public class BeanCopyUtils {
|
|||||||
* @return desc
|
* @return desc
|
||||||
*/
|
*/
|
||||||
public static <T, V> V oneCopy(T source, CopyOptions copyOptions, V desc) {
|
public static <T, V> V oneCopy(T source, CopyOptions copyOptions, V desc) {
|
||||||
|
if (ObjectUtil.isNull(source)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return BeanCopier.create(source, desc, copyOptions).copy();
|
return BeanCopier.create(source, desc, copyOptions).copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +53,12 @@ public class BeanCopyUtils {
|
|||||||
* @return desc
|
* @return desc
|
||||||
*/
|
*/
|
||||||
public static <T, V> List<V> listCopy(List<T> sourceList, CopyOptions copyOptions, Class<V> desc) {
|
public static <T, V> List<V> listCopy(List<T> sourceList, CopyOptions copyOptions, Class<V> desc) {
|
||||||
|
if (ObjectUtil.isNull(sourceList)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (CollUtil.isEmpty(sourceList)) {
|
||||||
|
return CollUtil.newArrayList();
|
||||||
|
}
|
||||||
return sourceList.stream()
|
return sourceList.stream()
|
||||||
.map(source -> oneCopy(source, copyOptions, desc))
|
.map(source -> oneCopy(source, copyOptions, desc))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
@ -3,8 +3,6 @@ package com.ruoyi.common.utils;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import com.ruoyi.common.constant.Constants;
|
import com.ruoyi.common.constant.Constants;
|
||||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||||
import com.ruoyi.common.core.redis.RedisCache;
|
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -29,7 +27,7 @@ public class DictUtils
|
|||||||
*/
|
*/
|
||||||
public static void setDictCache(String key, List<SysDictData> dictDatas)
|
public static void setDictCache(String key, List<SysDictData> dictDatas)
|
||||||
{
|
{
|
||||||
SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas);
|
RedisUtils.setCacheObject(getCacheKey(key), dictDatas);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +38,7 @@ public class DictUtils
|
|||||||
*/
|
*/
|
||||||
public static List<SysDictData> getDictCache(String key)
|
public static List<SysDictData> getDictCache(String key)
|
||||||
{
|
{
|
||||||
Object cacheObj = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
|
Object cacheObj = RedisUtils.getCacheObject(getCacheKey(key));
|
||||||
if (StringUtils.isNotNull(cacheObj))
|
if (StringUtils.isNotNull(cacheObj))
|
||||||
{
|
{
|
||||||
List<SysDictData> dictDatas = (List<SysDictData>)cacheObj;
|
List<SysDictData> dictDatas = (List<SysDictData>)cacheObj;
|
||||||
@ -160,7 +158,7 @@ public class DictUtils
|
|||||||
*/
|
*/
|
||||||
public static void removeDictCache(String key)
|
public static void removeDictCache(String key)
|
||||||
{
|
{
|
||||||
SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key));
|
RedisUtils.deleteObject(getCacheKey(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,8 +166,8 @@ public class DictUtils
|
|||||||
*/
|
*/
|
||||||
public static void clearDictCache()
|
public static void clearDictCache()
|
||||||
{
|
{
|
||||||
Collection<String> keys = SpringUtils.getBean(RedisCache.class).keys(Constants.SYS_DICT_KEY + "*");
|
Collection<String> keys = RedisUtils.keys(Constants.SYS_DICT_KEY + "*");
|
||||||
SpringUtils.getBean(RedisCache.class).deleteObject(keys);
|
RedisUtils.deleteObject(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,6 +4,9 @@ import cn.hutool.core.util.ArrayUtil;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -15,20 +18,10 @@ import java.util.Map;
|
|||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public class JsonUtils {
|
public class JsonUtils {
|
||||||
|
|
||||||
private static ObjectMapper objectMapper = new ObjectMapper();
|
private static ObjectMapper objectMapper = SpringUtils.getBean(ObjectMapper.class);
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化 objectMapper 属性
|
|
||||||
* <p>
|
|
||||||
* 通过这样的方式,使用 Spring 创建的 ObjectMapper Bean
|
|
||||||
*
|
|
||||||
* @param objectMapper ObjectMapper 对象
|
|
||||||
*/
|
|
||||||
public static void init(ObjectMapper objectMapper) {
|
|
||||||
JsonUtils.objectMapper = objectMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toJsonString(Object object) {
|
public static String toJsonString(Object object) {
|
||||||
if (StringUtils.isNull(object)) {
|
if (StringUtils.isNull(object)) {
|
||||||
|
@ -57,15 +57,12 @@ public class PageUtils {
|
|||||||
Integer pageSize = ServletUtils.getParameterToInt(PAGE_SIZE, DEFAULT_PAGE_SIZE);
|
Integer pageSize = ServletUtils.getParameterToInt(PAGE_SIZE, DEFAULT_PAGE_SIZE);
|
||||||
String orderByColumn = ServletUtils.getParameter(ORDER_BY_COLUMN);
|
String orderByColumn = ServletUtils.getParameter(ORDER_BY_COLUMN);
|
||||||
String isAsc = ServletUtils.getParameter(IS_ASC);
|
String isAsc = ServletUtils.getParameter(IS_ASC);
|
||||||
|
if (pageNum <= 0) {
|
||||||
|
pageNum = DEFAULT_PAGE_NUM;
|
||||||
|
}
|
||||||
PagePlus<T, K> page = new PagePlus<>(pageNum, pageSize);
|
PagePlus<T, K> page = new PagePlus<>(pageNum, pageSize);
|
||||||
if (StringUtils.isNotBlank(orderByColumn)) {
|
OrderItem orderItem = buildOrderItem(orderByColumn, isAsc);
|
||||||
String orderBy = SqlUtil.escapeOrderBySql(orderByColumn);
|
page.addOrder(orderItem);
|
||||||
if ("asc".equals(isAsc)) {
|
|
||||||
page.addOrder(OrderItem.asc(orderBy));
|
|
||||||
} else if ("desc".equals(isAsc)) {
|
|
||||||
page.addOrder(OrderItem.desc(orderBy));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,23 +80,32 @@ public class PageUtils {
|
|||||||
Integer pageSize = ServletUtils.getParameterToInt(PAGE_SIZE, DEFAULT_PAGE_SIZE);
|
Integer pageSize = ServletUtils.getParameterToInt(PAGE_SIZE, DEFAULT_PAGE_SIZE);
|
||||||
String orderByColumn = ServletUtils.getParameter(ORDER_BY_COLUMN, defaultOrderByColumn);
|
String orderByColumn = ServletUtils.getParameter(ORDER_BY_COLUMN, defaultOrderByColumn);
|
||||||
String isAsc = ServletUtils.getParameter(IS_ASC, defaultIsAsc);
|
String isAsc = ServletUtils.getParameter(IS_ASC, defaultIsAsc);
|
||||||
|
if (pageNum <= 0) {
|
||||||
|
pageNum = DEFAULT_PAGE_NUM;
|
||||||
|
}
|
||||||
|
Page<T> page = new Page<>(pageNum, pageSize);
|
||||||
|
OrderItem orderItem = buildOrderItem(orderByColumn, isAsc);
|
||||||
|
page.addOrder(orderItem);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static OrderItem buildOrderItem(String orderByColumn, String isAsc) {
|
||||||
// 兼容前端排序类型
|
// 兼容前端排序类型
|
||||||
if ("ascending".equals(isAsc)) {
|
if ("ascending".equals(isAsc)) {
|
||||||
isAsc = "asc";
|
isAsc = "asc";
|
||||||
} else if ("descending".equals(isAsc)) {
|
} else if ("descending".equals(isAsc)) {
|
||||||
isAsc = "desc";
|
isAsc = "desc";
|
||||||
}
|
}
|
||||||
Page<T> page = new Page<>(pageNum, pageSize);
|
|
||||||
if (StringUtils.isNotBlank(orderByColumn)) {
|
if (StringUtils.isNotBlank(orderByColumn)) {
|
||||||
String orderBy = SqlUtil.escapeOrderBySql(orderByColumn);
|
String orderBy = SqlUtil.escapeOrderBySql(orderByColumn);
|
||||||
orderBy = StringUtils.toUnderScoreCase(orderBy);
|
orderBy = StringUtils.toUnderScoreCase(orderBy);
|
||||||
if ("asc".equals(isAsc)) {
|
if ("asc".equals(isAsc)) {
|
||||||
page.addOrder(OrderItem.asc(orderBy));
|
return OrderItem.asc(orderBy);
|
||||||
} else if ("desc".equals(isAsc)) {
|
} else if ("desc".equals(isAsc)) {
|
||||||
page.addOrder(OrderItem.desc(orderBy));
|
return OrderItem.desc(orderBy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return page;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, K> TableDataInfo<K> buildDataInfo(PagePlus<T, K> page) {
|
public static <T, K> TableDataInfo<K> buildDataInfo(PagePlus<T, K> page) {
|
||||||
@ -129,4 +135,11 @@ public class PageUtils {
|
|||||||
return rspData;
|
return rspData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> TableDataInfo<T> buildDataInfo() {
|
||||||
|
TableDataInfo<T> rspData = new TableDataInfo<>();
|
||||||
|
rspData.setCode(HttpStatus.HTTP_OK);
|
||||||
|
rspData.setMsg("查询成功");
|
||||||
|
return rspData;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
258
ruoyi/src/main/java/com/ruoyi/common/utils/RedisUtils.java
Normal file
258
ruoyi/src/main/java/com/ruoyi/common/utils/RedisUtils.java
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
package com.ruoyi.common.utils;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.redisson.api.*;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* redis 工具类
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
* @version 3.1.0 新增
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
||||||
|
public class RedisUtils {
|
||||||
|
|
||||||
|
private static RedissonClient client = SpringUtils.getBean(RedissonClient.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布通道消息
|
||||||
|
*
|
||||||
|
* @param channelKey 通道key
|
||||||
|
* @param msg 发送数据
|
||||||
|
* @param consumer 自定义处理
|
||||||
|
*/
|
||||||
|
public static <T> void publish(String channelKey, T msg, Consumer<T> consumer) {
|
||||||
|
RTopic topic = client.getTopic(channelKey);
|
||||||
|
topic.publish(msg);
|
||||||
|
consumer.accept(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void publish(String channelKey, T msg) {
|
||||||
|
RTopic topic = client.getTopic(channelKey);
|
||||||
|
topic.publish(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订阅通道接收消息
|
||||||
|
*
|
||||||
|
* @param channelKey 通道key
|
||||||
|
* @param clazz 消息类型
|
||||||
|
* @param consumer 自定义处理
|
||||||
|
*/
|
||||||
|
public static <T> void subscribe(String channelKey, Class<T> clazz, Consumer<T> consumer) {
|
||||||
|
RTopic topic = client.getTopic(channelKey);
|
||||||
|
topic.addListener(clazz, (channel, msg) -> consumer.accept(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存基本的对象,Integer、String、实体类等
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param value 缓存的值
|
||||||
|
*/
|
||||||
|
public static <T> void setCacheObject(final String key, final T value) {
|
||||||
|
client.getBucket(key).set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存基本的对象,Integer、String、实体类等
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param value 缓存的值
|
||||||
|
* @param timeout 时间
|
||||||
|
* @param timeUnit 时间颗粒度
|
||||||
|
*/
|
||||||
|
public static <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
|
||||||
|
RBucket<T> result = client.getBucket(key);
|
||||||
|
result.set(value);
|
||||||
|
result.expire(timeout, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置有效时间
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param timeout 超时时间
|
||||||
|
* @return true=设置成功;false=设置失败
|
||||||
|
*/
|
||||||
|
public static 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 static boolean expire(final String key, final long timeout, final TimeUnit unit) {
|
||||||
|
RBucket rBucket = client.getBucket(key);
|
||||||
|
return rBucket.expire(timeout, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的基本对象。
|
||||||
|
*
|
||||||
|
* @param key 缓存键值
|
||||||
|
* @return 缓存键值对应的数据
|
||||||
|
*/
|
||||||
|
public static <T> T getCacheObject(final String key) {
|
||||||
|
RBucket<T> rBucket = client.getBucket(key);
|
||||||
|
return rBucket.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除单个对象
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
public static boolean deleteObject(final String key) {
|
||||||
|
return client.getBucket(key).delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除集合对象
|
||||||
|
*
|
||||||
|
* @param collection 多个对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static void deleteObject(final Collection collection) {
|
||||||
|
RBatch batch = client.createBatch();
|
||||||
|
collection.forEach(t -> {
|
||||||
|
batch.getBucket(t.toString()).deleteAsync();
|
||||||
|
});
|
||||||
|
batch.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存List数据
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param dataList 待缓存的List数据
|
||||||
|
* @return 缓存的对象
|
||||||
|
*/
|
||||||
|
public static <T> boolean setCacheList(final String key, final List<T> dataList) {
|
||||||
|
RList<T> rList = client.getList(key);
|
||||||
|
return rList.addAll(dataList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的list对象
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @return 缓存键值对应的数据
|
||||||
|
*/
|
||||||
|
public static <T> List<T> getCacheList(final String key) {
|
||||||
|
RList<T> rList = client.getList(key);
|
||||||
|
return rList.readAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存Set
|
||||||
|
*
|
||||||
|
* @param key 缓存键值
|
||||||
|
* @param dataSet 缓存的数据
|
||||||
|
* @return 缓存数据的对象
|
||||||
|
*/
|
||||||
|
public static <T> boolean setCacheSet(final String key, final Set<T> dataSet) {
|
||||||
|
RSet<T> rSet = client.getSet(key);
|
||||||
|
return rSet.addAll(dataSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的set
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> Set<T> getCacheSet(final String key) {
|
||||||
|
RSet<T> rSet = client.getSet(key);
|
||||||
|
return rSet.readAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存Map
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param dataMap
|
||||||
|
*/
|
||||||
|
public static <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
|
||||||
|
if (dataMap != null) {
|
||||||
|
RMap<String, T> rMap = client.getMap(key);
|
||||||
|
rMap.putAll(dataMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的Map
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> Map<String, T> getCacheMap(final String key) {
|
||||||
|
RMap<String, T> rMap = client.getMap(key);
|
||||||
|
return rMap.getAll(rMap.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 往Hash中存入数据
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param hKey Hash键
|
||||||
|
* @param value 值
|
||||||
|
*/
|
||||||
|
public static <T> void setCacheMapValue(final String key, final String hKey, final T value) {
|
||||||
|
RMap<String, T> rMap = client.getMap(key);
|
||||||
|
rMap.put(hKey, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Hash中的数据
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param hKey Hash键
|
||||||
|
* @return Hash中的对象
|
||||||
|
*/
|
||||||
|
public static <T> T getCacheMapValue(final String key, final String hKey) {
|
||||||
|
RMap<String, T> rMap = client.getMap(key);
|
||||||
|
return rMap.get(hKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取多个Hash中的数据
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param hKeys Hash键集合
|
||||||
|
* @return Hash对象集合
|
||||||
|
*/
|
||||||
|
public static <K, V> Map<K, V> getMultiCacheMapValue(final String key, final Set<K> hKeys) {
|
||||||
|
RMap<K, V> rMap = client.getMap(key);
|
||||||
|
return rMap.getAll(hKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的基本对象列表
|
||||||
|
*
|
||||||
|
* @param pattern 字符串前缀
|
||||||
|
* @return 对象列表
|
||||||
|
*/
|
||||||
|
public static Collection<String> keys(final String pattern) {
|
||||||
|
Iterable<String> iterable = client.getKeys().getKeysByPattern(pattern);
|
||||||
|
return Lists.newArrayList(iterable);
|
||||||
|
}
|
||||||
|
}
|
@ -48,6 +48,20 @@ public class ServletUtils extends ServletUtil {
|
|||||||
return Convert.toInt(getRequest().getParameter(name), defaultValue);
|
return Convert.toInt(getRequest().getParameter(name), defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Boolean参数
|
||||||
|
*/
|
||||||
|
public static Boolean getParameterToBool(String name) {
|
||||||
|
return Convert.toBool(getRequest().getParameter(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Boolean参数
|
||||||
|
*/
|
||||||
|
public static Boolean getParameterToBool(String name, Boolean defaultValue) {
|
||||||
|
return Convert.toBool(getRequest().getParameter(name), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取request
|
* 获取request
|
||||||
*/
|
*/
|
||||||
|
@ -3,6 +3,7 @@ package com.ruoyi.common.utils.poi;
|
|||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import com.alibaba.excel.EasyExcel;
|
import com.alibaba.excel.EasyExcel;
|
||||||
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||||
|
import com.ruoyi.common.convert.ExcelBigNumberConvert;
|
||||||
import com.ruoyi.common.utils.DictUtils;
|
import com.ruoyi.common.utils.DictUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.file.FileUtils;
|
import com.ruoyi.common.utils.file.FileUtils;
|
||||||
@ -52,6 +53,8 @@ public class ExcelUtil {
|
|||||||
.autoCloseStream(false)
|
.autoCloseStream(false)
|
||||||
// 自动适配
|
// 自动适配
|
||||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||||
|
// 大数值自动转换 防止失真
|
||||||
|
.registerConverter(new ExcelBigNumberConvert())
|
||||||
.sheet(sheetName).doWrite(list);
|
.sheet(sheetName).doWrite(list);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("导出Excel异常");
|
throw new RuntimeException("导出Excel异常");
|
||||||
|
@ -2,6 +2,8 @@ package com.ruoyi.demo.controller;
|
|||||||
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.demo.feign.FeignTestService;
|
import com.ruoyi.demo.feign.FeignTestService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -14,6 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
|
@Api(value = "feign测试", tags = {"feign测试"})
|
||||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/feign/test")
|
@RequestMapping("/feign/test")
|
||||||
@ -21,6 +24,10 @@ public class FeignTestController {
|
|||||||
|
|
||||||
private final FeignTestService feignTestService;
|
private final FeignTestService feignTestService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索数据
|
||||||
|
*/
|
||||||
|
@ApiOperation("测试使用feign请求数据")
|
||||||
@GetMapping("/search/{wd}")
|
@GetMapping("/search/{wd}")
|
||||||
public AjaxResult search(@PathVariable String wd) {
|
public AjaxResult search(@PathVariable String wd) {
|
||||||
String search = feignTestService.search(wd);
|
String search = feignTestService.search(wd);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.ruoyi.demo.controller;
|
package com.ruoyi.demo.controller;
|
||||||
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
@ -17,6 +19,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
*/
|
*/
|
||||||
// 类级别 缓存统一配置
|
// 类级别 缓存统一配置
|
||||||
//@CacheConfig(cacheNames = "redissonCacheMap")
|
//@CacheConfig(cacheNames = "redissonCacheMap")
|
||||||
|
@Api(value = "spring-cache 演示案例", tags = {"spring-cache 演示案例"})
|
||||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/cache")
|
@RequestMapping("/demo/cache")
|
||||||
@ -33,6 +36,7 @@ public class RedisCacheController {
|
|||||||
*
|
*
|
||||||
* cacheNames 为配置文件内 groupId
|
* cacheNames 为配置文件内 groupId
|
||||||
*/
|
*/
|
||||||
|
@ApiOperation("测试 @Cacheable")
|
||||||
@Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
@Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
||||||
@GetMapping("/test1")
|
@GetMapping("/test1")
|
||||||
public AjaxResult<String> test1(String key, String value){
|
public AjaxResult<String> test1(String key, String value){
|
||||||
@ -47,6 +51,7 @@ public class RedisCacheController {
|
|||||||
*
|
*
|
||||||
* cacheNames 为 配置文件内 groupId
|
* cacheNames 为 配置文件内 groupId
|
||||||
*/
|
*/
|
||||||
|
@ApiOperation("测试 @CachePut")
|
||||||
@CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
@CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
||||||
@GetMapping("/test2")
|
@GetMapping("/test2")
|
||||||
public AjaxResult<String> test2(String key, String value){
|
public AjaxResult<String> test2(String key, String value){
|
||||||
@ -61,6 +66,7 @@ public class RedisCacheController {
|
|||||||
*
|
*
|
||||||
* cacheNames 为 配置文件内 groupId
|
* cacheNames 为 配置文件内 groupId
|
||||||
*/
|
*/
|
||||||
|
@ApiOperation("测试 @CacheEvict")
|
||||||
@CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
@CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
|
||||||
@GetMapping("/test3")
|
@GetMapping("/test3")
|
||||||
public AjaxResult<String> test3(String key, String value){
|
public AjaxResult<String> test3(String key, String value){
|
||||||
|
@ -5,6 +5,8 @@ import com.baomidou.lock.LockTemplate;
|
|||||||
import com.baomidou.lock.annotation.Lock4j;
|
import com.baomidou.lock.annotation.Lock4j;
|
||||||
import com.baomidou.lock.executor.RedissonLockExecutor;
|
import com.baomidou.lock.executor.RedissonLockExecutor;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
@ -20,6 +22,7 @@ import java.time.LocalTime;
|
|||||||
*
|
*
|
||||||
* @author shenxinquan
|
* @author shenxinquan
|
||||||
*/
|
*/
|
||||||
|
@Api(value = "测试分布式锁的样例", tags = {"测试分布式锁的样例"})
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/redisLock")
|
@RequestMapping("/demo/redisLock")
|
||||||
@ -31,6 +34,7 @@ public class RedisLockController {
|
|||||||
/**
|
/**
|
||||||
* 测试lock4j 注解
|
* 测试lock4j 注解
|
||||||
*/
|
*/
|
||||||
|
@ApiOperation("测试lock4j 注解")
|
||||||
@Lock4j(keys = {"#key"})
|
@Lock4j(keys = {"#key"})
|
||||||
@GetMapping("/testLock4j")
|
@GetMapping("/testLock4j")
|
||||||
public AjaxResult<String> testLock4j(String key,String value){
|
public AjaxResult<String> testLock4j(String key,String value){
|
||||||
@ -47,6 +51,7 @@ public class RedisLockController {
|
|||||||
/**
|
/**
|
||||||
* 测试lock4j 工具
|
* 测试lock4j 工具
|
||||||
*/
|
*/
|
||||||
|
@ApiOperation("测试lock4j 工具")
|
||||||
@GetMapping("/testLock4jLockTemaplate")
|
@GetMapping("/testLock4jLockTemaplate")
|
||||||
public AjaxResult<String> testLock4jLockTemaplate(String key,String value){
|
public AjaxResult<String> testLock4jLockTemaplate(String key,String value){
|
||||||
final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
|
final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
|
||||||
@ -72,6 +77,7 @@ public class RedisLockController {
|
|||||||
/**
|
/**
|
||||||
* 测试spring-cache注解
|
* 测试spring-cache注解
|
||||||
*/
|
*/
|
||||||
|
@ApiOperation("测试spring-cache注解")
|
||||||
@Cacheable(value = "test", key = "#key")
|
@Cacheable(value = "test", key = "#key")
|
||||||
@GetMapping("/testCache")
|
@GetMapping("/testCache")
|
||||||
public AjaxResult<String> testCache(String key) {
|
public AjaxResult<String> testCache(String key) {
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.ruoyi.demo.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.utils.RedisUtils;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis 发布订阅 演示案例
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
|
@Api(value = "Redis发布订阅 演示案例", tags = {"Redis发布订阅"})
|
||||||
|
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/demo/redis/pubsub")
|
||||||
|
public class RedisPubSubController {
|
||||||
|
|
||||||
|
@ApiOperation("发布消息")
|
||||||
|
@GetMapping("/pub")
|
||||||
|
public AjaxResult<Void> pub(String key, String value){
|
||||||
|
RedisUtils.publish(key, value, consumer -> {
|
||||||
|
System.out.println("发布通道 => " + key + ", 发送值 => " + value);
|
||||||
|
});
|
||||||
|
return AjaxResult.success("操作成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("订阅消息")
|
||||||
|
@GetMapping("/sub")
|
||||||
|
public AjaxResult<Void> sub(String key){
|
||||||
|
RedisUtils.subscribe(key, String.class, msg -> {
|
||||||
|
System.out.println("订阅通道 => " + key + ", 接收值 => " + msg);
|
||||||
|
});
|
||||||
|
return AjaxResult.success("操作成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -32,10 +32,10 @@ public class TestBatchController extends BaseController {
|
|||||||
private final ITestDemoService iTestDemoService;
|
private final ITestDemoService iTestDemoService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增批量方法 ( 全量覆盖填充 )
|
* 新增批量方法 可完美替代 saveBatch 秒级插入上万数据 (对mysql负荷较大)
|
||||||
*/
|
*/
|
||||||
@ApiOperation(value = "新增批量方法")
|
@ApiOperation(value = "新增批量方法")
|
||||||
@PostMapping()
|
@PostMapping("/add")
|
||||||
// @DataSource(DataSourceType.SLAVE)
|
// @DataSource(DataSourceType.SLAVE)
|
||||||
public AjaxResult<Void> add() {
|
public AjaxResult<Void> add() {
|
||||||
List<TestDemo> list = new ArrayList<>();
|
List<TestDemo> list = new ArrayList<>();
|
||||||
@ -45,6 +45,28 @@ public class TestBatchController extends BaseController {
|
|||||||
return toAjax(iTestDemoService.saveAll(list) ? 1 : 0);
|
return toAjax(iTestDemoService.saveAll(list) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增或更新 可完美替代 saveOrUpdateBatch 高性能
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "新增或更新批量方法")
|
||||||
|
@PostMapping("/addOrUpdate")
|
||||||
|
// @DataSource(DataSourceType.SLAVE)
|
||||||
|
public AjaxResult<Void> addOrUpdate() {
|
||||||
|
List<TestDemo> list = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
list.add(new TestDemo().setOrderNum(-1L).setTestKey("批量新增").setValue("测试新增"));
|
||||||
|
}
|
||||||
|
iTestDemoService.saveAll(list);
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
TestDemo testDemo = list.get(i);
|
||||||
|
testDemo.setTestKey("批量新增或修改").setValue("批量新增或修改");
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
testDemo.setId(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toAjax(iTestDemoService.saveOrUpdateAll(list) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除批量方法
|
* 删除批量方法
|
||||||
*/
|
*/
|
||||||
|
@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
|||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.core.validate.AddGroup;
|
import com.ruoyi.common.core.validate.AddGroup;
|
||||||
import com.ruoyi.common.core.validate.EditGroup;
|
import com.ruoyi.common.core.validate.EditGroup;
|
||||||
|
import com.ruoyi.common.core.validate.QueryGroup;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.demo.domain.bo.TestDemoBo;
|
import com.ruoyi.demo.domain.bo.TestDemoBo;
|
||||||
@ -48,7 +49,7 @@ public class TestDemoController extends BaseController {
|
|||||||
@ApiOperation("查询测试单表列表")
|
@ApiOperation("查询测试单表列表")
|
||||||
@PreAuthorize("@ss.hasPermi('demo:demo:list')")
|
@PreAuthorize("@ss.hasPermi('demo:demo:list')")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo<TestDemoVo> list(@Validated TestDemoBo bo) {
|
public TableDataInfo<TestDemoVo> list(@Validated(QueryGroup.class) TestDemoBo bo) {
|
||||||
return iTestDemoService.queryPageList(bo);
|
return iTestDemoService.queryPageList(bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +72,10 @@ public class TestDemoController extends BaseController {
|
|||||||
@GetMapping("/export")
|
@GetMapping("/export")
|
||||||
public void export(@Validated TestDemoBo bo, HttpServletResponse response) {
|
public void export(@Validated TestDemoBo bo, HttpServletResponse response) {
|
||||||
List<TestDemoVo> list = iTestDemoService.queryList(bo);
|
List<TestDemoVo> list = iTestDemoService.queryList(bo);
|
||||||
|
// 测试雪花id导出
|
||||||
|
// for (TestDemoVo vo : list) {
|
||||||
|
// vo.setId(1234567891234567893L);
|
||||||
|
// }
|
||||||
ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response);
|
ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ package com.ruoyi.demo.controller;
|
|||||||
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.utils.MessageUtils;
|
import com.ruoyi.common.utils.MessageUtils;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@ -12,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
|
@Api(value = "测试国际化控制器", tags = {"测试国际化管理"})
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/demo/i18n")
|
@RequestMapping("/demo/i18n")
|
||||||
public class TestI18nController {
|
public class TestI18nController {
|
||||||
@ -22,6 +25,7 @@ public class TestI18nController {
|
|||||||
*
|
*
|
||||||
* 测试使用 user.register.success
|
* 测试使用 user.register.success
|
||||||
*/
|
*/
|
||||||
|
@ApiOperation("通过code获取国际化内容")
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public AjaxResult<Void> get(String code) {
|
public AjaxResult<Void> get(String code) {
|
||||||
return AjaxResult.success(MessageUtils.message(code));
|
return AjaxResult.success(MessageUtils.message(code));
|
||||||
|
@ -6,6 +6,7 @@ import com.ruoyi.common.core.controller.BaseController;
|
|||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.validate.AddGroup;
|
import com.ruoyi.common.core.validate.AddGroup;
|
||||||
import com.ruoyi.common.core.validate.EditGroup;
|
import com.ruoyi.common.core.validate.EditGroup;
|
||||||
|
import com.ruoyi.common.core.validate.QueryGroup;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.demo.domain.bo.TestTreeBo;
|
import com.ruoyi.demo.domain.bo.TestTreeBo;
|
||||||
@ -46,7 +47,7 @@ public class TestTreeController extends BaseController {
|
|||||||
@ApiOperation("查询测试树表列表")
|
@ApiOperation("查询测试树表列表")
|
||||||
@PreAuthorize("@ss.hasPermi('demo:tree:list')")
|
@PreAuthorize("@ss.hasPermi('demo:tree:list')")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public AjaxResult<List<TestTreeVo>> list(@Validated TestTreeBo bo) {
|
public AjaxResult<List<TestTreeVo>> list(@Validated(QueryGroup.class) TestTreeBo bo) {
|
||||||
List<TestTreeVo> list = iTestTreeService.queryList(bo);
|
List<TestTreeVo> list = iTestTreeService.queryList(bo);
|
||||||
return AjaxResult.success(list);
|
return AjaxResult.success(list);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package com.ruoyi.demo.domain;
|
package com.ruoyi.demo.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.*;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
@ -29,7 +27,6 @@ public class TestDemo implements Serializable {
|
|||||||
* 主键
|
* 主键
|
||||||
*/
|
*/
|
||||||
@TableId(value = "id")
|
@TableId(value = "id")
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,6 +26,7 @@ public class TestDemoVo {
|
|||||||
/**
|
/**
|
||||||
* 主键
|
* 主键
|
||||||
*/
|
*/
|
||||||
|
@ExcelProperty(value = "主键")
|
||||||
@ApiModelProperty("主键")
|
@ApiModelProperty("主键")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@ -10,7 +10,9 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
* feign测试service
|
* feign测试service
|
||||||
* 规范接口 Service 无感调用
|
* 规范接口 Service 无感调用
|
||||||
* 常量管理请求路径 更加规范
|
* 常量管理请求路径 更加规范
|
||||||
* 自定义容错处理 安全可靠
|
* 自定义容错处理 安全可靠 (需自行配置熔断器)
|
||||||
|
* 增加 feign 的目的为使 http 请求接口化
|
||||||
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@FeignClient(
|
@FeignClient(
|
||||||
|
@ -10,6 +10,8 @@ import org.springframework.stereotype.Component;
|
|||||||
* 自定义封装结构体熔断
|
* 自定义封装结构体熔断
|
||||||
* 需重写解码器 根据自定义实体 自行解析熔断
|
* 需重写解码器 根据自定义实体 自行解析熔断
|
||||||
*
|
*
|
||||||
|
* 熔断器需要自行添加配置
|
||||||
|
*
|
||||||
* @see {com.ruoyi.framework.config.FeignConfig#errorDecoder()}
|
* @see {com.ruoyi.framework.config.FeignConfig#errorDecoder()}
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
|
@ -5,11 +5,9 @@ import com.ruoyi.common.core.domain.BaseEntity;
|
|||||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
import com.ruoyi.common.utils.ServletUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.reflect.ReflectUtils;
|
import com.ruoyi.common.utils.reflect.ReflectUtils;
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
|
||||||
import com.ruoyi.framework.web.service.TokenService;
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.JoinPoint;
|
||||||
import org.aspectj.lang.Signature;
|
import org.aspectj.lang.Signature;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
@ -78,7 +76,7 @@ public class DataScopeAspect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 获取当前的用户
|
// 获取当前的用户
|
||||||
LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||||
if (StringUtils.isNotNull(loginUser)) {
|
if (StringUtils.isNotNull(loginUser)) {
|
||||||
SysUser currentUser = loginUser.getUser();
|
SysUser currentUser = loginUser.getUser();
|
||||||
// 如果是超级管理员,则不过滤数据
|
// 如果是超级管理员,则不过滤数据
|
||||||
|
@ -5,11 +5,11 @@ import com.ruoyi.common.core.domain.model.LoginUser;
|
|||||||
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;
|
||||||
|
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 com.ruoyi.framework.web.service.AsyncService;
|
||||||
import com.ruoyi.framework.web.service.TokenService;
|
|
||||||
import com.ruoyi.system.domain.SysOperLog;
|
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.Signature;
|
||||||
@ -83,7 +83,7 @@ public class LogAspect
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前的用户
|
// 获取当前的用户
|
||||||
LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||||
|
|
||||||
// *========数据库日志=========*//
|
// *========数据库日志=========*//
|
||||||
SysOperLog operLog = new SysOperLog();
|
SysOperLog operLog = new SysOperLog();
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
package com.ruoyi.framework.config;
|
package com.ruoyi.framework.config;
|
||||||
|
|
||||||
import java.awt.*;
|
import cn.hutool.captcha.CaptchaUtil;
|
||||||
|
import cn.hutool.captcha.CircleCaptcha;
|
||||||
import cn.hutool.captcha.*;
|
import cn.hutool.captcha.LineCaptcha;
|
||||||
|
import cn.hutool.captcha.ShearCaptcha;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码配置
|
* 验证码配置
|
||||||
@ -22,8 +26,9 @@ public class CaptchaConfig {
|
|||||||
/**
|
/**
|
||||||
* 圆圈干扰验证码
|
* 圆圈干扰验证码
|
||||||
*/
|
*/
|
||||||
@Bean(name = "CircleCaptcha")
|
@Lazy
|
||||||
public CircleCaptcha getCircleCaptcha() {
|
@Bean
|
||||||
|
public CircleCaptcha circleCaptcha() {
|
||||||
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(width, height);
|
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(width, height);
|
||||||
captcha.setBackground(background);
|
captcha.setBackground(background);
|
||||||
captcha.setFont(font);
|
captcha.setFont(font);
|
||||||
@ -33,8 +38,9 @@ public class CaptchaConfig {
|
|||||||
/**
|
/**
|
||||||
* 线段干扰的验证码
|
* 线段干扰的验证码
|
||||||
*/
|
*/
|
||||||
@Bean(name = "LineCaptcha")
|
@Lazy
|
||||||
public LineCaptcha getLineCaptcha() {
|
@Bean
|
||||||
|
public LineCaptcha lineCaptcha() {
|
||||||
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height);
|
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height);
|
||||||
captcha.setBackground(background);
|
captcha.setBackground(background);
|
||||||
captcha.setFont(font);
|
captcha.setFont(font);
|
||||||
@ -44,8 +50,9 @@ public class CaptchaConfig {
|
|||||||
/**
|
/**
|
||||||
* 扭曲干扰验证码
|
* 扭曲干扰验证码
|
||||||
*/
|
*/
|
||||||
@Bean(name = "ShearCaptcha")
|
@Lazy
|
||||||
public ShearCaptcha getShearCaptcha() {
|
@Bean
|
||||||
|
public ShearCaptcha shearCaptcha() {
|
||||||
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(width, height);
|
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(width, height);
|
||||||
captcha.setBackground(background);
|
captcha.setBackground(background);
|
||||||
captcha.setFont(font);
|
captcha.setFont(font);
|
||||||
|
@ -5,17 +5,18 @@ import com.fasterxml.jackson.databind.module.SimpleModule;
|
|||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||||
import com.ruoyi.common.utils.JsonUtils;
|
|
||||||
import com.ruoyi.framework.jackson.BigNumberSerializer;
|
import com.ruoyi.framework.jackson.BigNumberSerializer;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,30 +28,23 @@ import java.util.TimeZone;
|
|||||||
@Configuration
|
@Configuration
|
||||||
public class JacksonConfig {
|
public class JacksonConfig {
|
||||||
|
|
||||||
|
@Primary
|
||||||
@Bean
|
@Bean
|
||||||
public BeanPostProcessor objectMapperBeanPostProcessor() {
|
public ObjectMapper getObjectMapper(Jackson2ObjectMapperBuilder builder, JacksonProperties jacksonProperties) {
|
||||||
return new BeanPostProcessor() {
|
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
|
||||||
@Override
|
|
||||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
|
||||||
if (!(bean instanceof ObjectMapper)) {
|
|
||||||
return bean;
|
|
||||||
}
|
|
||||||
ObjectMapper objectMapper = (ObjectMapper) bean;
|
|
||||||
// 全局配置序列化返回 JSON 处理
|
// 全局配置序列化返回 JSON 处理
|
||||||
SimpleModule simpleModule = new SimpleModule();
|
SimpleModule simpleModule = new SimpleModule();
|
||||||
simpleModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
|
simpleModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
|
||||||
simpleModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
|
simpleModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
|
||||||
simpleModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
|
simpleModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
|
||||||
simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
|
simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
|
||||||
simpleModule.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE);
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(jacksonProperties.getDateFormat());
|
||||||
simpleModule.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
|
simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
|
||||||
|
simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
|
||||||
objectMapper.registerModule(simpleModule);
|
objectMapper.registerModule(simpleModule);
|
||||||
objectMapper.setTimeZone(TimeZone.getDefault());
|
objectMapper.setTimeZone(TimeZone.getDefault());
|
||||||
JsonUtils.init(objectMapper);
|
|
||||||
log.info("初始化 jackson 配置");
|
log.info("初始化 jackson 配置");
|
||||||
return bean;
|
return objectMapper;
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.ruoyi.framework.config;
|
package com.ruoyi.framework.config;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.DbType;
|
|
||||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||||
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
|
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||||
@ -46,10 +46,10 @@ public class MybatisPlusConfig {
|
|||||||
*/
|
*/
|
||||||
public PaginationInnerInterceptor paginationInnerInterceptor() {
|
public PaginationInnerInterceptor paginationInnerInterceptor() {
|
||||||
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
|
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
|
||||||
// 设置数据库类型为mysql
|
|
||||||
paginationInnerInterceptor.setDbType(DbType.MYSQL);
|
|
||||||
// 设置最大单页限制数量,默认 500 条,-1 不受限制
|
// 设置最大单页限制数量,默认 500 条,-1 不受限制
|
||||||
paginationInnerInterceptor.setMaxLimit(-1L);
|
paginationInnerInterceptor.setMaxLimit(-1L);
|
||||||
|
// 分页合理化
|
||||||
|
paginationInnerInterceptor.setOverflow(true);
|
||||||
return paginationInnerInterceptor;
|
return paginationInnerInterceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,8 +104,8 @@ public class MybatisPlusConfig {
|
|||||||
public ISqlInjector sqlInjector() {
|
public ISqlInjector sqlInjector() {
|
||||||
return new DefaultSqlInjector() {
|
return new DefaultSqlInjector() {
|
||||||
@Override
|
@Override
|
||||||
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
|
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
|
||||||
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
|
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
|
||||||
methodList.add(new InsertAll());
|
methodList.add(new InsertAll());
|
||||||
return methodList;
|
return methodList;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package com.ruoyi.framework.config;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.framework.config.properties.RedissonProperties;
|
import com.ruoyi.framework.config.properties.RedissonProperties;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.redisson.Redisson;
|
import org.redisson.Redisson;
|
||||||
import org.redisson.api.RedissonClient;
|
import org.redisson.api.RedissonClient;
|
||||||
import org.redisson.codec.JsonJacksonCodec;
|
import org.redisson.codec.JsonJacksonCodec;
|
||||||
@ -29,6 +30,7 @@ import java.util.Map;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
public class RedisConfig extends CachingConfigurerSupport {
|
public class RedisConfig extends CachingConfigurerSupport {
|
||||||
@ -73,7 +75,9 @@ public class RedisConfig extends CachingConfigurerSupport {
|
|||||||
.setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
|
.setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
|
||||||
.setConnectionPoolSize(singleServerConfig.getConnectionPoolSize())
|
.setConnectionPoolSize(singleServerConfig.getConnectionPoolSize())
|
||||||
.setDnsMonitoringInterval(singleServerConfig.getDnsMonitoringInterval());
|
.setDnsMonitoringInterval(singleServerConfig.getDnsMonitoringInterval());
|
||||||
return Redisson.create(config);
|
RedissonClient redissonClient = Redisson.create(config);
|
||||||
|
log.info("初始化 redis 配置");
|
||||||
|
return redissonClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.ruoyi.framework.config;
|
package com.ruoyi.framework.config;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.Threads;
|
import com.ruoyi.common.utils.Threads;
|
||||||
|
import com.ruoyi.common.utils.reflect.ReflectUtils;
|
||||||
import com.ruoyi.framework.config.properties.ThreadPoolProperties;
|
import com.ruoyi.framework.config.properties.ThreadPoolProperties;
|
||||||
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -12,7 +13,6 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|||||||
import java.util.concurrent.RejectedExecutionHandler;
|
import java.util.concurrent.RejectedExecutionHandler;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 线程池配置
|
* 线程池配置
|
||||||
@ -33,21 +33,7 @@ public class ThreadPoolConfig {
|
|||||||
executor.setCorePoolSize(threadPoolProperties.getCorePoolSize());
|
executor.setCorePoolSize(threadPoolProperties.getCorePoolSize());
|
||||||
executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
|
executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
|
||||||
executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
|
executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
|
||||||
RejectedExecutionHandler handler;
|
RejectedExecutionHandler handler = ReflectUtils.newInstance(threadPoolProperties.getRejectedExecutionHandler().getClazz());
|
||||||
switch (threadPoolProperties.getRejectedExecutionHandler()) {
|
|
||||||
case "CallerRunsPolicy":
|
|
||||||
handler = new ThreadPoolExecutor.CallerRunsPolicy();
|
|
||||||
break;
|
|
||||||
case "DiscardOldestPolicy":
|
|
||||||
handler = new ThreadPoolExecutor.DiscardOldestPolicy();
|
|
||||||
break;
|
|
||||||
case "DiscardPolicy":
|
|
||||||
handler = new ThreadPoolExecutor.DiscardPolicy();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
handler = new ThreadPoolExecutor.AbortPolicy();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
executor.setRejectedExecutionHandler(handler);
|
executor.setRejectedExecutionHandler(handler);
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.ruoyi.framework.config.properties;
|
package com.ruoyi.framework.config.properties;
|
||||||
|
|
||||||
|
import com.ruoyi.common.enums.CaptchaCategory;
|
||||||
|
import com.ruoyi.common.enums.CaptchaType;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -17,12 +19,12 @@ public class CaptchaProperties {
|
|||||||
/**
|
/**
|
||||||
* 验证码类型
|
* 验证码类型
|
||||||
*/
|
*/
|
||||||
private String type;
|
private CaptchaType type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码类别
|
* 验证码类别
|
||||||
*/
|
*/
|
||||||
private String category;
|
private CaptchaCategory category;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数字验证码位数
|
* 数字验证码位数
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user