瀏覽代碼

Merge branch 'starter' of 139-template-116/d8d-vite-starter into starter

18617351030 5 月之前
父節點
當前提交
5f738448e8
共有 2 個文件被更改,包括 748 次插入21 次删除
  1. 496 21
      .roo/rules/11-entity-creation.md
  2. 252 0
      .roo/rules/12-generic-crud.md

+ 496 - 21
.roo/rules/11-entity-creation.md

@@ -1,37 +1,97 @@
 # 新实体创建流程规范
 
-## 完整开发流程
+## 流程概述
 
-1. **创建实体**
+实体创建流程分为两种模式,根据业务复杂度选择合适的实现方式:
+
+- **标准通用CRUD**:适用于简单数据模型,使用`GenericCrudService`和`createCrudRoutes`快速生成基础CRUD接口
+- **自定义复杂CRUD**:适用于包含复杂业务逻辑的实体,需要手动实现服务方法和路由处理
+
+## 适用场景选择
+
+| 类型 | 适用场景 | 技术选型 |
+|------|----------|----------|
+| 标准通用CRUD | 简单数据管理、无复杂业务逻辑、基础CRUD操作 | `GenericCrudService` + `createCrudRoutes` |
+| 自定义复杂CRUD | 复杂业务规则、多表关联操作、特殊权限控制、非标准数据处理 | 自定义Service + 手动路由实现 |
+
+## 标准通用CRUD开发流程
+
+### 1. **创建实体**
    - 位置: `src/server/modules/[模块名]/[实体名].entity.ts`
    - 参考已有实体文件如`user.entity.ts`
    - 注意: 必须包含Zod Schema定义
 
-2. **创建Service**
+### 2. **注册实体到数据源**
+   - 在`src/server/data-source.ts`中添加实体导入和注册:
+     ```typescript
+     // 实体类导入
+     import { YourEntity } from "./modules/[模块名]/[实体名].entity"
+     
+     export const AppDataSource = new DataSource({
+       // ...其他配置
+       entities: [
+         User, Role, YourEntity // 添加新实体到数组
+       ],
+       // ...其他配置
+     });
+     ```
+
+### 3. **创建Service**
    - 位置: `src/server/modules/[模块名]/[实体名].service.ts`
+   - 继承`GenericCrudService`
    - 通过构造函数注入DataSource
-   - 使用实体Schema进行输入输出验证
+   ```typescript
+   import { GenericCrudService } from '@/server/utils/generic-crud.service';
+   import { DataSource } from 'typeorm';
+   import { YourEntity } from './your-entity.entity';
+   
+   export class YourEntityService extends GenericCrudService<YourEntity> {
+     constructor(dataSource: DataSource) {
+       super(dataSource, YourEntity);
+     }
+   }
+   ```
 
