59 lines
1.5 KiB
JavaScript
59 lines
1.5 KiB
JavaScript
|
|
// app/composables/useUpload.js
|
|||
|
|
// 统一图片上传:POST /upload-image -> { url: "..." }
|
|||
|
|
|
|||
|
|
import { useRuntimeConfig } from '#app'
|
|||
|
|
|
|||
|
|
export function useUpload() {
|
|||
|
|
const {
|
|||
|
|
public: { apiBase },
|
|||
|
|
} = useRuntimeConfig()
|
|||
|
|
|
|||
|
|
// 计算后端基础域名(去掉 /api 之类的前缀)
|
|||
|
|
const apiOrigin = (() => {
|
|||
|
|
try {
|
|||
|
|
const u = new URL(apiBase, window.location.origin)
|
|||
|
|
// 如果 apiBase 以 /api 结尾,去掉这一段,只保留协议+域名+端口
|
|||
|
|
if (u.pathname.endsWith('/api') || u.pathname.endsWith('/api/')) {
|
|||
|
|
u.pathname = u.pathname.replace(/\/api\/?$/, '')
|
|||
|
|
} else if (u.pathname !== '/' && u.pathname.endsWith('/')) {
|
|||
|
|
u.pathname = u.pathname.slice(0, -1)
|
|||
|
|
}
|
|||
|
|
return u.origin
|
|||
|
|
} catch {
|
|||
|
|
return ''
|
|||
|
|
}
|
|||
|
|
})()
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 上传图片文件,返回一个可直接用于 <img> 的 URL 字符串
|
|||
|
|
*/
|
|||
|
|
const uploadImage = async (file) => {
|
|||
|
|
if (!file) throw new Error('No file to upload')
|
|||
|
|
|
|||
|
|
const fd = new FormData()
|
|||
|
|
fd.append('file', file)
|
|||
|
|
|
|||
|
|
const res = await $fetch(`${apiBase}/upload-image`, {
|
|||
|
|
method: 'POST',
|
|||
|
|
body: fd,
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
let url = res?.url || res?.URL
|
|||
|
|
if (!url || typeof url !== 'string') {
|
|||
|
|
console.error('[useUpload] invalid upload response:', res)
|
|||
|
|
throw new Error('Upload response missing url')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果是相对路径(/static/...),补成后端完整地址
|
|||
|
|
if (url.startsWith('/')) {
|
|||
|
|
if (apiOrigin) {
|
|||
|
|
url = apiOrigin + url
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return url
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return { uploadImage }
|
|||
|
|
}
|