From 5d271ac23338a8e4ddb9f0a85cabc0f1ab657f54 Mon Sep 17 00:00:00 2001 From: KUN1007 Date: Sun, 15 Oct 2023 22:26:01 +0800 Subject: [PATCH] feat: upload avatar --- src/api/user/index.ts | 20 +++++- src/api/user/types/user.ts | 10 +++ src/store/modules/kungalgamer.ts | 21 ++++-- src/store/modules/topic.ts | 2 +- src/utils/request.ts | 19 +++++- src/views/kungalgamer/components/Avatar.vue | 67 +++++++++++-------- src/views/kungalgamer/content/Settings.vue | 10 +-- .../kungalgamer/utils/handleFileChange.ts | 19 ------ 8 files changed, 105 insertions(+), 63 deletions(-) diff --git a/src/api/user/index.ts b/src/api/user/index.ts index 1b098fd0..f558203f 100644 --- a/src/api/user/index.ts +++ b/src/api/user/index.ts @@ -1,4 +1,9 @@ -import { fetchGet, fetchPut, fetchPost } from '@/utils/request' +import { + fetchGet, + fetchPut, + fetchPost, + fetchPostWithFormData, +} from '@/utils/request' // 将对象转为请求参数的函数 import objectToQueryParams from '@/utils/objectToQueryParams' import * as User from './types/user' @@ -16,6 +21,19 @@ export async function getUserByUidApi( return response } +// 更新用户头像 +export async function updateUserAvatarApi( + request: User.UserUpdateAvatarRequestData +): Promise { + const url = `/user/${request.uid}/avatar` + const response = + await fetchPostWithFormData( + url, + request.avatar + ) + return response +} + // 更新用户 bio export async function updateUserBioApi( request: User.UserUpdateBioRequestData diff --git a/src/api/user/types/user.ts b/src/api/user/types/user.ts index f8c645ad..ca797eae 100644 --- a/src/api/user/types/user.ts +++ b/src/api/user/types/user.ts @@ -19,6 +19,12 @@ export interface UserInfo { upvote_topic: number[] } +// 用户更新头像 +export interface UserUpdateAvatarRequestData { + uid: number + avatar: FormData +} + // 用户更新签名 export interface UserUpdateBioRequestData { uid: number @@ -86,6 +92,10 @@ export interface UserResetPasswordByEmailRequestData { export type UserInfoResponseData = KUNGalgameResponseData +export type UserUpdateAvatarResponseData = KUNGalgameResponseData<{ + avatar: string +}> + export type UserUpdateBioResponseData = KUNGalgameResponseData<{}> export type UserGetUserEmailResponseData = KUNGalgameResponseData<{ diff --git a/src/store/modules/kungalgamer.ts b/src/store/modules/kungalgamer.ts index 5e373b98..04eadaff 100644 --- a/src/store/modules/kungalgamer.ts +++ b/src/store/modules/kungalgamer.ts @@ -18,6 +18,8 @@ import { import type { UserInfoResponseData, + UserUpdateAvatarRequestData, + UserUpdateAvatarResponseData, UserUpdateBioRequestData, UserUpdateBioResponseData, UserGetUserEmailResponseData, @@ -38,6 +40,7 @@ import type { import { getUserByUidApi, + updateUserAvatarApi, updateUserBioApi, getUserEmailApi, getUserResetEmailCodeApi, @@ -139,13 +142,21 @@ export const useKUNGalgameUserStore = defineStore({ return getUserByUidApi(uid) }, + // 更新用户 avatar + async updateAvatar( + avatar: FormData + ): Promise { + const request: UserUpdateAvatarRequestData = { + uid: this.uid, + avatar: avatar, + } + return updateUserAvatarApi(request) + }, + // 更新用户 bio - async updateBio( - uid: number, - bio: string - ): Promise { + async updateBio(bio: string): Promise { const request: UserUpdateBioRequestData = { - uid, + uid: this.uid, bio, } return updateUserBioApi(request) diff --git a/src/store/modules/topic.ts b/src/store/modules/topic.ts index a7bdf911..00217dfa 100644 --- a/src/store/modules/topic.ts +++ b/src/store/modules/topic.ts @@ -100,7 +100,7 @@ export const useKUNGalgameTopicStore = defineStore({ }, replyRequest: { page: 1, - limit: 5, + limit: 3, sortField: 'floor', sortOrder: 'asc', }, diff --git a/src/utils/request.ts b/src/utils/request.ts index eab008e6..e6258a8b 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -103,4 +103,21 @@ const fetchDelete = async ( return await kunFetchRequest(url, options) } -export { fetchGet, fetchPost, fetchPut, fetchDelete } +const fetchPostWithFormData = async ( + url: string, + formData: FormData, + headers?: Record +): Promise => { + const options: FetchOptions = { + method: 'POST', + credentials: 'include', + headers: { + ...headers, + }, + body: formData, + } + + return await kunFetchRequest(url, options) +} + +export { fetchGet, fetchPost, fetchPut, fetchDelete, fetchPostWithFormData } diff --git a/src/views/kungalgamer/components/Avatar.vue b/src/views/kungalgamer/components/Avatar.vue index 3bda5ed7..eab4bc30 100644 --- a/src/views/kungalgamer/components/Avatar.vue +++ b/src/views/kungalgamer/components/Avatar.vue @@ -2,11 +2,8 @@ import { ref } from 'vue' import Message from '@/components/alert/Message' // 上传头像的函数 -import { - checkImageValid, - resizeImage, - handleUploadAvatar, -} from '../utils/handleFileChange' +import { checkImageValid, resizeImage } from '../utils/handleFileChange' +import { useKUNGalgameUserStore } from '@/store/modules/kungalgamer' // 准备给后端的图片 const uploadedImage = ref() @@ -15,12 +12,28 @@ const selectedFileUrl = ref('') // 上传的 input const input = ref() +// 上传图片的函数 +const uploadImage = async (file: File) => { + // 检查图片是否合法,不合法则退出 + const isFileValid = checkImageValid(file) + if (!isFileValid) { + return + } + const resizedFile = await resizeImage(file) + uploadedImage.value = resizedFile + selectedFileUrl.value = URL.createObjectURL(resizedFile) +} + // 点击上传 const handleFileChange = async (event: Event) => { - const imgUrl = await handleUploadAvatar(event) - if (imgUrl) { - selectedFileUrl.value = imgUrl + const input = event.target as HTMLInputElement + + if (!input.files || !input.files[0]) { + return } + + const file = input.files[0] + uploadImage(file) } // 拖拽上传 @@ -32,14 +45,7 @@ const handleDrop = async (event: DragEvent) => { const dataTransfer = event.dataTransfer if (dataTransfer && dataTransfer.files.length > 0) { const file = dataTransfer.files[0] - - // 验证文件类型,正确则上传 - if (checkImageValid(file)) { - const resizedFile = await resizeImage(file) - uploadedImage.value = resizedFile - - selectedFileUrl.value = URL.createObjectURL(resizedFile) - } + uploadImage(file) } } @@ -49,20 +55,23 @@ const handleDragOver = (event: DragEvent) => { event.dataTransfer!.dropEffect = 'copy' } -// 更改头像 -const handleChangeAvatar = () => { - Message( - 'Image API is not yet completed, stay tuned for updates', - '图片接口还未完成,敬请期待', - 'warn' - ) - if (uploadedImage.value) { - const formData = new FormData() - formData.append('avatar', uploadedImage.value) +// 点击上传 +const handleClickUpload = () => { + input.value?.click() +} - // 在这里执行上传逻辑 TODO: - // 上传完成后可以显示成功消息或者刷新用户界面 +// 更改头像 +const handleChangeAvatar = async () => { + if (!uploadedImage.value) { + return } + + const formData = new FormData() + formData.append('avatar', uploadedImage.value, useKUNGalgameUserStore().name) + + console.log(uploadedImage.value) + + await useKUNGalgameUserStore().updateAvatar(formData) } @@ -77,7 +86,7 @@ const handleChangeAvatar = () => { class="avatar-upload" @drop="handleDrop($event)" @dragover="handleDragOver" - @click="input?.click()" + @click="handleClickUpload" > diff --git a/src/views/kungalgamer/content/Settings.vue b/src/views/kungalgamer/content/Settings.vue index b1643b05..f3ef38d3 100644 --- a/src/views/kungalgamer/content/Settings.vue +++ b/src/views/kungalgamer/content/Settings.vue @@ -1,12 +1,10 @@