Files
SeeyonFileSystem/web/src/api/file.ts
2026-07-10 17:33:33 +08:00

291 lines
6.6 KiB
TypeScript

/**
* 文件管理相关 API
*/
import request from './request'
/** 文件信息 */
export interface FileInfo {
id: string
name: string
extension: string
folder_id: string
size: number
storage_key: string
storage_policy_id: number
mime_type: string
is_favorite: number
download_count: number
version: number
download_url: string
preview_url: string
created_at: string
updated_at: string
}
/** 文件夹信息 */
export interface FolderInfo {
id: string
biz_id: string
name: string
parent_id: string
path: string
version: number
created_at: string
updated_at: string
}
/** 文件列表响应(分页) */
export interface FileListResult {
folders: FolderInfo[]
files: FileInfo[]
total_files: number
total_folders: number
page: number
page_size: number
}
/** 分享信息 */
export interface ShareInfo {
id: string
share_code: string
share_url: string
has_password: boolean
expire_at: string | null
max_download: number
download_count: number
allow_preview: number
allow_download: number
created_at: string
}
/**
* 上传文件
* @param file 文件对象
* @param folderId 目标文件夹ID, 0=根目录
*/
export function uploadFile(file: File, folderId: string = '0') {
const formData = new FormData()
formData.append('file', file)
return request.post<any, { data: FileInfo }>(`/file/upload?folder_id=${folderId}`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
})
}
/** 存储信息 */
export interface StorageInfo {
policy_id: number
policy_name: string
policy_type: string
storage_quota: number
used_storage: number
used_percent: number
max_file_size: number
chunk_threshold: number
}
/** 分片上传初始化结果 */
export interface ChunkInitResult {
upload_id: string
instant: boolean
file_id: number
chunk_size: number
total: number
}
/**
* 获取用户存储信息(含文件大小限制)
*/
export function getStorageInfo() {
return request.get<any, { data: StorageInfo }>('/user/storage-info')
}
/**
* 初始化分片上传
*/
export function initChunkUpload(data: { file_name: string; file_size: number; md5?: string; folder_id?: string }) {
return request.post<any, { data: ChunkInitResult }>('/file/upload/init', data)
}
/**
* 上传单个分片(本地模式)
*/
export function uploadChunk(uploadId: string, index: number, chunk: Blob) {
const formData = new FormData()
formData.append('chunk', chunk, 'chunk')
return request.put(`/file/upload/chunk/${uploadId}/${index}`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
})
}
/**
* 确认MinIO分片上传完成(直传模式)
*/
export function confirmChunk(uploadId: string, index: number, etag: string) {
return request.post(`/file/upload/chunk/${uploadId}/${index}/confirm`, { etag })
}
/**
* 合并分片完成上传
*/
export function mergeChunks(uploadId: string) {
return request.post<any, { data: FileInfo }>(`/file/upload/merge/${uploadId}`)
}
/**
* 查询上传进度
*/
export function getUploadProgress(uploadId: string) {
return request.get(`/file/upload/progress/${uploadId}`)
}
/**
* 取消上传
*/
export function cancelUpload(uploadId: string) {
return request.delete(`/file/upload/${uploadId}`)
}
/**
* 获取文件夹内容(文件+子文件夹, 支持分页)
*/
export function getFolderChildren(folderId: string, page: number = 1, pageSize: number = 50) {
return request.get<any, { data: FileListResult }>(`/folder/${folderId}/children`, {
params: { page, page_size: pageSize },
})
}
/**
* 创建文件夹
*/
export function createFolder(name: string, parentId: string = '0', bizId?: string) {
const data: any = { name, parent_id: parentId }
if (bizId) data.biz_id = bizId
return request.post('/folder', data)
}
/**
* 根据业务ID获取文件夹信息
*/
export function getFolderByBizId(bizId: string) {
return request.get<any, { data: FolderInfo }>(`/folder/by-bizid/${encodeURIComponent(bizId)}`)
}
/**
* 重命名文件
*/
export function renameFile(fileId: string, newName: string) {
return request.put(`/file/${fileId}/rename`, { new_name: newName })
}
/**
* 重命名文件夹
*/
export function renameFolder(folderId: string, newName: string) {
return request.put(`/folder/${folderId}/rename`, { new_name: newName })
}
/**
* 删除文件(移入回收站)
*/
export function deleteFile(fileId: string) {
return request.delete(`/file/${fileId}`)
}
/**
* 删除文件夹(移入回收站)
*/
export function deleteFolder(folderId: string) {
return request.delete(`/folder/${folderId}`)
}
/**
* 移动文件
*/
export function moveFile(fileId: string, targetFolderId: string) {
return request.post(`/file/${fileId}/move`, { target_folder_id: targetFolderId })
}
/**
* 搜索文件
*/
export function searchFiles(keyword: string) {
return request.get<any, { data: FileInfo[] }>('/file/search', { params: { keyword } })
}
/**
* 获取回收站列表
*/
export function getTrash() {
return request.get<any, { data: FileInfo[] }>('/file/trash')
}
/**
* 恢复文件
*/
export function restoreFile(fileId: string) {
return request.post(`/file/${fileId}/restore`)
}
/**
* 永久删除文件
*/
export function permanentDeleteFile(fileId: string) {
return request.delete(`/file/${fileId}/permanent`)
}
/**
* 获取文件下载链接
*/
export function getDownloadUrl(fileId: string): string {
return `/api/file/${fileId}/download`
}
/**
* 创建分享
*/
export function createShare(fileId: string, password?: string, expireHours?: number, maxDownload?: number, allowPreview?: number, allowDownload?: number) {
return request.post<any, { data: ShareInfo }>('/share', {
file_id: fileId,
password,
expire_hours: expireHours,
max_download: maxDownload,
allow_preview: allowPreview,
allow_download: allowDownload,
})
}
/**
* 获取我的分享列表
*/
export function getMyShares() {
return request.get<any, { data: ShareInfo[] }>('/share')
}
/**
* 取消分享
*/
export function cancelShare(shareId: string) {
return request.delete(`/share/${shareId}`)
}
/**
* 获取分享信息(公开)
*/
export function getShareInfo(code: string) {
return request.get(`/s/${code}`)
}
/**
* 获取文件授权列表
*/
export function getFilePermissions(fileId: string) {
return request.get<any, { data: Array<{ id: string; user_id: string; role_id: string; user_name: string; role_name: string; perm_level: string; grant_by_name: string }> }>(`/file/${fileId}/grant`)
}
/**
* 验证分享密码
*/
export function verifySharePassword(code: string, password: string) {
return request.post(`/s/${code}/verify`, { password })
}