feat(storage): integrate Alibaba Cloud OSS for file persistence - Add OSSAdapter and LocalAdapter with StorageFactory pattern - Integrate PKB module with OSS upload - Rename difyDocumentId to storageKey - Create 4 OSS buckets and development specification
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import type { FastifyRequest, FastifyReply } from 'fastify';
|
||||
import * as documentService from '../services/documentService.js';
|
||||
import { storage } from '../../../common/storage/index.js';
|
||||
import { randomUUID } from 'crypto';
|
||||
import path from 'path';
|
||||
|
||||
/**
|
||||
* 获取用户ID(从JWT Token中获取)
|
||||
@@ -12,6 +15,30 @@ function getUserId(request: FastifyRequest): string {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户ID(从JWT Token中获取)
|
||||
*/
|
||||
function getTenantId(request: FastifyRequest): string {
|
||||
const tenantId = (request as any).user?.tenantId;
|
||||
// 如果没有租户ID,使用默认值
|
||||
return tenantId || 'default';
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 PKB 文档存储 Key
|
||||
* 格式:tenants/{tenantId}/users/{userId}/pkb/{kbId}/{uuid}.{ext}
|
||||
*/
|
||||
function generatePkbStorageKey(
|
||||
tenantId: string,
|
||||
userId: string,
|
||||
kbId: string,
|
||||
filename: string
|
||||
): string {
|
||||
const uuid = randomUUID().replace(/-/g, '').substring(0, 16);
|
||||
const ext = path.extname(filename).toLowerCase();
|
||||
return `tenants/${tenantId}/users/${userId}/pkb/${kbId}/${uuid}${ext}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文档
|
||||
*/
|
||||
@@ -45,15 +72,15 @@ export async function uploadDocument(
|
||||
const fileType = data.mimetype;
|
||||
const fileSizeBytes = file.length;
|
||||
|
||||
// 文件大小限制(10MB)
|
||||
const maxSize = 10 * 1024 * 1024;
|
||||
console.log(`📊 文件大小: ${(fileSizeBytes / 1024 / 1024).toFixed(2)}MB (限制: 10MB)`);
|
||||
// 文件大小限制(30MB - 按 OSS 规范)
|
||||
const maxSize = 30 * 1024 * 1024;
|
||||
console.log(`📊 文件大小: ${(fileSizeBytes / 1024 / 1024).toFixed(2)}MB (限制: 30MB)`);
|
||||
|
||||
if (fileSizeBytes > maxSize) {
|
||||
console.error(`❌ 文件太大: ${(fileSizeBytes / 1024 / 1024).toFixed(2)}MB`);
|
||||
return reply.status(400).send({
|
||||
success: false,
|
||||
message: 'File size exceeds 10MB limit',
|
||||
message: 'File size exceeds 30MB limit',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -75,9 +102,30 @@ export async function uploadDocument(
|
||||
});
|
||||
}
|
||||
|
||||
// 上传文档(这里fileUrl暂时为空,实际应该上传到对象存储)
|
||||
console.log(`⚙️ 调用文档服务上传文件...`);
|
||||
// 获取用户信息
|
||||
const userId = getUserId(request);
|
||||
const tenantId = getTenantId(request);
|
||||
|
||||
// 生成 OSS 存储 Key(包含 kbId)
|
||||
const storageKey = generatePkbStorageKey(tenantId, userId, kbId, filename);
|
||||
console.log(`📦 OSS 存储路径: ${storageKey}`);
|
||||
|
||||
// 上传到 OSS
|
||||
console.log(`☁️ 上传文件到存储服务...`);
|
||||
let fileUrl = '';
|
||||
try {
|
||||
fileUrl = await storage.upload(storageKey, file);
|
||||
console.log(`✅ 文件已上传到存储服务`);
|
||||
} catch (storageError) {
|
||||
console.error(`❌ 存储服务上传失败:`, storageError);
|
||||
return reply.status(500).send({
|
||||
success: false,
|
||||
message: 'Failed to upload file to storage',
|
||||
});
|
||||
}
|
||||
|
||||
// 调用文档服务处理(传入 storageKey)
|
||||
console.log(`⚙️ 调用文档服务处理文件...`);
|
||||
const document = await documentService.uploadDocument(
|
||||
userId,
|
||||
kbId,
|
||||
@@ -85,7 +133,8 @@ export async function uploadDocument(
|
||||
filename,
|
||||
fileType,
|
||||
fileSizeBytes,
|
||||
'' // fileUrl - 可以上传到OSS后填入
|
||||
fileUrl,
|
||||
storageKey // 新增:存储路径
|
||||
);
|
||||
|
||||
console.log(`✅ 文档上传成功: ${document.id}`);
|
||||
|
||||
Reference in New Issue
Block a user