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.
250 lines
7.2 KiB
250 lines
7.2 KiB
<template>
|
|
<div className="application" style="height: 100%">
|
|
<div className="headerMenu" v-if="showLayout">
|
|
<ns-header :notifies="notifies" :showNotify="showNotify" />
|
|
</div>
|
|
<div className="contentMenu">
|
|
<div className="leftMenu" v-if="showLayout">
|
|
<ns-sider :appRecords="docks" />
|
|
</div>
|
|
<div className="content">
|
|
<ns-content />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { authorizationService } from '/nerv-lib/paas/store/modules/authorization-service';
|
|
import { CatalogConfigService, CatalogItem } from '/nerv-lib/paas/store/modules/catalog-config';
|
|
import {defineComponent, inject} from 'vue';
|
|
import NsHeader from './header.vue';
|
|
import NsSider from './sider.vue';
|
|
import NsContent from './content.vue';
|
|
import { storeToRefs } from 'pinia';
|
|
import { http } from '/nerv-lib/util/http';
|
|
import { cloneDeep } from 'lodash-es';
|
|
|
|
export default defineComponent({
|
|
name: 'NsLayout',
|
|
components: { NsHeader, NsSider, NsContent },
|
|
provide() {
|
|
return {
|
|
selecDocks: (item: CatalogItem) => {
|
|
this.toggleDock(item);
|
|
},
|
|
};
|
|
},
|
|
setup() {
|
|
const showLayout = inject('showLayout', true);
|
|
return { showLayout }
|
|
},
|
|
data() {
|
|
return {
|
|
authLoadComplete: false,
|
|
showNotify: false,
|
|
authService: {},
|
|
catalogConfig: {},
|
|
notifies: [], //未读通知
|
|
docks: [],
|
|
};
|
|
},
|
|
mounted() {
|
|
this.authService = authorizationService();
|
|
this.catalogConfig = CatalogConfigService();
|
|
this.catalogConfig.$subscribe((mutation, state) => {
|
|
this.restoreDocks(this.authService.itemMap);
|
|
});
|
|
},
|
|
created() {},
|
|
methods: {
|
|
restoreDocks(authorityMap: any) {
|
|
const storage = window.localStorage;
|
|
this.showNotify = this.authService.checkPermission('notify', 'WebConsoleMsg');
|
|
if (this.showNotify) {
|
|
this.getNotifies();
|
|
}
|
|
if (!storage) {
|
|
return;
|
|
}
|
|
if (!storage['docks']) {
|
|
storage['docks'] = JSON.stringify([]);
|
|
}
|
|
const cataItemNamesMap = {};
|
|
|
|
const { data } = this.catalogConfig;
|
|
let catalogs = cloneDeep(data);
|
|
// console.log('catalogs', catalogs);
|
|
if (catalogs) {
|
|
this.docks = [];
|
|
catalogs.forEach((catalog) => {
|
|
if (catalog.items) {
|
|
catalog.items.forEach((item) => {
|
|
cataItemNamesMap[item.name] = item;
|
|
});
|
|
}
|
|
});
|
|
let newDocksObjs;
|
|
if (storage['newDocks']) {
|
|
newDocksObjs = JSON.parse(storage['newDocks']);
|
|
}
|
|
let dockNames = JSON.parse(storage['docks']).filter((it) => {
|
|
return cataItemNamesMap[it] != null;
|
|
});
|
|
// console.log('cataItemNamesMap', cataItemNamesMap);
|
|
dockNames = dockNames.filter((it) => {
|
|
let name = it;
|
|
if (newDocksObjs && newDocksObjs instanceof Array) {
|
|
newDocksObjs.forEach((item) => {
|
|
if (item[it] != null) {
|
|
name = item[it] + '_' + it;
|
|
}
|
|
});
|
|
}
|
|
return authorityMap[name] != null || authorityMap['*'] != null;
|
|
});
|
|
storage['docks'] = JSON.stringify(dockNames);
|
|
dockNames.forEach((it) => {
|
|
cataItemNamesMap[it].dock = true;
|
|
this.docks.push(cataItemNamesMap[it]);
|
|
});
|
|
}
|
|
},
|
|
|
|
//获取通知信息
|
|
getNotifies() {
|
|
let where = {
|
|
where: 'status = ?',
|
|
values: 0,
|
|
order: 'created_at desc',
|
|
pageSize: 100,
|
|
};
|
|
http.get('/api/notify/notify/objs/WebConsoleMsg', where).then((response) => {
|
|
let data = response['data'];
|
|
if (data) {
|
|
this.notifies = data;
|
|
}
|
|
});
|
|
},
|
|
//处理产品与服务中用户选中的项目
|
|
toggleDock(item: CatalogItem): void {
|
|
//operate bind data
|
|
this.operateBindData(item);
|
|
|
|
//operate localStorage data
|
|
this.operateLocalStorageData(item);
|
|
},
|
|
/**
|
|
* 当点击"产品与服务"里面的子菜单时, 操作数据绑定对象来控制左侧边栏的图标
|
|
*
|
|
* @param item 当前选中的子菜单
|
|
*/
|
|
operateBindData(item: CatalogItem) {
|
|
var index = this.docks.findIndex((e) => e.name == item.name);
|
|
if (index > -1) {
|
|
this.docks.splice(index, 1);
|
|
} else {
|
|
this.docks.push(item);
|
|
if (item.url.indexOf('http') == 0 || item.isRedirect) {
|
|
var a = document.createElement('a');
|
|
a.setAttribute('href', item.url);
|
|
a.setAttribute('target', item.url.indexOf('http') == 0 ? '_blank' : '_self');
|
|
a.setAttribute('id', 'startTelMedicine');
|
|
// 防止反复添加
|
|
if (document.getElementById('startTelMedicine')) {
|
|
document.body.removeChild(document.getElementById('startTelMedicine'));
|
|
}
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
} else if (item.url.indexOf('http') == -1 && !item.isRedirect) {
|
|
// console.log(item);
|
|
// this.router.navigate([item.url], {
|
|
// relativeTo: this.route,
|
|
// queryParams: item.queryParams,
|
|
// });
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
* 当点击"产品与服务"里面的子菜单时, 操作做本地存储, 以便下次会话记住左侧菜单项
|
|
*
|
|
* @param item 当前选中的子菜单
|
|
*/
|
|
operateLocalStorageData(item: CatalogItem) {
|
|
let storage = window.localStorage;
|
|
|
|
if (!storage) {
|
|
return;
|
|
}
|
|
|
|
let docks = [];
|
|
let newDocks = [];
|
|
|
|
let jsonStr = storage['docks'];
|
|
let newDocksStr = storage['newDocks'];
|
|
if (jsonStr) {
|
|
docks = JSON.parse(jsonStr);
|
|
}
|
|
if (newDocksStr) {
|
|
newDocks = JSON.parse(newDocksStr);
|
|
}
|
|
|
|
let flag = false; //默认未选中
|
|
if (item['splitMenuModule']) {
|
|
newDocks = newDocks.filter((it) => {
|
|
for (let key in it) {
|
|
if (key == item.name) {
|
|
flag = true;
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
var index = docks.findIndex((e) => e == item.name);
|
|
if (index > -1) {
|
|
docks.splice(index, 1);
|
|
} else {
|
|
docks.push(item.name);
|
|
if (item['splitMenuModule'] && !flag) {
|
|
let obj = {};
|
|
obj[item.name] = item['splitMenuModule'];
|
|
newDocks.push(obj);
|
|
}
|
|
}
|
|
|
|
storage['docks'] = JSON.stringify(docks);
|
|
storage['newDocks'] = JSON.stringify(newDocks);
|
|
},
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.application {
|
|
display: block !important;
|
|
|
|
.headerMenu {
|
|
height: 48px;
|
|
width: 100%;
|
|
}
|
|
|
|
.contentMenu {
|
|
height: calc(100% - 48px);
|
|
display: flex;
|
|
|
|
.leftMenu {
|
|
width: 48px;
|
|
flex-shrink: 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
.content {
|
|
height: 100%;
|
|
min-height: 580px;
|
|
overflow: hidden;
|
|
width: 100%;
|
|
}
|
|
</style>
|
|
|