feat: display add icon when user avatar is not setting (#4694)

#### What type of PR is this?

/area console
/kind improvement
/milestone 2.10.x

#### What this PR does / why we need it:

当用户未设置头像时,头像显示添加图标,能够更好的提示用户如何设置头像。

<img width="528" alt="image" src="https://github.com/halo-dev/halo/assets/21301288/380ed906-2d76-41bd-ae17-6c31ca7c444a">

#### Which issue(s) this PR fixes:

Fixes #4693 

#### Special notes for your reviewer:

1. 测试未设置头像时,是否添加添加图标。
2. 测试设置头像之后,鼠标移动到头像时,是否显示修改图标。

#### Does this PR introduce a user-facing change?

```release-note
优化 Console 端个人资料的头像显示,未设置头像时显示添加图标。
```
pull/4703/head
Ryan Wang 2023-10-10 11:12:36 +08:00 committed by GitHub
parent 6411cef5ff
commit 0b8e0d9b99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 17 additions and 9 deletions

View File

@ -2,6 +2,7 @@
import { apiClient } from "@/utils/api-client"; import { apiClient } from "@/utils/api-client";
import { import {
IconRiPencilFill, IconRiPencilFill,
IconAddCircle,
VButton, VButton,
VAvatar, VAvatar,
VDropdown, VDropdown,
@ -18,6 +19,7 @@ import { useQueryClient } from "@tanstack/vue-query";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useFileDialog } from "@vueuse/core"; import { useFileDialog } from "@vueuse/core";
import { inject } from "vue"; import { inject } from "vue";
import { computed } from "vue";
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { currentUserHasPermission } = usePermission(); const { currentUserHasPermission } = usePermission();
@ -41,7 +43,6 @@ const user = inject<Ref<DetailedUser | undefined>>("user");
const isCurrentUser = inject<ComputedRef<boolean>>("isCurrentUser"); const isCurrentUser = inject<ComputedRef<boolean>>("isCurrentUser");
const userAvatarCropper = ref<IUserAvatarCropperType>(); const userAvatarCropper = ref<IUserAvatarCropperType>();
const showAvatarEditor = ref(false);
const visibleCropperModal = ref(false); const visibleCropperModal = ref(false);
const originalFile = ref<File>() as Ref<File>; const originalFile = ref<File>() as Ref<File>;
@ -117,14 +118,14 @@ const changeUploadAvatar = () => {
reset(); reset();
open(); open();
}; };
const hasAvatar = computed(() => {
return !!user?.value?.user.spec.avatar;
});
</script> </script>
<template> <template>
<div <div class="group h-full w-full">
class="h-full w-full"
@mouseover="showAvatarEditor = true"
@mouseout="showAvatarEditor = false"
>
<VAvatar <VAvatar
:src="user?.user.spec.avatar" :src="user?.user.spec.avatar"
:alt="user?.user.spec.displayName" :alt="user?.user.spec.displayName"
@ -137,10 +138,17 @@ const changeUploadAvatar = () => {
v-if="currentUserHasPermission(['system:users:manage']) || isCurrentUser" v-if="currentUserHasPermission(['system:users:manage']) || isCurrentUser"
> >
<div <div
v-show="showAvatarEditor" class="absolute left-0 right-0 top-0 hidden h-full w-full cursor-pointer items-center rounded-full border-0 bg-black/60 text-center transition-all duration-300 group-hover:flex"
class="absolute left-0 right-0 top-0 h-full w-full cursor-pointer rounded-full border-0 bg-black/60 text-center leading-[5rem] transition-opacity duration-300 group-hover:opacity-100" :class="{
'!flex': !hasAvatar,
}"
> >
<IconAddCircle
v-if="!hasAvatar"
class="inline-block w-full self-center text-2xl text-white"
/>
<IconRiPencilFill <IconRiPencilFill
v-else
class="inline-block w-full self-center text-2xl text-white" class="inline-block w-full self-center text-2xl text-white"
/> />
</div> </div>
@ -148,7 +156,7 @@ const changeUploadAvatar = () => {
<VDropdownItem @click="open()"> <VDropdownItem @click="open()">
{{ $t("core.common.buttons.upload") }} {{ $t("core.common.buttons.upload") }}
</VDropdownItem> </VDropdownItem>
<VDropdownItem @click="handleRemoveCurrentAvatar"> <VDropdownItem v-if="hasAvatar" @click="handleRemoveCurrentAvatar">
{{ $t("core.common.buttons.delete") }} {{ $t("core.common.buttons.delete") }}
</VDropdownItem> </VDropdownItem>
</template> </template>