-3. **创建API路由**
-   - 目录结构:
-     ```
-     src/server/api/[实体名]/
-     ├── get.ts       # 列表
-     ├── post.ts      # 创建
-     ├── [id]/
-     │   ├── get.ts   # 详情
-     │   ├── put.ts   # 更新
-     │   └── delete.ts # 删除
-     └── index.ts     # 路由聚合
+### 4. **创建API路由**
+   - 使用`createCrudRoutes`快速生成CRUD路由:
+     ```typescript
+     import { createCrudRoutes } from '@/server/utils/generic-crud.routes';
+     import { YourEntity } from '@/server/modules/your-module/your-entity.entity';
+     import { YourEntitySchema, CreateYourEntityDto, UpdateYourEntityDto } from '@/server/modules/your-module/your-entity.entity';
+     import { authMiddleware } from '@/server/middleware/auth.middleware';
+     
+     const yourEntityRoutes = createCrudRoutes({
+       entity: YourEntity,
+       createSchema: CreateYourEntityDto,
+       updateSchema: UpdateYourEntityDto,
+       getSchema: YourEntitySchema,
+       listSchema: YourEntitySchema,
+       searchFields: ['name', 'description'], // 可选,指定搜索字段
+       middleware: [authMiddleware] // 可选,添加中间件
+     });
+     
+     export default yourEntityRoutes;
      ```
-   - 必须使用实体Schema作为请求/响应Schema
-   - 参考`users`模块的实现
 
-4. **注册路由**
-   - 在`src/server/api.ts`中添加路由注册
+### 5. **注册路由**
+   - 在`src/server/api.ts`中添加路由注册:
+     ```typescript
+     import yourEntityRoutes from '@/server/api/your-entity/index';
+     
+     // 注册路由
+     api.route('/api/v1/your-entities', yourEntityRoutes);
+     ```
 
-5. **创建客户端API**
-   - 在`src/client/api.ts`中添加客户端定义
+### 6. **创建客户端API**
+   - 在`src/client/api.ts`中添加客户端定义:
+     ```typescript
+     import { hc } from 'hono/client';
+     import { YourEntityRoutes } from '@/server/api';
+     
+     export const yourEntityClient = hc<YourEntityRoutes>('/api/v1', {
+       fetch: axiosFetch,
+     }).your-entities;
+     ```
 
 6. **前端调用**
    - 在页面组件(如`pages_users.tsx`)中:
@@ -43,6 +103,421 @@
        type CreateRequest = InferRequestType<typeof entityClient.$post>['json'];
        ```
 
