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.
193 lines
9.5 KiB
193 lines
9.5 KiB
<template>
|
|
<div>
|
|
<div v-if="config.razor">
|
|
<slot></slot>
|
|
</div>
|
|
<div class="wrapper" v-else-if="store.state.layout">
|
|
<nav class="main-header navbar navbar-expand navbar-dark navbar-gray-dark text-sm">
|
|
<ul class="navbar-nav" v-if="store.state.layout">
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>
|
|
</li>
|
|
<li class="nav-item d-none d-sm-inline-block">
|
|
<router-link to="/" :class="getLinkClass()">首页</router-link>
|
|
</li>
|
|
<li v-for="item in getModules()">
|
|
<router-link :to="getPath(item.number)" :class="getLinkClass(item.number,getPath(item.number))">{{item.name}}</router-link>
|
|
</li>
|
|
</ul>
|
|
<ul class="navbar-nav ml-auto">
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="javascript:;">{{realName}}</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="javascript:;" v-on:click="logout">退出</a>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
<aside class="main-sidebar sidebar-dark-primary elevation-4">
|
|
<a class="brand-link" style="padding:8px .5rem;" href="./" v-if="store.state.layout.organs.length===0">
|
|
<img class="logo" style="height:33px;" :src="logo" />
|
|
<span class="brand-text font-weight-light" style="display:inline-block;line-height:33px;">{{store.state.layout.name}}</span>
|
|
</a>
|
|
<div class="brand-link" href="./" v-else>
|
|
<img class="logo" style="height:33px;" :src="logo" />
|
|
<select id="UserCurrentOrganNumber" name="UserCurrentOrganNumber"
|
|
style="height:30px;width:160px; background-color: rgb(52, 58, 64); color: rgba(255, 255, 255, 0.8);font-size:14px;"
|
|
v-on:change="changeOrgan"
|
|
v-model="currentOrganId">
|
|
<option v-for="option in store.state.layout.organs" v-bind:value="option.id">
|
|
{{ option.name }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
<div class="sidebar">
|
|
<nav class="mt-2">
|
|
<ul class="nav nav-pills nav-sidebar flex-column nav-flat" data-widget="treeview" role="menu" data-accordion="nav-icon false">
|
|
<template v-if="getArea()==='default'">
|
|
<li class="nav-header">智慧校园</li>
|
|
<li class="nav-item">
|
|
<router-link to="/" :class="getLinkClass('default','/')"><i class="far fa-circle nav-icon"></i><p>机构概览</p></router-link>
|
|
</li>
|
|
<li class="nav-item">
|
|
<router-link :to="viewPath+'default/devices.vue'" :class="getLinkClass('default','/devices.vue')"><i class="far fa-circle nav-icon"></i><p>设备中心</p></router-link>
|
|
</li>
|
|
</template>
|
|
<template v-else>
|
|
<li v-for="item in getMenus()">
|
|
<router-link :to="getPath(item.number)" :class="getLinkClass(item.number,getPath(item.number))"><i class="far fa-circle nav-icon"></i><p>{{item.name}}</p></router-link>
|
|
</li>
|
|
</template>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</aside>
|
|
<div class="content-wrapper">
|
|
<section class="content">
|
|
<div class="container-fluid">
|
|
<slot></slot>
|
|
</div>
|
|
</section>
|
|
<a id="back-to-top" href="#" class="btn btn-success back-to-top" role="button" aria-label="Scroll to top">
|
|
<i class="fas fa-chevron-up"></i>
|
|
</a>
|
|
</div>
|
|
<footer class="main-footer">
|
|
<p style="text-align:center;" v-if="store.state.layout">
|
|
<span v-html="store.state.layout.copyright.replace('{0}',new Date().getFullYear())"></span> v {{store.state.layout.version}}
|
|
</p>
|
|
</footer>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
export default {
|
|
data: function () {
|
|
return {
|
|
url: config.service('platform/api/v1/Site/Layout'),
|
|
viewPath: '/components/views/areas/'
|
|
}
|
|
},
|
|
computed: {
|
|
realName: function () {
|
|
return Enumerable.from(store.state.layout.user.claims).where(o => o.type === 'RealName').select(o => o.value).firstOrDefault();
|
|
},
|
|
logo: function () {
|
|
var result;
|
|
if (store.state.layout.organs.length > 0) {
|
|
var organ = Enumerable.from(store.state.layout.organs)
|
|
.orderByDescending(o => o.isDefault).orderBy(o => o.id)
|
|
.firstOrDefault();
|
|
if (organ) {
|
|
result = organ.image;
|
|
}
|
|
}
|
|
if (!result) {
|
|
result = store.state.layout.logo
|
|
}
|
|
return result;
|
|
},
|
|
currentOrganId: function () {
|
|
return store.state.layout.currentOrganId;
|
|
}
|
|
},
|
|
mounted: function () {
|
|
axios.post(this.url).then(function (response) {
|
|
store.set('layout', response.data);
|
|
}).catch(function (error) {
|
|
console.log(error);
|
|
});
|
|
},
|
|
methods: {
|
|
logout: function () {
|
|
store.commit('logout');
|
|
router.push('components/views/areas/default/login.vue');
|
|
},
|
|
changeOrgan: function (event) {
|
|
var url = config.service('platform/Account/ChangeOrgan?UserCurrentOrganNumber=' + event.target.value);
|
|
axios.post(url).then(function (response) {
|
|
if (response.status === 200) {
|
|
store.commit('login', response.data);
|
|
setTimeout(function () {
|
|
router.push({ path: '/components/views/shared/redirect.vue', query: { url: router.currentRoute.fullPath, message: '正在切换当前机构' } });
|
|
}, 1000);
|
|
}
|
|
else if (response.status === 400) {
|
|
store.commit('logout');
|
|
router.push('components/views/areas/default/login.vue');
|
|
}
|
|
});
|
|
},
|
|
getArea: function () {
|
|
var path = this.$route.path === '/' ? (this.viewPath + 'default/index.vue') : this.$route.path;
|
|
path = path.substr(this.viewPath.length);
|
|
return path === '/' ? 'default' : path.substr(0, path.indexOf('/'));
|
|
},
|
|
getPath: function (area) {
|
|
return this.viewPath + area + '/index.vue';
|
|
},
|
|
getModules: function () {
|
|
var numbers = Enumerable.from(store.state.layout.user.claims).where(o => o.type === store.state.layout.user.roleClaimType).select(o => o.value).toArray();
|
|
var modules = Enumerable.from(store.state.layout.modules)
|
|
.where(o => Enumerable.from(o.permissionCategories).selectMany(o => o.permissions).any(o => Enumerable.from(numbers).any(n => n == o.number)))
|
|
.orderBy(o => o.order).toArray();
|
|
return modules;
|
|
},
|
|
getMenus: function (area) {
|
|
area = area || this.getArea();
|
|
var module = Enumerable.from(store.state.layout.modules).firstOrDefault(o => o.number === area);
|
|
var numbers = Enumerable.from(store.state.layout.user.claims).where(o => o.type === store.state.layout.user.roleClaimType).select(o => o.value).toArray();
|
|
var permissions = Enumerable.from(module.permissionCategories)
|
|
.selectMany(o => o.permissions)
|
|
.where(o => Enumerable.from(numbers).any(n => n === o.number))
|
|
.orderBy(o => o.order)
|
|
.toArray()
|
|
return permissions;
|
|
},
|
|
getLinkClass: function (area, view) {
|
|
area = area || 'default';
|
|
var mapView = view ? true : false;
|
|
view = view || '/';
|
|
view = view === '/' ? '/index.vue' : view;
|
|
|
|
var path = this.$route.path;
|
|
var currentArea = this.getArea();
|
|
var currentView = path === '/' ? (this.viewPath + area + '/index.vue') : path;
|
|
|
|
var cls = 'nav-link';
|
|
|
|
if (area === currentArea) {
|
|
if (!mapView) {
|
|
cls += ' active';
|
|
}
|
|
else {
|
|
if (currentView === (this.viewPath + area + view)) {
|
|
cls += ' active';
|
|
}
|
|
}
|
|
}
|
|
return cls;
|
|
}
|
|
}
|
|
}
|
|
</script> |