334 lines
8.0 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.

// 文件上传相关API接口
import { ApiRequest } from '../request'
import type { ApiResponse } from '../types'
/**
* 上传API模块
*/
export class UploadApi {
// 上传单个文件
static uploadFile(
file: File,
type: 'image' | 'video' | 'document' | 'audio' = 'image',
onProgress?: (progress: number) => void
): Promise<ApiResponse<{
url: string
filename: string
size: number
type: string
hash?: string
}>> {
return ApiRequest.upload(`/upload/${type}`, file, onProgress)
}
// 上传头像
static uploadAvatar(
file: File,
onProgress?: (progress: number) => void
): Promise<ApiResponse<{
url: string
filename: string
size: number
}>> {
return ApiRequest.upload('/upload/avatar', file, onProgress)
}
// 上传课程封面
static uploadCourseThumbnail(
file: File,
courseId?: number,
onProgress?: (progress: number) => void
): Promise<ApiResponse<{
url: string
message: string
success: boolean
filename: string
size: number
}>> {
const formData = new FormData()
formData.append('file', file)
if (courseId) {
formData.append('courseId', courseId.toString())
}
return ApiRequest.post('/sys/common/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent: any) => {
if (onProgress && progressEvent.total) {
const progress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
onProgress(progress)
}
},
})
}
// 上传课程视频
static uploadCourseVideo(
file: File,
courseId?: number,
lessonId?: number,
onProgress?: (progress: number) => void
): Promise<ApiResponse<{
url: string
filename: string
size: number
duration?: number
resolution?: string
}>> {
const formData = new FormData()
formData.append('file', file)
if (courseId) {
formData.append('courseId', courseId.toString())
}
if (lessonId) {
formData.append('lessonId', lessonId.toString())
}
return ApiRequest.post('/upload/course-video', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent: any) => {
if (onProgress && progressEvent.total) {
const progress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
onProgress(progress)
}
},
})
}
// 上传课程资源文件
static uploadCourseResource(
file: File,
lessonId: number,
title?: string,
description?: string,
onProgress?: (progress: number) => void
): Promise<ApiResponse<{
id: number
url: string
filename: string
title: string
size: number
type: string
}>> {
const formData = new FormData()
formData.append('file', file)
formData.append('lessonId', lessonId.toString())
if (title) {
formData.append('title', title)
}
if (description) {
formData.append('description', description)
}
return ApiRequest.post('/upload/course-resource', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent: any) => {
if (onProgress && progressEvent.total) {
const progress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
onProgress(progress)
}
},
})
}
// 批量上传文件
static uploadMultipleFiles(
files: File[],
type: 'image' | 'video' | 'document' | 'audio' = 'image',
onProgress?: (progress: number) => void
): Promise<ApiResponse<Array<{
url: string
filename: string
size: number
type: string
success: boolean
error?: string
}>>> {
const formData = new FormData()
files.forEach((file) => {
formData.append(`files`, file)
})
return ApiRequest.post(`/upload/multiple/${type}`, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent: any) => {
if (onProgress && progressEvent.total) {
const progress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
onProgress(progress)
}
},
})
}
// 获取上传配置
static getUploadConfig(): Promise<ApiResponse<{
maxFileSize: number
allowedTypes: string[]
imageTypes: string[]
videoTypes: string[]
documentTypes: string[]
audioTypes: string[]
uploadUrl: string
cdnUrl: string
}>> {
return ApiRequest.get('/upload/config')
}
// 获取上传token用于直传OSS等
static getUploadToken(type: string = 'image'): Promise<ApiResponse<{
token: string
accessKeyId: string
accessKeySecret: string
securityToken: string
bucket: string
region: string
endpoint: string
expiration: string
policy: string
signature: string
}>> {
return ApiRequest.get(`/upload/token/${type}`)
}
// 删除文件
static deleteFile(url: string): Promise<ApiResponse<null>> {
return ApiRequest.delete('/upload/file', { url })
}
// 批量删除文件
static deleteMultipleFiles(urls: string[]): Promise<ApiResponse<{
success: string[]
failed: string[]
}>> {
return ApiRequest.delete('/upload/files', { urls })
}
// 获取文件信息
static getFileInfo(url: string): Promise<ApiResponse<{
url: string
filename: string
size: number
type: string
uploadedAt: string
uploadedBy?: string
downloads?: number
}>> {
return ApiRequest.get('/upload/file-info', { url })
}
// 压缩图片
static compressImage(
file: File,
options: {
quality?: number
maxWidth?: number
maxHeight?: number
format?: 'jpeg' | 'png' | 'webp'
} = {},
onProgress?: (progress: number) => void
): Promise<ApiResponse<{
url: string
filename: string
originalSize: number
compressedSize: number
compressionRatio: number
}>> {
const formData = new FormData()
formData.append('file', file)
formData.append('options', JSON.stringify(options))
return ApiRequest.post('/upload/compress-image', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent: any) => {
if (onProgress && progressEvent.total) {
const progress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
onProgress(progress)
}
},
})
}
// 生成缩略图
static generateThumbnail(
file: File,
sizes: Array<{ width: number; height: number }> = [
{ width: 150, height: 150 },
{ width: 300, height: 300 },
],
onProgress?: (progress: number) => void
): Promise<ApiResponse<{
original: string
thumbnails: Array<{
size: string
url: string
width: number
height: number
}>
}>> {
const formData = new FormData()
formData.append('file', file)
formData.append('sizes', JSON.stringify(sizes))
return ApiRequest.post('/upload/generate-thumbnail', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent: any) => {
if (onProgress && progressEvent.total) {
const progress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
onProgress(progress)
}
},
})
}
// 获取上传历史
static getUploadHistory(params?: {
page?: number
pageSize?: number
type?: string
startDate?: string
endDate?: string
}): Promise<ApiResponse<{
list: Array<{
id: number
filename: string
originalName: string
url: string
size: number
type: string
uploadedAt: string
downloads: number
}>
total: number
page: number
pageSize: number
}>> {
return ApiRequest.get('/upload/history', params)
}
}
export default UploadApi