vben
2020-12-03 c303ec1a23c4b1fbad4fbda9007af2147dc327e2
提交 | 用户 | age
ba068b 1 import './index.less';
V 2
0692b4 3 import type { FunctionalComponent } from 'vue';
e5f8ce 4 import type { Component } from '/@/components/types';
0692b4 5
25d43a 6 import { defineComponent, unref, computed, ref, nextTick } from 'vue';
770283 7
710158 8 import { Layout, Tooltip, Badge } from 'ant-design-vue';
ba068b 9 import { AppLogo } from '/@/components/Application';
2f6253 10 import UserDropdown from './UserDropdown';
0692b4 11 import LayoutMenu from '../menu';
c303ec 12 import LayoutBreadcrumb from './LayoutBreadcrumb.vue';
0692b4 13 import LockAction from '../lock/LockAction';
439291 14 import LayoutTrigger from '../LayoutTrigger';
V 15 import NoticeAction from './notice/NoticeActionItem.vue';
2f6253 16 import {
17   RedoOutlined,
18   FullscreenExitOutlined,
19   FullscreenOutlined,
20   LockOutlined,
710158 21   BugOutlined,
2f6253 22 } from '@ant-design/icons-vue';
ba068b 23 import { useModal } from '/@/components/Modal';
770283 24
2f6253 25 import { useFullscreen } from '/@/hooks/web/useFullScreen';
26 import { useTabs } from '/@/hooks/web/useTabs';
d9b196 27 import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
ba068b 28 import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
V 29 import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
30 import { useRootSetting } from '/@/hooks/setting/useRootSetting';
e5f8ce 31 import { useLocaleSetting } from '/@/hooks/setting/useLocaleSetting';
770283 32
ba068b 33 import { useRouter } from 'vue-router';
V 34
770283 35 import { errorStore } from '/@/store/modules/error';
V 36
ba068b 37 import { PageEnum } from '/@/enums/pageEnum';
V 38 import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
e5f8ce 39 import { AppLocalePicker } from '/@/components/Application';
V 40 import { useI18n } from '/@/hooks/web/useI18n';
73c8e0 41 import { propTypes } from '/@/utils/propTypes';
439291 42
0692b4 43 interface TooltipItemProps {
V 44   title: string;
45 }
46
47 const TooltipItem: FunctionalComponent<TooltipItemProps> = (props, { slots }) => {
48   return (
49     <Tooltip>
50       {{
51         title: () => props.title,
52         default: () => slots.default?.(),
53       }}
54     </Tooltip>
55   );
56 };
57
2f6253 58 export default defineComponent({
ba068b 59   name: 'LayoutHeader',
0692b4 60   props: {
73c8e0 61     fixed: propTypes.bool,
0692b4 62   },
V 63   setup(props) {
6e03e0 64     let logoEl: Element | null | undefined;
770283 65
25d43a 66     const logoWidthRef = ref(200);
6e03e0 67     const logoRef = ref<ComponentRef>(null);
6bffdb 68     const { refreshPage } = useTabs();
962f90 69     const { t } = useI18n();
ba068b 70
V 71     const { getShowTopMenu, getShowHeaderTrigger, getSplit, getTopMenuAlign } = useMenuSetting();
72
e5f8ce 73     const { getShowLocale } = useLocaleSetting();
ba068b 74     const { getUseErrorHandle, getShowBreadCrumbIcon } = useRootSetting();
V 75
76     const {
0692b4 77       getHeaderTheme,
ba068b 78       getShowRedo,
V 79       getUseLockPage,
80       getShowFullScreen,
81       getShowNotice,
82       getShowContent,
83       getShowBread,
84       getShowHeaderLogo,
85     } = useHeaderSetting();
86
6bffdb 87     const { push } = useRouter();
2f6253 88     const [register, { openModal }] = useModal();
89     const { toggleFullscreen, isFullscreenRef } = useFullscreen();
2f1255 90
V 91     useWindowSizeFn(
92       () => {
25d43a 93         nextTick(() => {
V 94           if (!unref(getShowTopMenu)) return;
95           let width = 0;
96           if (!logoEl) {
6e03e0 97             logoEl = unref(logoRef)?.$el;
0692b4 98           } else {
25d43a 99             width += logoEl.clientWidth;
V 100           }
101           logoWidthRef.value = width + 80;
102         });
2f1255 103       },
V 104       200,
105       { immediate: true }
106     );
2f6253 107
108     const headerClass = computed(() => {
0692b4 109       const theme = unref(getHeaderTheme);
2f6253 110       return theme ? `layout-header__header--${theme}` : '';
111     });
710158 112
ba068b 113     const getSplitType = computed(() => {
V 114       return unref(getSplit) ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE;
115     });
116
117     const getMenuMode = computed(() => {
118       return unref(getSplit) ? MenuModeEnum.HORIZONTAL : null;
4f6b65 119     });
V 120
710158 121     function handleToErrorList() {
ba068b 122       push(PageEnum.ERROR_LOG_PAGE).then(() => {
V 123         errorStore.commitErrorListCountState(0);
124       });
710158 125     }
V 126
2f6253 127     function handleLockPage() {
128       openModal(true);
129     }
770283 130
ba068b 131     function renderHeaderContent() {
25d43a 132       const width = unref(logoWidthRef);
ba068b 133       return (
V 134         <div class="layout-header__content ">
135           {unref(getShowHeaderLogo) && (
0692b4 136             <AppLogo class={`layout-header__logo`} ref={logoRef} theme={unref(getHeaderTheme)} />
ba068b 137           )}
770283 138
ba068b 139           {unref(getShowContent) && (
V 140             <div class="layout-header__left">
141               {unref(getShowHeaderTrigger) && (
0692b4 142                 <LayoutTrigger theme={unref(getHeaderTheme)} sider={false} />
ba068b 143               )}
V 144               {unref(getShowBread) && <LayoutBreadcrumb showIcon={unref(getShowBreadCrumbIcon)} />}
145             </div>
146           )}
147
148           {unref(getShowTopMenu) && (
149             <div class={[`layout-header__menu `]} style={{ width: `calc(100% - ${width}px)` }}>
150               <LayoutMenu
151                 isHorizontal={true}
152                 class={`justify-${unref(getTopMenuAlign)}`}
0692b4 153                 theme={unref(getHeaderTheme)}
ba068b 154                 splitType={unref(getSplitType)}
V 155                 menuMode={unref(getMenuMode)}
156                 showSearch={false}
157               />
158             </div>
159           )}
160         </div>
161       );
162     }
163
164     function renderActionDefault(Comp: Component | any, event: Fn) {
165       return (
e5f8ce 166         <div class="layout-header__action-item" onClick={event}>
V 167           <Comp class="layout-header__action-icon" />
ba068b 168         </div>
V 169       );
170     }
171
172     function renderAction() {
173       return (
174         <div class={`layout-header__action`}>
175           {unref(getUseErrorHandle) && (
e5f8ce 176             <TooltipItem title={t('layout.header.tooltipErrorLog')}>
0692b4 177               {() => (
V 178                 <Badge
179                   count={errorStore.getErrorListCountState}
180                   offset={[0, 10]}
181                   dot
182                   overflowCount={99}
183                 >
184                   {() => renderActionDefault(BugOutlined, handleToErrorList)}
185                 </Badge>
186               )}
187             </TooltipItem>
ba068b 188           )}
V 189
190           {unref(getUseLockPage) && (
e5f8ce 191             <TooltipItem title={t('layout.header.tooltipLock')}>
0692b4 192               {() => renderActionDefault(LockOutlined, handleLockPage)}
V 193             </TooltipItem>
ba068b 194           )}
V 195
196           {unref(getShowNotice) && (
e5f8ce 197             <TooltipItem title={t('layout.header.tooltipNotify')}>
V 198               {() => <NoticeAction />}
199             </TooltipItem>
ba068b 200           )}
V 201
202           {unref(getShowRedo) && (
e5f8ce 203             <TooltipItem title={t('layout.header.tooltipRedo')}>
0692b4 204               {() => renderActionDefault(RedoOutlined, refreshPage)}
V 205             </TooltipItem>
ba068b 206           )}
V 207
208           {unref(getShowFullScreen) && (
e5f8ce 209             <TooltipItem
V 210               title={
211                 unref(isFullscreenRef)
212                   ? t('layout.header.tooltipExitFull')
213                   : t('layout.header.tooltipEntryFull')
214               }
215             >
0692b4 216               {() => {
V 217                 const Icon = !unref(isFullscreenRef) ? (
218                   <FullscreenOutlined />
219                 ) : (
220                   <FullscreenExitOutlined />
221                 );
222                 return renderActionDefault(Icon, toggleFullscreen);
ba068b 223               }}
0692b4 224             </TooltipItem>
ba068b 225           )}
e5f8ce 226           <UserDropdown class="layout-header__user-dropdown" />
V 227           {unref(getShowLocale) && (
228             <AppLocalePicker
229               reload={true}
230               showText={false}
231               class="layout-header__action-item locale"
232             />
233           )}
ba068b 234         </div>
V 235       );
236     }
237
238     function renderHeaderDefault() {
239       return (
240         <>
241           {renderHeaderContent()}
242           {renderAction()}
243           <LockAction onRegister={register} />
244         </>
245       );
246     }
247
248     return () => {
2f6253 249       return (
0692b4 250         <Layout.Header
V 251           class={['layout-header', 'flex p-0 px-4 ', unref(headerClass), { fixed: props.fixed }]}
252         >
ba068b 253           {() => renderHeaderDefault()}
2f6253 254         </Layout.Header>
255       );
256     };
257   },
258 });