feat: 添加路由装饰器系统和全局异常处理

- 新增装饰器支持(@Get, @Post, @Put, @Delete, @Patch, @Controller)
- 实现路由自动注册机制(RouteScanner)
- 添加全局异常处理中间件(Exception)
- 实现统一响应体格式(ApiResponse)
- 新增请求体解析中间件(BodyParser)
- 重构控制器为类模式,支持装饰器路由
- 添加示例用户控制器(UserController)
- 更新TypeScript配置支持装饰器
- 添加reflect-metadata依赖
- 完善项目文档

Breaking Changes:
- 控制器现在返回数据而不是直接设置ctx.body
- 新增统一的API响应格式
This commit is contained in:
2025-09-01 00:14:17 +08:00
parent 47f36cd625
commit 63c1e4df63
15 changed files with 865 additions and 15 deletions

View File

@@ -0,0 +1,102 @@
import 'reflect-metadata';
/**
* 路由元数据键
*/
export const ROUTE_METADATA_KEY = Symbol('route');
/**
* HTTP 方法类型
*/
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
/**
* 路由元数据接口
*/
export interface RouteMetadata {
method: HttpMethod;
path: string;
propertyKey: string;
}
/**
* 创建HTTP方法装饰器的工厂函数
*/
function createMethodDecorator(method: HttpMethod) {
return function (path: string = '') {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
// 获取现有的路由元数据
const existingRoutes: RouteMetadata[] = (Reflect as any).getMetadata(ROUTE_METADATA_KEY, target.constructor) || [];
// 添加新的路由元数据
const newRoute: RouteMetadata = {
method,
path,
propertyKey
};
existingRoutes.push(newRoute);
// 保存路由元数据到类的构造函数上
(Reflect as any).defineMetadata(ROUTE_METADATA_KEY, existingRoutes, target.constructor);
return descriptor;
};
};
}
/**
* GET 请求装饰器
* @param path 路由路径
*/
export const Get = createMethodDecorator('GET');
/**
* POST 请求装饰器
* @param path 路由路径
*/
export const Post = createMethodDecorator('POST');
/**
* PUT 请求装饰器
* @param path 路由路径
*/
export const Put = createMethodDecorator('PUT');
/**
* DELETE 请求装饰器
* @param path 路由路径
*/
export const Delete = createMethodDecorator('DELETE');
/**
* PATCH 请求装饰器
* @param path 路由路径
*/
export const Patch = createMethodDecorator('PATCH');
/**
* 控制器装饰器
* @param prefix 路由前缀
*/
export function Controller(prefix: string = '') {
return function <T extends { new (...args: any[]): {} }>(constructor: T) {
// 保存控制器前缀到元数据
(Reflect as any).defineMetadata('prefix', prefix, constructor);
return constructor;
};
}
/**
* 获取控制器的路由元数据
*/
export function getRouteMetadata(constructor: any): RouteMetadata[] {
return (Reflect as any).getMetadata(ROUTE_METADATA_KEY, constructor) || [];
}
/**
* 获取控制器的路由前缀
*/
export function getControllerPrefix(constructor: any): string {
return (Reflect as any).getMetadata('prefix', constructor) || '';
}