Parcourir la source

✅ fix(server): 修复server包类型检查错误

- 修复商品模块类型重新导出问题,使用export type
- 修复订单商品schema中supplierId类型不匹配,添加nullable
- 修复退款服务类型引用错误,使用z.infer处理zod schema
- 修复路由类型转换问题,移除不必要的parseInt调用
- 修复文件实体类型不匹配,在路由中添加parseWithAwait处理
- 修复路由错误响应类型不匹配,为所有需要403错误的路由添加403响应定义

🤖 Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname il y a 1 mois
Parent
commit
55da8dd848

+ 1 - 1
packages/goods-module/src/types/index.ts

@@ -1,4 +1,4 @@
-export {
+export type {
   Goods as GoodsSchemaType,
   CreateGoods as CreateGoodsSchemaType,
   UpdateGoods as UpdateGoodsSchemaType,

+ 32 - 11
packages/orders-module/src/routes/user/order-items.ts

@@ -1,7 +1,7 @@
 import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
 import { z } from '@hono/zod-openapi';
 import { authMiddleware } from '@d8d/auth-module';
-import { AppDataSource, ErrorSchema } from '@d8d/shared-utils';
+import { AppDataSource, ErrorSchema, parseWithAwait } from '@d8d/shared-utils';
 import { AuthContext } from '@d8d/shared-types';
 import { OrderGoodsSchema, CreateOrderGoodsDto, UpdateOrderGoodsDto } from '../../schemas/order-goods.schema';
 import { UserOrderGoodsService } from '../../services/user-order-goods.service';
@@ -75,8 +75,12 @@ const getUserOrderItemRoute = createRoute({
       description: '认证失败',
       content: { 'application/json': { schema: ErrorSchema } }
     },
+    403: {
+      description: '无权访问该订单商品',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
     404: {
-      description: '订单商品不存在或无权访问',
+      description: '订单商品不存在',
       content: { 'application/json': { schema: ErrorSchema } }
     }
   }
@@ -146,8 +150,12 @@ const updateUserOrderItemRoute = createRoute({
       description: '认证失败',
       content: { 'application/json': { schema: ErrorSchema } }
     },
+    403: {
+      description: '无权更新该订单商品',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
     404: {
-      description: '订单商品不存在或无权访问',
+      description: '订单商品不存在',
       content: { 'application/json': { schema: ErrorSchema } }
     }
   }
@@ -173,8 +181,12 @@ const deleteUserOrderItemRoute = createRoute({
       description: '认证失败',
       content: { 'application/json': { schema: ErrorSchema } }
     },
+    403: {
+      description: '无权删除该订单商品',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
     404: {
-      description: '订单商品不存在或无权访问',
+      description: '订单商品不存在',
       content: { 'application/json': { schema: ErrorSchema } }
     }
   }
@@ -187,15 +199,18 @@ const app = new OpenAPIHono<AuthContext>()
 
     const orderGoodsService = new UserOrderGoodsService(AppDataSource);
     const [data, total] = await orderGoodsService.getUserOrderGoodsList(
-      parseInt(page),
-      parseInt(pageSize),
+      page,
+      pageSize,
       keyword,
       user?.id
     );
 
+    // 使用 parseWithAwait 确保数据格式正确
+    const validatedData = await parseWithAwait(z.array(OrderGoodsSchema), data);
+
     return c.json({
-      data,
-      pagination: { total, current: parseInt(page), pageSize: parseInt(pageSize) }
+      data: validatedData,
+      pagination: { total, current: page, pageSize: pageSize }
     }, 200);
   })
   .openapi(getUserOrderItemRoute, async (c) => {
@@ -209,7 +224,9 @@ const app = new OpenAPIHono<AuthContext>()
         return c.json({ code: 404, message: '订单商品不存在' }, 404);
       }
 
-      return c.json(orderGoods, 200);
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedData = await parseWithAwait(OrderGoodsSchema, orderGoods);
+      return c.json(validatedData, 200);
     } catch (error) {
       if (error instanceof Error && error.message.includes('无权')) {
         return c.json({ code: 403, message: error.message }, 403);
@@ -224,7 +241,9 @@ const app = new OpenAPIHono<AuthContext>()
     try {
       const orderGoodsService = new UserOrderGoodsService(AppDataSource);
       const orderGoods = await orderGoodsService.createUserOrderGoods(data, user?.id);
-      return c.json(orderGoods, 201);
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedData = await parseWithAwait(OrderGoodsSchema, orderGoods);
+      return c.json(validatedData, 201);
     } catch (error) {
       if (error instanceof Error && error.message.includes('无权')) {
         return c.json({ code: 403, message: error.message }, 403);
@@ -244,7 +263,9 @@ const app = new OpenAPIHono<AuthContext>()
         return c.json({ code: 404, message: '订单商品不存在' }, 404);
       }
 
-      return c.json(orderGoods, 200);
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedData = await parseWithAwait(OrderGoodsSchema, orderGoods);
+      return c.json(validatedData, 200);
     } catch (error) {
       if (error instanceof Error && error.message.includes('无权')) {
         return c.json({ code: 403, message: error.message }, 403);

+ 36 - 11
packages/orders-module/src/routes/user/refunds.ts

@@ -1,7 +1,7 @@
 import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
 import { z } from '@hono/zod-openapi';
 import { authMiddleware } from '@d8d/auth-module';
-import { AppDataSource, ErrorSchema } from '@d8d/shared-utils';
+import { AppDataSource, ErrorSchema, parseWithAwait } from '@d8d/shared-utils';
 import { AuthContext } from '@d8d/shared-types';
 import { OrderRefundSchema, CreateOrderRefundDto, UpdateOrderRefundDto } from '../../schemas/order-refund.schema';
 import { UserRefundsService } from '../../services/user-refunds.service';
@@ -79,8 +79,12 @@ const getUserRefundRoute = createRoute({
       description: '认证失败',
       content: { 'application/json': { schema: ErrorSchema } }
     },
+    403: {
+      description: '无权访问该退款',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
     404: {
-      description: '退款不存在或无权访问',
+      description: '退款不存在',
       content: { 'application/json': { schema: ErrorSchema } }
     }
   }
@@ -150,8 +154,12 @@ const updateUserRefundRoute = createRoute({
       description: '认证失败',
       content: { 'application/json': { schema: ErrorSchema } }
     },
+    403: {
+      description: '无权更新该退款',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
     404: {
-      description: '退款不存在或无权访问',
+      description: '退款不存在',
       content: { 'application/json': { schema: ErrorSchema } }
     }
   }
@@ -177,8 +185,12 @@ const deleteUserRefundRoute = createRoute({
       description: '认证失败',
       content: { 'application/json': { schema: ErrorSchema } }
     },
+    403: {
+      description: '无权删除该退款',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
     404: {
-      description: '退款不存在或无权访问',
+      description: '退款不存在',
       content: { 'application/json': { schema: ErrorSchema } }
     }
   }
@@ -191,16 +203,19 @@ const app = new OpenAPIHono<AuthContext>()
 
     const refundsService = new UserRefundsService(AppDataSource);
     const [data, total] = await refundsService.getUserRefundsList(
-      parseInt(page),
-      parseInt(pageSize),
+      page,
+      pageSize,
       keyword,
       user?.id,
       filters ? JSON.parse(filters) : undefined
     );
 
+    // 使用 parseWithAwait 确保数据格式正确
+    const validatedData = await parseWithAwait(z.array(OrderRefundSchema), data);
+
     return c.json({
-      data,
-      pagination: { total, current: parseInt(page), pageSize: parseInt(pageSize) }
+      data: validatedData,
+      pagination: { total, current: page, pageSize: pageSize }
     }, 200);
   })
   .openapi(getUserRefundRoute, async (c) => {
@@ -214,7 +229,10 @@ const app = new OpenAPIHono<AuthContext>()
         return c.json({ code: 404, message: '退款记录不存在' }, 404);
       }
 
-      return c.json(refund, 200);
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedRefund = await parseWithAwait(OrderRefundSchema, refund);
+
+      return c.json(validatedRefund, 200);
     } catch (error) {
       if (error instanceof Error && error.message.includes('无权')) {
         return c.json({ code: 403, message: error.message }, 403);
@@ -229,7 +247,11 @@ const app = new OpenAPIHono<AuthContext>()
     try {
       const refundsService = new UserRefundsService(AppDataSource);
       const refund = await refundsService.createUserRefund(data, user?.id);
-      return c.json(refund, 201);
+
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedRefund = await parseWithAwait(OrderRefundSchema, refund);
+
+      return c.json(validatedRefund, 201);
     } catch (error) {
       if (error instanceof Error && error.message.includes('无权')) {
         return c.json({ code: 403, message: error.message }, 403);
@@ -249,7 +271,10 @@ const app = new OpenAPIHono<AuthContext>()
         return c.json({ code: 404, message: '退款记录不存在' }, 404);
       }
 
-      return c.json(refund, 200);
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedRefund = await parseWithAwait(OrderRefundSchema, refund);
+
+      return c.json(validatedRefund, 200);
     } catch (error) {
       if (error instanceof Error && error.message.includes('无权')) {
         return c.json({ code: 403, message: error.message }, 403);

+ 3 - 3
packages/orders-module/src/schemas/order-goods.schema.ts

@@ -38,7 +38,7 @@ export const OrderGoodsSchema = z.object({
     description: '1实物产品2虚拟订单',
     example: 1
   }),
-  supplierId: z.coerce.number().int().positive().default(0).openapi({
+  supplierId: z.coerce.number().int().positive().nullable().openapi({
     description: '供货商ID',
     example: 1
   }),
@@ -152,7 +152,7 @@ export const CreateOrderGoodsDto = z.object({
     description: '1实物产品2虚拟订单',
     example: 1
   }),
-  supplierId: z.coerce.number().int().positive().default(0).optional().openapi({
+  supplierId: z.coerce.number().int().positive().nullable().optional().openapi({
     description: '供货商ID',
     example: 1
   }),
@@ -212,7 +212,7 @@ export const UpdateOrderGoodsDto = z.object({
     description: '1实物产品2虚拟订单',
     example: 1
   }),
-  supplierId: z.coerce.number().int().positive().optional().openapi({
+  supplierId: z.coerce.number().int().positive().nullable().optional().openapi({
     description: '供货商ID',
     example: 1
   }),

+ 4 - 3
packages/orders-module/src/services/user-refunds.service.ts

@@ -2,6 +2,7 @@ import { DataSource, Repository } from 'typeorm';
 import { OrderRefund } from '../entities/order-refund.entity';
 import { Order } from '../entities/order.entity';
 import { CreateOrderRefundDto, UpdateOrderRefundDto } from '../schemas/order-refund.schema';
+import type { z } from 'zod';
 
 export class UserRefundsService {
   private orderRefundRepository: Repository<OrderRefund>;
@@ -81,14 +82,14 @@ export class UserRefundsService {
   /**
    * 为当前用户创建退款
    */
-  async createUserRefund(data: CreateOrderRefundDto, userId?: number): Promise<OrderRefund> {
+  async createUserRefund(data: z.infer<typeof CreateOrderRefundDto>, userId?: number): Promise<OrderRefund> {
     if (!userId) {
       throw new Error('用户ID不能为空');
     }
 
     // 验证订单是否属于当前用户
     const order = await this.orderRepository.findOne({
-      where: { orderNo: data.orderNo, userId }
+      where: { orderNo: data.orderNo || undefined, userId }
     });
 
     if (!order) {
@@ -109,7 +110,7 @@ export class UserRefundsService {
    */
   async updateUserRefund(
     id: number,
-    data: UpdateOrderRefundDto,
+    data: z.infer<typeof UpdateOrderRefundDto>,
     userId?: number
   ): Promise<OrderRefund | null> {
     if (!userId) {