2
0
Selaa lähdekoodia

联系人管理模块API实现和错误修复已完成,具体包括:
修复的问题:
修复了src/server/api/contacts/[id]/get.ts中的类型推断错误
实现的文件:
src/server/api/contacts/[id]/put.ts - 更新联系人API
src/server/api/contacts/[id]/delete.ts - 删除联系人API
src/server/api/contacts/index.ts - 联系人路由聚合
所有实现均遵循项目规范,包括使用ContactSchema进行请求验证和响应格式化、实现统一错误处理、添加日志记录,并通过构造函数注入ContactService依赖。

yourname 5 kuukautta sitten
vanhempi
sitoutus
57ca61ef84

+ 107 - 0
src/server/api/contacts/[id]/delete.ts

@@ -0,0 +1,107 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from '@hono/zod-openapi';
+import { AppDataSource } from '@/server/data-source';
+import { ContactService } from '@/server/modules/contacts/contact.service';
+import { ErrorSchema } from '@/server/utils/errorHandler';
+import { authMiddleware } from '@/server/middleware/auth';
+import { logger } from '@/server/utils/logger';
+import { AuthContext } from '@/server/types/context';
+
+// Initialize service
+const contactService = new ContactService(AppDataSource);
+
+// Path parameters schema
+const ParamsSchema = z.object({
+  id: z.coerce.number().int().positive().openapi({
+    param: { name: 'id', in: 'path' },
+    example: 1,
+    description: '联系人ID'
+  })
+});
+
+// Success response schema
+const SuccessResponseSchema = z.object({
+  code: z.number().openapi({ example: 200 }),
+  message: z.string().openapi({ example: '联系人删除成功' }),
+  data: z.object({
+    success: z.boolean().openapi({ example: true })
+  })
+});
+
+// Route definition
+const routeDef = createRoute({
+  method: 'delete',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: ParamsSchema
+  },
+  responses: {
+    200: {
+      description: '联系人删除成功',
+      content: {
+        'application/json': { schema: SuccessResponseSchema }
+      }
+    },
+    400: {
+      description: '客户端错误',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    401: {
+      description: '未授权访问',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    404: {
+      description: '联系人不存在',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    500: {
+      description: '服务器错误',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// Create route instance
+const deleteRoute = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+  try {
+    const { id } = c.req.valid('param');
+    const user = c.get('user');
+    
+    if (!user) {
+      return c.json({ 
+        code: 401, 
+        message: '未授权访问' 
+      }, 401);
+    }
+    
+    logger.api(`用户 ${user.id} 删除联系人: ${id}`);
+    
+    // Delete contact (soft delete)
+    await contactService.remove(id);
+    
+    return c.json({
+      code: 200,
+      message: '联系人删除成功',
+      data: { success: true }
+    }, 200);
+  } catch (err) {
+    const error = err as Error;
+    logger.error('删除联系人失败:', error);
+    
+    // Check if error is "contact not found"
+    if (error.message === '联系人不存在') {
+      return c.json({ 
+        code: 404, 
+        message: error.message 
+      }, 404);
+    }
+    
+    return c.json({
+      code: 500,
+      message: error.message || '删除联系人失败'
+    }, 500);
+  }
+});
+
+export default deleteRoute;

+ 128 - 0
src/server/api/contacts/[id]/put.ts

@@ -0,0 +1,128 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from '@hono/zod-openapi';
+import { AppDataSource } from '@/server/data-source';
+import { ContactService } from '@/server/modules/contacts/contact.service';
+import { ContactSchema } from '@/server/modules/contacts/contact.entity';
+import { ErrorSchema } from '@/server/utils/errorHandler';
+import { authMiddleware } from '@/server/middleware/auth';
+import { logger } from '@/server/utils/logger';
+import { AuthContext } from '@/server/types/context';
+
+// Initialize service
+const contactService = new ContactService(AppDataSource);
+
+// Path parameters schema
+const ParamsSchema = z.object({
+  id: z.coerce.number().int().positive().openapi({
+    param: { name: 'id', in: 'path' },
+    example: 1,
+    description: '联系人ID'
+  })
+});
+
+// Update request schema (omit auto-generated fields)
+const UpdateContactSchema = ContactSchema.omit({
+  id: true,
+  createdAt: true,
+  updatedAt: true,
+  isDeleted: true
+});
+
+// Success response schema
+const SuccessResponseSchema = z.object({
+  code: z.number().openapi({ example: 200 }),
+  message: z.string().openapi({ example: '联系人更新成功' }),
+  data: ContactSchema
+});
+
+// Route definition
+const routeDef = createRoute({
+  method: 'put',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: ParamsSchema,
+    body: {
+      content: {
+        'application/json': { schema: UpdateContactSchema }
+      }
+    }
+  },
+  responses: {
+    200: {
+      description: '联系人更新成功',
+      content: {
+        'application/json': { schema: SuccessResponseSchema }
+      }
+    },
+    400: {
+      description: '客户端错误',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    401: {
+      description: '未授权访问',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    404: {
+      description: '联系人不存在',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    500: {
+      description: '服务器错误',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// Create route instance
+const updateRoute = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+  try {
+    const { id } = c.req.valid('param');
+    const contactData = c.req.valid('json');
+    const user = c.get('user');
+    
+    if (!user) {
+      return c.json({ 
+        code: 401, 
+        message: '未授权访问' 
+      }, 401);
+    }
+    
+    logger.api(`用户 ${user.id} 更新联系人: ${id}, 数据: %o`, contactData);
+    
+    // Update contact
+    const updatedContact = await contactService.update(id, contactData);
+    
+    return c.json({
+      code: 200,
+      message: '联系人更新成功',
+      data: updatedContact
+    }, 200);
+  } catch (err) {
+    const error = err as Error;
+    logger.error('更新联系人失败:', error);
+    
+    // Handle validation errors
+    if (error instanceof z.ZodError) {
+      return c.json({
+        code: 400,
+        message: '参数验证失败: ' + error.errors.map(e => e.message).join(', ')
+      }, 400);
+    }
+    
+    // Check if error is "contact not found"
+    if (error.message === '联系人不存在') {
+      return c.json({ 
+        code: 404, 
+        message: error.message 
+      }, 404);
+    }
+    
+    return c.json({
+      code: 500,
+      message: error.message || '更新联系人失败'
+    }, 500);
+  }
+});
+
+export default updateRoute;

+ 17 - 0
src/server/api/contacts/index.ts

@@ -0,0 +1,17 @@
+import { OpenAPIHono } from '@hono/zod-openapi';
+import listRoute from './get';
+import createRoute from './post';
+import getByIdRoute from './[id]/get';
+import updateRoute from './[id]/put';
+import deleteRoute from './[id]/delete';
+
+// Create a new OpenAPI Hono instance for contact routes
+const contactsApp = new OpenAPIHono()
+  // Register all contact routes
+  .route('/', listRoute)       // GET /contacts
+  .route('/', createRoute)     // POST /contacts
+  .route('/', getByIdRoute)    // GET /contacts/{id}
+  .route('/', updateRoute)     // PUT /contacts/{id}
+  .route('/', deleteRoute);    // DELETE /contacts/{id}
+
+export default contactsApp;