post.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi';
  2. import { FileService } from '@/server/modules/files/file.service';
  3. import { ErrorSchema } from '@/server/utils/errorHandler';
  4. import { AppDataSource } from '@/server/data-source';
  5. import { AuthContext } from '@/server/types/context';
  6. import { authMiddleware } from '@/server/middleware/auth.middleware';
  7. // 创建分片上传策略请求Schema
  8. const CreateMultipartUploadPolicyDto = z.object({
  9. fileKey: z.string().openapi({
  10. description: '文件键名',
  11. example: 'documents/report.pdf'
  12. }),
  13. totalSize: z.coerce.number().int().positive().openapi({
  14. description: '文件总大小(字节)',
  15. example: 10485760
  16. }),
  17. partSize: z.coerce.number().int().positive().openapi({
  18. description: '分片大小(字节)',
  19. example: 5242880
  20. })
  21. });
  22. // 创建分片上传策略路由定义
  23. const createMultipartUploadPolicyRoute = createRoute({
  24. method: 'post',
  25. path: '/',
  26. middleware: [authMiddleware],
  27. request: {
  28. body: {
  29. content: {
  30. 'application/json': { schema: CreateMultipartUploadPolicyDto }
  31. }
  32. }
  33. },
  34. responses: {
  35. 200: {
  36. description: '生成分片上传策略成功',
  37. content: {
  38. 'application/json': {
  39. schema: z.object({
  40. uploadId: z.string().openapi({
  41. description: '分片上传ID',
  42. example: '123e4567-e89b-12d3-a456-426614174000'
  43. }),
  44. bucket: z.string().openapi({
  45. description: '存储桶名称',
  46. example: 'my-bucket'
  47. }),
  48. key: z.string().openapi({
  49. description: '文件键名',
  50. example: 'documents/report.pdf'
  51. }),
  52. host: z.string().openapi({
  53. description: 'MinIO主机地址',
  54. example: 'minio.example.com'
  55. }),
  56. partUrls: z.array(z.string()).openapi({
  57. description: '分片上传URL列表',
  58. example: [
  59. 'https://minio.example.com/my-bucket/documents/report.pdf?uploadId=123e4567-e89b-12d3-a456-426614174000&partNumber=1',
  60. 'https://minio.example.com/my-bucket/documents/report.pdf?uploadId=123e4567-e89b-12d3-a456-426614174000&partNumber=2'
  61. ]
  62. })
  63. })
  64. }
  65. }
  66. },
  67. 400: {
  68. description: '请求参数错误',
  69. content: { 'application/json': { schema: ErrorSchema } }
  70. },
  71. 500: {
  72. description: '服务器错误',
  73. content: { 'application/json': { schema: ErrorSchema } }
  74. }
  75. }
  76. });
  77. // 创建文件服务实例
  78. const fileService = new FileService(AppDataSource);
  79. // 创建路由实例
  80. const app = new OpenAPIHono<AuthContext>().openapi(createMultipartUploadPolicyRoute, async (c) => {
  81. try {
  82. const data = await c.req.json();
  83. const result = await fileService.createMultipartUploadPolicy(data);
  84. return c.json(result, 200);
  85. } catch (error) {
  86. const message = error instanceof Error ? error.message : '生成分片上传策略失败';
  87. return c.json({ code: 500, message }, 500);
  88. }
  89. });
  90. export default app;