hookehuyr

feat(PosterPage): 添加海报图片上传至七牛云功能

实现图片上传至七牛云的功能,包括获取文件哈希、获取上传token、处理已存在文件和新文件上传逻辑
添加上传状态提示和错误处理
<!--
* @Date: 2025-12-23 15:50:59
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-12-23 17:02:26
* @LastEditTime: 2025-12-23 17:07:47
* @FilePath: /mlaj/src/views/recall/PosterPage.vue
* @Description: 分享海报页面
-->
......@@ -37,9 +37,14 @@ import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useTitle } from '@vueuse/core'
import RecallPoster from '@/components/ui/RecallPoster.vue'
import { qiniuTokenAPI, qiniuUploadAPI, saveFileAPI } from '@/api/common'
import { showToast, showLoadingToast } from 'vant'
import { qiniuFileHash } from '@/utils/qiniuFileHash'
import { useAuth } from '@/contexts/auth'
const $route = useRoute();
const $router = useRouter();
const { currentUser } = useAuth();
useTitle('分享海报');
// Assets
......@@ -51,10 +56,92 @@ const qrCodeUrl = 'https://cdn.ipadbiz.cn/mlaj/recall/poster/%E4%BA%8C%E7%BB%B4%
const posterBg = ref(defaultBg)
const title = ref('2017.7.6-7.11 【自然的恩典】“爱我中华”优秀传统文化夏令营-天津场开启~')
/**
* 获取文件哈希(与七牛云ETag一致)
*/
const getFileMD5 = async (file) => {
return await qiniuFileHash(file)
}
// 上传到七牛云
const uploadToQiniu = async (file, token, fileName) => {
const formData = new FormData()
formData.append('file', file)
formData.append('token', token)
formData.append('key', fileName)
const config = {
headers: { 'Content-Type': 'multipart/form-data' }
}
// 根据协议选择上传地址
const qiniuUploadUrl = window.location.protocol === 'https:'
? 'https://up.qbox.me'
: 'http://upload.qiniu.com'
return await qiniuUploadAPI(qiniuUploadUrl, formData, config)
}
// Actions
const afterRead = (file) => {
// Use Object URL for local preview to avoid uploading
posterBg.value = URL.createObjectURL(file.file)
const afterRead = async (file) => {
const toast = showLoadingToast({
message: '上传中...',
forbidClick: true,
duration: 0 // 持续展示
});
try {
// 获取MD5值
const md5 = await getFileMD5(file.file)
// 获取七牛token
const tokenResult = await qiniuTokenAPI({
name: file.file.name,
hash: md5
})
// 文件已存在,直接使用
if (tokenResult.data) {
posterBg.value = tokenResult.data.src;
showToast('图片上传成功');
return;
}
// 新文件上传
if (tokenResult.token) {
const suffix = /.[^.]+$/.exec(file.file.name) || ''
// 使用 recall/poster 路径
const mobile = currentUser.value?.mobile || 'guest'
const fileName = `mlaj/upload/recall/poster/${mobile}/${md5}${suffix}`
const { filekey, image_info } = await uploadToQiniu(
file.file,
tokenResult.token,
fileName
)
if (filekey) {
// 保存文件信息
const { data } = await saveFileAPI({
name: file.file.name,
filekey,
hash: md5,
height: image_info?.height,
width: image_info?.width
})
if (data) {
posterBg.value = data.src;
showToast('图片上传成功');
}
}
}
} catch (error) {
console.error('图片上传失败:', error)
showToast('图片上传失败,请重试')
} finally {
toast.close();
}
}
</script>
......