feat: upload avatar

This commit is contained in:
KUN1007 2023-10-15 22:26:01 +08:00
parent c425aac9b2
commit 5d271ac233
8 changed files with 105 additions and 63 deletions

View file

@ -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<User.UserUpdateAvatarResponseData> {
const url = `/user/${request.uid}/avatar`
const response =
await fetchPostWithFormData<User.UserUpdateAvatarResponseData>(
url,
request.avatar
)
return response
}
// 更新用户 bio
export async function updateUserBioApi(
request: User.UserUpdateBioRequestData

View file

@ -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<UserInfo>
export type UserUpdateAvatarResponseData = KUNGalgameResponseData<{
avatar: string
}>
export type UserUpdateBioResponseData = KUNGalgameResponseData<{}>
export type UserGetUserEmailResponseData = KUNGalgameResponseData<{

View file

@ -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<UserUpdateAvatarResponseData> {
const request: UserUpdateAvatarRequestData = {
uid: this.uid,
avatar: avatar,
}
return updateUserAvatarApi(request)
},
// 更新用户 bio
async updateBio(
uid: number,
bio: string
): Promise<UserUpdateBioResponseData> {
async updateBio(bio: string): Promise<UserUpdateBioResponseData> {
const request: UserUpdateBioRequestData = {
uid,
uid: this.uid,
bio,
}
return updateUserBioApi(request)

View file

@ -100,7 +100,7 @@ export const useKUNGalgameTopicStore = defineStore({
},
replyRequest: {
page: 1,
limit: 5,
limit: 3,
sortField: 'floor',
sortOrder: 'asc',
},

View file

@ -103,4 +103,21 @@ const fetchDelete = async <T>(
return await kunFetchRequest<T>(url, options)
}
export { fetchGet, fetchPost, fetchPut, fetchDelete }
const fetchPostWithFormData = async <T>(
url: string,
formData: FormData,
headers?: Record<string, string>
): Promise<T> => {
const options: FetchOptions = {
method: 'POST',
credentials: 'include',
headers: {
...headers,
},
body: formData,
}
return await kunFetchRequest<T>(url, options)
}
export { fetchGet, fetchPost, fetchPut, fetchDelete, fetchPostWithFormData }

View file

@ -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<Blob>()
@ -15,12 +12,28 @@ const selectedFileUrl = ref<string>('')
// input
const input = ref<HTMLElement>()
//
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)
// TODO:
//
//
const handleClickUpload = () => {
input.value?.click()
}
//
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)
}
</script>
@ -77,7 +86,7 @@ const handleChangeAvatar = () => {
class="avatar-upload"
@drop="handleDrop($event)"
@dragover="handleDragOver"
@click="input?.click()"
@click="handleClickUpload"
>
<!-- 加号提示 -->
<span class="plus" v-if="!selectedFileUrl"></span>

View file

@ -1,12 +1,10 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { ref } from 'vue'
import Avatar from '../components/Avatar.vue'
import Message from '@/components/alert/Message'
// store
import { useKUNGalgameUserStore } from '@/store/modules/kungalgamer'
const currentUserUid = computed(() => useKUNGalgameUserStore().uid)
//
const bioValue = ref('')
@ -22,10 +20,8 @@ const handleChangeBio = async () => {
return
}
const res = await useKUNGalgameUserStore().updateBio(
currentUserUid.value,
bioValue.value
)
const res = await useKUNGalgameUserStore().updateBio(bioValue.value)
if (res.code === 200) {
Message('Rewrite bio successfully!', 'Rewrite 签名成功', 'success')
bioValue.value = ''

View file

@ -70,22 +70,3 @@ export const resizeImage = (file: File): Promise<Blob> => {
}
})
}
// 上传头像
export const handleUploadAvatar = async (event: Event) => {
const input = event.target as HTMLInputElement
if (input.files && input.files[0]) {
const file = input.files[0]
// 检查图片是否合法,不合法则退出
const isFileValid = checkImageValid(file)
if (!isFileValid) {
return
}
// 处理图片
const resizedFile = await resizeImage(file)
return URL.createObjectURL(resizedFile)
}
}