You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

361 lines
12 KiB

7 months ago
<!-- @format -->
<template>
<a-layout class="ns-application" :id="iframe ? 'iframeApplication' : ''">
<ns-header
v-show="!iframe"
class="ns-header-menu"
:headerList="headers"
:initHeaderKey="selectedHeaderKeys" />
<a-layout class="ns-application-layout">
<ns-sider
:menuList="newMenu"
:initSiderKey="selectedSiderKeys"
:initSiderOpenKey="selectedSiderOpenKeys" />
<a-layout class="ns-application-layout-main">
6 months ago
<newNsTags v-if="configStore.useHistoryTag" />
<ns-tags v-else />
<NsBreadcrumb :breadcrumbList="breadcrumbList" />
7 months ago
<a-layout-content class="ns-content">
<!-- <transition name="fade-slide" mode="out-in"> -->
<!-- <div> -->
7 months ago
<ns-content />
<!-- </div> -->
7 months ago
<!-- </transition> -->
</a-layout-content>
</a-layout>
</a-layout>
</a-layout>
</template>
<script lang="ts">
import { computed, defineComponent, provide, ref, watch } from 'vue';
import NsHeader from './layout/header.vue';
import NsSider from './layout/sider.vue';
import NsBreadcrumb from './layout/breadcrumb.vue';
import NsTags from './layout/tags.vue';
import newNsTags from './layout/tag/index.vue';
import NsContent from './layout/baseContent.vue';
import { useRouter } from 'vue-router';
import { emitEvents, menusClass, tagsClass } from './application.d';
import { cloneDeep } from 'lodash-es';
import { storeToRefs } from 'pinia';
import { Cookies } from '/nerv-lib/util/cookie';
import { useKeepAlive } from '/nerv-base/store/modules/keepAlive';
import { appConfigStore } from '/nerv-lib/saas/store/modules/app-config';
import { useRouteStore } from '/nerv-base/store/modules/route';
import { useTags } from '/nerv-base/store/modules/tags';
import { authorizationService } from '/nerv-base/store/modules/authorization-service';
import mitt from 'mitt';
export default defineComponent({
name: 'NsApplication',
components: { NsBreadcrumb, NsHeader, NsSider, NsContent, newNsTags, NsTags },
provide() {
return {
selectTags: computed(() => this.selectTags),
baseHeader: computed(() => this.baseHeader),
};
},
setup() {
const mittEmit = mitt<emitEvents>();
provide('mittEmit', mittEmit);
const breadcrumbList = ref<object[]>([]);
const keepAliveStore = useKeepAlive();
const configStore = appConfigStore();
const authorizationStore = authorizationService();
const tagsStore = useTags();
tagsStore.initTags();
const tagList = computed(() => tagsStore.getTags);
const siderPosition = computed(() => configStore.siderPosition);
const initRouterList = computed(() => authorizationStore.getInitRouterList);
const userResourceList = computed(() => authorizationStore.getUserResourceList);
if (!authorizationStore.getPrjectId && Cookies.get('projectUuid')) {
authorizationStore.setProjectId(Cookies.get('projectUuid'));
}
const { route: routeModules, routeModuleObject, routeModule } = storeToRefs(useRouteStore());
const headers = computed(() => {
const module = cloneDeep(routeModules.value);
const list = [];
keepAliveStore.clearKeepAlive();
for (let i = 0, j = module.length; i < j; i++) {
const mod = module[i] || {};
const modList: menusClass[] = Array.isArray(mod) ? [...mod] : [mod];
dealKeepAlive(mod);
dealResource(modList[0]);
if (mod.children !== undefined) {
modList[0].ischoice = false;
list.push(modList[0]);
}
}
list.sort((a, b) => {
return a.meta.index - b.meta.index;
});
delProjectRouter(list);
setTimeout(() => {
if (siderPosition.value === 'top') {
newMenu.value = list.filter(
(x: menusClass) => x.name === router.currentRoute.value.matched[0].name,
);
} else {
newMenu.value = [{ children: list }];
}
}, 0);
return siderPosition.value === 'top' ? list : [];
});
const dealKeepAlive = (val) => {
if (val?.meta?.keepAlive) {
keepAliveStore.addKeepAlive(val.name);
}
if (val?.children?.length > 0) {
val.children.forEach((item) => {
dealKeepAlive(item);
});
}
};
const delProjectRouter = (val) => {
if (configStore.enablePermissions !== undefined && configStore.enablePermissions) {
const projectItem = val.filter((x) => x.name === 'project')[0];
if (projectItem !== undefined) {
if (!projectItem.children.filter((x) => x.name === 'Enter')[0].isHide) {
projectItem.children.forEach((item) => {
if (item.name !== 'Enter') {
if (authorizationStore.getPrjectId) {
item.isHide = false;
} else {
item.isHide = true;
}
}
});
}
}
}
};
const dealResource = (val) => {
if (configStore.enablePermissions !== undefined && configStore.enablePermissions) {
if (configStore.resourceName) {
val.isHide =
initRouterList.value.indexOf(`${configStore.resourceName}${val.name}`) === -1;
} else {
val.isHide = initRouterList.value.indexOf(val.name) === -1;
}
if (
Object.prototype.toString.call(val.children) === '[object Array]' &&
val.children.length !== 0
) {
val.children.forEach((item: any, i: number) => {
dealResource(item);
//支持部分小程序的菜单不可见
if (item.meta?.isHide) {
val.children.splice(i, 1);
return;
}
});
}
}
};
const mergetRouter = (rout, source) => {
let list: any = [];
let routCode: any = {};
let spiceMenu: any = [];
const setcode = (data) => {
data.forEach((el) => {
let codeItem = cloneDeep(el);
if (el.isHide) {
spiceMenu.push(codeItem);
return;
}
delete codeItem['children'];
routCode[el.name] = codeItem;
if (el['children'] !== undefined) {
setcode(el['children']);
}
});
};
setcode(rout);
const setMenu = (menus, Clist) => {
menus.forEach((menu: any) => {
let relaMenu: any = {};
if (routCode[menu['code']] || ['menus', 'noChildrenMenu'].includes(menu['type'])) {
relaMenu = routCode[menu['code']];
if (menu.menus) {
relaMenu['children'] = [];
setMenu(menu.menus, relaMenu['children']);
}
Clist.push(relaMenu);
}
});
};
setMenu(source, list);
// source.forEach((menu: any) => {
// let relaMenu: any = {};
// if (routCode[menu['code']] || ['menus', 'noChildrenMenu'].includes(menu['type'])) {
// relaMenu = routCode[menu['code']];
// if (menu.menus) {
// relaMenu['children'] = [];
// setMenu(menu.menus, relaMenu['children']);
// }
// list.push(relaMenu);
// }
// });
list = [...list, ...spiceMenu];
console.log(list);
return list;
};
const selectTags = ref({});
const newMenu = ref<menusClass[]>([]);
const selectedHeaderKeys = ref<string[]>([]);
const selectedSiderOpenKeys = ref<string[]>([]);
const selectedSiderKeys = ref<string[]>([]);
const baseHeader = headers.value[0] || [];
// 处理路由变化时导航栏选中事件
const initSider = (ary: Array<T>) => {
if (selectedHeaderKeys.value !== ary[0].name && siderPosition.value === 'top') {
selectedHeaderKeys.value = [ary[0].name];
newMenu.value = headers.value.filter((x: menusClass) => x.name === ary[0].name);
}
const index = ary.findIndex((x) =>
x.meta ? x.meta.hideChildren || (!x.redirect && siderPosition.value === 'left') : '',
);
//更新选中的tags标签
selectTags.value = index === -1 ? (ary.length > 2 ? ary[2] : ary[1]) : dealTags(ary[index]);
// console.log(selectTags);
//更新导航展开的key
console.log(ary);
selectedSiderOpenKeys.value = index === -1 ? [ary[1].name] : dealSiderOpenKey(ary, index);
// //更新导航选中的key
selectedSiderKeys.value =
index === -1 ? (ary.length > 2 ? [ary[2].name] : [ary[1].name]) : dealSelectKey(ary);
};
const dealSiderOpenKey = (ary: any, index: number) => {
const initList = [];
for (var i = 0; i <= index; i++) {
initList.push(ary[i].name);
}
return initList;
};
const dealSelectKey = (ary: any) => {
const selectKeyIndex = ary.findIndex((x) => x.name === router.currentRoute.value.name);
if (router.currentRoute.value.meta?.hideChildren) {
const initList = [];
for (var i = 0; i < selectKeyIndex; i++) {
initList.push(ary[i].name);
}
if (router.currentRoute.value.meta?.type === 'noChildrenMenu') {
initList.push(ary[selectKeyIndex].name);
}
return initList;
} else {
return [ary[selectKeyIndex].name];
}
};
const dealTags = (ary: any) => {
if (ary.children?.length > 0 && !ary.meta?.hideChildren) {
return ary.children.filter(
(x) =>
x.name === router.currentRoute.value.name ||
(x.meta.hideChildren && x.redirect?.name === router.currentRoute.value.name),
)[0];
} else {
return ary;
}
};
const router = useRouter();
watch(
() => router.currentRoute.value,
(e) => {
if (e.fullPath !== '/login' && e.matched.length > 1) {
breadcrumbList.value = e.matched as object[];
initSider(e.matched);
window.sessionStorage.setItem('url', e.fullPath);
}
},
);
watch(
() => routeModuleObject.value,
(e) => {
tagList.value.forEach((item: tagsClass, index: number) => {
if (e[item.name] !== undefined) {
if (item.title !== e[item.name].label) {
tagsStore.updateTagTitle(index, e[item.name].label);
}
}
});
},
{ deep: true },
);
return {
breadcrumbList,
iframe: computed(() => configStore.iframe),
configStore,
initRouterList,
selectedHeaderKeys,
selectedSiderKeys,
selectedSiderOpenKeys,
headers,
baseHeader,
selectTags,
initSider,
newMenu,
};
},
created() {
const e = this.$router.currentRoute.value;
if (e.fullPath !== '/login' && e.matched.length > 1) {
this.breadcrumbList = e.matched as object[];
this.initSider(e.matched);
}
},
});
</script>
<style lang="less" scoped>
.ns-application {
min-height: 100%;
.ns-application-layout {
min-height: 100%;
flex-direction: row;
}
}
.ns-application-layout-main {
padding-top: calc(@layout-header-height + @ns-nav-shutters-height * 2);
height: 100vh;
overflow: auto;
}
7 months ago
.ns-content {
position: relative;
flex: 1 1 auto;
padding: @ns-gap;
// padding-top: calc(@layout-header-height + @ns-nav-shutters-height);
background-color: @ns-content-bg;
7 months ago
> div {
height: 100%;
background-color: @white;
border-radius: @ns-border-radius;
// overflow-y: auto;
// overflow-x: hidden;
// margin: 0 16px 16px 16px;
7 months ago
}
.ns-content-main {
// margin: @ns-gap;
7 months ago
min-height: calc(100% - 48px);
// height: calc(100% - 16px);
7 months ago
// background-color: @white;
}
.ns-view {
// margin: @ns-content-padding;
// min-height: calc(100% - 48px);
// height: calc(100% - 48px);
background-color: @white;
}
}
#iframeApplication .ns-content {
padding-top: 55px !important;
}
</style>