|
|
@@ -216,4 +216,144 @@ export class FileService extends GenericCrudService<File> {
|
|
|
throw new Error('完成分片上传失败');
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存文件记录并将文件内容直接上传到MinIO
|
|
|
+ * @param fileData - 文件基础信息
|
|
|
+ * @param fileContent - 文件内容(Buffer)
|
|
|
+ * @param contentType - 文件MIME类型
|
|
|
+ * @returns 保存的文件记录和文件访问URL
|
|
|
+ */
|
|
|
+ async saveFile(
|
|
|
+ fileData: {
|
|
|
+ name: string;
|
|
|
+ size: number;
|
|
|
+ mimeType: string;
|
|
|
+ uploadUserId: number;
|
|
|
+ [key: string]: any;
|
|
|
+ },
|
|
|
+ fileContent: Buffer,
|
|
|
+ contentType?: string
|
|
|
+ ) {
|
|
|
+ try {
|
|
|
+ logger.db('Starting saveFile process:', {
|
|
|
+ filename: fileData.name,
|
|
|
+ size: fileData.size,
|
|
|
+ mimeType: fileData.mimeType,
|
|
|
+ uploadUserId: fileData.uploadUserId
|
|
|
+ });
|
|
|
+
|
|
|
+ // 生成唯一文件存储路径
|
|
|
+ const fileKey = `${fileData.uploadUserId}/${uuidv4()}-${fileData.name}`;
|
|
|
+
|
|
|
+ // 确保存储桶存在
|
|
|
+ await this.minioService.ensureBucketExists();
|
|
|
+
|
|
|
+ // 直接上传文件内容到MinIO
|
|
|
+ const fileUrl = await this.minioService.createObject(
|
|
|
+ this.minioService.bucketName,
|
|
|
+ fileKey,
|
|
|
+ fileContent,
|
|
|
+ contentType || fileData.mimeType
|
|
|
+ );
|
|
|
+
|
|
|
+ // 准备文件记录数据
|
|
|
+ const completeFileData = {
|
|
|
+ ...fileData,
|
|
|
+ path: fileKey,
|
|
|
+ uploadTime: new Date(),
|
|
|
+ };
|
|
|
+
|
|
|
+ // 保存文件记录到数据库
|
|
|
+ const savedFile = await this.create(completeFileData as any);
|
|
|
+
|
|
|
+ logger.db('File saved successfully:', {
|
|
|
+ fileId: savedFile.id,
|
|
|
+ filename: savedFile.name,
|
|
|
+ size: savedFile.size,
|
|
|
+ url: fileUrl
|
|
|
+ });
|
|
|
+
|
|
|
+ return {
|
|
|
+ file: savedFile,
|
|
|
+ url: fileUrl
|
|
|
+ };
|
|
|
+ } catch (error) {
|
|
|
+ logger.error('Failed to save file:', error);
|
|
|
+ throw new Error(`文件保存失败: ${error instanceof Error ? error.message : '未知错误'}`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存文件记录并将文件内容直接上传到MinIO(支持自定义存储路径)
|
|
|
+ * @param fileData - 文件基础信息
|
|
|
+ * @param fileContent - 文件内容(Buffer)
|
|
|
+ * @param customPath - 自定义存储路径(可选)
|
|
|
+ * @param contentType - 文件MIME类型
|
|
|
+ * @returns 保存的文件记录和文件访问URL
|
|
|
+ */
|
|
|
+ async saveFileWithCustomPath(
|
|
|
+ fileData: {
|
|
|
+ name: string;
|
|
|
+ size: number;
|
|
|
+ mimeType: string;
|
|
|
+ uploadUserId: number;
|
|
|
+ [key: string]: any;
|
|
|
+ },
|
|
|
+ fileContent: Buffer,
|
|
|
+ customPath?: string,
|
|
|
+ contentType?: string
|
|
|
+ ) {
|
|
|
+ try {
|
|
|
+ logger.db('Starting saveFileWithCustomPath process:', {
|
|
|
+ filename: fileData.name,
|
|
|
+ size: fileData.size,
|
|
|
+ mimeType: fileData.mimeType,
|
|
|
+ uploadUserId: fileData.uploadUserId,
|
|
|
+ customPath: customPath || 'auto-generated'
|
|
|
+ });
|
|
|
+
|
|
|
+ // 使用自定义路径或生成唯一文件存储路径
|
|
|
+ const fileKey = customPath || `${fileData.uploadUserId}/${uuidv4()}-${fileData.name}`;
|
|
|
+
|
|
|
+ // 确保存储桶存在
|
|
|
+ await this.minioService.ensureBucketExists();
|
|
|
+
|
|
|
+ // 直接上传文件内容到MinIO
|
|
|
+ const fileUrl = await this.minioService.createObject(
|
|
|
+ this.minioService.bucketName,
|
|
|
+ fileKey,
|
|
|
+ fileContent,
|
|
|
+ contentType || fileData.mimeType
|
|
|
+ );
|
|
|
+
|
|
|
+ // 准备文件记录数据
|
|
|
+ const completeFileData = {
|
|
|
+ ...fileData,
|
|
|
+ path: fileKey,
|
|
|
+ uploadTime: new Date(),
|
|
|
+ // createdAt: new Date(),
|
|
|
+ // updatedAt: new Date()
|
|
|
+ };
|
|
|
+
|
|
|
+ // 保存文件记录到数据库
|
|
|
+ const savedFile = await this.create(completeFileData as any);
|
|
|
+
|
|
|
+ logger.db('File saved with custom path successfully:', {
|
|
|
+ fileId: savedFile.id,
|
|
|
+ filename: savedFile.name,
|
|
|
+ size: savedFile.size,
|
|
|
+ path: fileKey,
|
|
|
+ url: fileUrl
|
|
|
+ });
|
|
|
+
|
|
|
+ return {
|
|
|
+ file: savedFile,
|
|
|
+ url: fileUrl
|
|
|
+ };
|
|
|
+ } catch (error) {
|
|
|
+ logger.error('Failed to save file with custom path:', error);
|
|
|
+ throw new Error(`文件保存失败: ${error instanceof Error ? error.message : '未知错误'}`);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|