提交 | 用户 | 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 |
}); |