2026-07-03 15:58:29 +08:00
|
|
|
/**
|
|
|
|
|
* 文件管理相关 API
|
|
|
|
|
*/
|
|
|
|
|
import request from './request'
|
|
|
|
|
|
|
|
|
|
/** 文件信息 */
|
|
|
|
|
export interface FileInfo {
|
2026-07-10 17:33:33 +08:00
|
|
|
id: string
|
2026-07-03 15:58:29 +08:00
|
|
|
name: string
|
|
|
|
|
extension: string
|
2026-07-10 17:33:33 +08:00
|
|
|
folder_id: string
|
2026-07-03 15:58:29 +08:00
|
|
|
size: number
|
2026-07-10 17:33:33 +08:00
|
|
|
storage_key: string
|
|
|
|
|
storage_policy_id: number
|
2026-07-03 15:58:29 +08:00
|
|
|
mime_type: string
|
|
|
|
|
is_favorite: number
|
|
|
|
|
download_count: number
|
2026-07-10 17:33:33 +08:00
|
|
|
version: number
|
|
|
|
|
download_url: string
|
|
|
|
|
preview_url: string
|
2026-07-03 15:58:29 +08:00
|
|
|
created_at: string
|
|
|
|
|
updated_at: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 文件夹信息 */
|
|
|
|
|
export interface FolderInfo {
|
2026-07-10 17:33:33 +08:00
|
|
|
id: string
|
|
|
|
|
biz_id: string
|
2026-07-03 15:58:29 +08:00
|
|
|
name: string
|
2026-07-10 17:33:33 +08:00
|
|
|
parent_id: string
|
2026-07-03 15:58:29 +08:00
|
|
|
path: string
|
2026-07-10 17:33:33 +08:00
|
|
|
version: number
|
2026-07-03 15:58:29 +08:00
|
|
|
created_at: string
|
|
|
|
|
updated_at: string
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-10 17:33:33 +08:00
|
|
|
/** 文件列表响应(分页) */
|
2026-07-03 15:58:29 +08:00
|
|
|
export interface FileListResult {
|
|
|
|
|
folders: FolderInfo[]
|
|
|
|
|
files: FileInfo[]
|
2026-07-10 17:33:33 +08:00
|
|
|
total_files: number
|
|
|
|
|
total_folders: number
|
|
|
|
|
page: number
|
|
|
|
|
page_size: number
|
2026-07-03 15:58:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 分享信息 */
|
|
|
|
|
export interface ShareInfo {
|
2026-07-10 17:33:33 +08:00
|
|
|
id: string
|
2026-07-03 15:58:29 +08:00
|
|
|
share_code: string
|
|
|
|
|
share_url: string
|
|
|
|
|
has_password: boolean
|
|
|
|
|
expire_at: string | null
|
|
|
|
|
max_download: number
|
|
|
|
|
download_count: number
|
2026-07-10 17:33:33 +08:00
|
|
|
allow_preview: number
|
|
|
|
|
allow_download: number
|
2026-07-03 15:58:29 +08:00
|
|
|
created_at: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 上传文件
|
|
|
|
|
* @param file 文件对象
|
|
|
|
|
* @param folderId 目标文件夹ID, 0=根目录
|
|
|
|
|
*/
|
2026-07-18 10:52:32 +08:00
|
|
|
export function uploadFile(file: File, folderId: string = '0', bizId?: string) {
|
2026-07-03 15:58:29 +08:00
|
|
|
const formData = new FormData()
|
|
|
|
|
formData.append('file', file)
|
2026-07-18 10:52:32 +08:00
|
|
|
let url = `/file/upload?folder_id=${folderId}`
|
|
|
|
|
if (bizId) url += `&biz_id=${encodeURIComponent(bizId)}`
|
|
|
|
|
return request.post<any, { data: FileInfo }>(url, formData, {
|
2026-07-03 15:58:29 +08:00
|
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-10 17:33:33 +08:00
|
|
|
/** 存储信息 */
|
|
|
|
|
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}`)
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-03 15:58:29 +08:00
|
|
|
/**
|
2026-07-10 17:33:33 +08:00
|
|
|
* 获取文件夹内容(文件+子文件夹, 支持分页)
|
2026-07-03 15:58:29 +08:00
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
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 },
|
|
|
|
|
})
|
2026-07-03 15:58:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 创建文件夹
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
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)}`)
|
2026-07-03 15:58:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 重命名文件
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
export function renameFile(fileId: string, newName: string) {
|
2026-07-03 15:58:29 +08:00
|
|
|
return request.put(`/file/${fileId}/rename`, { new_name: newName })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 重命名文件夹
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
export function renameFolder(folderId: string, newName: string) {
|
2026-07-03 15:58:29 +08:00
|
|
|
return request.put(`/folder/${folderId}/rename`, { new_name: newName })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 删除文件(移入回收站)
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
export function deleteFile(fileId: string) {
|
2026-07-03 15:58:29 +08:00
|
|
|
return request.delete(`/file/${fileId}`)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 删除文件夹(移入回收站)
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
export function deleteFolder(folderId: string) {
|
2026-07-03 15:58:29 +08:00
|
|
|
return request.delete(`/folder/${folderId}`)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 移动文件
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
export function moveFile(fileId: string, targetFolderId: string) {
|
2026-07-03 15:58:29 +08:00
|
|
|
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')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 恢复文件
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
export function restoreFile(fileId: string) {
|
2026-07-03 15:58:29 +08:00
|
|
|
return request.post(`/file/${fileId}/restore`)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 永久删除文件
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
export function permanentDeleteFile(fileId: string) {
|
2026-07-03 15:58:29 +08:00
|
|
|
return request.delete(`/file/${fileId}/permanent`)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取文件下载链接
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
export function getDownloadUrl(fileId: string): string {
|
2026-07-03 15:58:29 +08:00
|
|
|
return `/api/file/${fileId}/download`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 创建分享
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
export function createShare(fileId: string, password?: string, expireHours?: number, maxDownload?: number, allowPreview?: number, allowDownload?: number) {
|
2026-07-03 15:58:29 +08:00
|
|
|
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')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 取消分享
|
|
|
|
|
*/
|
2026-07-10 17:33:33 +08:00
|
|
|
export function cancelShare(shareId: string) {
|
2026-07-03 15:58:29 +08:00
|
|
|
return request.delete(`/share/${shareId}`)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取分享信息(公开)
|
|
|
|
|
*/
|
|
|
|
|
export function getShareInfo(code: string) {
|
|
|
|
|
return request.get(`/s/${code}`)
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-10 17:33:33 +08:00
|
|
|
/**
|
|
|
|
|
* 获取文件授权列表
|
|
|
|
|
*/
|
|
|
|
|
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`)
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-03 15:58:29 +08:00
|
|
|
/**
|
|
|
|
|
* 验证分享密码
|
|
|
|
|
*/
|
|
|
|
|
export function verifySharePassword(code: string, password: string) {
|
|
|
|
|
return request.post(`/s/${code}/verify`, { password })
|
|
|
|
|
}
|