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
40
41
42
43
44
|
</template>
<script lang="ts">
// components
import { Dropdown, Menu } from 'ant-design-vue';
import { defineComponent, computed } from 'vue';
import { DOC_URL } from '/@/settings/siteSetting';
|
Vben
authored
|
45
|
import { useUserStore } from '/@/store/modules/user';
|
vben
authored
|
46
47
48
|
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
import { useI18n } from '/@/hooks/web/useI18n';
import { useDesign } from '/@/hooks/web/useDesign';
|
vben
authored
|
49
50
|
import { useModal } from '/@/components/Modal';
|
vben
authored
|
51
|
import headerImg from '/@/assets/images/header.jpg';
|
vben
authored
|
52
53
54
55
|
import { propTypes } from '/@/utils/propTypes';
import { openWindow } from '/@/utils';
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
vben
authored
|
56
|
|
|
57
|
type MenuEvent = 'logout' | 'doc' | 'lock';
|
vben
authored
|
58
59
60
61
62
63
64
65
|
export default defineComponent({
name: 'UserDropdown',
components: {
Dropdown,
Menu,
MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
MenuDivider: Menu.Divider,
|
vben
authored
|
66
|
LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
|
vben
authored
|
67
68
69
70
71
72
73
|
},
props: {
theme: propTypes.oneOf(['dark', 'light']),
},
setup() {
const { prefixCls } = useDesign('header-user-dropdown');
const { t } = useI18n();
|
Vben
authored
|
74
|
const { getShowDoc, getUseLockPage } = useHeaderSetting();
|
Vben
authored
|
75
|
const userStore = useUserStore();
|
vben
authored
|
76
77
|
const getUserInfo = computed(() => {
|
|
78
79
|
const { realName = '', avatar, desc } = userStore.getUserInfo || {};
return { realName, avatar: avatar || headerImg, desc };
|
vben
authored
|
80
81
|
});
|
vben
authored
|
82
83
84
85
86
87
|
const [register, { openModal }] = useModal();
function handleLock() {
openModal(true);
}
|
vben
authored
|
88
89
90
91
92
93
94
95
96
97
|
// login out
function handleLoginOut() {
userStore.confirmLoginOut();
}
// open doc
function openDoc() {
openWindow(DOC_URL);
}
|
|
98
99
100
101
102
103
104
105
106
107
108
109
110
|
function handleMenuClick(e: { key: MenuEvent }) {
switch (e.key) {
case 'logout':
handleLoginOut();
break;
case 'doc':
openDoc();
break;
case 'lock':
handleLock();
break;
}
}
|
vben
authored
|
111
112
113
114
115
|
return {
prefixCls,
t,
getUserInfo,
|
|
116
|
handleMenuClick,
|
vben
authored
|
117
|
getShowDoc,
|
vben
authored
|
118
|
register,
|
Vben
authored
|
119
|
getUseLockPage,
|
vben
authored
|
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
};
},
});
</script>
<style lang="less">
@prefix-cls: ~'@{namespace}-header-user-dropdown';
.@{prefix-cls} {
height: @header-height;
padding: 0 0 0 10px;
padding-right: 10px;
overflow: hidden;
font-size: 12px;
cursor: pointer;
align-items: center;
img {
|
Vben
authored
|
137
138
|
width: 24px;
height: 24px;
|
vben
authored
|
139
140
141
142
143
144
145
146
147
148
149
150
151
|
margin-right: 12px;
}
&__header {
border-radius: 50%;
}
&__name {
font-size: 14px;
}
&--dark {
&:hover {
|
Vben
authored
|
152
|
background-color: @header-dark-bg-hover-color;
|
vben
authored
|
153
154
155
156
|
}
}
&--light {
|
|
157
158
159
|
&:hover {
background-color: @header-light-bg-hover-color;
}
|
Vben
authored
|
160
|
|
vben
authored
|
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
.@{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>
|