Blame view

src/layouts/default/header/UserDropdown.tsx 3.01 KB
陈文彬 authored
1
// components
vben authored
2
import { Dropdown, Menu } from 'ant-design-vue';
陈文彬 authored
3
4
5
6
7
8
9
10
11
12
13

import { defineComponent, computed, unref } from 'vue';

// res
import headerImg from '/@/assets/images/header.jpg';

import Icon from '/@/components/Icon/index';

import { userStore } from '/@/store/modules/user';

import { DOC_URL } from '/@/settings/siteSetting';
vben authored
14
15
16
17

import { openWindow } from '/@/utils';

import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
vben authored
18
import { FunctionalComponent } from 'vue';
vben authored
19
import { useI18n } from '/@/hooks/web/useI18n';
vben authored
20
vben authored
21
22
type MenuEvent = 'loginOut' | 'doc';
interface MenuItemProps {
vben authored
23
24
  icon: string;
  text: string;
vben authored
25
  key: MenuEvent;
vben authored
26
}
陈文彬 authored
27
28

const prefixCls = 'user-dropdown';
vben authored
29
vben authored
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const MenuItem: FunctionalComponent<MenuItemProps> = (props) => {
  const { key, icon, text } = props;
  return (
    <Menu.Item key={key}>
      {() => (
        <span class="flex items-center">
          <Icon icon={icon} class="mr-1" />
          <span>{text}</span>
        </span>
      )}
    </Menu.Item>
  );
};
陈文彬 authored
44
45
46
export default defineComponent({
  name: 'UserDropdown',
  setup() {
47
    const { t } = useI18n();
vben authored
48
    const { getShowDoc } = useHeaderSetting();
陈文彬 authored
49
50
51
52
53
54
    const getUserInfo = computed(() => {
      const { realName = '', desc } = userStore.getUserInfoState || {};
      return { realName, desc };
    });
55
    //  login out
陈文彬 authored
56
57
58
59
    function handleLoginOut() {
      userStore.confirmLoginOut();
    }
60
    // open doc
陈文彬 authored
61
    function openDoc() {
vben authored
62
      openWindow(DOC_URL);
陈文彬 authored
63
64
    }
vben authored
65
66
67
68
69
70
71
72
    function handleMenuClick(e: { key: MenuEvent }) {
      switch (e.key) {
        case 'loginOut':
          handleLoginOut();
          break;
        case 'doc':
          openDoc();
          break;
陈文彬 authored
73
74
      }
    }
75
vben authored
76
    function renderSlotsDefault() {
陈文彬 authored
77
      const { realName } = unref(getUserInfo);
vben authored
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
      return (
        <section class={prefixCls}>
          <img class={`${prefixCls}__header`} src={headerImg} />
          <section class={`${prefixCls}__info`}>
            <section class={`${prefixCls}__name`}>{realName}</section>
          </section>
        </section>
      );
    }

    function renderSlotOverlay() {
      const showDoc = unref(getShowDoc);
      return (
        <Menu onClick={handleMenuClick}>
          {() => (
            <>
94
95
96
97
98
99
100
              {showDoc && (
                <MenuItem
                  key="doc"
                  text={t('layout.header.dropdownItemDoc')}
                  icon="gg:loadbar-doc"
                />
              )}
vben authored
101
102
103
104
              {/* @ts-ignore */}
              {showDoc && <Menu.Divider />}
              <MenuItem
                key="loginOut"
105
                text={t('layout.header.dropdownItemLoginOut')}
vben authored
106
107
                icon="ant-design:poweroff-outlined"
              />
vben authored
108
109
110
111
112
113
114
            </>
          )}
        </Menu>
      );
    }

    return () => {
陈文彬 authored
115
      return (
vben authored
116
        <Dropdown placement="bottomLeft" overlayClassName="app-layout-header-user-dropdown-overlay">
陈文彬 authored
117
          {{
vben authored
118
119
            default: () => renderSlotsDefault(),
            overlay: () => renderSlotOverlay(),
陈文彬 authored
120
121
122
123
124
125
          }}
        </Dropdown>
      );
    };
  },
});