mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 06:58:53 +08:00
253 lines
8.4 KiB
TypeScript
253 lines
8.4 KiB
TypeScript
import { defineComponent, unref, computed, ref } from 'vue';
|
|
|
|
import { Layout, Tooltip, Badge } from 'ant-design-vue';
|
|
import Logo from '/@/layouts/logo/index.vue';
|
|
import UserDropdown from './UserDropdown';
|
|
import LayoutMenu from '/@/layouts/default/menu/LayoutMenu';
|
|
import LayoutBreadcrumb from './LayoutBreadcrumb';
|
|
import LockAction from './LockActionItem';
|
|
import LayoutTrigger from '../LayoutTrigger';
|
|
import NoticeAction from './notice/NoticeActionItem.vue';
|
|
import {
|
|
RedoOutlined,
|
|
FullscreenExitOutlined,
|
|
FullscreenOutlined,
|
|
GithubFilled,
|
|
LockOutlined,
|
|
BugOutlined,
|
|
} from '@ant-design/icons-vue';
|
|
|
|
import { useFullscreen } from '/@/hooks/web/useFullScreen';
|
|
import { useTabs } from '/@/hooks/web/useTabs';
|
|
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
|
import { useRouter } from 'vue-router';
|
|
import { useModal } from '/@/components/Modal';
|
|
|
|
import { appStore } from '/@/store/modules/app';
|
|
import { errorStore } from '/@/store/modules/error';
|
|
|
|
import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum';
|
|
import { GITHUB_URL } from '/@/settings/siteSetting';
|
|
|
|
import './index.less';
|
|
export default defineComponent({
|
|
name: 'DefaultLayoutHeader',
|
|
setup() {
|
|
const widthRef = ref(200);
|
|
let logoEl: Element | null;
|
|
|
|
const { refreshPage } = useTabs();
|
|
const { push } = useRouter();
|
|
const [register, { openModal }] = useModal();
|
|
const { toggleFullscreen, isFullscreenRef } = useFullscreen();
|
|
|
|
const getProjectConfigRef = computed(() => {
|
|
return appStore.getProjectConfig;
|
|
});
|
|
|
|
const showTopMenu = computed(() => {
|
|
const getProjectConfig = unref(getProjectConfigRef);
|
|
const {
|
|
menuSetting: { mode, split: splitMenu },
|
|
} = getProjectConfig;
|
|
return mode === MenuModeEnum.HORIZONTAL || splitMenu;
|
|
});
|
|
|
|
useWindowSizeFn(
|
|
() => {
|
|
if (!unref(showTopMenu)) return;
|
|
let width = 0;
|
|
if (!logoEl) {
|
|
logoEl = document.querySelector('.layout-header__logo');
|
|
}
|
|
if (logoEl) {
|
|
width += logoEl.clientWidth;
|
|
}
|
|
widthRef.value = width + 60;
|
|
},
|
|
200,
|
|
{ immediate: true }
|
|
);
|
|
|
|
function goToGithub() {
|
|
window.open(GITHUB_URL, '__blank');
|
|
}
|
|
|
|
const headerClass = computed(() => {
|
|
const theme = unref(getProjectConfigRef).headerSetting.theme;
|
|
return theme ? `layout-header__header--${theme}` : '';
|
|
});
|
|
|
|
const showHeaderTrigger = computed(() => {
|
|
const { show, trigger, hidden, type } = unref(getProjectConfigRef).menuSetting;
|
|
if (type === MenuTypeEnum.TOP_MENU || !show || !hidden) return false;
|
|
return trigger === TriggerEnum.HEADER;
|
|
});
|
|
|
|
function handleToErrorList() {
|
|
errorStore.commitErrorListCountState(0);
|
|
push('/exception/error-log');
|
|
}
|
|
|
|
/**
|
|
* @description: 锁定屏幕
|
|
*/
|
|
function handleLockPage() {
|
|
openModal(true);
|
|
}
|
|
|
|
return () => {
|
|
const getProjectConfig = unref(getProjectConfigRef);
|
|
const {
|
|
useErrorHandle,
|
|
showLogo,
|
|
multiTabsSetting: { show: showTab },
|
|
headerSetting: {
|
|
theme: headerTheme,
|
|
useLockPage,
|
|
showRedo,
|
|
showGithub,
|
|
showFullScreen,
|
|
showNotice,
|
|
},
|
|
menuSetting: { mode, type: menuType, split: splitMenu, topMenuAlign },
|
|
showBreadCrumb,
|
|
showBreadCrumbIcon,
|
|
} = getProjectConfig;
|
|
|
|
const isSidebarType = menuType === MenuTypeEnum.SIDEBAR;
|
|
|
|
const width = unref(widthRef);
|
|
|
|
return (
|
|
<Layout.Header class={['layout-header', 'flex p-0 px-4 ', unref(headerClass)]}>
|
|
{() => (
|
|
<>
|
|
<div class="layout-header__content ">
|
|
{showLogo && !isSidebarType && (
|
|
<Logo class={`layout-header__logo`} theme={headerTheme} />
|
|
)}
|
|
|
|
<div class="layout-header__left">
|
|
{unref(showHeaderTrigger) && <LayoutTrigger theme={headerTheme} sider={false} />}
|
|
{mode !== MenuModeEnum.HORIZONTAL && showBreadCrumb && !splitMenu && (
|
|
<LayoutBreadcrumb showIcon={showBreadCrumbIcon} />
|
|
)}
|
|
</div>
|
|
|
|
{unref(showTopMenu) && (
|
|
<div
|
|
class={[`layout-header__menu `]}
|
|
style={{ width: `calc(100% - ${unref(width)}px)` }}
|
|
>
|
|
<LayoutMenu
|
|
isTop={true}
|
|
class={`justify-${topMenuAlign}`}
|
|
theme={headerTheme}
|
|
splitType={splitMenu ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE}
|
|
menuMode={splitMenu ? MenuModeEnum.HORIZONTAL : null}
|
|
showSearch={false}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div class={`layout-header__action`}>
|
|
{useErrorHandle && (
|
|
<Tooltip>
|
|
{{
|
|
title: () => '错误日志',
|
|
default: () => (
|
|
<Badge
|
|
count={errorStore.getErrorListCountState}
|
|
offset={[0, 10]}
|
|
dot
|
|
overflowCount={99}
|
|
>
|
|
{() => (
|
|
<div class={`layout-header__action-item`} onClick={handleToErrorList}>
|
|
<BugOutlined class={`layout-header__action-icon`} />
|
|
</div>
|
|
)}
|
|
</Badge>
|
|
),
|
|
}}
|
|
</Tooltip>
|
|
)}
|
|
|
|
{showGithub && (
|
|
<Tooltip>
|
|
{{
|
|
title: () => 'github',
|
|
default: () => (
|
|
<div class={`layout-header__action-item`} onClick={goToGithub}>
|
|
<GithubFilled class={`layout-header__action-icon`} />
|
|
</div>
|
|
),
|
|
}}
|
|
</Tooltip>
|
|
)}
|
|
{useLockPage && (
|
|
<Tooltip>
|
|
{{
|
|
title: () => '锁定屏幕',
|
|
default: () => (
|
|
<div class={`layout-header__action-item`} onClick={handleLockPage}>
|
|
<LockOutlined class={`layout-header__action-icon`} />
|
|
</div>
|
|
),
|
|
}}
|
|
</Tooltip>
|
|
)}
|
|
{showNotice && (
|
|
<div>
|
|
<Tooltip>
|
|
{{
|
|
title: () => '消息通知',
|
|
default: () => <NoticeAction />,
|
|
}}
|
|
</Tooltip>
|
|
</div>
|
|
)}
|
|
{showRedo && showTab && (
|
|
<Tooltip>
|
|
{{
|
|
title: () => '刷新',
|
|
default: () => (
|
|
<div class={`layout-header__action-item`} onClick={refreshPage}>
|
|
<RedoOutlined class={`layout-header__action-icon`} />
|
|
</div>
|
|
),
|
|
}}
|
|
</Tooltip>
|
|
)}
|
|
{showFullScreen && (
|
|
<Tooltip>
|
|
{{
|
|
title: () => (unref(isFullscreenRef) ? '退出全屏' : '全屏'),
|
|
default: () => {
|
|
const Icon: any = !unref(isFullscreenRef) ? (
|
|
<FullscreenOutlined />
|
|
) : (
|
|
<FullscreenExitOutlined />
|
|
);
|
|
return (
|
|
<div class={`layout-header__action-item`} onClick={toggleFullscreen}>
|
|
<Icon class={`layout-header__action-icon`} />
|
|
</div>
|
|
);
|
|
},
|
|
}}
|
|
</Tooltip>
|
|
)}
|
|
<UserDropdown class={`layout-header__user-dropdown`} />
|
|
</div>
|
|
<LockAction onRegister={register} />
|
|
</>
|
|
)}
|
|
</Layout.Header>
|
|
);
|
|
};
|
|
},
|
|
});
|