334 lines
8.0 KiB
TypeScript
334 lines
8.0 KiB
TypeScript
// 文件上传相关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
|