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.
345 lines
8.5 KiB
345 lines
8.5 KiB
<template>
|
|
<ele-pro-layout
|
|
:menus="menus"
|
|
:tabs="tabs"
|
|
:collapse="collapse"
|
|
:side-nav-collapse="sideNavCollapse"
|
|
:body-fullscreen="bodyFullscreen"
|
|
:show-tabs="showTabs"
|
|
:show-footer="showFooter"
|
|
:head-style="headStyle"
|
|
:side-style="sideStyle"
|
|
:layout-style="layoutStyle"
|
|
:side-menu-style="sideMenuStyle"
|
|
:tab-style="tabStyle"
|
|
:fixed-header="fixedHeader"
|
|
:fixed-sidebar="fixedSidebar"
|
|
:fixed-body="fixedBody"
|
|
:body-full="bodyFull"
|
|
:logo-auto-size="logoAutoSize"
|
|
:colorful-icon="colorfulIcon"
|
|
:side-unique-open="sideUniqueOpen"
|
|
:style-responsive="styleResponsive"
|
|
:project-name="projectName"
|
|
:hide-footers="HIDE_FOOTERS"
|
|
:hide-sidebars="HIDE_SIDEBARS"
|
|
:repeatable-tabs="REPEATABLE_TABS"
|
|
:home-title="HOME_TITLE || t('layout.home')"
|
|
:home-path="HOME_PATH"
|
|
:layout-path="LAYOUT_PATH"
|
|
:redirect-path="REDIRECT_PATH"
|
|
:locale="locale"
|
|
:i18n="i18n"
|
|
@update:collapse="updateCollapse"
|
|
@update:side-nav-collapse="updateSideNavCollapse"
|
|
@update:body-fullscreen="updateBodyFullscreen"
|
|
@tab-add="addPageTab"
|
|
@tab-remove="removePageTab"
|
|
@tab-remove-all="removeAllPageTab"
|
|
@tab-remove-left="removeLeftPageTab"
|
|
@tab-remove-right="removeRightPageTab"
|
|
@tab-remove-other="removeOtherPageTab"
|
|
@reload-page="reloadPageTab"
|
|
@logo-click="onLogoClick"
|
|
@screen-size-change="screenSizeChange"
|
|
@set-home-components="setHomeComponents"
|
|
@tab-context-menu="onTabContextMenu"
|
|
>
|
|
<!-- 路由出口 -->
|
|
<router-layout />
|
|
<!-- logo 图标 -->
|
|
<template #logo>
|
|
<img :src="logoPath" alt="logo" />
|
|
</template>
|
|
<!-- 顶栏右侧区域 -->
|
|
<template #right>
|
|
<header-tools :fullscreen="fullscreen" @fullscreen="onFullscreen" />
|
|
</template>
|
|
<!-- 全局页脚 -->
|
|
<template #footer>
|
|
<page-footer />
|
|
</template>
|
|
<!-- 菜单图标 -->
|
|
<template #icon="{ icon }">
|
|
<component :is="icon" class="ant-menu-item-icon" />
|
|
</template>
|
|
<!-- 自定义菜单标题增加徽章、小红点 -->
|
|
<template #title="{ item }">
|
|
<menu-title :item="item" />
|
|
</template>
|
|
<template #top-title="{ item }">
|
|
<menu-title :item="item" />
|
|
</template>
|
|
<template #nav-title="{ item }">
|
|
<menu-title :item="item" />
|
|
</template>
|
|
</ele-pro-layout>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref } from 'vue';
|
|
import { useRouter } from 'vue-router';
|
|
import { storeToRefs } from 'pinia';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { message } from 'ant-design-vue/es';
|
|
import { toggleFullscreen, isFullscreen } from 'ele-admin-pro/es';
|
|
import { useTenantStore } from '@/store/modules/tenant';
|
|
import { useUserStore } from '@/store/modules/user';
|
|
import { useThemeStore } from '@/store/modules/theme';
|
|
import RouterLayout from '@/components/RouterLayout/index.vue';
|
|
import HeaderTools from './components/header-tools.vue';
|
|
import PageFooter from './components/page-footer.vue';
|
|
import MenuTitle from './components/menu-title.vue';
|
|
import {
|
|
HIDE_SIDEBARS,
|
|
HIDE_FOOTERS,
|
|
REPEATABLE_TABS,
|
|
HOME_TITLE,
|
|
HOME_PATH,
|
|
LAYOUT_PATH,
|
|
REDIRECT_PATH,
|
|
I18N_ENABLE
|
|
} from '@/config/setting';
|
|
import {
|
|
addPageTab,
|
|
removePageTab,
|
|
removeAllPageTab,
|
|
removeLeftPageTab,
|
|
removeRightPageTab,
|
|
removeOtherPageTab,
|
|
reloadPageTab,
|
|
setHomeComponents
|
|
} from '@/utils/page-tab-util';
|
|
import type { TabCtxMenuOption } from 'ele-admin-pro/es/ele-pro-layout/types';
|
|
|
|
const { push } = useRouter();
|
|
const { t, locale } = useI18n();
|
|
const tenantStore = useTenantStore();
|
|
const userStore = useUserStore();
|
|
const themeStore = useThemeStore();
|
|
// 租户信息
|
|
const { company } = storeToRefs(tenantStore);
|
|
// 网站名称
|
|
const projectName = company.value?.shortName || '网站名称';
|
|
// 网站LOGO
|
|
const logoPath =
|
|
company.value?.companyLogo || 'https://www.gxwebsoft.com/ws-logo.svg';
|
|
|
|
// 是否全屏
|
|
const fullscreen = ref(false);
|
|
|
|
// 菜单数据
|
|
const { menus } = storeToRefs(userStore);
|
|
|
|
// 布局风格
|
|
const {
|
|
tabs,
|
|
collapse,
|
|
sideNavCollapse,
|
|
bodyFullscreen,
|
|
showTabs,
|
|
showFooter,
|
|
headStyle,
|
|
sideStyle,
|
|
layoutStyle,
|
|
sideMenuStyle,
|
|
tabStyle,
|
|
fixedHeader,
|
|
fixedSidebar,
|
|
fixedBody,
|
|
bodyFull,
|
|
logoAutoSize,
|
|
colorfulIcon,
|
|
sideUniqueOpen,
|
|
styleResponsive
|
|
} = storeToRefs(themeStore);
|
|
|
|
/* 侧栏折叠切换 */
|
|
const updateCollapse = (value: boolean) => {
|
|
themeStore.setCollapse(value);
|
|
};
|
|
|
|
/* 双侧栏一级折叠切换 */
|
|
const updateSideNavCollapse = (value: boolean) => {
|
|
themeStore.setSideNavCollapse(value);
|
|
};
|
|
|
|
/* 内容区域全屏切换 */
|
|
const updateBodyFullscreen = (value: boolean) => {
|
|
themeStore.setBodyFullscreen(value);
|
|
};
|
|
|
|
/* logo 点击事件 */
|
|
const onLogoClick = (isHome: boolean) => {
|
|
isHome || push(LAYOUT_PATH);
|
|
};
|
|
|
|
/* 监听屏幕尺寸改变 */
|
|
const screenSizeChange = () => {
|
|
themeStore.updateScreenSize();
|
|
fullscreen.value = isFullscreen();
|
|
};
|
|
|
|
/* 全屏切换 */
|
|
const onFullscreen = () => {
|
|
try {
|
|
fullscreen.value = toggleFullscreen();
|
|
} catch (e) {
|
|
message.error('您的浏览器不支持全屏模式');
|
|
}
|
|
};
|
|
|
|
/* 页签右键菜单点击事件 */
|
|
const onTabContextMenu = ({
|
|
key,
|
|
tabKey,
|
|
item,
|
|
active
|
|
}: TabCtxMenuOption) => {
|
|
switch (key) {
|
|
case 'reload': // 刷新
|
|
reloadPageTab({
|
|
isHome: !item,
|
|
fullPath: item?.fullPath ?? tabKey
|
|
});
|
|
break;
|
|
case 'close': // 关闭当前
|
|
removePageTab({
|
|
key: item?.fullPath ?? tabKey,
|
|
active
|
|
});
|
|
break;
|
|
case 'left': // 关闭左侧
|
|
removeLeftPageTab({
|
|
key: tabKey,
|
|
active
|
|
});
|
|
break;
|
|
case 'right': // 关闭右侧
|
|
removeRightPageTab({
|
|
key: tabKey,
|
|
active
|
|
});
|
|
break;
|
|
case 'other': // 关闭其他
|
|
removeOtherPageTab({
|
|
key: tabKey,
|
|
active
|
|
});
|
|
break;
|
|
}
|
|
};
|
|
|
|
/* 菜单标题国际化 */
|
|
const i18n = (_path: string, key?: string) => {
|
|
if (!I18N_ENABLE || !key) {
|
|
return;
|
|
}
|
|
const k = 'route.' + key + '._name';
|
|
const title = t(k);
|
|
if (title !== k) {
|
|
return title;
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<script lang="ts">
|
|
import * as MenuIcons from './menu-icons';
|
|
|
|
export default {
|
|
name: 'EleLayout',
|
|
components: MenuIcons
|
|
};
|
|
</script>
|
|
|
|
<style lang="less">
|
|
// 侧栏菜单徽章样式,定位在右侧垂直居中并调小尺寸
|
|
.ele-menu-badge {
|
|
position: absolute;
|
|
top: 50%;
|
|
right: 14px;
|
|
line-height: 1;
|
|
margin-top: -9px;
|
|
font-size: 0;
|
|
|
|
.ant-badge-count {
|
|
height: 18px;
|
|
line-height: 18px;
|
|
border-radius: 9px;
|
|
box-shadow: none;
|
|
min-width: 18px;
|
|
padding: 0 4px;
|
|
}
|
|
|
|
.ant-scroll-number-only {
|
|
height: 18px;
|
|
|
|
& > p.ant-scroll-number-only-unit {
|
|
height: 18px;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 父级菜单标题中右侧多定位一点,避免与箭头重合
|
|
.ant-menu-submenu-title > .ant-menu-title-content .ele-menu-badge {
|
|
right: 36px;
|
|
}
|
|
|
|
// 折叠悬浮中样式调整
|
|
.ant-menu-submenu-popup {
|
|
.ant-menu-submenu-title > .ant-menu-title-content .ele-menu-badge {
|
|
right: 30px;
|
|
}
|
|
}
|
|
|
|
// 顶栏菜单标题中样式调整
|
|
.ele-admin-header-nav > .ant-menu {
|
|
& > .ant-menu-item,
|
|
& > .ant-menu-submenu > .ant-menu-submenu-title {
|
|
& > .ant-menu-title-content .ele-menu-badge {
|
|
position: static;
|
|
right: auto;
|
|
top: auto;
|
|
display: inline-block;
|
|
vertical-align: 5px;
|
|
margin: 0 0 0 4px;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 双侧栏时一级侧栏菜单中样式调整,定位在右上角
|
|
.ele-admin-sidebar-nav-menu > .ant-menu {
|
|
& > .ant-menu-item,
|
|
& > .ant-menu-submenu > .ant-menu-submenu-title {
|
|
& > .ant-menu-title-content .ele-menu-badge {
|
|
top: 0;
|
|
right: 0;
|
|
margin: 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 双侧栏时一级侧栏菜单折叠后样式调整
|
|
.ele-admin-nav-collapse .ele-admin-sidebar-nav-menu > .ant-menu {
|
|
& > .ant-menu-item,
|
|
& > .ant-menu-submenu > .ant-menu-submenu-title {
|
|
& > .ant-menu-title-content .ele-menu-badge {
|
|
top: 0;
|
|
right: 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 菜单折叠后在 tooltip 中不显示徽章
|
|
.ant-tooltip-inner .ele-menu-badge {
|
|
display: none;
|
|
}
|
|
|
|
// logo
|
|
.ele-admin-logo {
|
|
margin-right: 12px;
|
|
img {
|
|
border-radius: 4px !important;
|
|
}
|
|
}
|
|
</style>
|