Merge branch 'master' of https://gitee.com/y_project/RuoYi-Vue
Conflicts: ruoyi-ui/package.json ruoyi-ui/src/api/system/config.js ruoyi-ui/src/api/system/dict/data.js ruoyi-ui/src/api/system/dict/type.js ruoyi-ui/src/assets/styles/element-variables.scss ruoyi-ui/src/components/SvgIcon/index.vue ruoyi-ui/src/layout/components/Sidebar/Link.vue ruoyi-ui/src/layout/components/Sidebar/index.vue ruoyi-ui/src/layout/components/TagsView/ScrollPane.vue ruoyi-ui/src/layout/components/TagsView/index.vue ruoyi-ui/src/views/monitor/job/index.vue ruoyi-ui/src/views/system/config/index.vue ruoyi-ui/src/views/system/dept/index.vue ruoyi-ui/src/views/system/dict/data.vue ruoyi-ui/src/views/system/dict/index.vue ruoyi-ui/src/views/system/menu/index.vue ruoyi-ui/src/views/system/notice/index.vue ruoyi-ui/src/views/system/post/index.vue ruoyi-ui/src/views/system/role/index.vue ruoyi-ui/src/views/system/user/index.vue ruoyi-ui/src/views/system/user/profile/resetPwd.vue ruoyi-ui/src/views/system/user/profile/userAvatar.vue ruoyi-ui/src/views/system/user/profile/userInfo.vue ruoyi-ui/vue.config.js ruoyi/pom.xml ruoyi/src/main/java/com/ruoyi/common/constant/Constants.java ruoyi/src/main/java/com/ruoyi/common/utils/StringUtils.java ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysMenuServiceImpl.java ruoyi/src/main/resources/application.yml ruoyi/src/main/resources/vm/sql/sql.vm ruoyi/src/main/resources/vm/vue/index.vue.vm
This commit is contained in:
commit
5f866906d1
@ -12,6 +12,7 @@
|
||||
* 权限认证使用Jwt,支持多终端认证系统。
|
||||
* 支持加载动态权限菜单,多方式轻松权限控制。
|
||||
* 高效率开发,使用代码生成器可以一键生成前后端代码。
|
||||
* 提供了一个Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
|
||||
* 感谢[Vue-Element-Admin](https://github.com/PanJiaChen/vue-element-admin),[eladmin-web](https://gitee.com/elunez/eladmin-web?_from=gitee_search)。
|
||||
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
|
||||
* 阿里云优惠券:[点我进入](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)
|
||||
|
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "ruoyi",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.0",
|
||||
"description": "若依管理系统",
|
||||
"author": "若依",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve",
|
||||
"dev": "vue-cli-service serve --open",
|
||||
"build:prod": "vue-cli-service build",
|
||||
"build:stage": "vue-cli-service build --mode staging",
|
||||
"preview": "node build/index.js --preview",
|
||||
|
@ -51,6 +51,14 @@ export function delConfig(configId) {
|
||||
})
|
||||
}
|
||||
|
||||
// 清理参数缓存
|
||||
export function clearCache() {
|
||||
return request({
|
||||
url: '/system/config/clearCache',
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出参数
|
||||
export function exportConfig(query) {
|
||||
return request({
|
||||
|
@ -20,7 +20,7 @@ export function getData(dictCode) {
|
||||
// 根据字典类型查询字典数据信息
|
||||
export function getDicts(dictType) {
|
||||
return request({
|
||||
url: '/system/dict/data/dictType/' + dictType,
|
||||
url: '/system/dict/data/type/' + dictType,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
@ -43,6 +43,14 @@ export function delType(dictId) {
|
||||
})
|
||||
}
|
||||
|
||||
// 清理参数缓存
|
||||
export function clearCache() {
|
||||
return request({
|
||||
url: '/system/dict/type/clearCache',
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出字典类型
|
||||
export function exportType(query) {
|
||||
return request({
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* theme color */
|
||||
$--color-primary: #1890ff;
|
||||
$--color-success: #13ce66;
|
||||
$--color-warning: #FFBA00;
|
||||
$--color-warning: #ffba00;
|
||||
$--color-danger: #ff4949;
|
||||
// $--color-info: #1E1E1E;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
|
||||
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
|
||||
<use :href="iconName" />
|
||||
<use :xlink:href="iconName" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
|
||||
<template>
|
||||
<!-- eslint-disable vue/require-component-is -->
|
||||
<component v-bind="linkProps(to)">
|
||||
<component :is="type" v-bind="linkProps(to)">
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
@ -16,19 +14,28 @@ export default {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isExternal() {
|
||||
return isExternal(this.to)
|
||||
},
|
||||
type() {
|
||||
if (this.isExternal) {
|
||||
return 'a'
|
||||
}
|
||||
return 'router-link'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
linkProps(url) {
|
||||
if (isExternal(url)) {
|
||||
linkProps(to) {
|
||||
if (this.isExternal) {
|
||||
return {
|
||||
is: 'a',
|
||||
href: url,
|
||||
href: to,
|
||||
target: '_blank',
|
||||
rel: 'noopener'
|
||||
}
|
||||
}
|
||||
return {
|
||||
is: 'router-link',
|
||||
to: url
|
||||
to: to
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
mode="vertical"
|
||||
>
|
||||
<sidebar-item
|
||||
v-for="route in permission_routes"
|
||||
:key="route.path"
|
||||
v-for="(route, index) in permission_routes"
|
||||
:key="route.path + index"
|
||||
:item="route"
|
||||
:base-path="route.path"
|
||||
/>
|
||||
|
@ -19,12 +19,21 @@ export default {
|
||||
return this.$refs.scrollContainer.$refs.wrap
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.scrollWrapper.removeEventListener('scroll', this.emitScroll)
|
||||
},
|
||||
methods: {
|
||||
handleScroll(e) {
|
||||
const eventDelta = e.wheelDelta || -e.deltaY * 40
|
||||
const $scrollWrapper = this.scrollWrapper
|
||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
|
||||
},
|
||||
emitScroll() {
|
||||
this.$emit('scroll')
|
||||
},
|
||||
moveToTarget(currentTag) {
|
||||
const $container = this.$refs.scrollContainer.$el
|
||||
const $containerWidth = $container.offsetWidth
|
||||
|
@ -1,318 +1,303 @@
|
||||
<template>
|
||||
<div id="tags-view-container" class="tags-view-container">
|
||||
<scroll-pane ref="scrollPane" class="tags-view-wrapper">
|
||||
<router-link
|
||||
v-for="tag in visitedViews"
|
||||
ref="tag"
|
||||
:key="tag.path"
|
||||
:class="isActive(tag)?'active':''"
|
||||
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||
tag="span"
|
||||
class="tags-view-item"
|
||||
:style="activeStyle(tag)"
|
||||
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
|
||||
@contextmenu.prevent.native="openMenu(tag,$event)"
|
||||
>
|
||||
{{ tag.title }}
|
||||
<span
|
||||
v-if="!isAffix(tag)"
|
||||
class="el-icon-close"
|
||||
@click.prevent.stop="closeSelectedTag(tag)"
|
||||
/>
|
||||
</router-link>
|
||||
</scroll-pane>
|
||||
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
||||
<li @click="refreshSelectedTag(selectedTag)">刷新页面</li>
|
||||
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">关闭当前</li>
|
||||
<li @click="closeOthersTags">关闭其他</li>
|
||||
<li @click="closeAllTags(selectedTag)">关闭所有</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="tags-view-container" class="tags-view-container">
|
||||
<scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
|
||||
<router-link
|
||||
v-for="tag in visitedViews"
|
||||
ref="tag"
|
||||
:key="tag.path"
|
||||
:class="isActive(tag)?'active':''"
|
||||
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||
tag="span"
|
||||
class="tags-view-item"
|
||||
:style="activeStyle(tag)"
|
||||
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
|
||||
@contextmenu.prevent.native="openMenu(tag,$event)"
|
||||
>
|
||||
{{ tag.title }}
|
||||
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
||||
</router-link>
|
||||
</scroll-pane>
|
||||
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
||||
<li @click="refreshSelectedTag(selectedTag)">刷新页面</li>
|
||||
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">关闭当前</li>
|
||||
<li @click="closeOthersTags">关闭其他</li>
|
||||
<li @click="closeAllTags(selectedTag)">关闭所有</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ScrollPane from "./ScrollPane";
|
||||
import path from "path";
|
||||
import ScrollPane from './ScrollPane'
|
||||
import path from 'path'
|
||||
|
||||
export default {
|
||||
components: { ScrollPane },
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
top: 0,
|
||||
left: 0,
|
||||
selectedTag: {},
|
||||
affixTags: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
visitedViews() {
|
||||
return this.$store.state.tagsView.visitedViews;
|
||||
},
|
||||
routes() {
|
||||
return this.$store.state.permission.routes;
|
||||
},
|
||||
theme() {
|
||||
return this.$store.state.settings.theme;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.addTags();
|
||||
this.moveToCurrentTag();
|
||||
},
|
||||
visible(value) {
|
||||
if (value) {
|
||||
document.body.addEventListener("click", this.closeMenu);
|
||||
} else {
|
||||
document.body.removeEventListener("click", this.closeMenu);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initTags();
|
||||
this.addTags();
|
||||
},
|
||||
methods: {
|
||||
isActive(route) {
|
||||
return route.path === this.$route.path;
|
||||
},
|
||||
activeStyle(tag) {
|
||||
if (!this.isActive(tag)) return {};
|
||||
return {
|
||||
"background-color": this.theme,
|
||||
"border-color": this.theme
|
||||
};
|
||||
},
|
||||
isAffix(tag) {
|
||||
return tag.meta && tag.meta.affix;
|
||||
},
|
||||
filterAffixTags(routes, basePath = "/") {
|
||||
let tags = [];
|
||||
routes.forEach(route => {
|
||||
if (route.meta && route.meta.affix) {
|
||||
const tagPath = path.resolve(basePath, route.path);
|
||||
tags.push({
|
||||
fullPath: tagPath,
|
||||
path: tagPath,
|
||||
name: route.name,
|
||||
meta: { ...route.meta }
|
||||
});
|
||||
}
|
||||
if (route.children) {
|
||||
const tempTags = this.filterAffixTags(
|
||||
route.children,
|
||||
route.path
|
||||
);
|
||||
if (tempTags.length >= 1) {
|
||||
tags = [...tags, ...tempTags];
|
||||
}
|
||||
}
|
||||
});
|
||||
return tags;
|
||||
},
|
||||
initTags() {
|
||||
const affixTags = (this.affixTags = this.filterAffixTags(
|
||||
this.routes
|
||||
));
|
||||
for (const tag of affixTags) {
|
||||
// Must have tag name
|
||||
if (tag.name) {
|
||||
this.$store.dispatch("tagsView/addVisitedView", tag);
|
||||
}
|
||||
}
|
||||
},
|
||||
addTags() {
|
||||
const { name } = this.$route;
|
||||
if (name) {
|
||||
this.$store.dispatch("tagsView/addView", this.$route);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
moveToCurrentTag() {
|
||||
const tags = this.$refs.tag;
|
||||
this.$nextTick(() => {
|
||||
for (const tag of tags) {
|
||||
if (tag.to.path === this.$route.path) {
|
||||
this.$refs.scrollPane.moveToTarget(tag);
|
||||
// when query is different then update
|
||||
if (tag.to.fullPath !== this.$route.fullPath) {
|
||||
this.$store.dispatch(
|
||||
"tagsView/updateVisitedView",
|
||||
this.$route
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
refreshSelectedTag(view) {
|
||||
this.$store.dispatch("tagsView/delCachedView", view).then(() => {
|
||||
const { fullPath } = view;
|
||||
this.$nextTick(() => {
|
||||
this.$router.replace({
|
||||
path: "/redirect" + fullPath
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
closeSelectedTag(view) {
|
||||
this.$store
|
||||
.dispatch("tagsView/delView", view)
|
||||
.then(({ visitedViews }) => {
|
||||
if (this.isActive(view)) {
|
||||
this.toLastView(visitedViews, view);
|
||||
}
|
||||
});
|
||||
},
|
||||
closeOthersTags() {
|
||||
this.$router.push(this.selectedTag);
|
||||
this.$store
|
||||
.dispatch("tagsView/delOthersViews", this.selectedTag)
|
||||
.then(() => {
|
||||
this.moveToCurrentTag();
|
||||
});
|
||||
},
|
||||
closeAllTags(view) {
|
||||
this.$store
|
||||
.dispatch("tagsView/delAllViews")
|
||||
.then(({ visitedViews }) => {
|
||||
if (this.affixTags.some(tag => tag.path === view.path)) {
|
||||
return;
|
||||
}
|
||||
this.toLastView(visitedViews, view);
|
||||
});
|
||||
},
|
||||
toLastView(visitedViews, view) {
|
||||
const latestView = visitedViews.slice(-1)[0];
|
||||
if (latestView) {
|
||||
this.$router.push(latestView.fullPath);
|
||||
} else {
|
||||
// now the default is to redirect to the home page if there is no tags-view,
|
||||
// you can adjust it according to your needs.
|
||||
if (view.name === "Dashboard") {
|
||||
// to reload home page
|
||||
this.$router.replace({ path: "/redirect" + view.fullPath });
|
||||
} else {
|
||||
this.$router.push("/");
|
||||
}
|
||||
}
|
||||
},
|
||||
openMenu(tag, e) {
|
||||
const menuMinWidth = 105;
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left; // container margin left
|
||||
const offsetWidth = this.$el.offsetWidth; // container width
|
||||
const maxLeft = offsetWidth - menuMinWidth; // left boundary
|
||||
const left = e.clientX - offsetLeft + 15; // 15: margin right
|
||||
|
||||
if (left > maxLeft) {
|
||||
this.left = maxLeft;
|
||||
} else {
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
this.top = e.clientY;
|
||||
this.visible = true;
|
||||
this.selectedTag = tag;
|
||||
},
|
||||
closeMenu() {
|
||||
this.visible = false;
|
||||
}
|
||||
components: { ScrollPane },
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
top: 0,
|
||||
left: 0,
|
||||
selectedTag: {},
|
||||
affixTags: []
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
visitedViews() {
|
||||
return this.$store.state.tagsView.visitedViews
|
||||
},
|
||||
routes() {
|
||||
return this.$store.state.permission.routes
|
||||
},
|
||||
theme() {
|
||||
return this.$store.state.settings.theme;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.addTags()
|
||||
this.moveToCurrentTag()
|
||||
},
|
||||
visible(value) {
|
||||
if (value) {
|
||||
document.body.addEventListener('click', this.closeMenu)
|
||||
} else {
|
||||
document.body.removeEventListener('click', this.closeMenu)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initTags()
|
||||
this.addTags()
|
||||
},
|
||||
methods: {
|
||||
isActive(route) {
|
||||
return route.path === this.$route.path
|
||||
},
|
||||
activeStyle(tag) {
|
||||
if (!this.isActive(tag)) return {};
|
||||
return {
|
||||
"background-color": this.theme,
|
||||
"border-color": this.theme
|
||||
};
|
||||
},
|
||||
isAffix(tag) {
|
||||
return tag.meta && tag.meta.affix
|
||||
},
|
||||
filterAffixTags(routes, basePath = '/') {
|
||||
let tags = []
|
||||
routes.forEach(route => {
|
||||
if (route.meta && route.meta.affix) {
|
||||
const tagPath = path.resolve(basePath, route.path)
|
||||
tags.push({
|
||||
fullPath: tagPath,
|
||||
path: tagPath,
|
||||
name: route.name,
|
||||
meta: { ...route.meta }
|
||||
})
|
||||
}
|
||||
if (route.children) {
|
||||
const tempTags = this.filterAffixTags(route.children, route.path)
|
||||
if (tempTags.length >= 1) {
|
||||
tags = [...tags, ...tempTags]
|
||||
}
|
||||
}
|
||||
})
|
||||
return tags
|
||||
},
|
||||
initTags() {
|
||||
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
|
||||
for (const tag of affixTags) {
|
||||
// Must have tag name
|
||||
if (tag.name) {
|
||||
this.$store.dispatch('tagsView/addVisitedView', tag)
|
||||
}
|
||||
}
|
||||
},
|
||||
addTags() {
|
||||
const { name } = this.$route
|
||||
if (name) {
|
||||
this.$store.dispatch('tagsView/addView', this.$route)
|
||||
}
|
||||
return false
|
||||
},
|
||||
moveToCurrentTag() {
|
||||
const tags = this.$refs.tag
|
||||
this.$nextTick(() => {
|
||||
for (const tag of tags) {
|
||||
if (tag.to.path === this.$route.path) {
|
||||
this.$refs.scrollPane.moveToTarget(tag)
|
||||
// when query is different then update
|
||||
if (tag.to.fullPath !== this.$route.fullPath) {
|
||||
this.$store.dispatch('tagsView/updateVisitedView', this.$route)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
refreshSelectedTag(view) {
|
||||
this.$store.dispatch('tagsView/delCachedView', view).then(() => {
|
||||
const { fullPath } = view
|
||||
this.$nextTick(() => {
|
||||
this.$router.replace({
|
||||
path: '/redirect' + fullPath
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
closeSelectedTag(view) {
|
||||
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
|
||||
if (this.isActive(view)) {
|
||||
this.toLastView(visitedViews, view)
|
||||
}
|
||||
})
|
||||
},
|
||||
closeOthersTags() {
|
||||
this.$router.push(this.selectedTag)
|
||||
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
|
||||
this.moveToCurrentTag()
|
||||
})
|
||||
},
|
||||
closeAllTags(view) {
|
||||
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
|
||||
if (this.affixTags.some(tag => tag.path === view.path)) {
|
||||
return
|
||||
}
|
||||
this.toLastView(visitedViews, view)
|
||||
})
|
||||
},
|
||||
toLastView(visitedViews, view) {
|
||||
const latestView = visitedViews.slice(-1)[0]
|
||||
if (latestView) {
|
||||
this.$router.push(latestView.fullPath)
|
||||
} else {
|
||||
// now the default is to redirect to the home page if there is no tags-view,
|
||||
// you can adjust it according to your needs.
|
||||
if (view.name === 'Dashboard') {
|
||||
// to reload home page
|
||||
this.$router.replace({ path: '/redirect' + view.fullPath })
|
||||
} else {
|
||||
this.$router.push('/')
|
||||
}
|
||||
}
|
||||
},
|
||||
openMenu(tag, e) {
|
||||
const menuMinWidth = 105
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
|
||||
const offsetWidth = this.$el.offsetWidth // container width
|
||||
const maxLeft = offsetWidth - menuMinWidth // left boundary
|
||||
const left = e.clientX - offsetLeft + 15 // 15: margin right
|
||||
|
||||
if (left > maxLeft) {
|
||||
this.left = maxLeft
|
||||
} else {
|
||||
this.left = left
|
||||
}
|
||||
|
||||
this.top = e.clientY
|
||||
this.visible = true
|
||||
this.selectedTag = tag
|
||||
},
|
||||
closeMenu() {
|
||||
this.visible = false
|
||||
},
|
||||
handleScroll() {
|
||||
this.closeMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tags-view-container {
|
||||
height: 34px;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #d8dce5;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
|
||||
.tags-view-wrapper {
|
||||
.tags-view-item {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
border: 1px solid #d8dce5;
|
||||
color: #495060;
|
||||
background: #fff;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
margin-left: 5px;
|
||||
margin-top: 4px;
|
||||
&:first-of-type {
|
||||
margin-left: 15px;
|
||||
}
|
||||
&:last-of-type {
|
||||
margin-right: 15px;
|
||||
}
|
||||
&.active {
|
||||
background-color: #42b983;
|
||||
color: #fff;
|
||||
border-color: #42b983;
|
||||
&::before {
|
||||
content: '';
|
||||
background: #fff;
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.contextmenu {
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #d8dce5;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
|
||||
.tags-view-wrapper {
|
||||
.tags-view-item {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
border: 1px solid #d8dce5;
|
||||
color: #495060;
|
||||
background: #fff;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
margin-left: 5px;
|
||||
margin-top: 4px;
|
||||
&:first-of-type {
|
||||
margin-left: 15px;
|
||||
}
|
||||
&:last-of-type {
|
||||
margin-right: 15px;
|
||||
}
|
||||
&.active {
|
||||
background-color: #42b983;
|
||||
color: #fff;
|
||||
border-color: #42b983;
|
||||
&::before {
|
||||
content: "";
|
||||
background: #fff;
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.contextmenu {
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
z-index: 3000;
|
||||
position: absolute;
|
||||
list-style-type: none;
|
||||
padding: 5px 0;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 7px 16px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
z-index: 3000;
|
||||
position: absolute;
|
||||
list-style-type: none;
|
||||
padding: 5px 0;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 7px 16px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
//reset element css of el-icon-close
|
||||
.tags-view-wrapper {
|
||||
.tags-view-item {
|
||||
.el-icon-close {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: 2px;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
transform-origin: 100% 50%;
|
||||
&:before {
|
||||
transform: scale(0.6);
|
||||
display: inline-block;
|
||||
vertical-align: -3px;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #b4bccc;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.tags-view-item {
|
||||
.el-icon-close {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: 2px;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1);
|
||||
transform-origin: 100% 50%;
|
||||
&:before {
|
||||
transform: scale(.6);
|
||||
display: inline-block;
|
||||
vertical-align: -3px;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #b4bccc;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -438,8 +438,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -448,8 +446,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -88,6 +88,15 @@
|
||||
v-hasPermi="['system:config:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
icon="el-icon-refresh"
|
||||
size="mini"
|
||||
@click="handleClearCache"
|
||||
v-hasPermi="['system:config:remove']"
|
||||
>清理缓存</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
|
||||
@ -165,7 +174,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listConfig, getConfig, delConfig, addConfig, updateConfig, exportConfig } from "@/api/system/config";
|
||||
import { listConfig, getConfig, delConfig, addConfig, updateConfig, exportConfig, clearCache } from "@/api/system/config";
|
||||
|
||||
export default {
|
||||
name: "Config",
|
||||
@ -296,8 +305,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -306,8 +313,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -340,6 +345,14 @@ export default {
|
||||
}).then(response => {
|
||||
this.download(response.msg);
|
||||
}).catch(function() {});
|
||||
},
|
||||
/** 清理缓存按钮操作 */
|
||||
handleClearCache() {
|
||||
clearCache().then(response => {
|
||||
if (response.code === 200) {
|
||||
this.msgSuccess("清理成功");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -281,8 +281,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -291,8 +289,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -305,8 +305,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -315,8 +313,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -94,6 +94,15 @@
|
||||
v-hasPermi="['system:dict:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
icon="el-icon-refresh"
|
||||
size="mini"
|
||||
@click="handleClearCache"
|
||||
v-hasPermi="['system:dict:remove']"
|
||||
>清理缓存</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange">
|
||||
@ -173,7 +182,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listType, getType, delType, addType, updateType, exportType } from "@/api/system/dict/type";
|
||||
import { listType, getType, delType, addType, updateType, exportType, clearCache } from "@/api/system/dict/type";
|
||||
|
||||
export default {
|
||||
name: "Dict",
|
||||
@ -300,8 +309,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -310,8 +317,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -344,6 +349,14 @@ export default {
|
||||
}).then(response => {
|
||||
this.download(response.msg);
|
||||
}).catch(function() {});
|
||||
},
|
||||
/** 清理缓存按钮操作 */
|
||||
handleClearCache() {
|
||||
clearCache().then(response => {
|
||||
if (response.code === 200) {
|
||||
this.msgSuccess("清理成功");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -340,8 +340,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -350,8 +348,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -308,8 +308,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -318,8 +316,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -277,8 +277,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -287,8 +285,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -482,8 +482,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -493,8 +491,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -510,8 +506,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.openDataScope = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -572,8 +572,6 @@ export default {
|
||||
resetUserPwd(row.userId, value).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.msgSuccess("修改成功,新密码是:" + value);
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
@ -588,8 +586,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -598,8 +594,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -59,8 +59,6 @@ export default {
|
||||
response => {
|
||||
if (response.code === 200) {
|
||||
this.msgSuccess("修改成功");
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -122,8 +122,6 @@ export default {
|
||||
this.open = false;
|
||||
this.options.img = process.env.VUE_APP_BASE_API + response.imgUrl;
|
||||
this.msgSuccess("修改成功");
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
this.$refs.cropper.clearCrop();
|
||||
});
|
||||
|
@ -64,8 +64,6 @@ export default {
|
||||
updateUserProfile(this.user).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.msgSuccess("修改成功");
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -82,12 +82,6 @@ module.exports = {
|
||||
})
|
||||
.end()
|
||||
|
||||
config
|
||||
// https://webpack.js.org/configuration/devtool/#development
|
||||
.when(process.env.NODE_ENV === 'development',
|
||||
config => config.devtool('cheap-source-map')
|
||||
)
|
||||
|
||||
config
|
||||
.when(process.env.NODE_ENV !== 'development',
|
||||
config => {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>2.2.0</version>
|
||||
<version>2.3.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>ruoyi</name>
|
||||
@ -25,7 +25,7 @@
|
||||
<java.version>1.8</java.version>
|
||||
<mybatis.spring.boot.starter.version>1.3.2</mybatis.spring.boot.starter.version>
|
||||
<pagehelper.spring.boot.starter.version>1.2.5</pagehelper.spring.boot.starter.version>
|
||||
<fastjson.version>1.2.68</fastjson.version>
|
||||
<fastjson.version>1.2.70</fastjson.version>
|
||||
<druid.version>1.1.14</druid.version>
|
||||
<commons.io.version>2.5</commons.io.version>
|
||||
<commons.fileupload.version>1.3.3</commons.fileupload.version>
|
||||
|
@ -109,6 +109,16 @@ public class Constants
|
||||
*/
|
||||
public static final String JWT_AUTHORITIES = "authorities";
|
||||
|
||||
/**
|
||||
* 参数管理 cache key
|
||||
*/
|
||||
public static final String SYS_CONFIG_KEY = "sys_config:";
|
||||
|
||||
/**
|
||||
* 字典管理 cache key
|
||||
*/
|
||||
public static final String SYS_DICT_KEY = "sys_dict:";
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
|
64
ruoyi/src/main/java/com/ruoyi/common/utils/DictUtils.java
Normal file
64
ruoyi/src/main/java/com/ruoyi/common/utils/DictUtils.java
Normal file
@ -0,0 +1,64 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
import com.ruoyi.framework.redis.RedisCache;
|
||||
import com.ruoyi.project.system.domain.SysDictData;
|
||||
|
||||
/**
|
||||
* 字典工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class DictUtils
|
||||
{
|
||||
/**
|
||||
* 设置字典缓存
|
||||
*
|
||||
* @param key 参数键
|
||||
* @param dictDatas 字典数据列表
|
||||
*/
|
||||
public static void setDictCache(String key, List<SysDictData> dictDatas)
|
||||
{
|
||||
SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典缓存
|
||||
*
|
||||
* @param key 参数键
|
||||
* @return dictDatas 字典数据列表
|
||||
*/
|
||||
public static List<SysDictData> getDictCache(String key)
|
||||
{
|
||||
Object cacheObj = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
|
||||
if (StringUtils.isNotNull(cacheObj))
|
||||
{
|
||||
List<SysDictData> DictDatas = StringUtils.cast(cacheObj);
|
||||
return DictDatas;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空字典缓存
|
||||
*/
|
||||
public static void clearDictCache()
|
||||
{
|
||||
Collection<String> keys = SpringUtils.getBean(RedisCache.class).keys(Constants.SYS_DICT_KEY + "*");
|
||||
SpringUtils.getBean(RedisCache.class).deleteObject(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置cache key
|
||||
*
|
||||
* @param configKey 参数键
|
||||
* @return 缓存键key
|
||||
*/
|
||||
public static String getCacheKey(String configKey)
|
||||
{
|
||||
return Constants.SYS_DICT_KEY + configKey;
|
||||
}
|
||||
}
|
@ -450,4 +450,10 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T cast(Object obj)
|
||||
{
|
||||
return (T) obj;
|
||||
}
|
||||
}
|
@ -118,4 +118,16 @@ public class SysConfigController extends BaseController
|
||||
{
|
||||
return toAjax(configService.deleteConfigByIds(configIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:config:remove')")
|
||||
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
|
||||
@DeleteMapping("/clearCache")
|
||||
public AjaxResult clearCache()
|
||||
{
|
||||
configService.clearCache();
|
||||
return AjaxResult.success();
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import com.ruoyi.framework.web.domain.AjaxResult;
|
||||
import com.ruoyi.framework.web.page.TableDataInfo;
|
||||
import com.ruoyi.project.system.domain.SysDictData;
|
||||
import com.ruoyi.project.system.service.ISysDictDataService;
|
||||
import com.ruoyi.project.system.service.ISysDictTypeService;
|
||||
|
||||
/**
|
||||
* 数据字典信息
|
||||
@ -34,6 +35,9 @@ public class SysDictDataController extends BaseController
|
||||
@Autowired
|
||||
private ISysDictDataService dictDataService;
|
||||
|
||||
@Autowired
|
||||
private ISysDictTypeService dictTypeService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysDictData dictData)
|
||||
@ -66,10 +70,10 @@ public class SysDictDataController extends BaseController
|
||||
/**
|
||||
* 根据字典类型查询字典数据信息
|
||||
*/
|
||||
@GetMapping(value = "/dictType/{dictType}")
|
||||
@GetMapping(value = "/type/{dictType}")
|
||||
public AjaxResult dictType(@PathVariable String dictType)
|
||||
{
|
||||
return AjaxResult.success(dictDataService.selectDictDataByType(dictType));
|
||||
return AjaxResult.success(dictTypeService.selectDictDataByType(dictType));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,6 +107,18 @@ public class SysDictTypeController extends BaseController
|
||||
return toAjax(dictTypeService.deleteDictTypeByIds(dictIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
|
||||
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
|
||||
@DeleteMapping("/clearCache")
|
||||
public AjaxResult clearCache()
|
||||
{
|
||||
dictTypeService.clearCache();
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典选择框列表
|
||||
*/
|
||||
|
@ -50,14 +50,6 @@ public interface ISysConfigService
|
||||
*/
|
||||
public int updateConfig(SysConfig config);
|
||||
|
||||
/**
|
||||
* 删除参数配置信息
|
||||
*
|
||||
* @param configId 参数ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteConfigById(Long configId);
|
||||
|
||||
/**
|
||||
* 批量删除参数信息
|
||||
*
|
||||
@ -66,6 +58,11 @@ public interface ISysConfigService
|
||||
*/
|
||||
public int deleteConfigByIds(Long[] configIds);
|
||||
|
||||
/**
|
||||
* 清空缓存数据
|
||||
*/
|
||||
public void clearCache();
|
||||
|
||||
/**
|
||||
* 校验参数键名是否唯一
|
||||
*
|
||||
|
@ -18,14 +18,6 @@ public interface ISysDictDataService
|
||||
*/
|
||||
public List<SysDictData> selectDictDataList(SysDictData dictData);
|
||||
|
||||
/**
|
||||
* 根据字典类型查询字典数据
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典数据集合信息
|
||||
*/
|
||||
public List<SysDictData> selectDictDataByType(String dictType);
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典键值查询字典数据信息
|
||||
*
|
||||
@ -43,14 +35,6 @@ public interface ISysDictDataService
|
||||
*/
|
||||
public SysDictData selectDictDataById(Long dictCode);
|
||||
|
||||
/**
|
||||
* 通过字典ID删除字典数据信息
|
||||
*
|
||||
* @param dictCode 字典数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteDictDataById(Long dictCode);
|
||||
|
||||
/**
|
||||
* 批量删除字典数据信息
|
||||
*
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.ruoyi.project.system.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.project.system.domain.SysDictData;
|
||||
import com.ruoyi.project.system.domain.SysDictType;
|
||||
|
||||
/**
|
||||
@ -25,6 +26,14 @@ public interface ISysDictTypeService
|
||||
*/
|
||||
public List<SysDictType> selectDictTypeAll();
|
||||
|
||||
/**
|
||||
* 根据字典类型查询字典数据
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典数据集合信息
|
||||
*/
|
||||
public List<SysDictData> selectDictDataByType(String dictType);
|
||||
|
||||
/**
|
||||
* 根据字典类型ID查询信息
|
||||
*
|
||||
@ -41,14 +50,6 @@ public interface ISysDictTypeService
|
||||
*/
|
||||
public SysDictType selectDictTypeByType(String dictType);
|
||||
|
||||
/**
|
||||
* 通过字典ID删除字典信息
|
||||
*
|
||||
* @param dictId 字典ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteDictTypeById(Long dictId);
|
||||
|
||||
/**
|
||||
* 批量删除字典信息
|
||||
*
|
||||
@ -57,6 +58,11 @@ public interface ISysDictTypeService
|
||||
*/
|
||||
public int deleteDictTypeByIds(Long[] dictIds);
|
||||
|
||||
/**
|
||||
* 清空缓存数据
|
||||
*/
|
||||
public void clearCache();
|
||||
|
||||
/**
|
||||
* 新增保存字典类型信息
|
||||
*
|
||||
|
@ -1,10 +1,15 @@
|
||||
package com.ruoyi.project.system.service.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.core.text.Convert;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.framework.redis.RedisCache;
|
||||
import com.ruoyi.project.system.domain.SysConfig;
|
||||
import com.ruoyi.project.system.mapper.SysConfigMapper;
|
||||
import com.ruoyi.project.system.service.ISysConfigService;
|
||||
@ -20,6 +25,22 @@ public class SysConfigServiceImpl implements ISysConfigService
|
||||
@Autowired
|
||||
private SysConfigMapper configMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
/**
|
||||
* 项目启动时,初始化参数到缓存
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init()
|
||||
{
|
||||
List<SysConfig> configsList = configMapper.selectConfigList(new SysConfig());
|
||||
for (SysConfig config : configsList)
|
||||
{
|
||||
redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询参数配置信息
|
||||
*
|
||||
@ -43,10 +64,20 @@ public class SysConfigServiceImpl implements ISysConfigService
|
||||
@Override
|
||||
public String selectConfigByKey(String configKey)
|
||||
{
|
||||
String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey)));
|
||||
if (StringUtils.isNotEmpty(configValue))
|
||||
{
|
||||
return configValue;
|
||||
}
|
||||
SysConfig config = new SysConfig();
|
||||
config.setConfigKey(configKey);
|
||||
SysConfig retConfig = configMapper.selectConfig(config);
|
||||
return StringUtils.isNotNull(retConfig) ? retConfig.getConfigValue() : "";
|
||||
if (StringUtils.isNotNull(retConfig))
|
||||
{
|
||||
redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue());
|
||||
return retConfig.getConfigValue();
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,7 +101,12 @@ public class SysConfigServiceImpl implements ISysConfigService
|
||||
@Override
|
||||
public int insertConfig(SysConfig config)
|
||||
{
|
||||
return configMapper.insertConfig(config);
|
||||
int row = configMapper.insertConfig(config);
|
||||
if (row > 0)
|
||||
{
|
||||
redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,19 +118,12 @@ public class SysConfigServiceImpl implements ISysConfigService
|
||||
@Override
|
||||
public int updateConfig(SysConfig config)
|
||||
{
|
||||
return configMapper.updateConfig(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除参数配置信息
|
||||
*
|
||||
* @param configId 参数ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteConfigById(Long configId)
|
||||
{
|
||||
return configMapper.deleteConfigById(configId);
|
||||
int row = configMapper.updateConfig(config);
|
||||
if (row > 0)
|
||||
{
|
||||
redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,7 +135,22 @@ public class SysConfigServiceImpl implements ISysConfigService
|
||||
@Override
|
||||
public int deleteConfigByIds(Long[] configIds)
|
||||
{
|
||||
return configMapper.deleteConfigByIds(configIds);
|
||||
int count = configMapper.deleteConfigByIds(configIds);
|
||||
if (count > 0)
|
||||
{
|
||||
Collection<String> keys = redisCache.keys(Constants.SYS_CONFIG_KEY + "*");
|
||||
redisCache.deleteObject(keys);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存数据
|
||||
*/
|
||||
public void clearCache()
|
||||
{
|
||||
Collection<String> keys = redisCache.keys(Constants.SYS_CONFIG_KEY + "*");
|
||||
redisCache.deleteObject(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,4 +170,15 @@ public class SysConfigServiceImpl implements ISysConfigService
|
||||
}
|
||||
return UserConstants.UNIQUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置cache key
|
||||
*
|
||||
* @param configKey 参数键
|
||||
* @return 缓存键key
|
||||
*/
|
||||
private String getCacheKey(String configKey)
|
||||
{
|
||||
return Constants.SYS_CONFIG_KEY + configKey;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.ruoyi.project.system.service.impl;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.common.utils.DictUtils;
|
||||
import com.ruoyi.project.system.domain.SysDictData;
|
||||
import com.ruoyi.project.system.mapper.SysDictDataMapper;
|
||||
import com.ruoyi.project.system.service.ISysDictDataService;
|
||||
@ -30,18 +31,6 @@ public class SysDictDataServiceImpl implements ISysDictDataService
|
||||
return dictDataMapper.selectDictDataList(dictData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型查询字典数据
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典数据集合信息
|
||||
*/
|
||||
@Override
|
||||
public List<SysDictData> selectDictDataByType(String dictType)
|
||||
{
|
||||
return dictDataMapper.selectDictDataByType(dictType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典键值查询字典数据信息
|
||||
*
|
||||
@ -67,18 +56,6 @@ public class SysDictDataServiceImpl implements ISysDictDataService
|
||||
return dictDataMapper.selectDictDataById(dictCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过字典ID删除字典数据信息
|
||||
*
|
||||
* @param dictCode 字典数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteDictDataById(Long dictCode)
|
||||
{
|
||||
return dictDataMapper.deleteDictDataById(dictCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除字典数据信息
|
||||
*
|
||||
@ -87,7 +64,12 @@ public class SysDictDataServiceImpl implements ISysDictDataService
|
||||
*/
|
||||
public int deleteDictDataByIds(Long[] dictCodes)
|
||||
{
|
||||
return dictDataMapper.deleteDictDataByIds(dictCodes);
|
||||
int row = dictDataMapper.deleteDictDataByIds(dictCodes);
|
||||
if (row > 0)
|
||||
{
|
||||
DictUtils.clearDictCache();
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,7 +81,12 @@ public class SysDictDataServiceImpl implements ISysDictDataService
|
||||
@Override
|
||||
public int insertDictData(SysDictData dictData)
|
||||
{
|
||||
return dictDataMapper.insertDictData(dictData);
|
||||
int row = dictDataMapper.insertDictData(dictData);
|
||||
if (row > 0)
|
||||
{
|
||||
DictUtils.clearDictCache();
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,6 +98,11 @@ public class SysDictDataServiceImpl implements ISysDictDataService
|
||||
@Override
|
||||
public int updateDictData(SysDictData dictData)
|
||||
{
|
||||
return dictDataMapper.updateDictData(dictData);
|
||||
int row = dictDataMapper.updateDictData(dictData);
|
||||
if (row > 0)
|
||||
{
|
||||
DictUtils.clearDictCache();
|
||||
}
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
package com.ruoyi.project.system.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.exception.CustomException;
|
||||
import com.ruoyi.common.utils.DictUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.project.system.domain.SysDictData;
|
||||
import com.ruoyi.project.system.domain.SysDictType;
|
||||
import com.ruoyi.project.system.mapper.SysDictDataMapper;
|
||||
import com.ruoyi.project.system.mapper.SysDictTypeMapper;
|
||||
@ -25,6 +29,20 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
|
||||
@Autowired
|
||||
private SysDictDataMapper dictDataMapper;
|
||||
|
||||
/**
|
||||
* 项目启动时,初始化字典到缓存
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init()
|
||||
{
|
||||
List<SysDictType> dictTypeList = dictTypeMapper.selectDictTypeAll();
|
||||
for (SysDictType dictType : dictTypeList)
|
||||
{
|
||||
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dictType.getDictType());
|
||||
DictUtils.setDictCache(dictType.getDictType(), dictDatas);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件分页查询字典类型
|
||||
*
|
||||
@ -48,6 +66,29 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
|
||||
return dictTypeMapper.selectDictTypeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型查询字典数据
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典数据集合信息
|
||||
*/
|
||||
@Override
|
||||
public List<SysDictData> selectDictDataByType(String dictType)
|
||||
{
|
||||
List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
|
||||
if (StringUtils.isNotNull(dictDatas))
|
||||
{
|
||||
return dictDatas;
|
||||
}
|
||||
dictDatas = dictDataMapper.selectDictDataByType(dictType);
|
||||
if (StringUtils.isNotNull(dictDatas))
|
||||
{
|
||||
DictUtils.setDictCache(dictType, dictDatas);
|
||||
return dictDatas;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型ID查询信息
|
||||
*
|
||||
@ -71,18 +112,6 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
|
||||
return dictTypeMapper.selectDictTypeByType(dictType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过字典ID删除字典信息
|
||||
*
|
||||
* @param dictId 字典ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteDictTypeById(Long dictId)
|
||||
{
|
||||
return dictTypeMapper.deleteDictTypeById(dictId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除字典类型信息
|
||||
*
|
||||
@ -91,7 +120,28 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
|
||||
*/
|
||||
public int deleteDictTypeByIds(Long[] dictIds)
|
||||
{
|
||||
return dictTypeMapper.deleteDictTypeByIds(dictIds);
|
||||
for (Long dictId : dictIds)
|
||||
{
|
||||
SysDictType dictType = selectDictTypeById(dictId);
|
||||
if (dictDataMapper.countDictDataByType(dictType.getDictType()) > 0)
|
||||
{
|
||||
throw new CustomException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
|
||||
}
|
||||
}
|
||||
int count = dictTypeMapper.deleteDictTypeByIds(dictIds);
|
||||
if (count > 0)
|
||||
{
|
||||
DictUtils.clearDictCache();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存数据
|
||||
*/
|
||||
public void clearCache()
|
||||
{
|
||||
DictUtils.clearDictCache();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,7 +153,12 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
|
||||
@Override
|
||||
public int insertDictType(SysDictType dictType)
|
||||
{
|
||||
return dictTypeMapper.insertDictType(dictType);
|
||||
int row = dictTypeMapper.insertDictType(dictType);
|
||||
if (row > 0)
|
||||
{
|
||||
DictUtils.clearDictCache();
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,7 +173,12 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
|
||||
{
|
||||
SysDictType oldDict = dictTypeMapper.selectDictTypeById(dictType.getDictId());
|
||||
dictDataMapper.updateDictDataType(oldDict.getDictType(), dictType.getDictType());
|
||||
return dictTypeMapper.updateDictType(dictType);
|
||||
int row = dictTypeMapper.updateDictType(dictType);
|
||||
if (row > 0)
|
||||
{
|
||||
DictUtils.clearDictCache();
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,7 +140,7 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
{
|
||||
RouterVo router = new RouterVo();
|
||||
router.setHidden("1".equals(menu.getVisible()));
|
||||
router.setName(StringUtils.capitalize(menu.getPath()));
|
||||
router.setName(getRouteName(menu));
|
||||
router.setPath(getRouterPath(menu));
|
||||
router.setComponent(getComponent(menu));
|
||||
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
|
||||
@ -299,6 +299,23 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
return UserConstants.UNIQUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路由名称
|
||||
*
|
||||
* @param menu 菜单信息
|
||||
* @return 路由名称
|
||||
*/
|
||||
public String getRouteName(SysMenu menu)
|
||||
{
|
||||
String routerName = StringUtils.capitalize(menu.getPath());
|
||||
// 非外链并且是一级目录(类型为目录)
|
||||
if (isMeunFrame(menu))
|
||||
{
|
||||
routerName = StringUtils.EMPTY;
|
||||
}
|
||||
return routerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路由地址
|
||||
*
|
||||
|
@ -3,7 +3,7 @@ ruoyi:
|
||||
# 名称
|
||||
name: RuoYi
|
||||
# 版本
|
||||
version: 2.2.0
|
||||
version: 2.3.0
|
||||
# 版权年份
|
||||
copyrightYear: 2019
|
||||
# 实例演示开关
|
||||
|
@ -6,17 +6,17 @@ values('${functionName}', '3', '1', '${businessName}', '${moduleName}/${business
|
||||
SELECT @parentId := LAST_INSERT_ID();
|
||||
|
||||
-- 按钮 SQL
|
||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||
values('${functionName}查询', @parentId, '1', '#', '', 1, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '');
|
||||
|
||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||
values('${functionName}新增', @parentId, '2', '#', '', 1, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '');
|
||||
|
||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||
values('${functionName}修改', @parentId, '3', '#', '', 1, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '');
|
||||
|
||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||
values('${functionName}删除', @parentId, '4', '#', '', 1, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '');
|
||||
|
||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||
values('${functionName}导出', @parentId, '5', '#', '', 1, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '');
|
@ -375,8 +375,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -385,8 +383,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -392,8 +392,6 @@ export default {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -402,8 +400,6 @@ export default {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
} else {
|
||||
this.msgError(response.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user