铜陵经侦
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.

170 lines
4.6 KiB

1 month ago
<template>
<div class="module-portal">
<header class="portal-header">
<div class="portal-header-inner">
<div class="portal-header-left" @click="goPortal">
<img :src="logoImg" alt="logo" class="portal-logo" />
<h1 class="portal-title">{{ websiteName }}</h1>
</div>
<div class="portal-header-right">
<span class="portal-time">{{ currentTime }}</span>
<span class="portal-user"><UserOutlined /> {{ userName }}</span>
<a class="portal-logout" @click="handleLogout"><LogoutOutlined /> 退出</a>
</div>
</div>
</header>
<main class="portal-main">
<div class="portal-bg-decor">
<div class="portal-grid"></div>
</div>
<div class="portal-container">
<div class="portal-section-head">
<div class="portal-section-bar"></div>
<h2>业务导航</h2>
</div>
<div class="portal-modules">
<div
v-for="item in portalModules"
:key="item.name"
class="portal-module-card"
@click="enterModule(item.menu)"
>
<div class="portal-module-icon">
<component :is="$antIcons[item.menu?.icon || item.icon]" />
</div>
<div class="portal-module-body">
<h3>{{ item.name }}</h3>
<span class="portal-module-link">进入模块 <RightOutlined /></span>
</div>
</div>
</div>
</div>
</main>
<footer class="portal-footer">
<span>内部平台,严禁外传</span>
</footer>
</div>
</template>
<script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import dayjs from 'dayjs';
import { Modal, message } from 'ant-design-vue';
import { LogoutOutlined, RightOutlined, UserOutlined } from '@ant-design/icons-vue';
import logoImg from '/@/assets/images/logo/smart-admin-logo.png';
import { PORTAL_SUB_PAGE_PATH } from '/@/constants/system/portal-const';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import { usePortalModuleStore } from '/@/store/modules/system/portal-module';
import { useUserStore } from '/@/store/modules/system/user';
import { loginApi } from '/@/api/system/login-api';
import {
buildPortalModules,
findFirstLeafMenu,
getModuleSubEntries,
} from '/@/utils/portal-menu-util';
const router = useRouter();
const userStore = useUserStore();
const portalStore = usePortalModuleStore();
const appConfigStore = useAppConfigStore();
const websiteName = computed(() => appConfigStore.websiteName);
const userName = computed(() => userStore.actualName || userStore.loginName || '用户');
const portalModules = computed(() => buildPortalModules(userStore.getMenuTree || []));
const currentTime = ref('');
let timer = null;
function updateTime() {
const now = dayjs();
const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
currentTime.value = `${now.format('YYYY-MM-DD HH:mm:ss')} ${weekDays[now.day()]}`;
}
function goPortal() {
portalStore.clearActiveModule();
router.push('/portal');
}
function pushMenuPath(menu) {
if (!menu?.path) {
return false;
}
router.push(menu.path.startsWith('/') ? menu.path : `/${menu.path}`);
return true;
}
function enterModule(module) {
if (!module) {
message.warning('您暂无该模块权限');
return;
}
portalStore.setActiveModule(module.menuId);
if (isTopLeafModule(module)) {
pushMenuPath(module);
return;
}
const entries = getModuleSubEntries(module);
if (!entries.length) {
message.warning('该模块暂无可用菜单');
return;
}
if (entries.length === 1) {
const leaf = findFirstLeafMenu(entries) || entries[0];
if (pushMenuPath(leaf)) {
return;
}
}
router.push({
path: PORTAL_SUB_PAGE_PATH,
query: { moduleId: module.menuId },
});
}
function isTopLeafModule(module) {
return !!module.path && (!module.children || module.children.length === 0);
}
function handleLogout() {
Modal.confirm({
title: '确定退出系统吗?',
okText: '确定',
cancelText: '取消',
onOk: async () => {
try {
await loginApi.logout();
} catch (e) {
// ignore
}
portalStore.clearActiveModule();
userStore.logout();
router.push('/login');
},
});
}
onMounted(() => {
portalStore.clearActiveModule();
9 hours ago
userStore.resetBusinessNavigation();
1 month ago
updateTime();
timer = setInterval(updateTime, 1000);
});
onUnmounted(() => {
if (timer) {
clearInterval(timer);
}
});
</script>
<style lang="less" scoped>
@import './portal-common.less';
</style>