<script lang="ts" setup>
|
import type { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
|
|
import { computed, inject } from 'vue';
|
|
import { useGlobSetting } from '@jnpf/hooks';
|
import { useModal } from '@jnpf/ui/modal';
|
|
import { preferences } from '@vben/preferences';
|
import { useAccessStore, useUserStore } from '@vben/stores';
|
|
import { Avatar, Dropdown, Menu } from 'ant-design-vue';
|
|
import { $t } from '#/locales';
|
import { useAuthStore } from '#/store';
|
|
import AboutModal from './AboutModal.vue';
|
import DropMenuItem from './DropMenuItem.vue';
|
import ProfileModal from './ProfileModal.vue';
|
|
defineOptions({ name: 'UserDropdown' });
|
|
const MenuItem = DropMenuItem;
|
const MenuDivider = Menu.Divider;
|
const globSetting = useGlobSetting();
|
const apiUrl = globSetting.apiURL;
|
const prefixCls = 'jnpf-header-user-dropdown';
|
const userStore = useUserStore();
|
const authStore = useAuthStore();
|
const accessStore = useAccessStore();
|
const [registerProfileModal, { openModal: openProfileModal }] = useModal();
|
const [registerAboutModal, { openModal: openAboutModal }] = useModal();
|
|
const emitter: any = inject('emitter');
|
|
emitter.on('openProfileModal', (data = {}) => {
|
openProfileModal(true, data);
|
});
|
|
const getUserInfo: any = computed(() => userStore.getUserInfo || {});
|
|
function handleMenuClick(e: MenuInfo) {
|
if (e.key === 'logout') return handleLoginOut();
|
if (e.key === 'lock') return handleLock();
|
if (e.key === 'profile') return openProfileModal(true, {});
|
if (e.key === 'about') return openAboutModal(true);
|
}
|
function handleLock() {
|
accessStore.lockScreen();
|
}
|
function handleLoginOut() {
|
authStore.confirmLoginOut();
|
}
|
</script>
|
<template>
|
<Dropdown :overlay-class-name="`${prefixCls}-dropdown-overlay`" placement="bottomLeft">
|
<span :class="[prefixCls]" class="flex hover:bg-accent">
|
<Avatar :class="`${prefixCls}__header`" :size="30" :src="apiUrl + getUserInfo.headIcon" />
|
</span>
|
<template #overlay>
|
<Menu @click="handleMenuClick">
|
<div class="dropdown-user-info">
|
<Avatar :class="`${prefixCls}__header mr-[8px]`" :size="30" :src="apiUrl + getUserInfo.headIcon" />
|
<span :class="`${prefixCls}__info block`">
|
<span :class="`${prefixCls}__name truncate`">{{ getUserInfo.userName }}</span>
|
</span>
|
</div>
|
<MenuDivider />
|
<MenuItem key="profile" :text="$t('layout.header.profile')" icon="icon-ym icon-ym-header-userInfo" item-key="profile" />
|
<MenuItem key="about" :text="$t('layout.header.about')" icon="icon-ym icon-ym-header-about" item-key="about" />
|
<MenuItem
|
key="lock"
|
:text="$t('layout.header.tooltipLock')"
|
icon="icon-ym icon-ym-header-lockScreen"
|
item-key="lock"
|
v-if="preferences.widget.lockScreen" />
|
<MenuDivider />
|
<MenuItem key="logout" :text="$t('layout.header.dropdownItemLoginOut')" icon="icon-ym icon-ym-header-loginOut" item-key="logout" />
|
</Menu>
|
</template>
|
</Dropdown>
|
<AboutModal @register="registerAboutModal" />
|
<ProfileModal @register="registerProfileModal" />
|
</template>
|
<style lang="scss">
|
.jnpf-header-user-dropdown {
|
align-items: center;
|
height: 36px;
|
padding: 10px;
|
margin-right: 10px;
|
overflow: hidden;
|
font-size: 12px;
|
cursor: pointer;
|
border-radius: var(--radius);
|
|
&-dropdown-overlay {
|
min-width: 160px !important;
|
}
|
|
&__info {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin-left: 4px;
|
}
|
|
&__name {
|
display: inline-block;
|
max-width: 100px;
|
font-size: 14px;
|
}
|
|
&--light {
|
.jnpf-header-user-dropdown__name {
|
color: var(--text-color-base);
|
}
|
|
.jnpf-header-user-dropdown__desc {
|
color: var(--header-light-desc-color);
|
}
|
}
|
}
|
|
.dropdown-user-info {
|
display: flex;
|
align-items: center;
|
padding: 12px;
|
}
|
|
html:not(.dark) {
|
.jnpf-header-user-dropdown {
|
&:hover {
|
background-color: rgb(255 255 255 / 40%);
|
}
|
}
|
}
|
</style>
|