Merge branch 'master' of https://gitee.com/y_project/RuoYi-Vue
Conflicts: ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java ruoyi-common/src/main/java/com/ruoyi/common/constant/UserConstants.java ruoyi-common/src/main/java/com/ruoyi/common/core/text/CharsetKit.java ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java ruoyi-ui/package.json ruoyi-ui/src/layout/components/AppMain.vue ruoyi-ui/src/layout/components/TagsView/index.vue ruoyi-ui/src/router/index.js ruoyi-ui/src/store/modules/permission.js ruoyi-ui/src/views/system/user/profile/userAvatar.vue sql/ry_20201128.sql
This commit is contained in:
commit
ce438f182a
2
pom.xml
2
pom.xml
|
@ -43,7 +43,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
<version>2.1.17.RELEASE</version>
|
<version>2.1.18.RELEASE</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class GenConstants
|
||||||
|
|
||||||
/** 数据库数字类型 */
|
/** 数据库数字类型 */
|
||||||
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
|
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
|
||||||
"bit", "bigint", "float", "float", "double", "decimal" };
|
"bit", "bigint", "float", "double", "decimal" };
|
||||||
|
|
||||||
/** 页面不需要编辑字段 */
|
/** 页面不需要编辑字段 */
|
||||||
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
|
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
|
||||||
|
|
|
@ -54,6 +54,9 @@ public class UserConstants
|
||||||
/** Layout组件标识 */
|
/** Layout组件标识 */
|
||||||
public final static String LAYOUT = "Layout";
|
public final static String LAYOUT = "Layout";
|
||||||
|
|
||||||
|
/** ParentView组件标识 */
|
||||||
|
public final static String PARENT_VIEW = "ParentView";
|
||||||
|
|
||||||
/** 校验返回结果码 */
|
/** 校验返回结果码 */
|
||||||
public final static String UNIQUE = "0";
|
public final static String UNIQUE = "0";
|
||||||
public final static String NOT_UNIQUE = "1";
|
public final static String NOT_UNIQUE = "1";
|
||||||
|
|
|
@ -274,6 +274,10 @@ public class ExcelUtil<T>
|
||||||
val = DateUtil.getJavaDate((Double) val);
|
val = DateUtil.getJavaDate((Double) val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (Boolean.TYPE == fieldType || Boolean.class == fieldType)
|
||||||
|
{
|
||||||
|
val = Convert.toBool(val, false);
|
||||||
|
}
|
||||||
if (StringUtils.isNotNull(fieldType))
|
if (StringUtils.isNotNull(fieldType))
|
||||||
{
|
{
|
||||||
Excel attr = field.getAnnotation(Excel.class);
|
Excel attr = field.getAnnotation(Excel.class);
|
||||||
|
|
|
@ -204,6 +204,10 @@ public class ReflectUtils
|
||||||
args[i] = DateUtil.getJavaDate((Double) args[i]);
|
args[i] = DateUtil.getJavaDate((Double) args[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (cs[i] == boolean.class || cs[i] == Boolean.class)
|
||||||
|
{
|
||||||
|
args[i] = Convert.toBool(args[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (E) method.invoke(obj, args);
|
return (E) method.invoke(obj, args);
|
||||||
|
|
|
@ -364,6 +364,10 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||||
{
|
{
|
||||||
component = menu.getComponent();
|
component = menu.getComponent();
|
||||||
}
|
}
|
||||||
|
else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu))
|
||||||
|
{
|
||||||
|
component = UserConstants.PARENT_VIEW;
|
||||||
|
}
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,6 +383,17 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||||
&& menu.getIsFrame().equals(UserConstants.NO_FRAME);
|
&& menu.getIsFrame().equals(UserConstants.NO_FRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为parent_view组件
|
||||||
|
*
|
||||||
|
* @param menu 菜单信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public boolean isParentView(SysMenu menu)
|
||||||
|
{
|
||||||
|
return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据父节点的ID获取所有子节点
|
* 根据父节点的ID获取所有子节点
|
||||||
*
|
*
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
"clipboard": "2.0.4",
|
"clipboard": "2.0.4",
|
||||||
"core-js": "3.6.5",
|
"core-js": "3.6.5",
|
||||||
"echarts": "4.2.1",
|
"echarts": "4.2.1",
|
||||||
"element-ui": "2.13.2",
|
"element-ui": "2.14.1",
|
||||||
"file-saver": "2.0.1",
|
"file-saver": "2.0.1",
|
||||||
"js-beautify": "1.10.2",
|
"js-beautify": "1.10.2",
|
||||||
"fuse.js": "3.4.4",
|
"fuse.js": "3.4.4",
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
<!-- @author ruoyi 20201128 支持三级以上菜单缓存 -->
|
||||||
<template>
|
<template>
|
||||||
<section class="app-main">
|
<section class="app-main">
|
||||||
<transition name="fade-transform" mode="out-in">
|
<transition name="fade-transform" mode="out-in">
|
||||||
<keep-alive :include="cachedViews">
|
<keep-alive :max="20" :exclude="notCacheName">
|
||||||
<router-view :key="key" />
|
<router-view :key="key" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
|
@ -9,17 +10,119 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Global from "@/layout/components/global.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AppMain',
|
name: 'AppMain',
|
||||||
computed: {
|
computed: {
|
||||||
cachedViews() {
|
notCacheName() {
|
||||||
return this.$store.state.tagsView.cachedViews
|
var visitedViews = this.$store.state.tagsView.visitedViews;
|
||||||
|
var noCacheViews = [];
|
||||||
|
Object.keys(visitedViews).some((index) => {
|
||||||
|
if (visitedViews[index].meta.noCache) {
|
||||||
|
noCacheViews.push(visitedViews[index].name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return noCacheViews;
|
||||||
},
|
},
|
||||||
key() {
|
key() {
|
||||||
return this.$route.path
|
return this.$route.path;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 关闭标签触发
|
||||||
|
Global.$on("removeCache", (name, view) => {
|
||||||
|
this.removeCache(name, view);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 获取有keep-alive子节点的Vnode
|
||||||
|
getVnode() {
|
||||||
|
// 判断子集非空
|
||||||
|
if (this.$children.length == 0) return false;
|
||||||
|
let vnode;
|
||||||
|
for (let item of this.$children) {
|
||||||
|
// 如果data中有key则代表找到了keep-alive下面的子集,这个key就是router-view上的key
|
||||||
|
if (item.$vnode.data.key) {
|
||||||
|
vnode = item.$vnode;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return vnode ? vnode : false;
|
||||||
|
},
|
||||||
|
// 移除keep-alive缓存
|
||||||
|
removeCache(name, view = {}) {
|
||||||
|
let vnode = this.getVnode();
|
||||||
|
if (!vnode) return false;
|
||||||
|
let componentInstance = vnode.parent.componentInstance;
|
||||||
|
// 这个key是用来获取前缀用来后面正则匹配用的
|
||||||
|
let keyStart = vnode.key.split("/")[0];
|
||||||
|
let thisKey = `${keyStart}${view.fullPath}`;
|
||||||
|
let regKey = `${keyStart}${view.path}`;
|
||||||
|
|
||||||
|
this[name]({ componentInstance, thisKey, regKey });
|
||||||
|
},
|
||||||
|
// 移除其他
|
||||||
|
closeOthersTags({ componentInstance, thisKey }) {
|
||||||
|
Object.keys(componentInstance.cache).forEach((key, index) => {
|
||||||
|
if (key != thisKey) {
|
||||||
|
// 销毁实例(这里存在多个key指向一个缓存的情况可能前面一个已经清除掉了所有要加判断)
|
||||||
|
if (componentInstance.cache[key]) {
|
||||||
|
componentInstance.cache[key].componentInstance.$destroy();
|
||||||
|
}
|
||||||
|
// 删除缓存
|
||||||
|
delete componentInstance.cache[key];
|
||||||
|
// 移除key中对应的key
|
||||||
|
componentInstance.keys.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 移除所有缓存
|
||||||
|
closeAllTags({ componentInstance }) {
|
||||||
|
// 销毁实例
|
||||||
|
Object.keys(componentInstance.cache).forEach((key) => {
|
||||||
|
if (componentInstance.cache[key]) {
|
||||||
|
componentInstance.cache[key].componentInstance.$destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 删除缓存
|
||||||
|
componentInstance.cache = {};
|
||||||
|
// 移除key中对应的key
|
||||||
|
componentInstance.keys = [];
|
||||||
|
},
|
||||||
|
// 移除单个缓存
|
||||||
|
closeSelectedTag({ componentInstance, regKey }) {
|
||||||
|
let reg = new RegExp(`^${regKey}`);
|
||||||
|
Object.keys(componentInstance.cache).forEach((key, i) => {
|
||||||
|
if (reg.test(key)) {
|
||||||
|
// 销毁实例
|
||||||
|
if (componentInstance.cache[key]) {
|
||||||
|
componentInstance.cache[key].componentInstance.$destroy();
|
||||||
|
}
|
||||||
|
// 删除缓存
|
||||||
|
delete componentInstance.cache[key];
|
||||||
|
// 移除key中对应的key
|
||||||
|
componentInstance.keys.splice(i, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 刷新单个缓存
|
||||||
|
refreshSelectedTag({ componentInstance, thisKey }) {
|
||||||
|
Object.keys(componentInstance.cache).forEach((key, index) => {
|
||||||
|
if (null != thisKey && key.replace("/redirect", "") == thisKey) {
|
||||||
|
// 1 销毁实例(这里存在多个key指向一个缓存的情况可能前面一个已经清除掉了所有要加判断)
|
||||||
|
if (componentInstance.cache[key]) {
|
||||||
|
componentInstance.cache[key].componentInstance.$destroy();
|
||||||
|
}
|
||||||
|
// 2 删除缓存
|
||||||
|
delete componentInstance.cache[key];
|
||||||
|
// 3 移除key中对应的key
|
||||||
|
componentInstance.keys.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -31,7 +134,7 @@ export default {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fixed-header+.app-main {
|
.fixed-header + .app-main {
|
||||||
padding-top: 50px;
|
padding-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +144,7 @@ export default {
|
||||||
min-height: calc(100vh - 84px);
|
min-height: calc(100vh - 84px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.fixed-header+.app-main {
|
.fixed-header + .app-main {
|
||||||
padding-top: 84px;
|
padding-top: 84px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
<script>
|
<script>
|
||||||
import ScrollPane from './ScrollPane'
|
import ScrollPane from './ScrollPane'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import Global from "@/layout/components/global.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ScrollPane },
|
components: { ScrollPane },
|
||||||
|
@ -144,6 +145,7 @@ export default {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Global.$emit("removeCache", "refreshSelectedTag", this.selectedTag);
|
||||||
},
|
},
|
||||||
closeSelectedTag(view) {
|
closeSelectedTag(view) {
|
||||||
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
|
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
|
||||||
|
@ -151,12 +153,14 @@ export default {
|
||||||
this.toLastView(visitedViews, view)
|
this.toLastView(visitedViews, view)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Global.$emit("removeCache", "closeSelectedTag", view);
|
||||||
},
|
},
|
||||||
closeOthersTags() {
|
closeOthersTags() {
|
||||||
this.$router.push(this.selectedTag)
|
this.$router.push(this.selectedTag)
|
||||||
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
|
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
|
||||||
this.moveToCurrentTag()
|
this.moveToCurrentTag()
|
||||||
})
|
})
|
||||||
|
Global.$emit("removeCache", "closeOthersTags", this.selectedTag);
|
||||||
},
|
},
|
||||||
closeAllTags(view) {
|
closeAllTags(view) {
|
||||||
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
|
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
|
||||||
|
@ -165,6 +169,7 @@ export default {
|
||||||
}
|
}
|
||||||
this.toLastView(visitedViews, view)
|
this.toLastView(visitedViews, view)
|
||||||
})
|
})
|
||||||
|
Global.$emit("removeCache", "closeAllTags");
|
||||||
},
|
},
|
||||||
toLastView(visitedViews, view) {
|
toLastView(visitedViews, view) {
|
||||||
const latestView = visitedViews.slice(-1)[0]
|
const latestView = visitedViews.slice(-1)[0]
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
const global = new Vue()
|
||||||
|
export default global
|
|
@ -5,6 +5,7 @@ Vue.use(Router)
|
||||||
|
|
||||||
/* Layout */
|
/* Layout */
|
||||||
import Layout from '@/layout'
|
import Layout from '@/layout'
|
||||||
|
import ParentView from '@/components/ParentView';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: 路由配置项
|
* Note: 路由配置项
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { constantRoutes } from '@/router'
|
import { constantRoutes } from '@/router'
|
||||||
import { getRouters } from '@/api/menu'
|
import { getRouters } from '@/api/menu'
|
||||||
import Layout from '@/layout/index'
|
import Layout from '@/layout/index'
|
||||||
|
import ParentView from '@/components/ParentView';
|
||||||
|
|
||||||
const permission = {
|
const permission = {
|
||||||
state: {
|
state: {
|
||||||
|
@ -33,9 +34,11 @@ const permission = {
|
||||||
function filterAsyncRouter(asyncRouterMap) {
|
function filterAsyncRouter(asyncRouterMap) {
|
||||||
return asyncRouterMap.filter(route => {
|
return asyncRouterMap.filter(route => {
|
||||||
if (route.component) {
|
if (route.component) {
|
||||||
// Layout组件特殊处理
|
// Layout ParentView 组件特殊处理
|
||||||
if (route.component === 'Layout') {
|
if (route.component === 'Layout') {
|
||||||
route.component = Layout
|
route.component = Layout
|
||||||
|
} else if (route.component === 'ParentView') {
|
||||||
|
route.component = ParentView
|
||||||
} else {
|
} else {
|
||||||
route.component = loadView(route.component)
|
route.component = loadView(route.component)
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,14 +117,14 @@ export default {
|
||||||
this.usedmemory = echarts.init(this.$refs.usedmemory, "macarons");
|
this.usedmemory = echarts.init(this.$refs.usedmemory, "macarons");
|
||||||
this.usedmemory.setOption({
|
this.usedmemory.setOption({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
formatter: "{b} <br/>{a} : {c}M",
|
formatter: "{b} <br/>{a} : {c}K",
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: "峰值",
|
name: "峰值",
|
||||||
type: "gauge",
|
type: "gauge",
|
||||||
detail: {
|
detail: {
|
||||||
formatter: "{value}M",
|
formatter: "{value}K",
|
||||||
},
|
},
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -144,6 +144,7 @@ export default {
|
||||||
.user-info-head {
|
.user-info-head {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
height: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-info-head:hover:after {
|
.user-info-head:hover:after {
|
||||||
|
|
|
@ -169,7 +169,7 @@ insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 's
|
||||||
insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单');
|
insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单');
|
||||||
insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单');
|
insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单');
|
||||||
insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单');
|
insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单');
|
||||||
insert into sys_menu values('108', '日志管理', '1', '9', 'log', 'system/log/index', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单');
|
insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单');
|
||||||
insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单');
|
insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单');
|
||||||
insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单');
|
insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单');
|
||||||
insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单');
|
insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单');
|
Loading…
Reference in New Issue