gtsoft-snail-job-admin/src/layouts/modules/global-header/components/user-avatar.vue

102 lines
2.3 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue';
import type { VNode } from 'vue';
import { useBoolean } from '@sa/hooks';
import { useAuthStore } from '@/store/modules/auth';
import { useRouterPush } from '@/hooks/common/router';
import { useSvgIcon } from '@/hooks/common/icon';
import { $t } from '@/locales';
import ChangePassword from './change-password.vue';
defineOptions({
name: 'UserAvatar'
});
const authStore = useAuthStore();
const { routerPushByKey, toLogin } = useRouterPush();
const { SvgIconVNode } = useSvgIcon();
function loginOrRegister() {
toLogin();
}
type DropdownKey = 'password' | 'logout';
type DropdownOption =
| {
key: DropdownKey;
label: string;
icon?: () => VNode;
}
| {
type: 'divider';
key: string;
};
const options = computed(() => {
const opts: DropdownOption[] = [
{
label: $t('common.updatePassword'),
key: 'password',
icon: SvgIconVNode({ icon: 'ph:password', fontSize: 18 })
},
{
type: 'divider',
key: 'divider'
},
{
label: $t('common.logout'),
key: 'logout',
icon: SvgIconVNode({ icon: 'ph:sign-out', fontSize: 18 })
}
];
return opts;
});
const { bool: drawerVisible, setTrue: openDrawer } = useBoolean(false);
function logout() {
window.$dialog?.info({
title: $t('common.tip'),
content: $t('common.logoutConfirm'),
positiveText: $t('common.confirm'),
negativeText: $t('common.cancel'),
onPositiveClick: () => {
authStore.resetStore();
}
});
}
function handleDropdown(key: DropdownKey) {
if (key === 'logout') {
logout();
} else if (key === 'password') {
handleChangePassword();
} else {
routerPushByKey(key);
}
}
function handleChangePassword() {
openDrawer();
}
</script>
<template>
<NButton v-if="!authStore.isLogin" quaternary @click="loginOrRegister">
{{ $t('page.login.common.loginOrRegister') }}
</NButton>
<NDropdown v-else placement="bottom" trigger="click" :options="options" @select="handleDropdown">
<div>
<ButtonIcon>
<SvgIcon icon="ph:user-circle" class="text-icon-large" />
<span class="text-16px font-medium">{{ authStore.userInfo.userName }}</span>
</ButtonIcon>
</div>
</NDropdown>
<ChangePassword v-model:visible="drawerVisible"></ChangePassword>
</template>
<style scoped></style>