Blame view

src/layouts/default/header/LayoutHeader.tsx 8.39 KB
1
import { defineComponent, unref, computed, ref } from 'vue';
2
vben authored
3
import { Layout, Tooltip, Badge } from 'ant-design-vue';
vben authored
4
import Logo from '/@/layouts/logo/index.vue';
陈文彬 authored
5
import UserDropdown from './UserDropdown';
vben authored
6
import LayoutMenu from '/@/layouts/default/menu/LayoutMenu';
陈文彬 authored
7
import LayoutBreadcrumb from './LayoutBreadcrumb';
vben authored
8
9
10
import LockAction from './LockActionItem';
import LayoutTrigger from '../LayoutTrigger';
import NoticeAction from './notice/NoticeActionItem.vue';
陈文彬 authored
11
12
13
14
15
16
import {
  RedoOutlined,
  FullscreenExitOutlined,
  FullscreenOutlined,
  GithubFilled,
  LockOutlined,
vben authored
17
  BugOutlined,
陈文彬 authored
18
} from '@ant-design/icons-vue';
19
陈文彬 authored
20
21
import { useFullscreen } from '/@/hooks/web/useFullScreen';
import { useTabs } from '/@/hooks/web/useTabs';
22
import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
23
import { useRouter } from 'vue-router';
24
25
26
27
28
import { useModal } from '/@/components/Modal/index';

import { appStore } from '/@/store/modules/app';
import { errorStore } from '/@/store/modules/error';
29
import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum';
30
import { GITHUB_URL } from '/@/settings/siteSetting';
vben authored
31
32

import './index.less';
陈文彬 authored
33
34
35
export default defineComponent({
  name: 'DefaultLayoutHeader',
  setup() {
36
    const widthRef = ref(200);
37
38
    let logoEl: Element | null;
39
40
    const { refreshPage } = useTabs();
    const { push } = useRouter();
陈文彬 authored
41
42
    const [register, { openModal }] = useModal();
    const { toggleFullscreen, isFullscreenRef } = useFullscreen();
43
陈文彬 authored
44
45
46
    const getProjectConfigRef = computed(() => {
      return appStore.getProjectConfig;
    });
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    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 }
    );
陈文彬 authored
71
72
73
74
75
76
77
78
79

    function goToGithub() {
      window.open(GITHUB_URL, '__blank');
    }

    const headerClass = computed(() => {
      const theme = unref(getProjectConfigRef).headerSetting.theme;
      return theme ? `layout-header__header--${theme}` : '';
    });
vben authored
80
81
    const showHeaderTrigger = computed(() => {
82
83
      const { show, trigger, hidden, type } = unref(getProjectConfigRef).menuSetting;
      if (type === MenuTypeEnum.TOP_MENU || !show || !hidden) return false;
84
85
86
      return trigger === TriggerEnum.HEADER;
    });
vben authored
87
88
    function handleToErrorList() {
      errorStore.commitErrorListCountState(0);
89
      push('/exception/error-log');
vben authored
90
91
    }
陈文彬 authored
92
93
94
95
96
97
    /**
     * @description: 锁定屏幕
     */
    function handleLockPage() {
      openModal(true);
    }
98
陈文彬 authored
99
100
101
    return () => {
      const getProjectConfig = unref(getProjectConfigRef);
      const {
vben authored
102
        useErrorHandle,
陈文彬 authored
103
        showLogo,
104
        multiTabsSetting: { show: showTab },
chen-xt authored
105
106
107
108
109
110
111
112
        headerSetting: {
          theme: headerTheme,
          useLockPage,
          showRedo,
          showGithub,
          showFullScreen,
          showNotice,
        },
陈文彬 authored
113
114
        menuSetting: { mode, type: menuType, split: splitMenu, topMenuAlign },
        showBreadCrumb,
115
        showBreadCrumbIcon,
陈文彬 authored
116
117
118
      } = getProjectConfig;

      const isSidebarType = menuType === MenuTypeEnum.SIDEBAR;
119
120
      const width = unref(widthRef);
121
陈文彬 authored
122
      return (
123
        <Layout.Header class={['layout-header', 'flex p-0 px-4 ', unref(headerClass)]}>
陈文彬 authored
124
125
          {() => (
            <>
126
              <div class="layout-header__content ">
127
128
                {showLogo && !isSidebarType && (
                  <Logo class={`layout-header__logo`} theme={headerTheme} />
陈文彬 authored
129
                )}
130
131
132
133
134
135
136
137

                <div class="layout-header__left">
                  {unref(showHeaderTrigger) && <LayoutTrigger theme={headerTheme} sider={false} />}
                  {mode !== MenuModeEnum.HORIZONTAL && showBreadCrumb && !splitMenu && (
                    <LayoutBreadcrumb showIcon={showBreadCrumbIcon} />
                  )}
                </div>
138
139
                {unref(showTopMenu) && (
                  <div
140
                    class={[`layout-header__menu `]}
141
142
                    style={{ width: `calc(100% - ${unref(width)}px)` }}
                  >
陈文彬 authored
143
                    <LayoutMenu
144
145
                      isTop={true}
                      class={`justify-${topMenuAlign}`}
陈文彬 authored
146
147
148
149
150
151
152
153
154
155
                      theme={headerTheme}
                      splitType={splitMenu ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE}
                      menuMode={splitMenu ? MenuModeEnum.HORIZONTAL : null}
                      showSearch={false}
                    />
                  </div>
                )}
              </div>

              <div class={`layout-header__action`}>
vben authored
156
157
158
159
160
161
162
163
                {useErrorHandle && (
                  <Tooltip>
                    {{
                      title: () => '错误日志',
                      default: () => (
                        <Badge
                          count={errorStore.getErrorListCountState}
                          offset={[0, 10]}
164
                          dot
vben authored
165
166
167
168
169
170
171
172
173
174
175
176
177
                          overflowCount={99}
                        >
                          {() => (
                            <div class={`layout-header__action-item`} onClick={handleToErrorList}>
                              <BugOutlined class={`layout-header__action-icon`} />
                            </div>
                          )}
                        </Badge>
                      ),
                    }}
                  </Tooltip>
                )}
陈文彬 authored
178
179
180
181
182
183
184
185
186
187
188
189
                {showGithub && (
                  <Tooltip>
                    {{
                      title: () => 'github',
                      default: () => (
                        <div class={`layout-header__action-item`} onClick={goToGithub}>
                          <GithubFilled class={`layout-header__action-icon`} />
                        </div>
                      ),
                    }}
                  </Tooltip>
                )}
vben authored
190
                {useLockPage && (
陈文彬 authored
191
192
193
194
195
196
197
198
199
200
201
                  <Tooltip>
                    {{
                      title: () => '锁定屏幕',
                      default: () => (
                        <div class={`layout-header__action-item`} onClick={handleLockPage}>
                          <LockOutlined class={`layout-header__action-icon`} />
                        </div>
                      ),
                    }}
                  </Tooltip>
                )}
chen-xt authored
202
203
204
205
                {showNotice && (
                  <div>
                    <Tooltip>
                      {{
206
207
                        title: () => '消息通知',
                        default: () => <NoticeAction />,
chen-xt authored
208
209
210
211
                      }}
                    </Tooltip>
                  </div>
                )}
212
                {showRedo && showTab && (
陈文彬 authored
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
                  <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>
      );
    };
  },
});