import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi'; import { FileService } from '../../../modules/files/file.service'; import { FileSchema, CreateFileDto } from '../../../modules/files/file.schema'; import { ErrorSchema } from '../../../utils/errorHandler'; import { AppDataSource } from '../../../data-source'; import { AuthContext } from '../../../types/context'; import { authMiddleware } from '../../../middleware/auth.middleware'; import { parseWithAwait } from '../../../utils/parseWithAwait'; // 创建文件上传策略响应Schema,不包含关联的uploadUser字段 const CreateFileResponseSchema = z.object({ file: z.object({ id: z.number().int().positive().openapi({ description: '文件ID', example: 1 }), name: z.string().max(255).openapi({ description: '文件名称', example: '项目计划书.pdf' }), type: z.string().max(50).nullable().openapi({ description: '文件类型', example: 'application/pdf' }), size: z.number().int().positive().nullable().openapi({ description: '文件大小,单位字节', example: 102400 }), path: z.string().max(512).openapi({ description: '文件存储路径', example: '/uploads/documents/2023/project-plan.pdf' }), description: z.string().nullable().openapi({ description: '文件描述', example: '2023年度项目计划书' }), uploadUserId: z.number().int().positive().openapi({ description: '上传用户ID', example: 1 }), uploadTime: z.coerce.date().openapi({ description: '上传时间', example: '2023-01-15T10:30:00Z' }), lastUpdated: z.date().nullable().openapi({ description: '最后更新时间', example: '2023-01-16T14:20:00Z' }), createdAt: z.coerce.date().openapi({ description: '创建时间', example: '2023-01-15T10:30:00Z' }), updatedAt: z.coerce.date().openapi({ description: '更新时间', example: '2023-01-16T14:20:00Z' }) }), uploadPolicy: z.object({ 'x-amz-algorithm': z.string(), 'x-amz-credential': z.string(), 'x-amz-date': z.string(), 'x-amz-security-token': z.string().optional(), policy: z.string(), 'x-amz-signature': z.string(), host: z.string(), key: z.string(), bucket: z.string() }) }); // 创建文件上传策略路由 const createUploadPolicyRoute = createRoute({ method: 'post', path: '/', middleware: [authMiddleware], request: { body: { content: { 'application/json': { schema: CreateFileDto } } } }, responses: { 200: { description: '生成文件上传策略成功', content: { 'application/json': { schema: CreateFileResponseSchema } } }, 400: { description: '请求参数错误', content: { 'application/json': { schema: ErrorSchema } } }, 500: { description: '服务器错误', content: { 'application/json': { schema: ErrorSchema } } } } }); // 创建路由实例 const app = new OpenAPIHono().openapi(createUploadPolicyRoute, async (c) => { try { const data = await c.req.json(); const user = c.get('user'); // 创建文件服务实例 const fileService = new FileService(AppDataSource); // 添加用户ID到文件数据 const fileData = { ...data, uploadUserId: user.id, uploadTime: new Date() }; const result = await fileService.createFile(fileData); const typedResult = await parseWithAwait(CreateFileResponseSchema, result); return c.json(typedResult, 200); } catch (error) { if (error instanceof z.ZodError) { return c.json({ code: 400, message: '参数错误', errors: error.issues }, 400); } const message = error instanceof Error ? error.message : '生成上传策略失败'; return c.json({ code: 500, message }, 500); } }); export default app;