74 lines
2.1 KiB
TypeScript
74 lines
2.1 KiB
TypeScript
import { type ActionFunctionArgs } from '@remix-run/node';
|
|
import { requireAuth } from '~/.server/service/auth';
|
|
import { storageProvider } from '~/.server/storage/index.server';
|
|
import { errorResponse, successResponse } from '~/.server/utils/api-response';
|
|
import { createScopedLogger } from '~/utils/logger';
|
|
|
|
const logger = createScopedLogger('api.upload');
|
|
|
|
/**
|
|
* 处理文件上传请求
|
|
*
|
|
* 参数:
|
|
* - file: 要上传的文件
|
|
*
|
|
* 返回:
|
|
* - url: 文件访问URL
|
|
* - filename: 文件名
|
|
* - contentType: 文件类型
|
|
* - size: 文件大小(字节)
|
|
*/
|
|
export async function action({ request }: ActionFunctionArgs) {
|
|
try {
|
|
const authResult = await requireAuth(request, { isApi: true });
|
|
if (authResult instanceof Response) {
|
|
return authResult;
|
|
}
|
|
|
|
const userId = authResult.userInfo?.sub;
|
|
if (!userId) {
|
|
return errorResponse(401, '用户未登录');
|
|
}
|
|
|
|
if (request.method !== 'POST') {
|
|
return errorResponse(405, '不支持的请求方法');
|
|
}
|
|
|
|
// 获取上传的文件
|
|
const formData = await request.formData();
|
|
const file = formData.get('file');
|
|
|
|
if (!file || !(file instanceof File)) {
|
|
return errorResponse(400, '未找到有效的文件');
|
|
}
|
|
|
|
const maxFileSizeMB = process.env.MAX_UPLOAD_SIZE_MB ? parseInt(process.env.MAX_UPLOAD_SIZE_MB) : 5;
|
|
const maxFileSize = maxFileSizeMB * 1024 * 1024;
|
|
|
|
if (file.size > maxFileSize) {
|
|
return errorResponse(413, `文件大小超过限制,最大允许${maxFileSizeMB}MB`);
|
|
}
|
|
|
|
const fileBuffer = Buffer.from(await file.arrayBuffer());
|
|
const result = await storageProvider.uploadFile({
|
|
userId,
|
|
contentType: file.type || 'application/octet-stream',
|
|
filename: file.name,
|
|
data: fileBuffer,
|
|
});
|
|
|
|
return successResponse(
|
|
{
|
|
url: storageProvider.getFileUrl(userId, result.filename),
|
|
filename: result.filename,
|
|
contentType: result.contentType,
|
|
size: result.size,
|
|
},
|
|
'文件上传成功',
|
|
);
|
|
} catch (error) {
|
|
logger.error('文件上传失败:', error);
|
|
return errorResponse(500, '文件上传失败');
|
|
}
|
|
}
|