import { Repository } from 'typeorm'; import { FileEntity } from '../entities/file.entity'; import { FileMetadataEntity } from '../entities/file-metadata.entity'; import { CreateFileDto } from '../dto/create-file.dto'; import { UpdateFileDto } from '../dto/update-file.dto'; import { FindFilesDto } from '../dto/find-files.dto'; import { PaginationDto } from '../dto/pagination.dto'; import { IStorageProvider } from '../interfaces/storage-provider.interface'; import { FileBuffer } from '../interfaces/file-buffer.interface'; import { Readable } from 'stream'; /** * 存储统计信息 */ export interface StorageStats { totalFiles: number; totalSize: number; providers: Record; } /** * 文件查询结果 */ export interface FileQueryResult { files: FileEntity[]; total: number; page: number; limit: number; totalPages: number; } /** * 文件管理服务 */ export declare class FileService { private readonly fileRepository; private readonly metadataRepository; private readonly storageProvider?; private readonly localStorageProvider?; private readonly s3StorageProvider?; private readonly logger; private readonly ALLOWED_ORDER_FIELDS; private readonly ALLOWED_ORDER_DIRECTIONS; constructor(fileRepository: Repository, metadataRepository: Repository, storageProvider?: IStorageProvider, localStorageProvider?: IStorageProvider, s3StorageProvider?: IStorageProvider); /** * 创建文件记录 */ create(createFileDto: CreateFileDto): Promise; /** * 根据ID查找文件 */ findById(id: string, includeDeleted?: boolean): Promise; /** * 根据uploadId查找文件 */ findByUploadId(uploadId: string): Promise; /** * 查找文件列表 */ findFiles(query: FindFilesDto, pagination: PaginationDto): Promise; /** * 更新文件记录 */ update(id: string, updateFileDto: UpdateFileDto): Promise; /** * 软删除文件 * @param id 文件ID * @param deletePhysicalFile 是否同时删除物理文件,默认 false */ softDelete(id: string, deletePhysicalFile?: boolean): Promise; /** * 硬删除文件 * @param id 文件ID * @param deletePhysicalFile 是否同时删除物理文件,默认 true */ hardDelete(id: string, deletePhysicalFile?: boolean): Promise; /** * 添加元数据 */ addMetadata(fileId: string, key: string, value: any, isPublic?: boolean): Promise; /** * 获取元数据 */ getMetadata(fileId: string, keys?: string[]): Promise>; /** * 获取存储统计 */ getStorageStats(userId?: string): Promise; /** * 更新处理状态 * 处理状态信息保存到 file_metadata 表 */ updateProcessingStatus(fileId: string, processor: string, status: 'pending' | 'completed' | 'failed', result?: any, error?: string): Promise; /** * 清理临时文件(定时任务) */ cleanupTempFiles(olderThanHours?: number): Promise<{ deleted: number; }>; /** * 获取文件内容(二进制) * 适用于服务间调用,获取完整文件内容 * * @param fileId 文件ID * @returns 文件缓冲区对象 * @throws NotFoundException 文件不存在 * @throws BadRequestException 文件未完成上传 */ getFileContent(fileId: string): Promise; /** * 获取文件流(用于大文件) * 适用于流式处理,避免一次性加载到内存 * 注意:仅支持本地存储,对象存储请使用 getSignedUrl * * @param fileId 文件ID * @returns 可读流 * @throws NotFoundException 文件不存在或物理文件缺失 * @throws BadRequestException 文件未完成或存储类型不支持 */ getFileStream(fileId: string): Promise; /** * 获取预签名 URL(对象存储) * 适用于客户端直接下载,或临时授权访问 * * @param fileId 文件ID * @param expiresIn 过期时间(秒),默认 3600 秒(1小时) * @returns 预签名 URL * @throws NotFoundException 文件不存在 */ getSignedUrl(fileId: string, expiresIn?: number): Promise; /** * 批量获取文件内容 * 适用于需要同时处理多个文件的场景 * 失败的文件会被跳过,不会中断整个流程 * * @param fileIds 文件ID列表 * @returns Map<文件ID, 文件内容> */ getFilesContent(fileIds: string[]): Promise>; /** * 获取文件访问 URL * 根据存储类型返回不同的 URL * * @param fileId 文件ID * @param baseUrl 基础 URL(可选,用于本地存储) * @returns 文件访问 URL */ getFileUrl(fileId: string, baseUrl?: string): Promise; /** * 批量删除文件 * @param fileIds 文件ID列表 * @param deletePhysicalFile 是否同时删除物理文件,默认 true * @returns 删除结果统计 */ batchDelete(fileIds: string[], deletePhysicalFile?: boolean): Promise<{ success: string[]; failed: Array<{ id: string; error: string; }>; }>; /** * 复制文件(创建新记录) * @param sourceFileId 源文件ID * @param userId 新文件的用户ID(可选) * @returns 新的文件实体 */ copyFile(sourceFileId: string, userId?: string): Promise; /** * 移动文件到新路径 * @param fileId 文件ID * @param newPath 新路径 * @returns 更新后的文件实体 */ moveFile(fileId: string, newPath: string): Promise; /** * 删除物理文件 * @private */ private deletePhysicalFile; /** * 根据存储类型获取存储提供者 * * @param storageType 存储类型 * @returns 存储提供者实例 * @throws Error 存储提供者未配置或不支持 */ private getStorageProvider; /** * 转义 LIKE 操作符中的特殊字符 */ private escapeLikeString; }