<!-- 用户菜单 -->
|
<template>
|
<ElPopover
|
ref="userMenuPopover"
|
placement="bottom-end"
|
:width="240"
|
:hide-after="0"
|
:offset="10"
|
trigger="hover"
|
:show-arrow="false"
|
popper-class="user-menu-popover"
|
popper-style="padding: 5px 16px;"
|
>
|
<template #reference>
|
<img
|
class="size-8.5 mr-5 c-p rounded-full max-sm:w-6.5 max-sm:h-6.5 max-sm:mr-[16px]"
|
src="@imgs/user/avatar.webp"
|
alt="avatar"
|
/>
|
</template>
|
<template #default>
|
<div class="pt-3">
|
<div class="flex-c pb-1 px-0">
|
<img
|
class="w-10 h-10 mr-3 ml-0 overflow-hidden rounded-full float-left"
|
src="@imgs/user/avatar.webp"
|
/>
|
<div class="w-[calc(100%-60px)] h-full">
|
<span class="block text-sm font-medium text-g-800 truncate">{{
|
userInfo.userName
|
}}</span>
|
<span class="block mt-0.5 text-xs text-g-500 truncate">{{ userInfo.email }}</span>
|
</div>
|
</div>
|
<ul class="py-4 mt-3 border-t border-g-300/80">
|
<li class="btn-item" @click="goPage('/system/user-center')">
|
<ArtSvgIcon icon="ri:user-3-line" />
|
<span>{{ $t('topBar.user.userCenter') }}</span>
|
</li>
|
<li class="btn-item" @click="toDocs()">
|
<ArtSvgIcon icon="ri:book-2-line" />
|
<span>{{ $t('topBar.user.docs') }}</span>
|
</li>
|
<li class="btn-item" @click="toGithub()">
|
<ArtSvgIcon icon="ri:github-line" />
|
<span>{{ $t('topBar.user.github') }}</span>
|
</li>
|
<li class="btn-item" @click="lockScreen()">
|
<ArtSvgIcon icon="ri:lock-line" />
|
<span>{{ $t('topBar.user.lockScreen') }}</span>
|
</li>
|
<div class="w-full h-px my-2 bg-g-300/80"></div>
|
<div class="log-out c-p" @click="loginOut">
|
{{ $t('topBar.user.logout') }}
|
</div>
|
</ul>
|
</div>
|
</template>
|
</ElPopover>
|
</template>
|
|
<script setup>
|
import { useI18n } from 'vue-i18n'
|
import { useRouter } from 'vue-router'
|
import { ElMessageBox } from 'element-plus'
|
import { useUserStore } from '@/store/modules/user'
|
import { WEB_LINKS } from '@/utils/constants'
|
import { mittBus } from '@/utils/sys'
|
defineOptions({ name: 'ArtUserMenu' })
|
const router = useRouter()
|
const { t } = useI18n()
|
const userStore = useUserStore()
|
const { getUserInfo: userInfo } = storeToRefs(userStore)
|
const userMenuPopover = ref()
|
const goPage = (path) => {
|
router.push(path)
|
}
|
const toDocs = () => {
|
window.open(WEB_LINKS.DOCS)
|
}
|
const toGithub = () => {
|
window.open(WEB_LINKS.GITHUB)
|
}
|
const lockScreen = () => {
|
mittBus.emit('openLockScreen')
|
}
|
const loginOut = () => {
|
closeUserMenu()
|
setTimeout(() => {
|
ElMessageBox.confirm(t('common.logOutTips'), t('common.tips'), {
|
confirmButtonText: t('common.confirm'),
|
cancelButtonText: t('common.cancel'),
|
customClass: 'login-out-dialog'
|
}).then(() => {
|
userStore.logOut()
|
})
|
}, 200)
|
}
|
const closeUserMenu = () => {
|
setTimeout(() => {
|
userMenuPopover.value.hide()
|
}, 100)
|
}
|
</script>
|
|
<style scoped>
|
@reference '@styles/core/tailwind.css';
|
|
@layer components {
|
.btn-item {
|
@apply flex items-center p-2 mb-3 select-none rounded-md cursor-pointer last:mb-0;
|
|
span {
|
@apply text-sm;
|
}
|
|
.art-svg-icon {
|
@apply mr-2 text-base;
|
}
|
|
&:hover {
|
background-color: var(--art-gray-200);
|
}
|
}
|
}
|
|
.log-out {
|
@apply py-1.5
|
mt-5
|
text-xs
|
text-center
|
border
|
border-g-400
|
rounded-md
|
transition-all
|
duration-200
|
hover:shadow-xl;
|
}
|
</style>
|