🎃 发布 4.8.1 稳定性增强 修复部分bug
This commit is contained in:
parent
8a692ed45a
commit
a6f62ca86f
@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||||
<deployment type="dockerfile">
|
<deployment type="dockerfile">
|
||||||
<settings>
|
<settings>
|
||||||
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:4.8.0" />
|
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:4.8.1" />
|
||||||
<option name="buildOnly" value="true" />
|
<option name="buildOnly" value="true" />
|
||||||
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" />
|
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" />
|
||||||
</settings>
|
</settings>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||||
<deployment type="dockerfile">
|
<deployment type="dockerfile">
|
||||||
<settings>
|
<settings>
|
||||||
<option name="imageTag" value="ruoyi/ruoyi-server:4.8.0" />
|
<option name="imageTag" value="ruoyi/ruoyi-server:4.8.1" />
|
||||||
<option name="buildOnly" value="true" />
|
<option name="buildOnly" value="true" />
|
||||||
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" />
|
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" />
|
||||||
</settings>
|
</settings>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="ruoyi-xxl-job-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
<configuration default="false" name="ruoyi-xxl-job-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||||
<deployment type="dockerfile">
|
<deployment type="dockerfile">
|
||||||
<settings>
|
<settings>
|
||||||
<option name="imageTag" value="ruoyi/ruoyi-xxl-job-admin:4.8.0" />
|
<option name="imageTag" value="ruoyi/ruoyi-xxl-job-admin:4.8.1" />
|
||||||
<option name="buildOnly" value="true" />
|
<option name="buildOnly" value="true" />
|
||||||
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile" />
|
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile" />
|
||||||
</settings>
|
</settings>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
[](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE)
|
[](https://gitee.com/dromara/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/dromara/RuoYi-Vue-Plus)
|
[](https://gitee.com/dromara/RuoYi-Vue-Plus)
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
|
18
pom.xml
18
pom.xml
@ -6,15 +6,15 @@
|
|||||||
|
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<version>4.8.0</version>
|
<version>4.8.1</version>
|
||||||
|
|
||||||
<name>RuoYi-Vue-Plus</name>
|
<name>RuoYi-Vue-Plus</name>
|
||||||
<url>https://gitee.com/dromara/RuoYi-Vue-Plus</url>
|
<url>https://gitee.com/dromara/RuoYi-Vue-Plus</url>
|
||||||
<description>RuoYi-Vue-Plus后台管理系统</description>
|
<description>RuoYi-Vue-Plus后台管理系统</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<ruoyi-vue-plus.version>4.8.0</ruoyi-vue-plus.version>
|
<ruoyi-vue-plus.version>4.8.1</ruoyi-vue-plus.version>
|
||||||
<spring-boot.version>2.7.13</spring-boot.version>
|
<spring-boot.version>2.7.16</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>
|
||||||
@ -22,20 +22,20 @@
|
|||||||
<spring-boot.mybatis>2.2.2</spring-boot.mybatis>
|
<spring-boot.mybatis>2.2.2</spring-boot.mybatis>
|
||||||
<springdoc.version>1.6.15</springdoc.version>
|
<springdoc.version>1.6.15</springdoc.version>
|
||||||
<poi.version>5.2.3</poi.version>
|
<poi.version>5.2.3</poi.version>
|
||||||
<easyexcel.version>3.3.1</easyexcel.version>
|
<easyexcel.version>3.3.2</easyexcel.version>
|
||||||
<velocity.version>2.3</velocity.version>
|
<velocity.version>2.3</velocity.version>
|
||||||
<satoken.version>1.35.0.RC</satoken.version>
|
<satoken.version>1.36.0</satoken.version>
|
||||||
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
|
<mybatis-plus.version>3.5.3.2</mybatis-plus.version>
|
||||||
<p6spy.version>3.9.1</p6spy.version>
|
<p6spy.version>3.9.1</p6spy.version>
|
||||||
<hutool.version>5.8.18</hutool.version>
|
<hutool.version>5.8.20</hutool.version>
|
||||||
<okhttp.version>4.10.0</okhttp.version>
|
<okhttp.version>4.10.0</okhttp.version>
|
||||||
<spring-boot-admin.version>2.7.10</spring-boot-admin.version>
|
<spring-boot-admin.version>2.7.11</spring-boot-admin.version>
|
||||||
<redisson.version>3.20.1</redisson.version>
|
<redisson.version>3.20.1</redisson.version>
|
||||||
<lock4j.version>2.2.3</lock4j.version>
|
<lock4j.version>2.2.3</lock4j.version>
|
||||||
<dynamic-ds.version>3.5.2</dynamic-ds.version>
|
<dynamic-ds.version>3.5.2</dynamic-ds.version>
|
||||||
<alibaba-ttl.version>2.14.2</alibaba-ttl.version>
|
<alibaba-ttl.version>2.14.2</alibaba-ttl.version>
|
||||||
<xxl-job.version>2.4.0</xxl-job.version>
|
<xxl-job.version>2.4.0</xxl-job.version>
|
||||||
<lombok.version>1.18.26</lombok.version>
|
<lombok.version>1.18.30</lombok.version>
|
||||||
<bouncycastle.version>1.72</bouncycastle.version>
|
<bouncycastle.version>1.72</bouncycastle.version>
|
||||||
<!-- 离线IP地址定位库 -->
|
<!-- 离线IP地址定位库 -->
|
||||||
<ip2region.version>2.7.0</ip2region.version>
|
<ip2region.version>2.7.0</ip2region.version>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>4.8.0</version>
|
<version>4.8.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>ruoyi-extend</artifactId>
|
<artifactId>ruoyi-extend</artifactId>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-extend</artifactId>
|
<artifactId>ruoyi-extend</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>4.8.0</version>
|
<version>4.8.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-extend</artifactId>
|
<artifactId>ruoyi-extend</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>4.8.0</version>
|
<version>4.8.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>ruoyi-xxl-job-admin</artifactId>
|
<artifactId>ruoyi-xxl-job-admin</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ruoyi-vue-plus",
|
"name": "ruoyi-vue-plus",
|
||||||
"version": "4.8.0",
|
"version": "4.8.1",
|
||||||
"description": "RuoYi-Vue-Plus后台管理系统",
|
"description": "RuoYi-Vue-Plus后台管理系统",
|
||||||
"author": "LionLi",
|
"author": "LionLi",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -38,6 +38,6 @@
|
|||||||
"vite": "3.2.3",
|
"vite": "3.2.3",
|
||||||
"vite-plugin-compression": "0.5.1",
|
"vite-plugin-compression": "0.5.1",
|
||||||
"vite-plugin-svg-icons": "2.0.1",
|
"vite-plugin-svg-icons": "2.0.1",
|
||||||
"vite-plugin-vue-setup-extend": "0.4.0"
|
"unplugin-vue-setup-extend-plus": "0.4.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<template v-for="(item, index) in options">
|
<template v-for="(item, index) in options">
|
||||||
<template v-if="values.includes(item.value)">
|
<template v-if="values.includes(item.value)">
|
||||||
<span
|
<span
|
||||||
v-if="item.elTagType == 'default' || item.elTagType == ''"
|
v-if="(item.elTagType == 'default' || item.elTagType == '') && (item.elTagClass == '' || item.elTagClass == null)"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:index="index"
|
:index="index"
|
||||||
:class="item.elTagClass"
|
:class="item.elTagClass"
|
||||||
@ -41,34 +41,30 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
separator: {
|
||||||
|
type: String,
|
||||||
|
default: ",",
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const values = computed(() => {
|
const values = computed(() => {
|
||||||
if (props.value !== null && typeof props.value !== 'undefined') {
|
if (props.value === null || typeof props.value === 'undefined' || props.value === '') return [];
|
||||||
return Array.isArray(props.value) ? props.value : [String(props.value)];
|
return Array.isArray(props.value) ? props.value.map(item => '' + item) : String(props.value).split(props.separator);
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const unmatch = computed(() => {
|
const unmatch = computed(() => {
|
||||||
unmatchArray.value = [];
|
unmatchArray.value = [];
|
||||||
if (props.value !== null && typeof props.value !== "undefined") {
|
|
||||||
// 传入值为非数组
|
|
||||||
if (!Array.isArray(props.value)) {
|
|
||||||
if (props.options.some((v) => v.value == props.value)) return false;
|
|
||||||
unmatchArray.value.push(props.value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// 传入值为Array
|
|
||||||
props.value.forEach((item) => {
|
|
||||||
if (!props.options.some((v) => v.value == item))
|
|
||||||
unmatchArray.value.push(item);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// 没有value不显示
|
// 没有value不显示
|
||||||
return false;
|
if (props.value === null || typeof props.value === 'undefined' || props.value === '' || props.options.length === 0) return false
|
||||||
|
// 传入值为数组
|
||||||
|
let unmatch = false // 添加一个标志来判断是否有未匹配项
|
||||||
|
values.value.forEach(item => {
|
||||||
|
if (!props.options.some(v => v.value === item)) {
|
||||||
|
unmatchArray.value.push(item)
|
||||||
|
unmatch = true // 如果有未匹配项,将标志设置为true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return unmatch // 返回标志的值
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleArray(array) {
|
function handleArray(array) {
|
||||||
|
@ -6,10 +6,12 @@
|
|||||||
:ellipsis="false"
|
:ellipsis="false"
|
||||||
>
|
>
|
||||||
<template v-for="(item, index) in topMenus">
|
<template v-for="(item, index) in topMenus">
|
||||||
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"
|
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber">
|
||||||
><svg-icon :icon-class="item.meta.icon" />
|
<svg-icon
|
||||||
{{ item.meta.title }}</el-menu-item
|
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||||
>
|
:icon-class="item.meta.icon"/>
|
||||||
|
{{ item.meta.title }}
|
||||||
|
</el-menu-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 顶部菜单超出数量折叠 -->
|
<!-- 顶部菜单超出数量折叠 -->
|
||||||
@ -19,10 +21,12 @@
|
|||||||
<el-menu-item
|
<el-menu-item
|
||||||
:index="item.path"
|
:index="item.path"
|
||||||
:key="index"
|
:key="index"
|
||||||
v-if="index >= visibleNumber"
|
v-if="index >= visibleNumber">
|
||||||
><svg-icon :icon-class="item.meta.icon" />
|
<svg-icon
|
||||||
{{ item.meta.title }}</el-menu-item
|
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||||
>
|
:icon-class="item.meta.icon"/>
|
||||||
|
{{ item.meta.title }}
|
||||||
|
</el-menu-item>
|
||||||
</template>
|
</template>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
@ -189,4 +193,22 @@ onMounted(() => {
|
|||||||
padding: 0 5px !important;
|
padding: 0 5px !important;
|
||||||
margin: 0 10px !important;
|
margin: 0 10px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 背景色隐藏 */
|
||||||
|
.topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图标右间距 */
|
||||||
|
.topmenu-container .svg-icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* topmenu more arrow */
|
||||||
|
.topmenu-container .el-sub-menu .el-sub-menu__icon-arrow {
|
||||||
|
position: static;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: 8px;
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
<router-link to="/user/profile">
|
<router-link to="/user/profile">
|
||||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||||
</router-link>
|
</router-link>
|
||||||
<el-dropdown-item command="setLayout">
|
<el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
||||||
<span>布局设置</span>
|
<span>布局设置</span>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item divided command="logout">
|
<el-dropdown-item divided command="logout">
|
||||||
|
@ -280,7 +280,7 @@ function handleScroll() {
|
|||||||
height: 8px;
|
height: 8px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-right: 2px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ export default {
|
|||||||
/**
|
/**
|
||||||
* 是否系统布局配置
|
* 是否系统布局配置
|
||||||
*/
|
*/
|
||||||
showSettings: false,
|
showSettings: true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否显示顶部导航
|
* 是否显示顶部导航
|
||||||
|
@ -103,7 +103,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="Index">
|
<script setup name="Index">
|
||||||
const version = ref('4.8.0')
|
const version = ref('4.8.1')
|
||||||
|
|
||||||
function goTarget(url) {
|
function goTarget(url) {
|
||||||
window.open(url, '__blank')
|
window.open(url, '__blank')
|
||||||
|
@ -143,10 +143,10 @@ function handleRegister() {
|
|||||||
|
|
||||||
function getCode() {
|
function getCode() {
|
||||||
getCodeImg().then(res => {
|
getCodeImg().then(res => {
|
||||||
captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
|
captchaEnabled.value = res.data.captchaEnabled === undefined ? true : res.data.captchaEnabled;
|
||||||
if (captchaEnabled.value) {
|
if (captchaEnabled.value) {
|
||||||
codeUrl.value = "data:image/gif;base64," + res.img;
|
codeUrl.value = "data:image/gif;base64," + res.data.img;
|
||||||
registerForm.value.uuid = res.uuid;
|
registerForm.value.uuid = res.data.uuid;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -91,8 +91,8 @@
|
|||||||
<el-table-column label="字典编码" align="center" prop="dictCode" />
|
<el-table-column label="字典编码" align="center" prop="dictCode" />
|
||||||
<el-table-column label="字典标签" align="center" prop="dictLabel">
|
<el-table-column label="字典标签" align="center" prop="dictLabel">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span v-if="scope.row.listClass == '' || scope.row.listClass == 'default'">{{ scope.row.dictLabel }}</span>
|
<span v-if="(scope.row.listClass == '' || scope.row.listClass == 'default') && (scope.row.cssClass == '' || scope.row.cssClass == null)">{{ scope.row.dictLabel }}</span>
|
||||||
<el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass">{{ scope.row.dictLabel }}</el-tag>
|
<el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass" :class="scope.row.cssClass">{{ scope.row.dictLabel }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="字典键值" align="center" prop="dictValue" />
|
<el-table-column label="字典键值" align="center" prop="dictValue" />
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<userAvatar :user="state.user" />
|
<userAvatar />
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group list-group-striped">
|
<ul class="list-group list-group-striped">
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import setupExtend from 'vite-plugin-vue-setup-extend'
|
import setupExtend from 'unplugin-vue-setup-extend-plus/vite'
|
||||||
|
|
||||||
export default function createSetupExtend() {
|
export default function createSetupExtend() {
|
||||||
return setupExtend()
|
return setupExtend({})
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ruoyi-vue-plus",
|
"name": "ruoyi-vue-plus",
|
||||||
"version": "4.8.0",
|
"version": "4.8.1",
|
||||||
"description": "RuoYi-Vue-Plus后台管理系统",
|
"description": "RuoYi-Vue-Plus后台管理系统",
|
||||||
"author": "LionLi",
|
"author": "LionLi",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<template v-for="(item, index) in options">
|
<template v-for="(item, index) in options">
|
||||||
<template v-if="values.includes(item.value)">
|
<template v-if="values.includes(item.value)">
|
||||||
<span
|
<span
|
||||||
v-if="item.raw.listClass == 'default' || item.raw.listClass == ''"
|
v-if="(item.raw.listClass == 'default' || item.raw.listClass == '') && (item.raw.cssClass == '' || item.raw.cssClass == null)"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:index="index"
|
:index="index"
|
||||||
:class="item.raw.cssClass"
|
:class="item.raw.cssClass"
|
||||||
@ -40,6 +40,10 @@ export default {
|
|||||||
showValue: {
|
showValue: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
|
},
|
||||||
|
separator: {
|
||||||
|
type: String,
|
||||||
|
default: ","
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@ -49,35 +53,28 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
values() {
|
values() {
|
||||||
if (this.value !== null && typeof this.value !== 'undefined') {
|
if (this.value === null || typeof this.value === 'undefined' || this.value === '') return []
|
||||||
return Array.isArray(this.value) ? this.value : [String(this.value)];
|
return Array.isArray(this.value) ? this.value.map(item => '' + item) : String(this.value).split(this.separator)
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
unmatch(){
|
unmatch() {
|
||||||
this.unmatchArray = [];
|
this.unmatchArray = []
|
||||||
if (this.value !== null && typeof this.value !== 'undefined') {
|
|
||||||
// 传入值为非数组
|
|
||||||
if(!Array.isArray(this.value)){
|
|
||||||
if(this.options.some(v=> v.value == this.value )) return false;
|
|
||||||
this.unmatchArray.push(this.value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// 传入值为Array
|
|
||||||
this.value.forEach(item => {
|
|
||||||
if (!this.options.some(v=> v.value == item )) this.unmatchArray.push(item)
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// 没有value不显示
|
// 没有value不显示
|
||||||
return false;
|
if (this.value === null || typeof this.value === 'undefined' || this.value === '' || this.options.length === 0) return false
|
||||||
|
// 传入值为数组
|
||||||
|
let unmatch = false // 添加一个标志来判断是否有未匹配项
|
||||||
|
this.values.forEach(item => {
|
||||||
|
if (!this.options.some(v => v.value === item)) {
|
||||||
|
this.unmatchArray.push(item)
|
||||||
|
unmatch = true // 如果有未匹配项,将标志设置为true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return unmatch // 返回标志的值
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
filters: {
|
filters: {
|
||||||
handleArray(array) {
|
handleArray(array) {
|
||||||
if(array.length===0) return '';
|
if (array.length === 0) return '';
|
||||||
return array.reduce((pre, cur) => {
|
return array.reduce((pre, cur) => {
|
||||||
return pre + ' ' + cur;
|
return pre + ' ' + cur;
|
||||||
})
|
})
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
>
|
>
|
||||||
<template v-for="(item, index) in topMenus">
|
<template v-for="(item, index) in topMenus">
|
||||||
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"
|
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber">
|
||||||
><svg-icon :icon-class="item.meta.icon" />
|
<svg-icon
|
||||||
{{ item.meta.title }}</el-menu-item
|
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||||
>
|
:icon-class="item.meta.icon"/>
|
||||||
|
{{ item.meta.title }}
|
||||||
|
</el-menu-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 顶部菜单超出数量折叠 -->
|
<!-- 顶部菜单超出数量折叠 -->
|
||||||
@ -18,10 +20,12 @@
|
|||||||
<el-menu-item
|
<el-menu-item
|
||||||
:index="item.path"
|
:index="item.path"
|
||||||
:key="index"
|
:key="index"
|
||||||
v-if="index >= visibleNumber"
|
v-if="index >= visibleNumber">
|
||||||
><svg-icon :icon-class="item.meta.icon" />
|
<svg-icon
|
||||||
{{ item.meta.title }}</el-menu-item
|
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||||
>
|
:icon-class="item.meta.icon"/>
|
||||||
|
{{ item.meta.title }}
|
||||||
|
</el-menu-item>
|
||||||
</template>
|
</template>
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
|
@ -14,7 +14,7 @@ const mutations = {
|
|||||||
try {
|
try {
|
||||||
for (let i = 0; i < state.dict.length; i++) {
|
for (let i = 0; i < state.dict.length; i++) {
|
||||||
if (state.dict[i].key == key) {
|
if (state.dict[i].key == key) {
|
||||||
state.dict.splice(i, i)
|
state.dict.splice(i, 1)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 版本号
|
// 版本号
|
||||||
version: "4.8.0",
|
version: "4.8.1",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -95,8 +95,8 @@
|
|||||||
<el-table-column label="字典编码" align="center" prop="dictCode" />
|
<el-table-column label="字典编码" align="center" prop="dictCode" />
|
||||||
<el-table-column label="字典标签" align="center" prop="dictLabel">
|
<el-table-column label="字典标签" align="center" prop="dictLabel">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span v-if="scope.row.listClass == '' || scope.row.listClass == 'default'">{{scope.row.dictLabel}}</span>
|
<span v-if="(scope.row.listClass == '' || scope.row.listClass == 'default') && (scope.row.cssClass == '' || scope.row.cssClass == null)">{{ scope.row.dictLabel }}</span>
|
||||||
<el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass">{{scope.row.dictLabel}}</el-tag>
|
<el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass" :class="scope.row.cssClass">{{ scope.row.dictLabel }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="字典键值" align="center" prop="dictValue" />
|
<el-table-column label="字典键值" align="center" prop="dictValue" />
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<userAvatar :user="user" />
|
<userAvatar />
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group list-group-striped">
|
<ul class="list-group list-group-striped">
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
|
@ -61,11 +61,6 @@ import { debounce } from '@/utils'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { VueCropper },
|
components: { VueCropper },
|
||||||
props: {
|
|
||||||
user: {
|
|
||||||
type: Object
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 是否显示弹出层
|
// 是否显示弹出层
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi-vue-plus</artifactId>
|
<artifactId>ruoyi-vue-plus</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>4.8.0</version>
|
<version>4.8.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.ruoyi.common.config;
|
package com.ruoyi.common.config;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -31,24 +30,9 @@ public class RuoYiConfig {
|
|||||||
*/
|
*/
|
||||||
private String copyrightYear;
|
private String copyrightYear;
|
||||||
|
|
||||||
/**
|
|
||||||
* 实例演示开关
|
|
||||||
*/
|
|
||||||
private boolean demoEnabled;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存懒加载
|
* 缓存懒加载
|
||||||
*/
|
*/
|
||||||
private boolean cacheLazy;
|
private boolean cacheLazy;
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取地址开关
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
private static boolean addressEnabled;
|
|
||||||
|
|
||||||
public void setAddressEnabled(boolean addressEnabled) {
|
|
||||||
RuoYiConfig.addressEnabled = addressEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,16 @@ public interface UserConstants {
|
|||||||
*/
|
*/
|
||||||
String DEPT_DISABLE = "1";
|
String DEPT_DISABLE = "1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 岗位正常状态
|
||||||
|
*/
|
||||||
|
String POST_NORMAL = "0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 岗位停用状态
|
||||||
|
*/
|
||||||
|
String POST_DISABLE = "1";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典正常状态
|
* 字典正常状态
|
||||||
*/
|
*/
|
||||||
|
@ -180,12 +180,12 @@ public interface BaseMapperPlus<M, T, V> extends BaseMapper<T> {
|
|||||||
* 分页查询VO
|
* 分页查询VO
|
||||||
*/
|
*/
|
||||||
default <C, P extends IPage<C>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<C> voClass) {
|
default <C, P extends IPage<C>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<C> voClass) {
|
||||||
IPage<T> pageData = this.selectPage(page, wrapper);
|
List<T> list = this.selectList(page, wrapper);
|
||||||
IPage<C> voPage = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal());
|
IPage<C> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
|
||||||
if (CollUtil.isEmpty(pageData.getRecords())) {
|
if (CollUtil.isEmpty(list)) {
|
||||||
return (P) voPage;
|
return (P) voPage;
|
||||||
}
|
}
|
||||||
voPage.setRecords(BeanCopyUtils.copyList(pageData.getRecords(), voClass));
|
voPage.setRecords(BeanCopyUtils.copyList(list, voClass));
|
||||||
return (P) voPage;
|
return (P) voPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
package com.ruoyi.common.encrypt.encryptor;
|
package com.ruoyi.common.encrypt.encryptor;
|
||||||
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.crypto.SecureUtil;
|
|
||||||
import cn.hutool.crypto.symmetric.AES;
|
|
||||||
import com.ruoyi.common.encrypt.EncryptContext;
|
import com.ruoyi.common.encrypt.EncryptContext;
|
||||||
import com.ruoyi.common.enums.AlgorithmType;
|
import com.ruoyi.common.enums.AlgorithmType;
|
||||||
import com.ruoyi.common.enums.EncodeType;
|
import com.ruoyi.common.enums.EncodeType;
|
||||||
|
import com.ruoyi.common.utils.EncryptUtils;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AES算法实现
|
* AES算法实现
|
||||||
@ -18,20 +13,11 @@ import java.nio.charset.StandardCharsets;
|
|||||||
*/
|
*/
|
||||||
public class AesEncryptor extends AbstractEncryptor {
|
public class AesEncryptor extends AbstractEncryptor {
|
||||||
|
|
||||||
private final AES aes;
|
private final EncryptContext context;
|
||||||
|
|
||||||
public AesEncryptor(EncryptContext context) {
|
public AesEncryptor(EncryptContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
String password = context.getPassword();
|
this.context = context;
|
||||||
if (StrUtil.isBlank(password)) {
|
|
||||||
throw new IllegalArgumentException("AES没有获得秘钥信息");
|
|
||||||
}
|
|
||||||
// aes算法的秘钥要求是16位、24位、32位
|
|
||||||
int[] array = {16, 24, 32};
|
|
||||||
if (!ArrayUtil.contains(array, password.length())) {
|
|
||||||
throw new IllegalArgumentException("AES秘钥长度应该为16位、24位、32位,实际为" + password.length() + "位");
|
|
||||||
}
|
|
||||||
aes = SecureUtil.aes(context.getPassword().getBytes(StandardCharsets.UTF_8));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,9 +37,9 @@ public class AesEncryptor extends AbstractEncryptor {
|
|||||||
@Override
|
@Override
|
||||||
public String encrypt(String value, EncodeType encodeType) {
|
public String encrypt(String value, EncodeType encodeType) {
|
||||||
if (encodeType == EncodeType.HEX) {
|
if (encodeType == EncodeType.HEX) {
|
||||||
return aes.encryptHex(value);
|
return EncryptUtils.encryptByAesHex(value, context.getPassword());
|
||||||
} else {
|
} else {
|
||||||
return aes.encryptBase64(value);
|
return EncryptUtils.encryptByAes(value, context.getPassword());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +50,6 @@ public class AesEncryptor extends AbstractEncryptor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String decrypt(String value) {
|
public String decrypt(String value) {
|
||||||
return this.aes.decryptStr(value);
|
return EncryptUtils.decryptByAes(value, context.getPassword());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.ruoyi.common.encrypt.encryptor;
|
package com.ruoyi.common.encrypt.encryptor;
|
||||||
|
|
||||||
import cn.hutool.core.codec.Base64;
|
|
||||||
import com.ruoyi.common.encrypt.EncryptContext;
|
import com.ruoyi.common.encrypt.EncryptContext;
|
||||||
import com.ruoyi.common.enums.AlgorithmType;
|
import com.ruoyi.common.enums.AlgorithmType;
|
||||||
import com.ruoyi.common.enums.EncodeType;
|
import com.ruoyi.common.enums.EncodeType;
|
||||||
|
import com.ruoyi.common.utils.EncryptUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base64算法实现
|
* Base64算法实现
|
||||||
@ -33,7 +33,7 @@ public class Base64Encryptor extends AbstractEncryptor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String encrypt(String value, EncodeType encodeType) {
|
public String encrypt(String value, EncodeType encodeType) {
|
||||||
return Base64.encode(value);
|
return EncryptUtils.encryptByBase64(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,6 +43,6 @@ public class Base64Encryptor extends AbstractEncryptor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String decrypt(String value) {
|
public String decrypt(String value) {
|
||||||
return Base64.decodeStr(value);
|
return EncryptUtils.decryptByBase64(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
package com.ruoyi.common.encrypt.encryptor;
|
package com.ruoyi.common.encrypt.encryptor;
|
||||||
|
|
||||||
import cn.hutool.core.codec.Base64;
|
|
||||||
import cn.hutool.crypto.SecureUtil;
|
|
||||||
import cn.hutool.crypto.asymmetric.KeyType;
|
|
||||||
import cn.hutool.crypto.asymmetric.RSA;
|
|
||||||
import com.ruoyi.common.encrypt.EncryptContext;
|
import com.ruoyi.common.encrypt.EncryptContext;
|
||||||
import com.ruoyi.common.enums.AlgorithmType;
|
import com.ruoyi.common.enums.AlgorithmType;
|
||||||
import com.ruoyi.common.enums.EncodeType;
|
import com.ruoyi.common.enums.EncodeType;
|
||||||
|
import com.ruoyi.common.utils.EncryptUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
|
|
||||||
@ -18,7 +15,7 @@ import com.ruoyi.common.utils.StringUtils;
|
|||||||
*/
|
*/
|
||||||
public class RsaEncryptor extends AbstractEncryptor {
|
public class RsaEncryptor extends AbstractEncryptor {
|
||||||
|
|
||||||
private final RSA rsa;
|
private final EncryptContext context;
|
||||||
|
|
||||||
public RsaEncryptor(EncryptContext context) {
|
public RsaEncryptor(EncryptContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -27,7 +24,7 @@ public class RsaEncryptor extends AbstractEncryptor {
|
|||||||
if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
|
if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
|
||||||
throw new IllegalArgumentException("RSA公私钥均需要提供,公钥加密,私钥解密。");
|
throw new IllegalArgumentException("RSA公私钥均需要提供,公钥加密,私钥解密。");
|
||||||
}
|
}
|
||||||
this.rsa = SecureUtil.rsa(Base64.decode(privateKey), Base64.decode(publicKey));
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,9 +44,9 @@ public class RsaEncryptor extends AbstractEncryptor {
|
|||||||
@Override
|
@Override
|
||||||
public String encrypt(String value, EncodeType encodeType) {
|
public String encrypt(String value, EncodeType encodeType) {
|
||||||
if (encodeType == EncodeType.HEX) {
|
if (encodeType == EncodeType.HEX) {
|
||||||
return rsa.encryptHex(value, KeyType.PublicKey);
|
return EncryptUtils.encryptByRsaHex(value, context.getPublicKey());
|
||||||
} else {
|
} else {
|
||||||
return rsa.encryptBase64(value, KeyType.PublicKey);
|
return EncryptUtils.encryptByRsa(value, context.getPublicKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +57,6 @@ public class RsaEncryptor extends AbstractEncryptor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String decrypt(String value) {
|
public String decrypt(String value) {
|
||||||
return this.rsa.decryptStr(value, KeyType.PrivateKey);
|
return EncryptUtils.decryptByRsa(value, context.getPrivateKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
package com.ruoyi.common.encrypt.encryptor;
|
package com.ruoyi.common.encrypt.encryptor;
|
||||||
|
|
||||||
|
|
||||||
import cn.hutool.core.codec.Base64;
|
|
||||||
import cn.hutool.crypto.SmUtil;
|
|
||||||
import cn.hutool.crypto.asymmetric.KeyType;
|
|
||||||
import cn.hutool.crypto.asymmetric.SM2;
|
|
||||||
import com.ruoyi.common.encrypt.EncryptContext;
|
import com.ruoyi.common.encrypt.EncryptContext;
|
||||||
import com.ruoyi.common.enums.AlgorithmType;
|
import com.ruoyi.common.enums.AlgorithmType;
|
||||||
import com.ruoyi.common.enums.EncodeType;
|
import com.ruoyi.common.enums.EncodeType;
|
||||||
|
import com.ruoyi.common.utils.EncryptUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,7 +15,7 @@ import com.ruoyi.common.utils.StringUtils;
|
|||||||
*/
|
*/
|
||||||
public class Sm2Encryptor extends AbstractEncryptor {
|
public class Sm2Encryptor extends AbstractEncryptor {
|
||||||
|
|
||||||
private final SM2 sm2;
|
private final EncryptContext context;
|
||||||
|
|
||||||
public Sm2Encryptor(EncryptContext context) {
|
public Sm2Encryptor(EncryptContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -27,7 +24,7 @@ public class Sm2Encryptor extends AbstractEncryptor {
|
|||||||
if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
|
if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
|
||||||
throw new IllegalArgumentException("SM2公私钥均需要提供,公钥加密,私钥解密。");
|
throw new IllegalArgumentException("SM2公私钥均需要提供,公钥加密,私钥解密。");
|
||||||
}
|
}
|
||||||
this.sm2 = SmUtil.sm2(Base64.decode(privateKey), Base64.decode(publicKey));
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,9 +44,9 @@ public class Sm2Encryptor extends AbstractEncryptor {
|
|||||||
@Override
|
@Override
|
||||||
public String encrypt(String value, EncodeType encodeType) {
|
public String encrypt(String value, EncodeType encodeType) {
|
||||||
if (encodeType == EncodeType.HEX) {
|
if (encodeType == EncodeType.HEX) {
|
||||||
return sm2.encryptHex(value, KeyType.PublicKey);
|
return EncryptUtils.encryptBySm2Hex(value, context.getPublicKey());
|
||||||
} else {
|
} else {
|
||||||
return sm2.encryptBase64(value, KeyType.PublicKey);
|
return EncryptUtils.encryptBySm2(value, context.getPublicKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +57,6 @@ public class Sm2Encryptor extends AbstractEncryptor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String decrypt(String value) {
|
public String decrypt(String value) {
|
||||||
return this.sm2.decryptStr(value, KeyType.PrivateKey);
|
return EncryptUtils.decryptBySm2(value, context.getPrivateKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
package com.ruoyi.common.encrypt.encryptor;
|
package com.ruoyi.common.encrypt.encryptor;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.crypto.SmUtil;
|
|
||||||
import cn.hutool.crypto.symmetric.SM4;
|
|
||||||
import com.ruoyi.common.encrypt.EncryptContext;
|
import com.ruoyi.common.encrypt.EncryptContext;
|
||||||
import com.ruoyi.common.enums.AlgorithmType;
|
import com.ruoyi.common.enums.AlgorithmType;
|
||||||
import com.ruoyi.common.enums.EncodeType;
|
import com.ruoyi.common.enums.EncodeType;
|
||||||
|
import com.ruoyi.common.utils.EncryptUtils;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sm4算法实现
|
* sm4算法实现
|
||||||
@ -17,19 +13,11 @@ import java.nio.charset.StandardCharsets;
|
|||||||
*/
|
*/
|
||||||
public class Sm4Encryptor extends AbstractEncryptor {
|
public class Sm4Encryptor extends AbstractEncryptor {
|
||||||
|
|
||||||
private final SM4 sm4;
|
private final EncryptContext context;
|
||||||
|
|
||||||
public Sm4Encryptor(EncryptContext context) {
|
public Sm4Encryptor(EncryptContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
String password = context.getPassword();
|
this.context = context;
|
||||||
if (StrUtil.isBlank(password)) {
|
|
||||||
throw new IllegalArgumentException("SM4没有获得秘钥信息");
|
|
||||||
}
|
|
||||||
// sm4算法的秘钥要求是16位长度
|
|
||||||
if (16 != password.length()) {
|
|
||||||
throw new IllegalArgumentException("SM4秘钥长度应该为16位,实际为" + password.length() + "位");
|
|
||||||
}
|
|
||||||
this.sm4 = SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,9 +37,9 @@ public class Sm4Encryptor extends AbstractEncryptor {
|
|||||||
@Override
|
@Override
|
||||||
public String encrypt(String value, EncodeType encodeType) {
|
public String encrypt(String value, EncodeType encodeType) {
|
||||||
if (encodeType == EncodeType.HEX) {
|
if (encodeType == EncodeType.HEX) {
|
||||||
return sm4.encryptHex(value);
|
return EncryptUtils.encryptBySm4Hex(value, context.getPassword());
|
||||||
} else {
|
} else {
|
||||||
return sm4.encryptBase64(value);
|
return EncryptUtils.encryptBySm4(value, context.getPassword());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +50,6 @@ public class Sm4Encryptor extends AbstractEncryptor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String decrypt(String value) {
|
public String decrypt(String value) {
|
||||||
return this.sm4.decryptStr(value);
|
return EncryptUtils.decryptBySm4(value, context.getPassword());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,9 @@ import cn.hutool.core.util.ArrayUtil;
|
|||||||
import cn.hutool.core.util.EnumUtil;
|
import cn.hutool.core.util.EnumUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.metadata.FieldCache;
|
||||||
|
import com.alibaba.excel.metadata.FieldWrapper;
|
||||||
|
import com.alibaba.excel.util.ClassUtils;
|
||||||
import com.alibaba.excel.write.handler.SheetWriteHandler;
|
import com.alibaba.excel.write.handler.SheetWriteHandler;
|
||||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
||||||
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
|
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
|
||||||
@ -83,16 +85,18 @@ public class ExcelDownHandler implements SheetWriteHandler {
|
|||||||
Sheet sheet = writeSheetHolder.getSheet();
|
Sheet sheet = writeSheetHolder.getSheet();
|
||||||
// 开始设置下拉框 HSSFWorkbook
|
// 开始设置下拉框 HSSFWorkbook
|
||||||
DataValidationHelper helper = sheet.getDataValidationHelper();
|
DataValidationHelper helper = sheet.getDataValidationHelper();
|
||||||
Field[] fields = writeWorkbookHolder.getClazz().getDeclaredFields();
|
|
||||||
Workbook workbook = writeWorkbookHolder.getWorkbook();
|
Workbook workbook = writeWorkbookHolder.getWorkbook();
|
||||||
int length = fields.length;
|
FieldCache fieldCache = ClassUtils.declaredFields(writeWorkbookHolder.getClazz(), writeWorkbookHolder);
|
||||||
for (int i = 0; i < length; i++) {
|
for (Map.Entry<Integer, FieldWrapper> entry : fieldCache.getSortedFieldMap().entrySet()) {
|
||||||
|
Integer index = entry.getKey();
|
||||||
|
FieldWrapper wrapper = entry.getValue();
|
||||||
|
Field field = wrapper.getField();
|
||||||
// 循环实体中的每个属性
|
// 循环实体中的每个属性
|
||||||
// 可选的下拉值
|
// 可选的下拉值
|
||||||
List<String> options = new ArrayList<>();
|
List<String> options = new ArrayList<>();
|
||||||
if (fields[i].isAnnotationPresent(ExcelDictFormat.class)) {
|
if (field.isAnnotationPresent(ExcelDictFormat.class)) {
|
||||||
// 如果指定了@ExcelDictFormat,则使用字典的逻辑
|
// 如果指定了@ExcelDictFormat,则使用字典的逻辑
|
||||||
ExcelDictFormat format = fields[i].getDeclaredAnnotation(ExcelDictFormat.class);
|
ExcelDictFormat format = field.getDeclaredAnnotation(ExcelDictFormat.class);
|
||||||
String dictType = format.dictType();
|
String dictType = format.dictType();
|
||||||
String converterExp = format.readConverterExp();
|
String converterExp = format.readConverterExp();
|
||||||
if (StrUtil.isNotBlank(dictType)) {
|
if (StrUtil.isNotBlank(dictType)) {
|
||||||
@ -105,20 +109,14 @@ public class ExcelDownHandler implements SheetWriteHandler {
|
|||||||
// 如果指定了确切的值,则直接解析确切的值
|
// 如果指定了确切的值,则直接解析确切的值
|
||||||
options = StrUtil.split(converterExp, format.separator(), true, true);
|
options = StrUtil.split(converterExp, format.separator(), true, true);
|
||||||
}
|
}
|
||||||
} else if (fields[i].isAnnotationPresent(ExcelEnumFormat.class)) {
|
} else if (field.isAnnotationPresent(ExcelEnumFormat.class)) {
|
||||||
// 否则如果指定了@ExcelEnumFormat,则使用枚举的逻辑
|
// 否则如果指定了@ExcelEnumFormat,则使用枚举的逻辑
|
||||||
ExcelEnumFormat format = fields[i].getDeclaredAnnotation(ExcelEnumFormat.class);
|
ExcelEnumFormat format = field.getDeclaredAnnotation(ExcelEnumFormat.class);
|
||||||
List<Object> values = EnumUtil.getFieldValues(format.enumClass(), format.textField());
|
List<Object> values = EnumUtil.getFieldValues(format.enumClass(), format.textField());
|
||||||
options = StreamUtils.toList(values, String::valueOf);
|
options = StreamUtils.toList(values, String::valueOf);
|
||||||
}
|
}
|
||||||
if (ObjectUtil.isNotEmpty(options)) {
|
if (ObjectUtil.isNotEmpty(options)) {
|
||||||
// 仅当下拉可选项不为空时执行
|
// 仅当下拉可选项不为空时执行
|
||||||
// 获取列下标,默认为当前循环次数
|
|
||||||
int index = i;
|
|
||||||
if (fields[i].isAnnotationPresent(ExcelProperty.class)) {
|
|
||||||
// 如果指定了列下标,以指定的为主
|
|
||||||
index = fields[i].getDeclaredAnnotation(ExcelProperty.class).index();
|
|
||||||
}
|
|
||||||
if (options.size() > 20) {
|
if (options.size() > 20) {
|
||||||
// 这里限制如果可选项大于20,则使用额外表形式
|
// 这里限制如果可选项大于20,则使用额外表形式
|
||||||
dropDownWithSheet(helper, workbook, sheet, index, options);
|
dropDownWithSheet(helper, workbook, sheet, index, options);
|
||||||
@ -128,6 +126,9 @@ public class ExcelDownHandler implements SheetWriteHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (CollUtil.isEmpty(dropDownOptions)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
dropDownOptions.forEach(everyOptions -> {
|
dropDownOptions.forEach(everyOptions -> {
|
||||||
// 如果传递了下拉框选择器参数
|
// 如果传递了下拉框选择器参数
|
||||||
if (!everyOptions.getNextOptions().isEmpty()) {
|
if (!everyOptions.getNextOptions().isEmpty()) {
|
||||||
|
@ -67,6 +67,25 @@ public class EncryptUtils {
|
|||||||
return SecureUtil.aes(password.getBytes(StandardCharsets.UTF_8)).encryptBase64(data, StandardCharsets.UTF_8);
|
return SecureUtil.aes(password.getBytes(StandardCharsets.UTF_8)).encryptBase64(data, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES加密
|
||||||
|
*
|
||||||
|
* @param data 待解密数据
|
||||||
|
* @param password 秘钥字符串
|
||||||
|
* @return 加密后字符串, 采用Hex编码
|
||||||
|
*/
|
||||||
|
public static String encryptByAesHex(String data, String password) {
|
||||||
|
if (StrUtil.isBlank(password)) {
|
||||||
|
throw new IllegalArgumentException("AES需要传入秘钥信息");
|
||||||
|
}
|
||||||
|
// aes算法的秘钥要求是16位、24位、32位
|
||||||
|
int[] array = {16, 24, 32};
|
||||||
|
if (!ArrayUtil.contains(array, password.length())) {
|
||||||
|
throw new IllegalArgumentException("AES秘钥长度要求为16位、24位、32位");
|
||||||
|
}
|
||||||
|
return SecureUtil.aes(password.getBytes(StandardCharsets.UTF_8)).encryptHex(data, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AES解密
|
* AES解密
|
||||||
*
|
*
|
||||||
@ -105,6 +124,25 @@ public class EncryptUtils {
|
|||||||
return SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8)).encryptBase64(data, StandardCharsets.UTF_8);
|
return SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8)).encryptBase64(data, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sm4加密
|
||||||
|
*
|
||||||
|
* @param data 待加密数据
|
||||||
|
* @param password 秘钥字符串
|
||||||
|
* @return 加密后字符串, 采用Base64编码
|
||||||
|
*/
|
||||||
|
public static String encryptBySm4Hex(String data, String password) {
|
||||||
|
if (StrUtil.isBlank(password)) {
|
||||||
|
throw new IllegalArgumentException("SM4需要传入秘钥信息");
|
||||||
|
}
|
||||||
|
// sm4算法的秘钥要求是16位长度
|
||||||
|
int sm4PasswordLength = 16;
|
||||||
|
if (sm4PasswordLength != password.length()) {
|
||||||
|
throw new IllegalArgumentException("SM4秘钥长度要求为16位");
|
||||||
|
}
|
||||||
|
return SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8)).encryptHex(data, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sm4解密
|
* sm4解密
|
||||||
*
|
*
|
||||||
@ -152,6 +190,21 @@ public class EncryptUtils {
|
|||||||
return sm2.encryptBase64(data, StandardCharsets.UTF_8, KeyType.PublicKey);
|
return sm2.encryptBase64(data, StandardCharsets.UTF_8, KeyType.PublicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sm2公钥加密
|
||||||
|
*
|
||||||
|
* @param data 待加密数据
|
||||||
|
* @param publicKey 公钥
|
||||||
|
* @return 加密后字符串, 采用Hex编码
|
||||||
|
*/
|
||||||
|
public static String encryptBySm2Hex(String data, String publicKey) {
|
||||||
|
if (StrUtil.isBlank(publicKey)) {
|
||||||
|
throw new IllegalArgumentException("SM2需要传入公钥进行加密");
|
||||||
|
}
|
||||||
|
SM2 sm2 = SmUtil.sm2(null, publicKey);
|
||||||
|
return sm2.encryptHex(data, StandardCharsets.UTF_8, KeyType.PublicKey);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sm2私钥解密
|
* sm2私钥解密
|
||||||
*
|
*
|
||||||
@ -195,6 +248,21 @@ public class EncryptUtils {
|
|||||||
return rsa.encryptBase64(data, StandardCharsets.UTF_8, KeyType.PublicKey);
|
return rsa.encryptBase64(data, StandardCharsets.UTF_8, KeyType.PublicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rsa公钥加密
|
||||||
|
*
|
||||||
|
* @param data 待加密数据
|
||||||
|
* @param publicKey 公钥
|
||||||
|
* @return 加密后字符串, 采用Hex编码
|
||||||
|
*/
|
||||||
|
public static String encryptByRsaHex(String data, String publicKey) {
|
||||||
|
if (StrUtil.isBlank(publicKey)) {
|
||||||
|
throw new IllegalArgumentException("RSA需要传入公钥进行加密");
|
||||||
|
}
|
||||||
|
RSA rsa = SecureUtil.rsa(null, publicKey);
|
||||||
|
return rsa.encryptHex(data, StandardCharsets.UTF_8, KeyType.PublicKey);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rsa私钥解密
|
* rsa私钥解密
|
||||||
*
|
*
|
||||||
|
@ -30,7 +30,6 @@ public class StreamUtils {
|
|||||||
if (CollUtil.isEmpty(collection)) {
|
if (CollUtil.isEmpty(collection)) {
|
||||||
return CollUtil.newArrayList();
|
return CollUtil.newArrayList();
|
||||||
}
|
}
|
||||||
// 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
|
|
||||||
return collection.stream().filter(function).collect(Collectors.toList());
|
return collection.stream().filter(function).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +70,6 @@ public class StreamUtils {
|
|||||||
if (CollUtil.isEmpty(collection)) {
|
if (CollUtil.isEmpty(collection)) {
|
||||||
return CollUtil.newArrayList();
|
return CollUtil.newArrayList();
|
||||||
}
|
}
|
||||||
// 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
|
|
||||||
return collection.stream().filter(Objects::nonNull).sorted(comparing).collect(Collectors.toList());
|
return collection.stream().filter(Objects::nonNull).sorted(comparing).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +188,6 @@ public class StreamUtils {
|
|||||||
.stream()
|
.stream()
|
||||||
.map(function)
|
.map(function)
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
// 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,10 +196,8 @@ public class ExcelUtil {
|
|||||||
// 合并处理器
|
// 合并处理器
|
||||||
builder.registerWriteHandler(new CellMergeStrategy(list, true));
|
builder.registerWriteHandler(new CellMergeStrategy(list, true));
|
||||||
}
|
}
|
||||||
if (CollUtil.isNotEmpty(options)) {
|
// 添加下拉框操作
|
||||||
// 添加下拉框操作
|
builder.registerWriteHandler(new ExcelDownHandler(options));
|
||||||
builder.registerWriteHandler(new ExcelDownHandler(options));
|
|
||||||
}
|
|
||||||
builder.doWrite(list);
|
builder.doWrite(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +131,32 @@ public class QueueUtils {
|
|||||||
return priorityBlockingQueue.offer(data);
|
return priorityBlockingQueue.offer(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优先队列获取一个队列数据 没有数据返回 null(不支持延迟队列)
|
||||||
|
*
|
||||||
|
* @param queueName 队列名
|
||||||
|
*/
|
||||||
|
public static <T> T getPriorityQueueObject(String queueName) {
|
||||||
|
RPriorityBlockingQueue<T> queue = CLIENT.getPriorityBlockingQueue(queueName);
|
||||||
|
return queue.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优先队列删除队列数据(不支持延迟队列)
|
||||||
|
*/
|
||||||
|
public static <T> boolean removePriorityQueueObject(String queueName, T data) {
|
||||||
|
RPriorityBlockingQueue<T> queue = CLIENT.getPriorityBlockingQueue(queueName);
|
||||||
|
return queue.remove(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优先队列销毁队列 所有阻塞监听 报错(不支持延迟队列)
|
||||||
|
*/
|
||||||
|
public static <T> boolean destroyPriorityQueue(String queueName) {
|
||||||
|
RPriorityBlockingQueue<T> queue = CLIENT.getPriorityBlockingQueue(queueName);
|
||||||
|
return queue.delete();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 尝试设置 有界队列 容量 用于限制数量
|
* 尝试设置 有界队列 容量 用于限制数量
|
||||||
*
|
*
|
||||||
@ -169,6 +195,32 @@ public class QueueUtils {
|
|||||||
return boundedBlockingQueue.offer(data);
|
return boundedBlockingQueue.offer(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 有界队列获取一个队列数据 没有数据返回 null(不支持延迟队列)
|
||||||
|
*
|
||||||
|
* @param queueName 队列名
|
||||||
|
*/
|
||||||
|
public static <T> T getBoundedQueueObject(String queueName) {
|
||||||
|
RBoundedBlockingQueue<T> queue = CLIENT.getBoundedBlockingQueue(queueName);
|
||||||
|
return queue.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 有界队列删除队列数据(不支持延迟队列)
|
||||||
|
*/
|
||||||
|
public static <T> boolean removeBoundedQueueObject(String queueName, T data) {
|
||||||
|
RBoundedBlockingQueue<T> queue = CLIENT.getBoundedBlockingQueue(queueName);
|
||||||
|
return queue.remove(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 有界队列销毁队列 所有阻塞监听 报错(不支持延迟队列)
|
||||||
|
*/
|
||||||
|
public static <T> boolean destroyBoundedQueue(String queueName) {
|
||||||
|
RBoundedBlockingQueue<T> queue = CLIENT.getBoundedBlockingQueue(queueName);
|
||||||
|
return queue.delete();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订阅阻塞队列(可订阅所有实现类 例如: 延迟 优先 有界 等)
|
* 订阅阻塞队列(可订阅所有实现类 例如: 延迟 优先 有界 等)
|
||||||
*/
|
*/
|
||||||
|
@ -34,7 +34,7 @@ public class RedisCacheController {
|
|||||||
* 如果没有,就调用方法,然后把结果缓存起来
|
* 如果没有,就调用方法,然后把结果缓存起来
|
||||||
* 这个注解「一般用在查询方法上」
|
* 这个注解「一般用在查询方法上」
|
||||||
* <p>
|
* <p>
|
||||||
* 重点说明: 缓存注解严谨与其他筛选数据功能一起使用
|
* 重点说明: 缓存注解严禁与其他筛选数据功能一起使用
|
||||||
* 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题
|
* 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题
|
||||||
* <p>
|
* <p>
|
||||||
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数
|
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数
|
||||||
|
@ -35,7 +35,7 @@ public class BoundedQueueController {
|
|||||||
@GetMapping("/add")
|
@GetMapping("/add")
|
||||||
public R<Void> add(String queueName, int capacity) {
|
public R<Void> add(String queueName, int capacity) {
|
||||||
// 用完了一定要销毁 否则会一直存在
|
// 用完了一定要销毁 否则会一直存在
|
||||||
boolean b = QueueUtils.destroyQueue(queueName);
|
boolean b = QueueUtils.destroyBoundedQueue(queueName);
|
||||||
log.info("通道: {} , 删除: {}", queueName, b);
|
log.info("通道: {} , 删除: {}", queueName, b);
|
||||||
// 初始化设置一次即可
|
// 初始化设置一次即可
|
||||||
if (QueueUtils.trySetBoundedQueueCapacity(queueName, capacity)) {
|
if (QueueUtils.trySetBoundedQueueCapacity(queueName, capacity)) {
|
||||||
@ -64,7 +64,7 @@ public class BoundedQueueController {
|
|||||||
@GetMapping("/remove")
|
@GetMapping("/remove")
|
||||||
public R<Void> remove(String queueName) {
|
public R<Void> remove(String queueName) {
|
||||||
String data = "data-" + 5;
|
String data = "data-" + 5;
|
||||||
if (QueueUtils.removeQueueObject(queueName, data)) {
|
if (QueueUtils.removeBoundedQueueObject(queueName, data)) {
|
||||||
log.info("通道: {} , 删除数据: {}", queueName, data);
|
log.info("通道: {} , 删除数据: {}", queueName, data);
|
||||||
} else {
|
} else {
|
||||||
return R.fail("操作失败");
|
return R.fail("操作失败");
|
||||||
@ -81,7 +81,7 @@ public class BoundedQueueController {
|
|||||||
public R<Void> get(String queueName) {
|
public R<Void> get(String queueName) {
|
||||||
String data;
|
String data;
|
||||||
do {
|
do {
|
||||||
data = QueueUtils.getQueueObject(queueName);
|
data = QueueUtils.getBoundedQueueObject(queueName);
|
||||||
log.info("通道: {} , 获取数据: {}", queueName, data);
|
log.info("通道: {} , 获取数据: {}", queueName, data);
|
||||||
} while (data != null);
|
} while (data != null);
|
||||||
return R.ok("操作成功");
|
return R.ok("操作成功");
|
||||||
|
@ -34,7 +34,7 @@ public class PriorityQueueController {
|
|||||||
@GetMapping("/add")
|
@GetMapping("/add")
|
||||||
public R<Void> add(String queueName) {
|
public R<Void> add(String queueName) {
|
||||||
// 用完了一定要销毁 否则会一直存在
|
// 用完了一定要销毁 否则会一直存在
|
||||||
boolean b = QueueUtils.destroyQueue(queueName);
|
boolean b = QueueUtils.destroyPriorityQueue(queueName);
|
||||||
log.info("通道: {} , 删除: {}", queueName, b);
|
log.info("通道: {} , 删除: {}", queueName, b);
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
@ -63,7 +63,7 @@ public class PriorityQueueController {
|
|||||||
PriorityDemo data = new PriorityDemo();
|
PriorityDemo data = new PriorityDemo();
|
||||||
data.setName(name);
|
data.setName(name);
|
||||||
data.setOrderNum(orderNum);
|
data.setOrderNum(orderNum);
|
||||||
if (QueueUtils.removeQueueObject(queueName, data)) {
|
if (QueueUtils.removePriorityQueueObject(queueName, data)) {
|
||||||
log.info("通道: {} , 删除数据: {}", queueName, data);
|
log.info("通道: {} , 删除数据: {}", queueName, data);
|
||||||
} else {
|
} else {
|
||||||
return R.fail("操作失败");
|
return R.fail("操作失败");
|
||||||
@ -80,7 +80,7 @@ public class PriorityQueueController {
|
|||||||
public R<Void> get(String queueName) {
|
public R<Void> get(String queueName) {
|
||||||
PriorityDemo data;
|
PriorityDemo data;
|
||||||
do {
|
do {
|
||||||
data = QueueUtils.getQueueObject(queueName);
|
data = QueueUtils.getPriorityQueueObject(queueName);
|
||||||
log.info("通道: {} , 获取数据: {}", queueName, data);
|
log.info("通道: {} , 获取数据: {}", queueName, data);
|
||||||
} while (data != null);
|
} while (data != null);
|
||||||
return R.ok("操作成功");
|
return R.ok("操作成功");
|
||||||
|
@ -33,7 +33,7 @@ public interface TestDemoMapper extends BaseMapperPlus<TestDemoMapper, TestDemo,
|
|||||||
@DataColumn(key = "deptName", value = "dept_id"),
|
@DataColumn(key = "deptName", value = "dept_id"),
|
||||||
@DataColumn(key = "userName", value = "user_id")
|
@DataColumn(key = "userName", value = "user_id")
|
||||||
})
|
})
|
||||||
<P extends IPage<TestDemo>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper);
|
List<TestDemo> selectList(IPage<TestDemo> page, @Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DataPermission({
|
@DataPermission({
|
||||||
|
@ -51,7 +51,7 @@ public class SaTokenConfig implements WebMvcConfigurer {
|
|||||||
// 有效率影响 用于临时测试
|
// 有效率影响 用于临时测试
|
||||||
// if (log.isDebugEnabled()) {
|
// if (log.isDebugEnabled()) {
|
||||||
// log.debug("剩余有效时间: {}", StpUtil.getTokenTimeout());
|
// log.debug("剩余有效时间: {}", StpUtil.getTokenTimeout());
|
||||||
// log.debug("临时有效时间: {}", StpUtil.getTokenActivityTimeout());
|
// log.debug("临时有效时间: {}", StpUtil.getTokenActiveTimeout());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.ruoyi.framework.config;
|
package com.ruoyi.framework.config;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.framework.config.properties.SwaggerProperties;
|
import com.ruoyi.framework.config.properties.SpringDocProperties;
|
||||||
import com.ruoyi.framework.handler.OpenApiHandler;
|
import com.ruoyi.framework.handler.OpenApiHandler;
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
import io.swagger.v3.oas.models.Paths;
|
import io.swagger.v3.oas.models.Paths;
|
||||||
@ -34,25 +34,24 @@ import java.util.Set;
|
|||||||
@Configuration
|
@Configuration
|
||||||
@AutoConfigureBefore(SpringDocConfiguration.class)
|
@AutoConfigureBefore(SpringDocConfiguration.class)
|
||||||
@ConditionalOnProperty(name = "springdoc.api-docs.enabled", havingValue = "true", matchIfMissing = true)
|
@ConditionalOnProperty(name = "springdoc.api-docs.enabled", havingValue = "true", matchIfMissing = true)
|
||||||
public class SwaggerConfig {
|
public class SpringDocConfig {
|
||||||
|
|
||||||
private final SwaggerProperties swaggerProperties;
|
|
||||||
private final ServerProperties serverProperties;
|
private final ServerProperties serverProperties;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(OpenAPI.class)
|
@ConditionalOnMissingBean(OpenAPI.class)
|
||||||
public OpenAPI openApi() {
|
public OpenAPI openApi(SpringDocProperties properties) {
|
||||||
OpenAPI openApi = new OpenAPI();
|
OpenAPI openApi = new OpenAPI();
|
||||||
// 文档基本信息
|
// 文档基本信息
|
||||||
SwaggerProperties.InfoProperties infoProperties = swaggerProperties.getInfo();
|
SpringDocProperties.InfoProperties infoProperties = properties.getInfo();
|
||||||
Info info = convertInfo(infoProperties);
|
Info info = convertInfo(infoProperties);
|
||||||
openApi.info(info);
|
openApi.info(info);
|
||||||
// 扩展文档信息
|
// 扩展文档信息
|
||||||
openApi.externalDocs(swaggerProperties.getExternalDocs());
|
openApi.externalDocs(properties.getExternalDocs());
|
||||||
openApi.tags(swaggerProperties.getTags());
|
openApi.tags(properties.getTags());
|
||||||
openApi.paths(swaggerProperties.getPaths());
|
openApi.paths(properties.getPaths());
|
||||||
openApi.components(swaggerProperties.getComponents());
|
openApi.components(properties.getComponents());
|
||||||
Set<String> keySet = swaggerProperties.getComponents().getSecuritySchemes().keySet();
|
Set<String> keySet = properties.getComponents().getSecuritySchemes().keySet();
|
||||||
List<SecurityRequirement> list = new ArrayList<>();
|
List<SecurityRequirement> list = new ArrayList<>();
|
||||||
SecurityRequirement securityRequirement = new SecurityRequirement();
|
SecurityRequirement securityRequirement = new SecurityRequirement();
|
||||||
keySet.forEach(securityRequirement::addList);
|
keySet.forEach(securityRequirement::addList);
|
||||||
@ -62,7 +61,7 @@ public class SwaggerConfig {
|
|||||||
return openApi;
|
return openApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Info convertInfo(SwaggerProperties.InfoProperties infoProperties) {
|
private Info convertInfo(SpringDocProperties.InfoProperties infoProperties) {
|
||||||
Info info = new Info();
|
Info info = new Info();
|
||||||
info.setTitle(infoProperties.getTitle());
|
info.setTitle(infoProperties.getTitle());
|
||||||
info.setDescription(infoProperties.getDescription());
|
info.setDescription(infoProperties.getDescription());
|
@ -20,8 +20,8 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Component
|
@Component
|
||||||
@ConfigurationProperties(prefix = "swagger")
|
@ConfigurationProperties(prefix = "springdoc")
|
||||||
public class SwaggerProperties {
|
public class SpringDocProperties {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文档基本信息
|
* 文档基本信息
|
@ -1,6 +1,7 @@
|
|||||||
package com.ruoyi.framework.encrypt;
|
package com.ruoyi.framework.encrypt;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.ruoyi.common.annotation.EncryptField;
|
import com.ruoyi.common.annotation.EncryptField;
|
||||||
import com.ruoyi.common.encrypt.EncryptContext;
|
import com.ruoyi.common.encrypt.EncryptContext;
|
||||||
@ -76,7 +77,7 @@ public class MybatisDecryptInterceptor implements Interceptor {
|
|||||||
Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
|
Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
|
||||||
try {
|
try {
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
field.set(sourceObject, this.decryptField(String.valueOf(field.get(sourceObject)), field));
|
field.set(sourceObject, this.decryptField(Convert.toStr(field.get(sourceObject)), field));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("处理解密字段时出错", e);
|
log.error("处理解密字段时出错", e);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.ruoyi.framework.encrypt;
|
package com.ruoyi.framework.encrypt;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.ruoyi.common.annotation.EncryptField;
|
import com.ruoyi.common.annotation.EncryptField;
|
||||||
import com.ruoyi.common.encrypt.EncryptContext;
|
import com.ruoyi.common.encrypt.EncryptContext;
|
||||||
@ -86,7 +87,7 @@ public class MybatisEncryptInterceptor implements Interceptor {
|
|||||||
Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
|
Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
|
||||||
try {
|
try {
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
field.set(sourceObject, this.encryptField(String.valueOf(field.get(sourceObject)), field));
|
field.set(sourceObject, this.encryptField(Convert.toStr(field.get(sourceObject)), field));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("处理加密字段时出错", e);
|
log.error("处理加密字段时出错", e);
|
||||||
|
@ -8,6 +8,7 @@ import cn.hutool.http.HttpStatus;
|
|||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.common.exception.DemoModeException;
|
import com.ruoyi.common.exception.DemoModeException;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import com.ruoyi.common.exception.base.BaseException;
|
||||||
import com.ruoyi.common.utils.StreamUtils;
|
import com.ruoyi.common.utils.StreamUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.mybatis.spring.MyBatisSystemException;
|
import org.mybatis.spring.MyBatisSystemException;
|
||||||
@ -105,18 +106,27 @@ public class GlobalExceptionHandler {
|
|||||||
*/
|
*/
|
||||||
@ExceptionHandler(ServiceException.class)
|
@ExceptionHandler(ServiceException.class)
|
||||||
public R<Void> handleServiceException(ServiceException e, HttpServletRequest request) {
|
public R<Void> handleServiceException(ServiceException e, HttpServletRequest request) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage());
|
||||||
Integer code = e.getCode();
|
Integer code = e.getCode();
|
||||||
return ObjectUtil.isNotNull(code) ? R.fail(code, e.getMessage()) : R.fail(e.getMessage());
|
return ObjectUtil.isNotNull(code) ? R.fail(code, e.getMessage()) : R.fail(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(BaseException.class)
|
||||||
|
public R<Void> handleBaseException(BaseException e, HttpServletRequest request) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
return R.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求路径中缺少必需的路径变量
|
* 请求路径中缺少必需的路径变量
|
||||||
*/
|
*/
|
||||||
@ExceptionHandler(MissingPathVariableException.class)
|
@ExceptionHandler(MissingPathVariableException.class)
|
||||||
public R<Void> handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) {
|
public R<Void> handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) {
|
||||||
String requestURI = request.getRequestURI();
|
String requestURI = request.getRequestURI();
|
||||||
log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);
|
log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI);
|
||||||
return R.fail(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));
|
return R.fail(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +136,7 @@ public class GlobalExceptionHandler {
|
|||||||
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
||||||
public R<Void> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) {
|
public R<Void> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) {
|
||||||
String requestURI = request.getRequestURI();
|
String requestURI = request.getRequestURI();
|
||||||
log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
|
log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI);
|
||||||
return R.fail(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue()));
|
return R.fail(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +165,7 @@ public class GlobalExceptionHandler {
|
|||||||
*/
|
*/
|
||||||
@ExceptionHandler(BindException.class)
|
@ExceptionHandler(BindException.class)
|
||||||
public R<Void> handleBindException(BindException e) {
|
public R<Void> handleBindException(BindException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage());
|
||||||
String message = StreamUtils.join(e.getAllErrors(), DefaultMessageSourceResolvable::getDefaultMessage, ", ");
|
String message = StreamUtils.join(e.getAllErrors(), DefaultMessageSourceResolvable::getDefaultMessage, ", ");
|
||||||
return R.fail(message);
|
return R.fail(message);
|
||||||
}
|
}
|
||||||
@ -165,7 +175,7 @@ public class GlobalExceptionHandler {
|
|||||||
*/
|
*/
|
||||||
@ExceptionHandler(ConstraintViolationException.class)
|
@ExceptionHandler(ConstraintViolationException.class)
|
||||||
public R<Void> constraintViolationException(ConstraintViolationException e) {
|
public R<Void> constraintViolationException(ConstraintViolationException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage());
|
||||||
String message = StreamUtils.join(e.getConstraintViolations(), ConstraintViolation::getMessage, ", ");
|
String message = StreamUtils.join(e.getConstraintViolations(), ConstraintViolation::getMessage, ", ");
|
||||||
return R.fail(message);
|
return R.fail(message);
|
||||||
}
|
}
|
||||||
@ -175,7 +185,7 @@ public class GlobalExceptionHandler {
|
|||||||
*/
|
*/
|
||||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
public R<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
public R<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage());
|
||||||
String message = e.getBindingResult().getFieldError().getDefaultMessage();
|
String message = e.getBindingResult().getFieldError().getDefaultMessage();
|
||||||
return R.fail(message);
|
return R.fail(message);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@ import java.util.List;
|
|||||||
public interface SysRoleMapper extends BaseMapperPlus<SysRoleMapper, SysRole, SysRole> {
|
public interface SysRoleMapper extends BaseMapperPlus<SysRoleMapper, SysRole, SysRole> {
|
||||||
|
|
||||||
@DataPermission({
|
@DataPermission({
|
||||||
@DataColumn(key = "deptName", value = "d.dept_id")
|
@DataColumn(key = "deptName", value = "d.dept_id"),
|
||||||
|
@DataColumn(key = "userName", value = "us.user_id")
|
||||||
})
|
})
|
||||||
Page<SysRole> selectPageRoleList(@Param("page") Page<SysRole> page, @Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
|
Page<SysRole> selectPageRoleList(@Param("page") Page<SysRole> page, @Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
|
||||||
|
|
||||||
@ -30,7 +31,8 @@ public interface SysRoleMapper extends BaseMapperPlus<SysRoleMapper, SysRole, Sy
|
|||||||
* @return 角色数据集合信息
|
* @return 角色数据集合信息
|
||||||
*/
|
*/
|
||||||
@DataPermission({
|
@DataPermission({
|
||||||
@DataColumn(key = "deptName", value = "d.dept_id")
|
@DataColumn(key = "deptName", value = "d.dept_id"),
|
||||||
|
@DataColumn(key = "userName", value = "us.user_id")
|
||||||
})
|
})
|
||||||
List<SysRole> selectRoleList(@Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
|
List<SysRole> selectRoleList(@Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
|
||||||
|
|
||||||
|
@ -143,9 +143,13 @@ public class SysLoginService {
|
|||||||
public void logout() {
|
public void logout() {
|
||||||
try {
|
try {
|
||||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||||
StpUtil.logout();
|
|
||||||
recordLogininfor(loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
|
recordLogininfor(loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
|
||||||
} catch (NotLoginException ignored) {
|
} catch (NotLoginException ignored) {
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
StpUtil.logout();
|
||||||
|
} catch (NotLoginException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,8 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Tree<Long>> selectDeptTreeList(SysDept dept) {
|
public List<Tree<Long>> selectDeptTreeList(SysDept dept) {
|
||||||
|
// 只查询未禁用部门
|
||||||
|
dept.setStatus(UserConstants.DEPT_NORMAL);
|
||||||
List<SysDept> depts = this.selectDeptList(dept);
|
List<SysDept> depts = this.selectDeptList(dept);
|
||||||
return buildDeptTreeSelect(depts);
|
return buildDeptTreeSelect(depts);
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ public class SysPostServiceImpl implements ISysPostService {
|
|||||||
for (Long postId : postIds) {
|
for (Long postId : postIds) {
|
||||||
SysPost post = selectPostById(postId);
|
SysPost post = selectPostById(postId);
|
||||||
if (countUserPostById(postId) > 0) {
|
if (countUserPostById(postId) > 0) {
|
||||||
throw new ServiceException(String.format("%1$s已分配,不能删除", post.getPostName()));
|
throw new ServiceException(String.format("%1$s已分配,不能删除!", post.getPostName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return baseMapper.deleteBatchIds(Arrays.asList(postIds));
|
return baseMapper.deleteBatchIds(Arrays.asList(postIds));
|
||||||
|
@ -268,6 +268,9 @@ public class SysRoleServiceImpl implements ISysRoleService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int updateRoleStatus(SysRole role) {
|
public int updateRoleStatus(SysRole role) {
|
||||||
|
if (UserConstants.ROLE_DISABLE.equals(role.getStatus()) && this.countUserRoleByRoleId(role.getRoleId()) > 0) {
|
||||||
|
throw new ServiceException("角色已分配,不能禁用!");
|
||||||
|
}
|
||||||
return baseMapper.updateById(role);
|
return baseMapper.updateById(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +363,7 @@ public class SysRoleServiceImpl implements ISysRoleService {
|
|||||||
checkRoleAllowed(role);
|
checkRoleAllowed(role);
|
||||||
checkRoleDataScope(roleId);
|
checkRoleDataScope(roleId);
|
||||||
if (countUserRoleByRoleId(roleId) > 0) {
|
if (countUserRoleByRoleId(roleId) > 0) {
|
||||||
throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName()));
|
throw new ServiceException(String.format("%1$s已分配,不能删除!", role.getRoleName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<Long> ids = Arrays.asList(roleIds);
|
List<Long> ids = Arrays.asList(roleIds);
|
||||||
|
@ -91,9 +91,12 @@ public class SysDeptController extends BaseController {
|
|||||||
return R.fail("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
return R.fail("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
||||||
} else if (dept.getParentId().equals(deptId)) {
|
} else if (dept.getParentId().equals(deptId)) {
|
||||||
return R.fail("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
|
return R.fail("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
|
||||||
} else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus())
|
} else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus())) {
|
||||||
&& deptService.selectNormalChildrenDeptById(deptId) > 0) {
|
if (deptService.selectNormalChildrenDeptById(deptId) > 0) {
|
||||||
return R.fail("该部门包含未停用的子部门!");
|
return R.fail("该部门包含未停用的子部门!");
|
||||||
|
} else if (deptService.checkDeptExistUser(deptId)) {
|
||||||
|
return R.fail("该部门下存在已分配用户,不能禁用!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return toAjax(deptService.updateDept(dept));
|
return toAjax(deptService.updateDept(dept));
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,9 @@ public class SysPostController extends BaseController {
|
|||||||
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
|
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
|
||||||
} else if (!postService.checkPostCodeUnique(post)) {
|
} else if (!postService.checkPostCodeUnique(post)) {
|
||||||
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
|
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
|
||||||
|
} else if (UserConstants.POST_DISABLE.equals(post.getStatus())
|
||||||
|
&& postService.countUserPostById(post.getPostId()) > 0) {
|
||||||
|
return R.fail("该岗位下存在已分配用户,不能禁用!");
|
||||||
}
|
}
|
||||||
return toAjax(postService.updatePost(post));
|
return toAjax(postService.updatePost(post));
|
||||||
}
|
}
|
||||||
@ -109,7 +112,9 @@ public class SysPostController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("/optionselect")
|
@GetMapping("/optionselect")
|
||||||
public R<List<SysPost>> optionselect() {
|
public R<List<SysPost>> optionselect() {
|
||||||
List<SysPost> posts = postService.selectPostAll();
|
SysPost post = new SysPost();
|
||||||
|
post.setStatus(UserConstants.POST_NORMAL);
|
||||||
|
List<SysPost> posts = postService.selectPostList(post);
|
||||||
return R.ok(posts);
|
return R.ok(posts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,8 @@ public class SysProfileController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 重置密码
|
* 重置密码
|
||||||
*
|
*
|
||||||
* @param newPassword 旧密码
|
* @param newPassword 新密码
|
||||||
* @param oldPassword 新密码
|
* @param oldPassword 旧密码
|
||||||
*/
|
*/
|
||||||
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
|
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
|
||||||
@PutMapping("/updatePwd")
|
@PutMapping("/updatePwd")
|
||||||
|
@ -21,6 +21,7 @@ import com.ruoyi.common.helper.LoginHelper;
|
|||||||
import com.ruoyi.common.utils.StreamUtils;
|
import com.ruoyi.common.utils.StreamUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.system.domain.SysPost;
|
||||||
import com.ruoyi.system.domain.vo.SysUserExportVo;
|
import com.ruoyi.system.domain.vo.SysUserExportVo;
|
||||||
import com.ruoyi.system.domain.vo.SysUserImportVo;
|
import com.ruoyi.system.domain.vo.SysUserImportVo;
|
||||||
import com.ruoyi.system.listener.SysUserImportListener;
|
import com.ruoyi.system.listener.SysUserImportListener;
|
||||||
@ -117,9 +118,13 @@ public class SysUserController extends BaseController {
|
|||||||
public R<Map<String, Object>> getInfo(@PathVariable(value = "userId", required = false) Long userId) {
|
public R<Map<String, Object>> getInfo(@PathVariable(value = "userId", required = false) Long userId) {
|
||||||
userService.checkUserDataScope(userId);
|
userService.checkUserDataScope(userId);
|
||||||
Map<String, Object> ajax = new HashMap<>();
|
Map<String, Object> ajax = new HashMap<>();
|
||||||
List<SysRole> roles = roleService.selectRoleAll();
|
SysRole role = new SysRole();
|
||||||
|
role.setStatus(UserConstants.ROLE_NORMAL);
|
||||||
|
SysPost post = new SysPost();
|
||||||
|
post.setStatus(UserConstants.POST_NORMAL);
|
||||||
|
List<SysRole> roles = roleService.selectRoleList(role);
|
||||||
ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin()));
|
ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin()));
|
||||||
ajax.put("posts", postService.selectPostAll());
|
ajax.put("posts", postService.selectPostList(post));
|
||||||
if (ObjectUtil.isNotNull(userId)) {
|
if (ObjectUtil.isNotNull(userId)) {
|
||||||
SysUser sysUser = userService.selectUserById(userId);
|
SysUser sysUser = userService.selectUserById(userId);
|
||||||
ajax.put("user", sysUser);
|
ajax.put("user", sysUser);
|
||||||
@ -136,6 +141,7 @@ public class SysUserController extends BaseController {
|
|||||||
@Log(title = "用户管理", businessType = BusinessType.INSERT)
|
@Log(title = "用户管理", businessType = BusinessType.INSERT)
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public R<Void> add(@Validated @RequestBody SysUser user) {
|
public R<Void> add(@Validated @RequestBody SysUser user) {
|
||||||
|
deptService.checkDeptDataScope(user.getDeptId());
|
||||||
if (!userService.checkUserNameUnique(user)) {
|
if (!userService.checkUserNameUnique(user)) {
|
||||||
return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
|
return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
|
||||||
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
|
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
|
||||||
@ -156,6 +162,7 @@ public class SysUserController extends BaseController {
|
|||||||
public R<Void> edit(@Validated @RequestBody SysUser user) {
|
public R<Void> edit(@Validated @RequestBody SysUser user) {
|
||||||
userService.checkUserAllowed(user);
|
userService.checkUserAllowed(user);
|
||||||
userService.checkUserDataScope(user.getUserId());
|
userService.checkUserDataScope(user.getUserId());
|
||||||
|
deptService.checkDeptDataScope(user.getDeptId());
|
||||||
if (!userService.checkUserNameUnique(user)) {
|
if (!userService.checkUserNameUnique(user)) {
|
||||||
return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
|
return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
|
||||||
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
|
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
|
||||||
|
@ -19,8 +19,8 @@ xxl.job:
|
|||||||
executor:
|
executor:
|
||||||
# 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册
|
# 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册
|
||||||
appname: xxl-job-executor
|
appname: xxl-job-executor
|
||||||
# 执行器端口号 执行器从9101开始往后写
|
# 28080 端口 随着主应用端口飘逸 避免集群冲突
|
||||||
port: 9101
|
port: 2${server.port}
|
||||||
# 执行器注册:默认IP:PORT
|
# 执行器注册:默认IP:PORT
|
||||||
address:
|
address:
|
||||||
# 执行器IP:默认自动获取IP
|
# 执行器IP:默认自动获取IP
|
||||||
|
@ -22,8 +22,8 @@ xxl.job:
|
|||||||
executor:
|
executor:
|
||||||
# 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册
|
# 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册
|
||||||
appname: xxl-job-executor
|
appname: xxl-job-executor
|
||||||
# 执行器端口号 执行器从9101开始往后写
|
# 28080 端口 随着主应用端口飘逸 避免集群冲突
|
||||||
port: 9101
|
port: 2${server.port}
|
||||||
# 执行器注册:默认IP:PORT
|
# 执行器注册:默认IP:PORT
|
||||||
address:
|
address:
|
||||||
# 执行器IP:默认自动获取IP
|
# 执行器IP:默认自动获取IP
|
||||||
|
@ -5,11 +5,7 @@ ruoyi:
|
|||||||
# 版本
|
# 版本
|
||||||
version: ${ruoyi-vue-plus.version}
|
version: ${ruoyi-vue-plus.version}
|
||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2022
|
copyrightYear: 2023
|
||||||
# 实例演示开关
|
|
||||||
demoEnabled: true
|
|
||||||
# 获取ip地址开关
|
|
||||||
addressEnabled: true
|
|
||||||
# 缓存懒加载
|
# 缓存懒加载
|
||||||
cacheLazy: false
|
cacheLazy: false
|
||||||
|
|
||||||
@ -107,6 +103,8 @@ sa-token:
|
|||||||
# 多端不同 token 有效期 可查看 LoginHelper.loginByDevice 方法自定义
|
# 多端不同 token 有效期 可查看 LoginHelper.loginByDevice 方法自定义
|
||||||
# token最低活跃时间 (指定时间无操作就过期) 单位: 秒
|
# token最低活跃时间 (指定时间无操作就过期) 单位: 秒
|
||||||
active-timeout: 1800
|
active-timeout: 1800
|
||||||
|
# 允许动态设置 token 有效期
|
||||||
|
dynamic-active-timeout: true
|
||||||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||||
is-concurrent: true
|
is-concurrent: true
|
||||||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||||
@ -197,8 +195,13 @@ mybatis-encryptor:
|
|||||||
publicKey:
|
publicKey:
|
||||||
privateKey:
|
privateKey:
|
||||||
|
|
||||||
# Swagger配置
|
springdoc:
|
||||||
swagger:
|
api-docs:
|
||||||
|
# 是否开启接口文档
|
||||||
|
enabled: true
|
||||||
|
# swagger-ui:
|
||||||
|
# # 持久化认证数据
|
||||||
|
# persistAuthorization: true
|
||||||
info:
|
info:
|
||||||
# 标题
|
# 标题
|
||||||
title: '标题:${ruoyi.name}后台管理系统_接口文档'
|
title: '标题:${ruoyi.name}后台管理系统_接口文档'
|
||||||
@ -218,14 +221,6 @@ swagger:
|
|||||||
type: APIKEY
|
type: APIKEY
|
||||||
in: HEADER
|
in: HEADER
|
||||||
name: ${sa-token.token-name}
|
name: ${sa-token.token-name}
|
||||||
|
|
||||||
springdoc:
|
|
||||||
api-docs:
|
|
||||||
# 是否开启接口文档
|
|
||||||
enabled: true
|
|
||||||
swagger-ui:
|
|
||||||
# 持久化认证数据
|
|
||||||
persistAuthorization: true
|
|
||||||
#这里定义了两个分组,可定义多个,也可以不定义
|
#这里定义了两个分组,可定义多个,也可以不定义
|
||||||
group-configs:
|
group-configs:
|
||||||
- group: 1.演示模块
|
- group: 1.演示模块
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
from sys_role r
|
from sys_role r
|
||||||
left join sys_user_role sur on sur.role_id = r.role_id
|
left join sys_user_role sur on sur.role_id = r.role_id
|
||||||
left join sys_user u on u.user_id = sur.user_id
|
left join sys_user u on u.user_id = sur.user_id
|
||||||
|
left join sys_user us on us.user_name = r.create_by
|
||||||
left join sys_dept d on u.dept_id = d.dept_id
|
left join sys_dept d on u.dept_id = d.dept_id
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import com.ruoyi.common.convert.ExcelDictConvert;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ${functionName}视图对象 ${tableName}
|
* ${functionName}视图对象 ${tableName}
|
||||||
@ -20,7 +20,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
public class ${ClassName}Vo {
|
public class ${ClassName}Vo implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -434,7 +434,7 @@ export default {
|
|||||||
this.reset();
|
this.reset();
|
||||||
this.getTreeselect();
|
this.getTreeselect();
|
||||||
if (row != null && row.${treeCode}) {
|
if (row != null && row.${treeCode}) {
|
||||||
this.form.${treeParentCode} = row.${treeCode};
|
this.form.${treeParentCode} = row.${treeParentCode};
|
||||||
} else {
|
} else {
|
||||||
this.form.${treeParentCode} = 0;
|
this.form.${treeParentCode} = 0;
|
||||||
}
|
}
|
||||||
|
@ -398,7 +398,7 @@ function handleAdd(row) {
|
|||||||
reset();
|
reset();
|
||||||
getTreeselect();
|
getTreeselect();
|
||||||
if (row != null && row.${treeCode}) {
|
if (row != null && row.${treeCode}) {
|
||||||
form.value.${treeParentCode} = row.${treeCode};
|
form.value.${treeParentCode} = row.${treeParentCode};
|
||||||
} else {
|
} else {
|
||||||
form.value.${treeParentCode} = 0;
|
form.value.${treeParentCode} = 0;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ services:
|
|||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
ruoyi-server1:
|
ruoyi-server1:
|
||||||
image: ruoyi/ruoyi-server:4.8.0
|
image: ruoyi/ruoyi-server:4.8.1
|
||||||
container_name: ruoyi-server1
|
container_name: ruoyi-server1
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
@ -115,7 +115,7 @@ services:
|
|||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
ruoyi-server2:
|
ruoyi-server2:
|
||||||
image: "ruoyi/ruoyi-server:4.8.0"
|
image: "ruoyi/ruoyi-server:4.8.1"
|
||||||
container_name: ruoyi-server2
|
container_name: ruoyi-server2
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
@ -130,7 +130,7 @@ services:
|
|||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
ruoyi-monitor-admin:
|
ruoyi-monitor-admin:
|
||||||
image: ruoyi/ruoyi-monitor-admin:4.8.0
|
image: ruoyi/ruoyi-monitor-admin:4.8.1
|
||||||
container_name: ruoyi-monitor-admin
|
container_name: ruoyi-monitor-admin
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
@ -142,7 +142,7 @@ services:
|
|||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
|
||||||
ruoyi-xxl-job-admin:
|
ruoyi-xxl-job-admin:
|
||||||
image: ruoyi/ruoyi-xxl-job-admin:4.8.0
|
image: ruoyi/ruoyi-xxl-job-admin:4.8.1
|
||||||
container_name: ruoyi-xxl-job-admin
|
container_name: ruoyi-xxl-job-admin
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
|
Loading…
x
Reference in New Issue
Block a user