259 lines
6.8 KiB
Vue
259 lines
6.8 KiB
Vue
<template>
|
|
<section>
|
|
<a-layout
|
|
:class="{
|
|
[`yo-layout--top-nav--${$root.global.settings.container}`]: $root.global.settings.layout === 'top-nav',
|
|
[`yo-layout--${$root.global.settings.layout}`]: true,
|
|
}"
|
|
>
|
|
<Sider
|
|
:nav="nav"
|
|
@change-app="onChangeApp"
|
|
v-if="$root.global.settings.layout === 'left-menu'"
|
|
/>
|
|
<a-layout>
|
|
<Header :nav="nav" @reload="onReloadContentWindow" @setting="setting.visible = true" />
|
|
<a-layout>
|
|
<Content
|
|
:panes="panes"
|
|
:tabActived="tabActived"
|
|
@change="onChangeContentWindow"
|
|
@close="onCloseContentWindow"
|
|
@close-other="onCloseOtherContentWindow"
|
|
@close-right="onCloseRightContentWindow"
|
|
ref="content"
|
|
/>
|
|
</a-layout>
|
|
</a-layout>
|
|
<Sider :nav="nav" v-if="$root.global.settings.layout === 'right-menu'" />
|
|
</a-layout>
|
|
<Setting :visible="setting.visible" @close="setting.visible = false" />
|
|
</section>
|
|
</template>
|
|
<script>
|
|
import Vue from 'vue';
|
|
|
|
import Header from './_layout/header';
|
|
import Sider from './_layout/sider/index';
|
|
import Content from './_layout/content';
|
|
|
|
import Setting from './setting';
|
|
|
|
import { setGlobal } from '@/common/login';
|
|
import { ACTIVE_APP_KEY } from '@/common/storage';
|
|
|
|
import { EMPTY_ID } from '@/util/global';
|
|
|
|
const getNewID = () => {
|
|
return Math.random().toString(16).slice(2);
|
|
};
|
|
|
|
export default {
|
|
components: {
|
|
Header,
|
|
Sider,
|
|
Content,
|
|
Setting,
|
|
},
|
|
data() {
|
|
return {
|
|
panes: new Array(),
|
|
tabActived: '',
|
|
|
|
setting: {
|
|
visible: false,
|
|
},
|
|
nav: {
|
|
loading: false,
|
|
apps: [],
|
|
menus: [],
|
|
},
|
|
};
|
|
},
|
|
|
|
mounted() {
|
|
Vue.prototype.openContentWindow = this.onOpenContentWindow;
|
|
Vue.prototype.closeContentWindow = this.onCloseContentWindow;
|
|
|
|
this.nav.loading = true;
|
|
|
|
this.$api.getLoginUser().then(({ data }) => {
|
|
// 去除应用和菜单信息,存储基本信息
|
|
const info = this.$_.cloneDeep(data);
|
|
delete info.apps;
|
|
delete info.menus;
|
|
setGlobal(info);
|
|
|
|
data.apps.map((p) => (p.active = p.active));
|
|
this.onSetNav(data);
|
|
this.nav.loading = false;
|
|
|
|
this.$root.global.defaultWindow.map((options) => {
|
|
this.onOpenContentWindow(options);
|
|
});
|
|
});
|
|
},
|
|
|
|
methods: {
|
|
/**
|
|
* 打开一个新的标签页
|
|
* settings: {
|
|
* title: String,
|
|
* path: String,
|
|
* icon: String,
|
|
* param: Object,
|
|
* closable: Boolean = true,
|
|
* }
|
|
*/
|
|
onOpenContentWindow(settings) {
|
|
if (settings.path) {
|
|
const key = settings.key || getNewID();
|
|
|
|
/**
|
|
* 如果当前标签页已打开,则只需要选中
|
|
*/
|
|
const pane = this.panes.find((p) => p.key === key);
|
|
if (pane) {
|
|
this.onChangeContentWindow(key);
|
|
return;
|
|
}
|
|
|
|
const path = settings.path.startsWith('/') ? settings.path : `/${settings.path}`;
|
|
|
|
/**
|
|
* 向标签页队列中添加一个新的标签页
|
|
*/
|
|
this.panes.push({
|
|
key,
|
|
closable: settings.closable === undefined ? true : settings.closable,
|
|
icon: settings.icon,
|
|
title: settings.title || '新建窗口',
|
|
component: null,
|
|
path,
|
|
param: settings.param,
|
|
loaded: false,
|
|
});
|
|
|
|
this.onChangeContentWindow(key);
|
|
|
|
this.$refs.content.onLoadContentWindow(key);
|
|
} else {
|
|
console.warn('wrong component path');
|
|
}
|
|
},
|
|
|
|
onCloseContentWindow(key) {
|
|
key = key || this.tabActived;
|
|
const i = this.$_.findIndex(this.panes, (p) => p.key === key);
|
|
this.panes.splice(i, 1);
|
|
|
|
if (this.panes.length) {
|
|
if (key === this.tabActived) {
|
|
const pane = this.panes[i];
|
|
if (pane) {
|
|
this.onChangeContentWindow(pane.key);
|
|
} else {
|
|
this.onChangeContentWindow(this.panes[i - 1].key);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
onCloseOtherContentWindow(key) {
|
|
const panes = Object.assign([], this.panes);
|
|
let flag = false;
|
|
for (let i = panes.length - 1; i >= 0; i--) {
|
|
const p = panes[i];
|
|
if (p.key !== key && p.closable) {
|
|
if (p.key === this.tabActived) {
|
|
flag = true;
|
|
}
|
|
panes.splice(i, 1);
|
|
}
|
|
}
|
|
this.panes = panes;
|
|
if (flag) {
|
|
this.onChangeContentWindow(this.$_.last(panes).key);
|
|
}
|
|
},
|
|
|
|
onCloseRightContentWindow(key) {
|
|
const panes = Object.assign([], this.panes);
|
|
let flag = false;
|
|
for (let i = panes.length - 1; i >= 0; i--) {
|
|
const p = panes[i];
|
|
if (p.key !== key && p.closable) {
|
|
if (p.key === this.tabActived) {
|
|
flag = true;
|
|
}
|
|
panes.splice(i, 1);
|
|
} else if (p.key === key) {
|
|
break;
|
|
}
|
|
}
|
|
this.panes = panes;
|
|
if (flag) {
|
|
this.onChangeContentWindow(this.$_.last(panes).key);
|
|
}
|
|
},
|
|
|
|
onChangeContentWindow(key) {
|
|
this.tabActived = key;
|
|
},
|
|
|
|
onReloadContentWindow(key) {
|
|
if (!key) key = this.tabActived;
|
|
this.$refs.content.onLoadContentWindow(key);
|
|
},
|
|
|
|
onChangeApp(app) {
|
|
this.nav.loading = true;
|
|
this.$api.sysMenuChange({ application: app.code }).then(({ data }) => {
|
|
this.nav.apps.map((p) => (p.active = p.code === app.code));
|
|
window.localStorage.removeItem(ACTIVE_APP_KEY);
|
|
this.onSetNav({
|
|
apps: this.nav.apps,
|
|
menus: data,
|
|
});
|
|
|
|
this.nav.loading = false;
|
|
});
|
|
},
|
|
|
|
onSetNav(nav) {
|
|
// 从本地存储获取当前选中的应用及菜单
|
|
this.nav.apps = nav.apps;
|
|
const code = window.localStorage.getItem(ACTIVE_APP_KEY);
|
|
if (code) {
|
|
this.nav.apps.map((p) => (p.active = p.code === code.code));
|
|
this.onChangeApp({
|
|
code,
|
|
});
|
|
} else {
|
|
// 将默认选中菜单存储
|
|
const app = nav.apps.find((p) => p.active);
|
|
if (app) {
|
|
window.localStorage.setItem(ACTIVE_APP_KEY, app.code);
|
|
this.serializeMenu(nav.menus);
|
|
}
|
|
}
|
|
},
|
|
|
|
serializeMenu(menus) {
|
|
const menu = this.$_.cloneDeep(menus);
|
|
const children = this.$_.groupBy(menu, 'pid');
|
|
|
|
const serialize = (m) => {
|
|
m.map((p) => {
|
|
if (children[p.id]) {
|
|
p.children = serialize(children[p.id]);
|
|
}
|
|
});
|
|
return m;
|
|
};
|
|
|
|
this.nav.menus = children[EMPTY_ID] ? serialize(children[EMPTY_ID]) : new Array();
|
|
},
|
|
},
|
|
};
|
|
</script> |