+## 自定义复杂CRUD开发流程
+
+当实体需要复杂业务逻辑或非标准CRUD操作时,采用以下完整流程:
+
+### 1. **创建实体**
+   - 位置: `src/server/modules/[模块名]/[实体名].entity.ts`
+   - 定义实体类和Zod Schema
+   - 示例:
+     ```typescript
+     import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
+     import { z } from '@hono/zod-openapi';
+     
+     @Entity('your_entity')
+     export class YourEntity {
+       @PrimaryGeneratedColumn({ unsigned: true })
+       id!: number;
+       
+       @Column({ name: 'name', type: 'varchar', length: 255 })
+       name!: string;
+       
+       // 其他业务字段...
+     }
+     
+     // Zod Schema定义
+     export const YourEntitySchema = z.object({
+       id: z.number().int().positive().openapi({ description: '实体ID' }),
+       name: z.string().max(255).openapi({ description: '名称', example: '示例名称' })
+       // 其他字段Schema...
+     });
+     
+     export const CreateYourEntityDto = z.object({
+       name: z.string().max(255).openapi({ description: '名称', example: '示例名称' })
+       // 其他创建字段...
+     });
+     
+     export const UpdateYourEntityDto = z.object({
+       name: z.string().max(255).optional().openapi({ description: '名称', example: '示例名称' })
+       // 其他更新字段...
+     });
+     ```
+
+### 2. **注册实体到数据源**
+   - 在`src/server/data-source.ts`中添加实体导入和注册:
+     ```typescript
+     // 实体类导入
+     import { YourEntity } from "./modules/[模块名]/[实体名].entity"
+     
+     export const AppDataSource = new DataSource({
+       // ...其他配置
+       entities: [
+         User, Role, YourEntity // 添加新实体到数组
+       ],
+       // ...其他配置
+     });
+     ```
+
+### 3. **创建自定义Service**
+   - 位置: `src/server/modules/[模块名]/[实体名].service.ts`
+   - 实现自定义业务逻辑和数据访问
+   - 示例:
+     ```typescript
+     import { DataSource, Repository } from 'typeorm';
+     import { YourEntity } from './your-entity.entity';
+     import { CreateYourEntityDto, UpdateYourEntityDto } from './your-entity.entity';
+     import { AppError } from '@/server/utils/errorHandler';
+     
+     export class YourEntityService {
+       private repository: Repository<YourEntity>;
+       
+       constructor(dataSource: DataSource) {
+         this.repository = dataSource.getRepository(YourEntity);
+       }
+       
+       /**
+        * 获取实体列表(带复杂过滤条件)
+        */
+       async findAll(filters: any): Promise<[YourEntity[], number]> {
+         const query = this.repository.createQueryBuilder('entity');
+         
+         // 添加复杂业务过滤逻辑
+         if (filters.status) {
+           query.andWhere('entity.status = :status', { status: filters.status });
+         }
+         
+         // 多表关联查询示例
+         if (filters.includeRelated) {
+           query.leftJoinAndSelect('entity.relatedEntity', 'related');
+         }
+         
+         const [items, total] = await query.getManyAndCount();
+         return [items, total];
+       }
+       
+       /**
+        * 根据ID获取单个实体
+        */
+       async findById(id: number): Promise<YourEntity> {
+         const entity = await this.repository.findOneBy({ id });
+         if (!entity) {
+           throw new AppError('实体不存在', 404);
+         }
+         return entity;
+       }
+       
+       /**
+        * 创建实体(带业务规则验证)
+        */
+       async create(data: CreateYourEntityDto): Promise<YourEntity> {
+         // 业务规则验证示例
+         const existing = await this.repository.findOneBy({ name: data.name });
+         if (existing) {
+           throw new AppError('名称已存在', 400);
+         }
+         
+         const entity = this.repository.create(data);
+         return this.repository.save(entity);
+       }
+       
+       /**
+        * 更新实体(带业务逻辑处理)
+        */
+       async update(id: number, data: UpdateYourEntityDto): Promise<YourEntity> {
+         const entity = await this.findById(id);
+         
+         // 业务逻辑处理示例
+         if (data.name && data.name !== entity.name) {
+           // 记录名称变更日志等业务操作
+         }
+         
+         Object.assign(entity, data);
+         return this.repository.save(entity);
+       }
+       
+       /**
+        * 删除实体(带权限检查)
+        */
+       async delete(id: number, userId: number): Promise<boolean> {
+         const entity = await this.findById(id);
+         
+         // 权限检查示例
+         if (entity.createdBy !== userId) {
+           throw new AppError('没有删除权限', 403);
+         }
+         
+         await this.repository.remove(entity);
+         return true;
+       }
+       
+       /**
+        * 自定义业务方法示例
+        */
+       async customBusinessOperation(params: any): Promise<any> {
+         // 实现复杂业务逻辑
+         // 可能包含事务、多表操作等
+       }
+     }
+     ```
+
+### 4. **创建自定义API路由**
+   - 目录结构:
+     ```
+     src/server/api/[实体名]/
+     ├── get.ts       # 列表查询
+     ├── post.ts      # 创建实体
+     ├── [id]/
+     │   ├── get.ts   # 获取单个实体
+     │   ├── put.ts   # 更新实体
+     │   └── delete.ts # 删除实体
+     └── index.ts     # 路由聚合
+     ```
+   
+   - **列表查询路由示例** (get.ts):
+     ```typescript
+     import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+     import { z } from 'zod';
+     import { YourEntitySchema } from '@/server/modules/your-module/your-entity.entity';
+     import { ErrorSchema } from '@/server/utils/errorHandler';
+     import { AppDataSource } from '@/server/data-source';
+     import { YourEntityService } from '@/server/modules/your-module/your-entity.service';
+     import { AuthContext } from '@/server/types/context';
+     import { authMiddleware } from '@/server/middleware/auth.middleware';
+     
+     // 查询参数Schema
+     const ListQuery = z.object({
+       page: z.coerce.number().int().positive().default(1).openapi({
+         description: '页码',
+         example: 1
+       }),
+       pageSize: z.coerce.number().int().positive().default(10).openapi({
+         description: '每页条数',
+         example: 10
+       }),
+       status: z.coerce.number().optional().openapi({
+         description: '状态过滤',
+         example: 1
+       })
+     });
+     
+     // 响应Schema
+     const ListResponse = z.object({
+       data: z.array(YourEntitySchema),
+       pagination: z.object({
+         total: z.number().openapi({ example: 100, description: '总记录数' }),
+         current: z.number().openapi({ example: 1, description: '当前页码' }),
+         pageSize: z.number().openapi({ example: 10, description: '每页数量' })
+       })
+     });
+     
+     // 路由定义
+     const routeDef = createRoute({
+       method: 'get',
+       path: '/',
+       middleware: [authMiddleware],
+       request: {
+         query: ListQuery
+       },
+       responses: {
+         200: {
+           description: '成功获取实体列表',
+           content: { 'application/json': { schema: ListResponse } }
+         },
+         400: {
+           description: '请求参数错误',
+           content: { 'application/json': { schema: ErrorSchema } }
+         },
+         500: {
+           description: '服务器错误',
+           content: { 'application/json': { schema: ErrorSchema } }
+         }
+       }
+     });
+     
+     // 路由实现
+     const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+       try {
+         const query = c.req.valid('query');
+         const service = new YourEntityService(AppDataSource);
+         
+         const [data, total] = await service.findAll({
+           status: query.status,
+           // 其他过滤条件
+         });
+         
+         return c.json({
+           data,
+           pagination: {
+             total,
+             current: query.page,
+             pageSize: query.pageSize
+           }
+         }, 200);
+       } catch (error) {
+         const { code = 500, message = '获取列表失败' } = error as Error & { code?: number };
+         return c.json({ code, message }, code);
+       }
+     });
+     
+     export default app;
+     ```
+     
+   - **创建实体路由示例** (post.ts):
+     ```typescript
+     import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+     import { CreateYourEntityDto, YourEntitySchema } from '@/server/modules/your-module/your-entity.entity';
+     import { ErrorSchema } from '@/server/utils/errorHandler';
+     import { AppDataSource } from '@/server/data-source';
+     import { YourEntityService } from '@/server/modules/your-module/your-entity.service';
+     import { AuthContext } from '@/server/types/context';
+     import { authMiddleware } from '@/server/middleware/auth.middleware';
+     
+     // 路由定义
+     const routeDef = createRoute({
+       method: 'post',
+       path: '/',
+       middleware: [authMiddleware],
+       request: {
+         body: {
+           content: {
+             'application/json': { schema: CreateYourEntityDto }
+           }
+         }
+       },
+       responses: {
+         200: {
+           description: '成功创建实体',
+           content: { 'application/json': { schema: YourEntitySchema } }
+         },
+         400: {
+           description: '请求参数错误',
+           content: { 'application/json': { schema: ErrorSchema } }
+         },
+         500: {
+           description: '服务器错误',
+           content: { 'application/json': { schema: ErrorSchema } }
+         }
+       }
+     });
+     
+     // 路由实现
+     const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+       try {
+         const data = await c.req.json();
+         const service = new YourEntityService(AppDataSource);
+         const result = await service.create(data);
+         return c.json(result, 200);
+       } catch (error) {
+         const { code = 500, message = '创建实体失败' } = error as Error & { code?: number };
+         return c.json({ code, message }, code);
+       }
+     });
+     
+     export default app;
+     ```
+     
+   - **路由聚合示例** (index.ts):
+     ```typescript
+     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';
+     
+     const app = new OpenAPIHono()
+       .route('/', listRoute)
+       .route('/', createRoute)
+       .route('/', getByIdRoute)
+       .route('/', updateRoute)
+       .route('/', deleteRoute);
+     
+     export default app;
+     ```
+
+### 5. **注册路由**
+   - 在`src/server/api.ts`中添加路由注册:
+     ```typescript
+     import yourEntityRoutes from '@/server/api/your-entity/index';
+     
+     // 注册路由
+     api.route('/api/v1/your-entities', yourEntityRoutes);
+     ```
+
+### 6. **创建客户端API**
+   - 在`src/client/api.ts`中添加客户端定义:
+     ```typescript
+     import { hc } from 'hono/client';
+     import { YourEntityRoutes } from '@/server/api';
+     import { axiosFetch } from '@/client/utils/fetch';
+     
+     export const yourEntityClient = hc<YourEntityRoutes>('/api/v1', {
+       fetch: axiosFetch,
+     }).your_entities; // 注意: 路由路径中的连字符会转为下划线
+     
+     // 类型提取
+     import type { InferRequestType, InferResponseType } from 'hono/client';
+     
+     // 列表查询
+     export type YourEntityListQuery = InferRequestType<typeof yourEntityClient.$get>['query'];
+     export type YourEntityListResponse = InferResponseType<typeof yourEntityClient.$get, 200>;
+     
+     // 创建实体
+     export type CreateYourEntityRequest = InferRequestType<typeof yourEntityClient.$post>['json'];
+     export type CreateYourEntityResponse = InferResponseType<typeof yourEntityClient.$post, 200>;
+     
+     // 获取单个实体
+     export type GetYourEntityParams = InferRequestType<typeof yourEntityClient[':id']['$get']>['param'];
+     export type GetYourEntityResponse = InferResponseType<typeof yourEntityClient[':id']['$get'], 200>;
+     
+     // 更新实体
+     export type UpdateYourEntityParams = InferRequestType<typeof yourEntityClient[':id']['$put']>['param'];
+     export type UpdateYourEntityRequest = InferRequestType<typeof yourEntityClient[':id']['$put']>['json'];
+     export type UpdateYourEntityResponse = InferResponseType<typeof yourEntityClient[':id']['$put'], 200>;
+     
+     // 删除实体
+     export type DeleteYourEntityParams = InferRequestType<typeof yourEntityClient[':id']['$delete']>['param'];
+     export type DeleteYourEntityResponse = InferResponseType<typeof yourEntityClient[':id']['$delete'], 200>;
+     ```
+
+### 7. **前端调用示例**
+   - 在页面组件中使用客户端API:
+     ```typescript
+     import { yourEntityClient, type YourEntityListResponse } from '@/client/api';
+     import { useQuery, useMutation, useQueryClient } from 'react-query';
+     
+     // 获取列表数据
+     const fetchEntities = async () => {
+       const res = await yourEntityClient.$get({
+         query: { page: 1, pageSize: 10, status: 1 }
+       });
+       if (!res.ok) {
+         const error = await res.json();
+         throw new Error(error.message || '获取数据失败');
+       }
+       return res.json() as Promise<YourEntityListResponse>;
+     };
+     
+     // 使用React Query获取数据
+     export function useEntitiesData() {
+       return useQuery(['entities'], fetchEntities);
+     }
+     
+     // 创建实体
+     export function useCreateEntity() {
+       const queryClient = useQueryClient();
+       return useMutation(
+         (data) => yourEntityClient.$post({ json: data }),
+         {
+           onSuccess: () => {
+             queryClient.invalidateQueries(['entities']);
+           }
+         }
+       );
+     }
+     ```
+
 ## 注意事项
 
 1. 实体Schema必须在实体文件中定义,路由中直接引用,不要重复定义

