vben
authored
|
1
2
|
<template>
<Dropdown placement="bottomLeft" :overlayClassName="`${prefixCls}-dropdown-overlay`">
|
vben
authored
|
3
|
<span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex">
|
|
4
|
<img :class="`${prefixCls}__header`" :src="getUserInfo.avatar" />
|
vben
authored
|
5
6
7
8
|
<span :class="`${prefixCls}__info hidden md:block`">
<span :class="`${prefixCls}__name `" class="truncate">
{{ getUserInfo.realName }}
</span>
|
vben
authored
|
9
10
11
12
|
</span>
</span>
<template #overlay>
|
|
13
|
<Menu @click="handleMenuClick">
|
vben
authored
|
14
15
16
|
<MenuItem
key="doc"
:text="t('layout.header.dropdownItemDoc')"
|
vben
authored
|
17
|
icon="ion:document-text-outline"
|
vben
authored
|
18
19
|
v-if="getShowDoc"
/>
|
Vben
authored
|
20
|
<MenuDivider v-if="getShowDoc" />
|
vben
authored
|
21
|
<MenuItem
|
Vben
authored
|
22
|
v-if="getUseLockPage"
|
vben
authored
|
23
24
25
26
27
|
key="lock"
:text="t('layout.header.tooltipLock')"
icon="ion:lock-closed-outline"
/>
<MenuItem
|
vben
authored
|
28
|
key="logout"
|
vben
authored
|
29
|
:text="t('layout.header.dropdownItemLoginOut')"
|
vben
authored
|
30
|
icon="ion:power-outline"
|
vben
authored
|
31
32
33
34
|
/>
</Menu>
</template>
</Dropdown>
|
vben
authored
|
35
|
<LockAction @register="register" />
|
vben
authored
|
36
37
38
39
|
</template>
<script lang="ts">
// components
import { Dropdown, Menu } from 'ant-design-vue';
|
|
40
|
import type { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
|
vben
authored
|
41
42
43
44
45
|
import { defineComponent, computed } from 'vue';
import { DOC_URL } from '/@/settings/siteSetting';
|
Vben
authored
|
46
|
import { useUserStore } from '/@/store/modules/user';
|
vben
authored
|
47
48
49
|
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
import { useI18n } from '/@/hooks/web/useI18n';
import { useDesign } from '/@/hooks/web/useDesign';
|
vben
authored
|
50
51
|
import { useModal } from '/@/components/Modal';
|
vben
authored
|
52
|
import headerImg from '/@/assets/images/header.jpg';
|
vben
authored
|
53
54
55
56
|
import { propTypes } from '/@/utils/propTypes';
import { openWindow } from '/@/utils';
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
vben
authored
|
57
|
|
|
58
|
type MenuEvent = 'logout' | 'doc' | 'lock';
|
vben
authored
|
59
60
61
62
63
64
65
66
|
export default defineComponent({
name: 'UserDropdown',
components: {
Dropdown,
Menu,
MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
MenuDivider: Menu.Divider,
|
vben
authored
|
67
|
LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
|
vben
authored
|
68
69
70
71
72
73
74
|
},
props: {
theme: propTypes.oneOf(['dark', 'light']),
},
setup() {
const { prefixCls } = useDesign('header-user-dropdown');
const { t } = useI18n();
|
Vben
authored
|
75
|
const { getShowDoc, getUseLockPage } = useHeaderSetting();
|
Vben
authored
|
76
|
const userStore = useUserStore();
|
vben
authored
|
77
78
|
const getUserInfo = computed(() => {
|
|
79
80
|
const { realName = '', avatar, desc } = userStore.getUserInfo || {};
return { realName, avatar: avatar || headerImg, desc };
|
vben
authored
|
81
82
|
});
|
vben
authored
|
83
84
85
86
87
88
|
const [register, { openModal }] = useModal();
function handleLock() {
openModal(true);
}
|
vben
authored
|
89
90
91
92
93
94
95
96
97
98
|
// login out
function handleLoginOut() {
userStore.confirmLoginOut();
}
// open doc
function openDoc() {
openWindow(DOC_URL);
}
|
|
99
100
|
function handleMenuClick(e: MenuInfo) {
switch (e.key as MenuEvent) {
|
|
101
102
103
104
105
106
107
108
109
110
111
|
case 'logout':
handleLoginOut();
break;
case 'doc':
openDoc();
break;
case 'lock':
handleLock();
break;
}
}
|
vben
authored
|
112
113
114
115
116
|
return {
prefixCls,
t,
getUserInfo,
|
|
117
|
handleMenuClick,
|
vben
authored
|
118
|
getShowDoc,
|
vben
authored
|
119
|
register,
|
Vben
authored
|
120
|
getUseLockPage,
|
vben
authored
|
121
122
123
124
125
126
127
128
|
};
},
});
</script>
<style lang="less">
@prefix-cls: ~'@{namespace}-header-user-dropdown';
.@{prefix-cls} {
|
vben
authored
|
129
|
align-items: center;
|
vben
authored
|
130
131
132
133
134
135
136
137
|
height: @header-height;
padding: 0 0 0 10px;
padding-right: 10px;
overflow: hidden;
font-size: 12px;
cursor: pointer;
img {
|
Vben
authored
|
138
139
|
width: 24px;
height: 24px;
|
vben
authored
|
140
141
142
143
144
145
146
147
148
149
150
151
152
|
margin-right: 12px;
}
&__header {
border-radius: 50%;
}
&__name {
font-size: 14px;
}
&--dark {
&:hover {
|
Vben
authored
|
153
|
background-color: @header-dark-bg-hover-color;
|
vben
authored
|
154
155
156
157
|
}
}
&--light {
|
|
158
159
160
|
&:hover {
background-color: @header-light-bg-hover-color;
}
|
Vben
authored
|
161
|
|
vben
authored
|
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
.@{prefix-cls}__name {
color: @text-color-base;
}
.@{prefix-cls}__desc {
color: @header-light-desc-color;
}
}
&-dropdown-overlay {
.ant-dropdown-menu-item {
min-width: 160px;
}
}
}
</style>
|