177 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import axios from 'axios'
import { message } from 'ant-design-vue'
const API_BASE = (import.meta as any).env?.VITE_API_BASE_URL || '/api'
export interface FileUpload {
id: number
originalName: string
storedName: string
filePath: string
fileUrl: string
fileSize: number
fileType: string
uploaderId: number
uploaderName: string
relatedType?: string
relatedId?: number
createTime: string
}
/**
* 上传文件到S3
* @param files 文件列表
* @param relatedType 关联类型(可选,如 'task')
* @param relatedId 关联ID(可选)
* @param onProgress 上传进度回调
*/
export const uploadFilesToS3 = async (
files: File[],
relatedType?: string,
relatedId?: number,
onProgress?: (progress: number) => void
): Promise<string[]> => {
console.log('[uploadFilesToS3] 开始上传,文件数量:', files.length, 'relatedType:', relatedType, 'relatedId:', relatedId)
const formData = new FormData()
files.forEach((file, index) => {
console.log(`[uploadFilesToS3] 添加文件 ${index + 1}:`, file.name, file.size, file.type)
formData.append('files', file)
})
if (relatedType) {
formData.append('relatedType', relatedType)
}
if (relatedId) {
formData.append('relatedId', relatedId.toString())
}
const token = localStorage.getItem('token')
console.log('[uploadFilesToS3] Token存在:', !!token)
console.log('[uploadFilesToS3] 请求URL:', `${API_BASE}/file/upload`)
return new Promise((resolve, reject) => {
console.log('[uploadFilesToS3] 发送POST请求到:', `${API_BASE}/file/upload`)
axios.post<{ code: number; message: string; data: string[] }>(
`${API_BASE}/file/upload`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': token ? `Bearer ${token}` : ''
},
onUploadProgress: (progressEvent) => {
if (onProgress && progressEvent.total) {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)
onProgress(percent)
}
}
}
)
.then(response => {
console.log('[uploadFilesToS3] 上传响应:', response.data)
if (response.data.code === 200 && response.data.data) {
console.log('[uploadFilesToS3] 上传成功,文件URLs:', response.data.data)
resolve(response.data.data)
} else {
console.error('[uploadFilesToS3] 上传失败,响应:', response.data)
message.error(response.data.message || '上传失败')
reject(new Error(response.data.message || '上传失败'))
}
})
.catch(error => {
console.error('[uploadFilesToS3] 上传异常:', error)
console.error('[uploadFilesToS3] 错误详情:', {
message: error.message,
response: error.response?.data,
status: error.response?.status
})
const errorMsg = error.response?.data?.message || error.message || '上传失败'
message.error(errorMsg)
reject(new Error(errorMsg))
})
})
}
/**
* 下载文件(需要登录)
* @param fileId 文件ID
*/
export const downloadFile = (fileId: number) => {
const token = localStorage.getItem('token')
const url = `${API_BASE}/file/download/${fileId}`
// 创建隐藏的a标签进行下载
const link = document.createElement('a')
link.href = url
link.style.display = 'none'
// 添加Authorization header(通过fetch实现)
fetch(url, {
headers: {
'Authorization': token ? `Bearer ${token}` : ''
}
})
.then(response => {
if (response.ok) {
return response.blob()
} else {
throw new Error('下载失败')
}
})
.then(blob => {
const downloadUrl = window.URL.createObjectURL(blob)
link.href = downloadUrl
link.download = ''
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(downloadUrl)
})
.catch(error => {
message.error('文件下载失败: ' + error.message)
})
}
/**
* 获取文件信息
*/
export const getFileInfo = (fileId: number): Promise<FileUpload> => {
return axios.get(`${API_BASE}/file/${fileId}`, {
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
}).then(response => {
if (response.data.code === 200) {
return response.data.data
} else {
throw new Error(response.data.message || '获取文件信息失败')
}
})
}
/**
* 根据关联信息获取文件列表
*/
export const getFilesByRelated = (relatedType: string, relatedId: number): Promise<FileUpload[]> => {
return axios.get(`${API_BASE}/file/list`, {
params: { relatedType, relatedId },
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
}).then(response => {
if (response.data.code === 200) {
return response.data.data
} else {
throw new Error(response.data.message || '获取文件列表失败')
}
})
}
/**
* 直接打开文件URL(用于S3公开URL)
* @param fileUrl 文件URL
*/
export const openFileUrl = (fileUrl: string) => {
window.open(fileUrl, '_blank')
}