+ 252 - 0
.roo/rules/12-generic-crud.md

@@ -0,0 +1,252 @@
+# 通用CRUD实现规范
+
+## 概述
+
+通用CRUD模块提供标准化的增删改查功能实现,通过泛型机制支持快速创建实体的RESTful API接口。本规范定义了使用通用CRUD服务和路由的标准流程和最佳实践。
+
+## 1. 通用CRUD服务 (GenericCrudService)
+
+### 1.1 基础用法
+
+通用CRUD服务提供基础的数据操作方法,所有实体服务类应继承此类:
+
+```typescript
+import { GenericCrudService } from '@/server/utils/generic-crud.service';
+import { DataSource } from 'typeorm';
+import { YourEntity } from '@/server/modules/your-module/your-entity.entity';
+
+export class YourEntityService extends GenericCrudService<YourEntity> {
+  constructor(dataSource: DataSource) {
+    super(dataSource, YourEntity);
+  }
+  
+  // 可以重写或扩展基础方法
+  async customMethod() {
+    // 自定义业务逻辑
+  }
+}
+```
+
+### 1.2 核心方法
+
+| 方法 | 描述 | 参数 | 返回值 |
+|------|------|------|--------|
+| `getList` | 获取分页列表 | `page`, `pageSize`, `keyword`, `searchFields`, `where`, `relations`, `order` | `[T[], number]` |
+| `getById` | 根据ID获取单个实体 | `id: number` | `T \| null` |
+| `create` | 创建实体 | `data: DeepPartial<T>` | `T` |
+| `update` | 更新实体 | `id: number`, `data: Partial<T>` | `T \| null` |
+| `delete` | 删除实体 | `id: number` | `boolean` |
+| `createQueryBuilder` | 创建查询构建器 | `alias?: string` | `QueryBuilder<T>` |
+
+### 1.3 构造函数注入
+
+必须通过构造函数注入`DataSource`,禁止直接使用全局实例:
+
+```typescript
+// 正确示例
+constructor(private dataSource: DataSource) {
+  super(dataSource, YourEntity);
+}
+
+// 错误示例
+constructor() {
+  super(AppDataSource, YourEntity); // 禁止使用全局AppDataSource
+}
+```
+
+## 2. 通用CRUD路由 (createCrudRoutes)
+
+### 2.1 基础用法
+
+通过`createCrudRoutes`函数快速创建标准CRUD路由:
+
+```typescript
+import { createCrudRoutes } from '@/server/utils/generic-crud.routes';
+import { YourEntity } from '@/server/modules/your-module/your-entity.entity';
+import { YourEntitySchema, CreateYourEntityDto, UpdateYourEntityDto } from '@/server/modules/your-module/your-entity.entity';
+import { authMiddleware } from '@/server/middleware/auth.middleware';
+
+const yourEntityRoutes = createCrudRoutes({
+  entity: YourEntity,
+  createSchema: CreateYourEntityDto,
+  updateSchema: UpdateYourEntityDto,
+  getSchema: YourEntitySchema,
+  listSchema: YourEntitySchema,
+  searchFields: ['name', 'description'], // 可选,指定搜索字段
+  middleware: [authMiddleware] // 可选,添加中间件
+});
+
+export default yourEntityRoutes;
+```
+
+### 2.2 配置选项 (CrudOptions)
+
+| 参数 | 类型 | 描述 | 是否必需 |
+|------|------|------|----------|
+| `entity` | `new () => T` | 实体类构造函数 | 是 |
+| `createSchema` | `z.ZodSchema` | 创建实体的Zod验证 schema | 是 |
+| `updateSchema` | `z.ZodSchema` | 更新实体的Zod验证 schema | 是 |
+| `getSchema` | `z.ZodSchema` | 获取单个实体的响应 schema | 是 |
+| `listSchema` | `z.ZodSchema` | 获取列表的响应 schema | 是 |
+| `searchFields` | `string[]` | 搜索字段数组,用于关键词搜索 | 否 |
+| `middleware` | `any[]` | 应用于所有CRUD路由的中间件数组 | 否 |
+
+### 2.3 生成的路由
+
+调用`createCrudRoutes`会自动生成以下标准RESTful路由:
+
+| 方法 | 路径 | 描述 |
+|------|------|------|
+| GET | `/` | 获取实体列表(支持分页、搜索、排序) |
+| POST | `/` | 创建新实体 |
+| GET | `/{id}` | 获取单个实体详情 |
+| PUT | `/{id}` | 更新实体 |
+| DELETE | `/{id}` | 删除实体 |
+
+### 2.4 路由注册
+
+生成的路由需要在API入口文件中注册:
+
+```typescript
+// src/server/api.ts
+import yourEntityRoutes from '@/server/api/your-entity/index';
+
+// 注册路由
+api.route('/api/v1/your-entities', yourEntityRoutes);
+```
+
+## 3. 实体类要求
+
+使用通用CRUD模块的实体类必须满足以下要求:
+
+1. 必须包含主键`id`字段,类型为数字
+2. 必须定义配套的Zod schema:
+   - 实体完整schema(用于响应)
+   - 创建DTO schema(用于创建请求验证)
+   - 更新DTO schema(用于更新请求验证)
+
+示例:
+
+```typescript
+// your-entity.entity.ts
+import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
+import { z } from '@hono/zod-openapi';
+
+@Entity('your_entity')
+export class YourEntity {
+  @PrimaryGeneratedColumn({ unsigned: true })
+  id!: number;
+
+  @Column({ name: 'name', type: 'varchar', length: 255 })
+  name!: string;
+  
+  // 其他字段...
+}
+
+// Zod schemas
+export const YourEntitySchema = z.object({
+  id: z.number().int().positive().openapi({ description: '实体ID' }),
+  name: z.string().max(255).openapi({ description: '名称', example: '示例名称' }),
+  // 其他字段schema...
+});
+
+export const CreateYourEntityDto = z.object({
+  name: z.string().max(255).openapi({ description: '名称', example: '示例名称' }),
+  // 其他创建字段schema...
+});
+
+export const UpdateYourEntityDto = z.object({
+  name: z.string().max(255).optional().openapi({ description: '名称', example: '示例名称' }),
+  // 其他更新字段schema...
+});
+```
+
+## 4. 高级用法
+
+### 4.1 自定义中间件
+
+可以为CRUD路由添加自定义中间件,如认证和权限控制:
+
+```typescript
+import { authMiddleware } from '@/server/middleware/auth.middleware';
+import { permissionMiddleware } from '@/server/middleware/permission.middleware';
+
+const yourEntityRoutes = createCrudRoutes({
+  // ...其他配置
+  middleware: [
+    authMiddleware, 
+    permissionMiddleware(['your_entity:read', 'your_entity:write'])
+  ]
+});
+```
+
+### 4.2 扩展路由
+
+生成基础CRUD路由后,可以添加自定义路由:
+
+```typescript
+import { OpenAPIHono } from '@hono/zod-openapi';
+
+const app = new OpenAPIHono()
+  .route('/', yourEntityRoutes)
+  .get('/custom-action', (c) => {
+    // 自定义路由处理逻辑
+    return c.json({ message: '自定义操作' });
+  });
+
+export default app;
+```
+
+### 4.3 重写服务方法
+
+当通用CRUD服务的默认实现不满足需求时,可以重写相应方法:
+
+```typescript
+export class YourEntityService extends GenericCrudService<YourEntity> {
+  // ...构造函数
+  
+  async getList(
+    page: number = 1,
+    pageSize: number = 10,
+    keyword?: string,
+    searchFields?: string[],
+    where: Partial<YourEntity> = {},
+    relations: string[] = [],
+    order: { [P in keyof YourEntity]?: 'ASC' | 'DESC' } = {}
+  ): Promise<[YourEntity[], number]> {
+    // 添加自定义过滤条件
+    where.isDeleted = 0; // 例如:默认过滤已删除数据
+    
+    return super.getList(page, pageSize, keyword, searchFields, where, relations, order);
+  }
+}
+```
+
+## 5. 错误处理
+
+通用CRUD模块已内置标准错误处理机制:
+
+1. 参数验证错误:返回400状态码和验证错误详情
+2. 资源不存在:返回404状态码
+3. 服务器错误:返回500状态码和错误消息
+
+所有错误响应格式统一为:
+```json
+{
+  "code": 错误代码,
+  "message": "错误描述",
+  "errors": 可选的详细错误信息
+}
+```
+
+## 6. 最佳实践
+
+1. **单一职责**:通用CRUD仅处理标准数据操作,复杂业务逻辑应在具体服务类中实现
+2. **命名规范**:
+   - 服务类:`[EntityName]Service`
+   - 路由文件:遵循RESTful资源命名规范,使用复数形式
+3. **权限控制**:始终为CRUD路由添加适当的认证和授权中间件
+4. **数据验证**:确保Zod schema包含完整的验证规则和OpenAPI元数据
+5. **搜索优化**:合理设置`searchFields`,避免在大表的文本字段上进行模糊搜索
+6. **分页处理**:所有列表接口必须支持分页,避免返回大量数据
+7. **事务管理**:复杂操作应使用事务确保数据一致性