mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-09 09:46:44 +08:00
fix(user): 默认头像不再写入用户资料 (#740)
This commit is contained in:
@@ -46,7 +46,8 @@ const currentLoginUser = userStore.userName
|
||||
const userName = ref('')
|
||||
|
||||
// 当前头像缓存
|
||||
const currentAvatar = ref(avatar1)
|
||||
const currentAvatar = ref('')
|
||||
const displayedAvatar = computed(() => currentAvatar.value || avatar1)
|
||||
|
||||
// 用户名缓存
|
||||
const currentUserName = ref('')
|
||||
@@ -82,7 +83,7 @@ const userForm = ref<ExtendedUser>({
|
||||
email: '',
|
||||
is_active: true,
|
||||
is_superuser: false,
|
||||
avatar: avatar1,
|
||||
avatar: '',
|
||||
is_otp: false,
|
||||
permissions: {
|
||||
discovery: true,
|
||||
@@ -267,13 +268,13 @@ function changeAvatar(file: Event) {
|
||||
|
||||
/** 将头像恢复为系统默认头像。 */
|
||||
function resetDefaultAvatar() {
|
||||
currentAvatar.value = avatar1
|
||||
currentAvatar.value = ''
|
||||
$toast.success(t('dialog.userAddEdit.resetAvatarSuccess'))
|
||||
}
|
||||
|
||||
/** 还原为用户当前已保存的头像。 */
|
||||
function restoreCurrentAvatar() {
|
||||
currentAvatar.value = userForm.value.avatar
|
||||
currentAvatar.value = userForm.value.avatar || ''
|
||||
$toast.success(t('dialog.userAddEdit.restoreAvatarSuccess'))
|
||||
}
|
||||
|
||||
@@ -282,7 +283,7 @@ async function fetchUserInfo() {
|
||||
try {
|
||||
userForm.value = await api.get(`user/${props.username}`)
|
||||
if (userForm.value) {
|
||||
userForm.value.avatar = userForm.value.avatar || avatar1
|
||||
userForm.value.avatar = userForm.value.avatar || ''
|
||||
userForm.value.nickname = userForm.value.settings?.nickname ?? ''
|
||||
currentAvatar.value = userForm.value.avatar
|
||||
currentUserName.value = userForm.value.name
|
||||
@@ -455,7 +456,7 @@ onMounted(() => {
|
||||
<VCardItem>
|
||||
<!-- 👉 Avatar -->
|
||||
<div class="flex flex-row">
|
||||
<VAvatar rounded="lg" size="100" class="me-5" :image="currentAvatar" />
|
||||
<VAvatar rounded="lg" size="100" class="me-5" :image="displayedAvatar" />
|
||||
<!-- 👉 Upload Photo -->
|
||||
<div class="flex flex-col justify-center gap-5">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
|
||||
@@ -350,4 +350,17 @@ describe('UserAddEditDialog', () => {
|
||||
await waitFor(() => expect(mocks.apiPut).toHaveBeenCalledTimes(2))
|
||||
expect(mocks.apiPut.mock.calls[1][1]).toMatchObject({ avatar: 'saved-avatar.png' })
|
||||
})
|
||||
|
||||
it('persists an empty avatar after resetting a user to the built-in default', async () => {
|
||||
mocks.apiGet.mockResolvedValue(createUser({ avatar: 'saved-avatar.png', name: 'alice' }))
|
||||
mocks.apiPut.mockResolvedValue({ success: true })
|
||||
await renderDialog('edit', 'alice')
|
||||
await screen.findByDisplayValue('alice')
|
||||
|
||||
await fireEvent.click(screen.getByRole('button', { name: /重置默认头像/ }))
|
||||
await fireEvent.click(screen.getByRole('button', { name: '保存' }))
|
||||
|
||||
await waitFor(() => expect(mocks.apiPut).toHaveBeenCalledOnce())
|
||||
expect(mocks.apiPut.mock.calls[0][1]).toMatchObject({ avatar: '' })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -41,7 +41,8 @@ const isProfileLoading = ref(true)
|
||||
const profileLoadFailed = ref(false)
|
||||
|
||||
// 当前头像缓存
|
||||
const currentAvatar = ref(avatar1)
|
||||
const currentAvatar = ref('')
|
||||
const displayedAvatar = computed(() => currentAvatar.value || avatar1)
|
||||
|
||||
// 当前用户名
|
||||
const currentUserName = ref('')
|
||||
@@ -182,13 +183,13 @@ function changeAvatar(file: Event) {
|
||||
|
||||
// 重置默认头像
|
||||
function resetDefaultAvatar() {
|
||||
currentAvatar.value = avatar1
|
||||
currentAvatar.value = ''
|
||||
$toast.success(t('profile.resetAvatarSuccess'))
|
||||
}
|
||||
|
||||
// 还原当前头像
|
||||
function restoreCurrentAvatar() {
|
||||
currentAvatar.value = accountInfo.value.avatar
|
||||
currentAvatar.value = accountInfo.value.avatar || ''
|
||||
$toast.success(t('profile.restoreAvatarSuccess'))
|
||||
}
|
||||
|
||||
@@ -247,7 +248,7 @@ async function saveAccountInfo() {
|
||||
const updatedUser = await api.put<User>('user/current', userData, { feedback: 'silent' })
|
||||
applyUserProfile(updatedUser)
|
||||
userStore.setUserName(updatedUser.name)
|
||||
userStore.setAvatar(currentAvatar.value)
|
||||
userStore.setAvatar(updatedUser.avatar || '')
|
||||
// 凭据仅在服务端确认成功后清空,失败时保留输入便于修正或重试。
|
||||
newPassword.value = ''
|
||||
confirmPassword.value = ''
|
||||
@@ -288,7 +289,7 @@ function applyUserProfile(user: User) {
|
||||
nickname: user.settings?.nickname ?? '',
|
||||
}
|
||||
currentUserName.value = user.name
|
||||
currentAvatar.value = user.avatar || avatar1
|
||||
currentAvatar.value = user.avatar || ''
|
||||
}
|
||||
|
||||
// 密码验证并执行回调
|
||||
@@ -356,7 +357,7 @@ watch(
|
||||
<VCard :title="t('profile.personalInfo')">
|
||||
<VCardText class="flex">
|
||||
<!-- 👉 Avatar -->
|
||||
<VAvatar rounded="lg" size="100" class="me-6" :image="currentAvatar" />
|
||||
<VAvatar rounded="lg" size="100" class="me-6" :image="displayedAvatar" />
|
||||
|
||||
<!-- 👉 Upload Photo -->
|
||||
<form class="flex flex-col justify-center gap-5">
|
||||
|
||||
@@ -150,6 +150,7 @@ describe('UserProfileView', () => {
|
||||
|
||||
it('validates avatar files and supports restoring the saved or default avatar', async () => {
|
||||
mockSuccessfulLoad()
|
||||
mocks.apiPut.mockResolvedValue(currentUser({ avatar: '' }))
|
||||
const { container } = await renderProfile()
|
||||
await screen.findByDisplayValue('alice@example.com')
|
||||
const fileInput = container.querySelector('input[type="file"]') as HTMLInputElement
|
||||
@@ -167,6 +168,10 @@ describe('UserProfileView', () => {
|
||||
await fireEvent.click(screen.getByRole('button', { name: '默认' }))
|
||||
expect(mocks.toastSuccess).toHaveBeenCalledWith('已还原当前使用头像!')
|
||||
expect(mocks.toastSuccess).toHaveBeenCalledWith('已重置为默认头像,待保存后生效!')
|
||||
|
||||
await fireEvent.click(screen.getByRole('button', { name: '保存' }))
|
||||
await waitFor(() => expect(mocks.apiPut).toHaveBeenCalledOnce())
|
||||
expect(mocks.apiPut.mock.calls[0][1]).toMatchObject({ avatar: '' })
|
||||
})
|
||||
|
||||
it('keeps notification identity fields editable in the profile payload', async () => {
|
||||
|
||||
Reference in New Issue
Block a user