import COS from 'cos-js-sdk-v5'
|
import axios from 'axios'
|
|
// 从后端获取临时密钥
|
const getCredentialsFromBackend = async () => {
|
try {
|
const response = await axios.get('http://localhost:8080/api/cos/credentials')
|
return response.data
|
} catch (error) {
|
console.error('从后端获取临时密钥失败:', error)
|
throw error
|
}
|
}
|
|
// 创建COS实例
|
const cos = new COS({
|
getAuthorization: async function (options: any, callback: any) {
|
try {
|
console.log('正在从后端获取COS临时密钥...')
|
// 从后端获取临时密钥
|
const credentials = await getCredentialsFromBackend()
|
|
console.log('成功获取临时密钥:', {
|
TmpSecretId: credentials.TmpSecretId?.substring(0, 10) + '...',
|
bucket: credentials.config?.bucket,
|
region: credentials.config?.region
|
})
|
|
callback({
|
TmpSecretId: credentials.TmpSecretId,
|
TmpSecretKey: credentials.TmpSecretKey,
|
SecurityToken: credentials.SecurityToken,
|
StartTime: credentials.StartTime,
|
ExpiredTime: credentials.ExpiredTime,
|
})
|
} catch (error) {
|
console.error('获取临时密钥失败:', error)
|
callback(error)
|
}
|
}
|
})
|
|
// 获取COS配置信息
|
export const getCOSConfig = async () => {
|
try {
|
const response = await axios.get('http://localhost:8080/api/cos/config')
|
return response.data
|
} catch (error) {
|
console.error('获取COS配置失败:', error)
|
throw error
|
}
|
}
|
|
/**
|
* 上传文件到腾讯云COS
|
* @param file 要上传的文件
|
* @param folder 存储文件夹路径,如 'avatars/', 'documents/'
|
* @returns Promise<string> 返回文件的访问URL
|
*/
|
export const uploadToCOS = async (file: File, folder: string = ''): Promise<string> => {
|
try {
|
// 获取COS配置
|
const config = await getCOSConfig()
|
|
// 生成唯一文件名
|
const timestamp = Date.now()
|
const randomStr = Math.random().toString(36).substring(2, 8)
|
const fileExt = file.name.split('.').pop()
|
const fileName = `${folder}${timestamp}_${randomStr}.${fileExt}`
|
|
console.log('开始上传文件:', fileName, '到存储桶:', config.bucket)
|
|
return new Promise((resolve, reject) => {
|
cos.uploadFile({
|
Bucket: config.bucket,
|
Region: config.region,
|
Key: fileName,
|
Body: file,
|
SliceSize: 1024 * 1024 * 5, // 大于5MB的文件使用分块上传
|
onProgress: (progressData) => {
|
console.log('上传进度:', Math.round(progressData.percent * 100) + '%')
|
}
|
}, (err, data) => {
|
if (err) {
|
console.error('上传失败:', err)
|
reject(err)
|
} else {
|
console.log('上传成功:', data)
|
// 返回文件的访问URL
|
const fileUrl = `https://${data.Location}`
|
resolve(fileUrl)
|
}
|
})
|
})
|
} catch (error) {
|
console.error('上传文件失败:', error)
|
throw error
|
}
|
}
|
|
/**
|
* 删除COS中的文件
|
* @param key 文件的Key(路径)
|
* @returns Promise<boolean>
|
*/
|
export const deleteFromCOS = async (key: string): Promise<boolean> => {
|
try {
|
const config = await getCOSConfig()
|
|
return new Promise((resolve, reject) => {
|
cos.deleteObject({
|
Bucket: config.bucket,
|
Region: config.region,
|
Key: key
|
}, (err, data) => {
|
if (err) {
|
console.error('删除失败:', err)
|
reject(err)
|
} else {
|
console.log('删除成功:', data)
|
resolve(true)
|
}
|
})
|
})
|
} catch (error) {
|
console.error('删除文件失败:', error)
|
throw error
|
}
|
}
|
|
/**
|
* 获取文件的临时访问URL(用于私有读取的文件)
|
* @param key 文件的Key(路径)
|
* @param expires 过期时间(秒),默认1小时
|
* @returns Promise<string>
|
*/
|
export const getObjectUrl = async (key: string, expires: number = 3600): Promise<string> => {
|
try {
|
const config = await getCOSConfig()
|
|
return new Promise((resolve, reject) => {
|
cos.getObjectUrl({
|
Bucket: config.bucket,
|
Region: config.region,
|
Key: key,
|
Expires: expires,
|
Sign: true
|
}, (err, data) => {
|
if (err) {
|
console.error('获取URL失败:', err)
|
reject(err)
|
} else {
|
resolve(data.Url)
|
}
|
})
|
})
|
} catch (error) {
|
console.error('获取文件URL失败:', error)
|
throw error
|
}
|
}
|
|
export default cos
|