create-dp-koa 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -0
- package/index.mjs +97 -0
- package/package.json +33 -0
- package/template/.env.development +9 -0
- package/template/.env.production +12 -0
- package/template/.github/workflows/ci-cd.yml +182 -0
- package/template/.trae/documents/controller_development_plan.md +386 -0
- package/template/.trae/skills/00-backend-core.skill.md +50 -0
- package/template/.trae/skills/01-backend-skill-router.skill.md +55 -0
- package/template/.trae/skills/10-backend-api.skill.md +54 -0
- package/template/.trae/skills/11-backend-controller-recipes.skill.md +107 -0
- package/template/.trae/skills/20-backend-repository.skill.md +25 -0
- package/template/.trae/skills/21-backend-service.skill.md +135 -0
- package/template/.trae/skills/25-backend-comments-and-doc.skill.md +97 -0
- package/template/.trae/skills/30-backend-validation.skill.md +320 -0
- package/template/.trae/skills/40-backend-error-logging.skill.md +21 -0
- package/template/.trae/skills/50-backend-bootstrap-lifecycle.skill.md +90 -0
- package/template/.trae/skills/60-backend-router-registration.skill.md +71 -0
- package/template/.trae/skills/70-backend-middleware.skill.md +98 -0
- package/template/.trae/skills/80-backend-utils-and-libs.skill.md +90 -0
- package/template/.trae/skills/85-backend-plugins.rule.md +64 -0
- package/template/.trae/skills/90-backend-testing.skill.md +29 -0
- package/template/.trae/skills/README.md +49 -0
- package/template/.vscode/launch.json +38 -0
- package/template/.vscode/settings.json +1 -0
- package/template/Dockerfile +36 -0
- package/template/README.md +229 -0
- package/template/docker-compose.yml +135 -0
- package/template/docs/API_DOCUMENTATION.md +837 -0
- package/template/docs/ARCHITECTURE_REFACTOR.md +109 -0
- package/template/docs/CACHE_MIGRATION_GUIDE.md +142 -0
- package/template/docs/DEPLOYMENT_GUIDE.md +1062 -0
- package/template/docs/DEVELOPMENT_GUIDE.md +1097 -0
- package/template/docs/DOCUMENTATION_CLEANUP_REPORT.md +166 -0
- package/template/docs/DOCUMENTATION_COMPLETION_REPORT.md +223 -0
- package/template/docs/DOCUMENTATION_INDEX.md +294 -0
- package/template/docs/DOCUMENTATION_STRUCTURE.md +221 -0
- package/template/docs/ENTERPRISE_ANNOTATION_SYSTEM_GUIDE.md +2069 -0
- package/template/docs/ENTERPRISE_DATABASE_ARCHITECTURE.md +318 -0
- package/template/docs/ENTERPRISE_DEPLOYMENT_GUIDE.md +547 -0
- package/template/docs/ENTERPRISE_ERROR_HANDLING_GUIDE.md +357 -0
- package/template/docs/ENTERPRISE_LOGGING_SYSTEM_GUIDE.md +494 -0
- package/template/docs/ENVIRONMENT_CONFIG_EXAMPLE.md +69 -0
- package/template/docs/FINAL_IMPLEMENTATION_SUMMARY.md +206 -0
- package/template/docs/HEALTH_CHECK_ROUTE_FIX.md +134 -0
- package/template/docs/IMPLEMENTATION_CHECKLIST.md +204 -0
- package/template/docs/INSTALLATION_GUIDE.md +611 -0
- package/template/docs/INTERCEPTOR_TESTING_REPORT.md +226 -0
- package/template/docs/INTERCEPTOR_TESTING_SCRIPTS.md +143 -0
- package/template/docs/LOGGING_OPTIMIZATION_GUIDE.md +126 -0
- package/template/docs/MEMORY_DATABASE_GUIDE.md +212 -0
- package/template/docs/NEW_ROUTER_INTEGRATION_GUIDE.md +345 -0
- package/template/docs/NEW_ROUTER_INTEGRATION_SUMMARY.md +259 -0
- package/template/docs/NEW_ROUTER_USAGE_GUIDE.md +364 -0
- package/template/docs/QUICK_START.md +268 -0
- package/template/docs/ROUTE_SLASH_COMPATIBILITY_FIX.md +191 -0
- package/template/docs/SERVICE_INTERCEPTOR_GUIDE.md +243 -0
- package/template/docs/SERVICE_LAYER_INDEX.md +205 -0
- package/template/docs/SERVICE_PATTERN_GUIDE.md +270 -0
- package/template/docs/SERVICE_RETURN_VALUE_SPECIFICATION.md +466 -0
- package/template/docs/SWAGGER_DEBUG_MODE_GUIDE.md +80 -0
- package/template/docs/SWAGGER_INTEGRATION_GUIDE.md +416 -0
- package/template/docs/TRANSACTION_MANAGER_USAGE.md +360 -0
- package/template/docs/TROUBLESHOOTING.md +869 -0
- package/template/env.production.example +62 -0
- package/template/jest.config.js +34 -0
- package/template/package-lock.json +13240 -0
- package/template/package.json +119 -0
- package/template/patches/typeorm+0.3.25.patch +22 -0
- package/template/scripts/sync-template.mjs +84 -0
- package/template/scripts/test-annotation-system.sh +48 -0
- package/template/scripts/test-core-functionality.sh +28 -0
- package/template/src/annotations/decorators/ConfigManagement.ts +9 -0
- package/template/src/annotations/decorators/DistributedTracing.ts +9 -0
- package/template/src/annotations/decorators/EnterprisePerformance.ts +9 -0
- package/template/src/annotations/decorators/PerformanceMonitor.ts +32 -0
- package/template/src/annotations/decorators/SecurityAudit.ts +9 -0
- package/template/src/annotations/index.ts +50 -0
- package/template/src/annotations/processors/ConfigManagementProcessor.ts +369 -0
- package/template/src/annotations/processors/DistributedTracingProcessor.ts +288 -0
- package/template/src/annotations/processors/EnterprisePerformanceProcessor.ts +189 -0
- package/template/src/annotations/processors/PerformanceMonitorProcessor.ts +101 -0
- package/template/src/annotations/processors/SecurityAuditProcessor.ts +345 -0
- package/template/src/annotations/processors/SwaggerProcessor.ts +612 -0
- package/template/src/annotations/processors/index.ts +10 -0
- package/template/src/app.ts +123 -0
- package/template/src/controllers/base.controller.ts +41 -0
- package/template/src/controllers/cacheManagement.controller.ts +131 -0
- package/template/src/controllers/captcha.controller.ts +57 -0
- package/template/src/controllers/demo/AnnotationDemoController.ts +118 -0
- package/template/src/controllers/example/EnterpriseExampleController.ts +297 -0
- package/template/src/controllers/example/ExampleController.ts +110 -0
- package/template/src/controllers/example/NewAnnotationExampleController.ts +159 -0
- package/template/src/controllers/example/SwaggerExampleController.ts +205 -0
- package/template/src/controllers/example/TransactionExample.controller.ts +336 -0
- package/template/src/controllers/health.controller.ts +235 -0
- package/template/src/controllers/home/register.controller.ts +58 -0
- package/template/src/controllers/home/ytGoods.controller.ts +92 -0
- package/template/src/controllers/home/ytShop.controller.ts +135 -0
- package/template/src/controllers/home/ytUser.controller.ts +89 -0
- package/template/src/controllers/logManagement.controller.ts +396 -0
- package/template/src/controllers/public/emailSend.controller.ts +65 -0
- package/template/src/controllers/public/ytUserAuth.controller.ts +174 -0
- package/template/src/controllers/testData.controller.ts +253 -0
- package/template/src/dto/controller/example/NewAnnotationExampleController.dto.ts +73 -0
- package/template/src/dto/controller/home/emailSend.controller.dto.ts +40 -0
- package/template/src/dto/controller/home/register.controller.dto.ts +45 -0
- package/template/src/dto/controller/home/ytGoods.controller.dto.ts +55 -0
- package/template/src/dto/controller/home/ytShop.controller.dto.ts +69 -0
- package/template/src/dto/controller/home/ytUser.controller.dto.ts +44 -0
- package/template/src/dto/controller/public/ytUserAuth.controller.dto.ts +63 -0
- package/template/src/dto/goods.dto.ts +212 -0
- package/template/src/dto/service/ytService.dto.ts +13 -0
- package/template/src/dto/user.dto.ts +177 -0
- package/template/src/entity/base.entity.ts +13 -0
- package/template/src/entity/columnTypes.ts +13 -0
- package/template/src/entity/goodsImagesUnlockKey.entity.ts +33 -0
- package/template/src/entity/goodsUnlocker.entity.ts +34 -0
- package/template/src/entity/index.ts +15 -0
- package/template/src/entity/shop.entity.ts +52 -0
- package/template/src/entity/shopUser.entity.ts +41 -0
- package/template/src/entity/ytGoods.entity.ts +94 -0
- package/template/src/entity/ytUser.entity.ts +96 -0
- package/template/src/examples/InterceptorExampleRunner.ts +284 -0
- package/template/src/examples/ServiceInterceptorExample.ts +214 -0
- package/template/src/examples/SwaggerProcessorExample.ts +169 -0
- package/template/src/examples/TransactionManagerDemo.ts +377 -0
- package/template/src/examples/cacheExamples.ts +155 -0
- package/template/src/framework/decorator/controller.ts +311 -0
- package/template/src/framework/decorator/processor/AnnotationDecorators.ts +100 -0
- package/template/src/framework/decorator/processor/AnnotationProcessor.ts +156 -0
- package/template/src/framework/decorator/processor/AnnotationProcessorConfig.ts +45 -0
- package/template/src/framework/decorator/processor/AnnotationRegistry.ts +117 -0
- package/template/src/framework/decorator/processor/AnnotationSystemInitializer.ts +95 -0
- package/template/src/framework/decorator/processor/ProcessorManager.ts +76 -0
- package/template/src/framework/decorator/processor/processors/CustomProcessors.ts +126 -0
- package/template/src/framework/decorator/processor/processors/DefaultProcessors.ts +207 -0
- package/template/src/framework/decorator/refactored/DecoratorFactory.ts +99 -0
- package/template/src/framework/decorator/refactored/DecoratorMetadataManager.ts +125 -0
- package/template/src/framework/decorator/refactored/DecoratorValidator.ts +128 -0
- package/template/src/framework/decorator/refactored/TypeSafeDecorators.ts +139 -0
- package/template/src/framework/decorator/refactored/index.ts +98 -0
- package/template/src/framework/decorator/swagger.ts +150 -0
- package/template/src/framework/interceptors/AdvancedServiceCallInterceptor.ts +375 -0
- package/template/src/framework/interceptors/ServiceCallInterceptor.ts +348 -0
- package/template/src/framework/interceptors/index.ts +19 -0
- package/template/src/framework/plugins/registry.ts +63 -0
- package/template/src/framework/plugins/types.ts +15 -0
- package/template/src/framework/types/ServiceResult.ts +151 -0
- package/template/src/framework/types/index.ts +16 -0
- package/template/src/framework/utils/CacheManager.ts +430 -0
- package/template/src/framework/utils/CacheService.ts +248 -0
- package/template/src/framework/utils/DtoValidator.ts +164 -0
- package/template/src/framework/utils/MigrationHelper.ts +179 -0
- package/template/src/framework/utils/MigrationManager.ts +256 -0
- package/template/src/framework/utils/NewRouter.ts +207 -0
- package/template/src/framework/utils/TransactionManager.ts +172 -0
- package/template/src/framework/utils/bootstrap.ts +445 -0
- package/template/src/framework/utils/cache.ts +269 -0
- package/template/src/framework/utils/databaseConfig.ts +148 -0
- package/template/src/framework/utils/db.ts +39 -0
- package/template/src/framework/utils/dbMonitor.ts +106 -0
- package/template/src/framework/utils/dynamicSwagger.ts +410 -0
- package/template/src/framework/utils/function.ts +61 -0
- package/template/src/framework/utils/gracefulShutdown.ts +131 -0
- package/template/src/framework/utils/logger.ts +388 -0
- package/template/src/framework/utils/metrics.ts +182 -0
- package/template/src/framework/utils/router.ts +417 -0
- package/template/src/framework/utils/swagger.ts +184 -0
- package/template/src/framework/utils/testDb.ts +19 -0
- package/template/src/framework/utils/token.ts +23 -0
- package/template/src/framework/utils/transform.ts +17 -0
- package/template/src/libs/aokEmailSender.ts +42 -0
- package/template/src/libs/captcha.ts +37 -0
- package/template/src/libs/cos.ts +45 -0
- package/template/src/libs/mCache.ts +7 -0
- package/template/src/libs/serviceValidate.ts +3 -0
- package/template/src/libs/tecentSms.ts +51 -0
- package/template/src/middlewares/a.middleware.ts +6 -0
- package/template/src/middlewares/error.middleware.ts +14 -0
- package/template/src/middlewares/logging.middleware.ts +187 -0
- package/template/src/middlewares/static.middleware.ts +79 -0
- package/template/src/middlewares/swagger.middleware.ts +70 -0
- package/template/src/middlewares/token.middleware.ts +32 -0
- package/template/src/migrations/1700000000000-InitialDatabaseStructure.ts +172 -0
- package/template/src/migrations/index.ts +6 -0
- package/template/src/plugins/weboffice/core/context.ts +47 -0
- package/template/src/plugins/weboffice/core/errors.ts +51 -0
- package/template/src/plugins/weboffice/core/types.ts +63 -0
- package/template/src/plugins/weboffice/core/utils.ts +7 -0
- package/template/src/plugins/weboffice/entities/index.ts +3 -0
- package/template/src/plugins/weboffice/entities/webofficeFile.entity.ts +28 -0
- package/template/src/plugins/weboffice/entities/webofficeFileVersion.entity.ts +29 -0
- package/template/src/plugins/weboffice/http/routes.ts +179 -0
- package/template/src/plugins/weboffice/index.ts +23 -0
- package/template/src/plugins/weboffice/services/webofficeCallback.service.ts +274 -0
- package/template/src/repository/UserRepository.ts +122 -0
- package/template/src/repository/base/BaseRepository.ts +124 -0
- package/template/src/repository/interfaces/IBaseRepository.ts +67 -0
- package/template/src/routers/index.ts +49 -0
- package/template/src/service/base.service.ts +116 -0
- package/template/src/service/paramValidateTest.service.ts +139 -0
- package/template/src/service/ytGoods.service.ts +42 -0
- package/template/src/service/ytShop.service.ts +90 -0
- package/template/src/service/ytUser.service.ts +451 -0
- package/template/src/test/swaggerParameterTest.ts +90 -0
- package/template/src/utils/testDataInitializer.ts +296 -0
- package/template/static/output.json +15203 -0
- package/template/test/controllers/controllers.test.ts +173 -0
- package/template/test/controllers/example/ExampleController.test.ts +222 -0
- package/template/test/controllers/example/NewAnnotationExampleController.test.ts +200 -0
- package/template/test/framework/TransactionManagerDemo.test.ts +363 -0
- package/template/test/framework/annotation/AnnotationDecorators.test.ts +222 -0
- package/template/test/framework/annotation/AnnotationExecutor.test.ts +246 -0
- package/template/test/framework/annotation/AnnotationProcessor.test.ts +179 -0
- package/template/test/framework/annotation/CustomProcessors.test.ts +313 -0
- package/template/test/framework/annotation/DefaultProcessors.test.ts +371 -0
- package/template/test/framework/annotation/NewRouter.test.ts +272 -0
- package/template/test/framework/annotation/ProcessorManager.test.ts +248 -0
- package/template/test/framework/annotation/setup.ts +26 -0
- package/template/test/framework/cache.test.ts +101 -0
- package/template/test/framework/databaseConfig.test.ts +142 -0
- package/template/test/integration/integration.test.ts +153 -0
- package/template/test/plugins/weboffice/http.routes.int.test.ts +61 -0
- package/template/test/service/business.test.ts +87 -0
- package/template/test/service/paramValidateTest.service.test.ts +184 -0
- package/template/test/service/ytUser.service.test.ts +566 -0
- package/template/test/setup.ts +20 -0
- package/template/test/setupAfterEnv.ts +14 -0
- package/template/test/utils/testHelpers.ts +220 -0
- package/template/test_output.txt +0 -0
- package/template/tsconfig.build.json +17 -0
- package/template/tsconfig.json +31 -0
- package/template/webpack.config.js +71 -0
- package/template/yarn.lock +7354 -0
|
@@ -0,0 +1,2069 @@
|
|
|
1
|
+
# 🏢 企业级注解系统使用指南
|
|
2
|
+
|
|
3
|
+
## 📋 目录
|
|
4
|
+
|
|
5
|
+
- [系统概述](#系统概述)
|
|
6
|
+
- [架构设计](#架构设计)
|
|
7
|
+
- [核心组件](#核心组件)
|
|
8
|
+
- [企业级注解](#企业级注解)
|
|
9
|
+
- [使用示例](#使用示例)
|
|
10
|
+
- [最佳实践](#最佳实践)
|
|
11
|
+
- [配置管理](#配置管理)
|
|
12
|
+
- [监控和告警](#监控和告警)
|
|
13
|
+
- [安全审计](#安全审计)
|
|
14
|
+
- [分布式追踪](#分布式追踪)
|
|
15
|
+
- [故障排除](#故障排除)
|
|
16
|
+
|
|
17
|
+
## 🎯 系统概述
|
|
18
|
+
|
|
19
|
+
企业级注解系统是一个功能完整、可扩展的注解处理框架,专为企业级应用设计。它提供了性能监控、安全审计、分布式追踪、配置管理等核心功能,满足现代企业应用的各种需求。
|
|
20
|
+
|
|
21
|
+
### ✨ 核心特性
|
|
22
|
+
|
|
23
|
+
- **🔧 模块化架构**: 清晰的职责分离,易于扩展和维护
|
|
24
|
+
- **🛡️ 企业级安全**: 完整的安全审计和合规性支持
|
|
25
|
+
- **📊 性能监控**: 详细的性能指标和实时告警
|
|
26
|
+
- **🔍 分布式追踪**: 跨服务请求追踪和性能分析
|
|
27
|
+
- **⚙️ 配置管理**: 动态配置和环境变量管理
|
|
28
|
+
- **📝 类型安全**: 完整的 TypeScript 支持
|
|
29
|
+
- **🚀 高性能**: 优化的执行性能和内存使用
|
|
30
|
+
|
|
31
|
+
## 🏗️ 架构设计
|
|
32
|
+
|
|
33
|
+
### 整体架构图
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
37
|
+
│ 企业级注解系统架构 │
|
|
38
|
+
├─────────────────────────────────────────────────────────────┤
|
|
39
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
40
|
+
│ │ 业务层 │ │ 框架层 │ │ 基础层 │ │
|
|
41
|
+
│ │ │ │ │ │ │ │
|
|
42
|
+
│ │ • 自定义注解 │ │ • 核心注解 │ │ • 装饰器 │ │
|
|
43
|
+
│ │ • 业务逻辑 │ │ • 路由系统 │ │ • 元数据 │ │
|
|
44
|
+
│ │ • 领域模型 │ │ • 中间件 │ │ • 反射系统 │ │
|
|
45
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
46
|
+
├─────────────────────────────────────────────────────────────┤
|
|
47
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
48
|
+
│ │ 性能监控 │ │ 安全审计 │ │ 分布式追踪 │ │
|
|
49
|
+
│ │ │ │ │ │ │ │
|
|
50
|
+
│ │ • 执行时间 │ │ • 访问日志 │ │ • 请求追踪 │ │
|
|
51
|
+
│ │ • 内存使用 │ │ • 合规检查 │ │ • 性能分析 │ │
|
|
52
|
+
│ │ • CPU 使用 │ │ • 风险评估 │ │ • 服务依赖 │ │
|
|
53
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
54
|
+
├─────────────────────────────────────────────────────────────┤
|
|
55
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
56
|
+
│ │ 配置管理 │ │ 日志系统 │ │ 告警系统 │ │
|
|
57
|
+
│ │ │ │ │ │ │ │
|
|
58
|
+
│ │ • 动态配置 │ │ • 结构化日志│ │ • 实时告警 │ │
|
|
59
|
+
│ │ • 环境变量 │ │ • 日志级别 │ │ • 阈值监控 │ │
|
|
60
|
+
│ │ • 配置验证 │ │ • 日志聚合 │ │ • 通知系统 │ │
|
|
61
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
62
|
+
└─────────────────────────────────────────────────────────────┘
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 组件关系图
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
69
|
+
│ 注解装饰器 │ │ 注解处理器 │ │ 注解注册中心 │
|
|
70
|
+
│ │ │ │ │ │
|
|
71
|
+
│ @EnterprisePerf │───▶│ EnterprisePerf │───▶│ AnnotationReg │
|
|
72
|
+
│ @SecurityAudit │ │ SecurityAudit │ │ │
|
|
73
|
+
│ @DistributedTrac│ │ DistributedTrac │ │ │
|
|
74
|
+
│ @ConfigMgmt │ │ ConfigMgmt │ │ │
|
|
75
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
76
|
+
│ │ │
|
|
77
|
+
▼ ▼ ▼
|
|
78
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
79
|
+
│ 注解执行器 │ │ 注解初始化器 │ │ 注解配置 │
|
|
80
|
+
│ │ │ │ │ │
|
|
81
|
+
│ AnnotationExec │◀───│ AnnotationInit │◀───│ AnnotationConf │
|
|
82
|
+
│ │ │ │ │ │
|
|
83
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 🔧 核心组件
|
|
87
|
+
|
|
88
|
+
### 1. 注解注册中心 (AnnotationRegistry)
|
|
89
|
+
|
|
90
|
+
负责管理所有注解处理器的注册、查找和执行。
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { annotationRegistry } from '@src/framework/decorator/processor/AnnotationRegistry';
|
|
94
|
+
|
|
95
|
+
// 注册注解处理器
|
|
96
|
+
annotationRegistry.registerProcessor(new EnterprisePerformanceProcessor());
|
|
97
|
+
|
|
98
|
+
// 获取注解处理器
|
|
99
|
+
const processor = annotationRegistry.getProcessor('EnterprisePerformance');
|
|
100
|
+
|
|
101
|
+
// 获取所有处理器
|
|
102
|
+
const allProcessors = annotationRegistry.getAllProcessors();
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 2. 注解执行器 (AnnotationExecutor)
|
|
106
|
+
|
|
107
|
+
负责执行注解处理器的逻辑。
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { AnnotationExecutor } from '@src/framework/decorator/processor/AnnotationProcessor';
|
|
111
|
+
|
|
112
|
+
const executor = new AnnotationExecutor();
|
|
113
|
+
await executor.execute(ctx, controller, methodName, callParams);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 3. 注解系统初始化器 (AnnotationSystemInitializer)
|
|
117
|
+
|
|
118
|
+
负责在应用启动时初始化整个注解系统。
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { AnnotationSystemInitializer } from '@src/framework/decorator/processor/AnnotationSystemInitializer';
|
|
122
|
+
|
|
123
|
+
// 在应用启动时调用
|
|
124
|
+
AnnotationSystemInitializer.initialize();
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## 🏢 企业级注解
|
|
128
|
+
|
|
129
|
+
### 1. 企业级性能监控 (@EnterprisePerformance)
|
|
130
|
+
|
|
131
|
+
提供详细的性能指标监控和告警功能。
|
|
132
|
+
|
|
133
|
+
#### 配置选项
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
interface PerformanceConfig {
|
|
137
|
+
maxExecutionTime?: number; // 最大执行时间(毫秒)
|
|
138
|
+
maxMemoryUsage?: number; // 最大内存使用(MB)
|
|
139
|
+
enableMetrics?: boolean; // 是否启用指标收集
|
|
140
|
+
enableAlerts?: boolean; // 是否启用告警
|
|
141
|
+
alertThresholds?: { // 告警阈值
|
|
142
|
+
executionTime?: number;
|
|
143
|
+
memoryUsage?: number;
|
|
144
|
+
errorRate?: number;
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### 使用示例
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { EnterprisePerformance } from '@src/annotations/decorators/EnterprisePerformance';
|
|
153
|
+
|
|
154
|
+
export class UserController {
|
|
155
|
+
@Get('/users')
|
|
156
|
+
@EnterprisePerformance({
|
|
157
|
+
maxExecutionTime: 1000,
|
|
158
|
+
maxMemoryUsage: 50,
|
|
159
|
+
enableMetrics: true,
|
|
160
|
+
enableAlerts: true,
|
|
161
|
+
alertThresholds: {
|
|
162
|
+
executionTime: 500,
|
|
163
|
+
memoryUsage: 30
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
async getUsers(@Query() query: any) {
|
|
167
|
+
// 业务逻辑
|
|
168
|
+
return { users: [] };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
#### 性能指标
|
|
174
|
+
|
|
175
|
+
- **执行时间**: 方法执行的总时间
|
|
176
|
+
- **内存使用**: RSS、堆使用、堆总计、外部内存
|
|
177
|
+
- **CPU 使用**: 用户时间和系统时间
|
|
178
|
+
- **请求大小**: 请求体大小
|
|
179
|
+
- **响应大小**: 响应体大小
|
|
180
|
+
|
|
181
|
+
### 2. 安全审计 (@SecurityAudit)
|
|
182
|
+
|
|
183
|
+
提供完整的安全事件记录和合规性检查。
|
|
184
|
+
|
|
185
|
+
#### 配置选项
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
interface SecurityAuditConfig {
|
|
189
|
+
enableAudit?: boolean; // 是否启用审计
|
|
190
|
+
logLevel?: 'info' | 'warn' | 'error'; // 日志级别
|
|
191
|
+
includeRequestData?: boolean; // 是否包含请求数据
|
|
192
|
+
includeResponseData?: boolean; // 是否包含响应数据
|
|
193
|
+
sensitiveFields?: string[]; // 敏感字段列表
|
|
194
|
+
complianceMode?: 'GDPR' | 'SOX' | 'HIPAA' | 'PCI-DSS'; // 合规模式
|
|
195
|
+
retentionDays?: number; // 日志保留天数
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### 使用示例
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { SecurityAudit } from '@src/annotations/decorators/SecurityAudit';
|
|
203
|
+
|
|
204
|
+
export class PaymentController {
|
|
205
|
+
@Post('/payments')
|
|
206
|
+
@SecurityAudit({
|
|
207
|
+
enableAudit: true,
|
|
208
|
+
logLevel: 'warn',
|
|
209
|
+
includeRequestData: true,
|
|
210
|
+
complianceMode: 'PCI-DSS',
|
|
211
|
+
sensitiveFields: ['cardNumber', 'cvv', 'amount']
|
|
212
|
+
})
|
|
213
|
+
async processPayment(@Body() payment: any) {
|
|
214
|
+
// 支付处理逻辑
|
|
215
|
+
return { success: true };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### 安全事件类型
|
|
221
|
+
|
|
222
|
+
- **AUTHENTICATION**: 身份验证事件
|
|
223
|
+
- **AUTHORIZATION**: 授权事件
|
|
224
|
+
- **DATA_ACCESS**: 数据访问事件
|
|
225
|
+
- **DATA_MODIFICATION**: 数据修改事件
|
|
226
|
+
- **SYSTEM_ACCESS**: 系统访问事件
|
|
227
|
+
|
|
228
|
+
#### 风险评估
|
|
229
|
+
|
|
230
|
+
系统会根据以下因素计算风险评分(0-10分):
|
|
231
|
+
|
|
232
|
+
- HTTP 方法类型
|
|
233
|
+
- 用户权限级别
|
|
234
|
+
- IP 地址可疑性
|
|
235
|
+
- 访问时间
|
|
236
|
+
- 操作类型
|
|
237
|
+
|
|
238
|
+
### 3. 分布式追踪 (@DistributedTracing)
|
|
239
|
+
|
|
240
|
+
提供跨服务的请求追踪和性能分析。
|
|
241
|
+
|
|
242
|
+
#### 配置选项
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
interface TracingConfig {
|
|
246
|
+
enableTracing?: boolean; // 是否启用追踪
|
|
247
|
+
traceIdHeader?: string; // 追踪ID头名称
|
|
248
|
+
spanIdHeader?: string; // Span ID头名称
|
|
249
|
+
parentSpanIdHeader?: string; // 父Span ID头名称
|
|
250
|
+
samplingRate?: number; // 采样率 (0-1)
|
|
251
|
+
exportToJaeger?: boolean; // 是否导出到Jaeger
|
|
252
|
+
exportToZipkin?: boolean; // 是否导出到Zipkin
|
|
253
|
+
customTags?: Record<string, string>; // 自定义标签
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### 使用示例
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
import { DistributedTracing } from '@src/annotations/decorators/DistributedTracing';
|
|
261
|
+
|
|
262
|
+
export class OrderController {
|
|
263
|
+
@Get('/orders/:id')
|
|
264
|
+
@DistributedTracing({
|
|
265
|
+
enableTracing: true,
|
|
266
|
+
samplingRate: 1.0,
|
|
267
|
+
customTags: {
|
|
268
|
+
'service.version': '1.0.0',
|
|
269
|
+
'deployment.environment': 'production',
|
|
270
|
+
'business.unit': 'ecommerce'
|
|
271
|
+
}
|
|
272
|
+
})
|
|
273
|
+
async getOrder(@Params() params: any) {
|
|
274
|
+
// 订单查询逻辑
|
|
275
|
+
return { order: {} };
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### 追踪信息
|
|
281
|
+
|
|
282
|
+
- **Trace ID**: 请求的唯一标识
|
|
283
|
+
- **Span ID**: 操作的唯一标识
|
|
284
|
+
- **Parent Span ID**: 父操作的标识
|
|
285
|
+
- **操作名称**: 控制器.方法名
|
|
286
|
+
- **开始时间**: Span 开始时间
|
|
287
|
+
- **结束时间**: Span 结束时间
|
|
288
|
+
- **持续时间**: 操作执行时间
|
|
289
|
+
- **标签**: 自定义元数据
|
|
290
|
+
- **日志**: 操作过程中的日志
|
|
291
|
+
|
|
292
|
+
### 4. 配置管理 (@ConfigManagement)
|
|
293
|
+
|
|
294
|
+
提供动态配置和环境变量管理。
|
|
295
|
+
|
|
296
|
+
#### 配置选项
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
interface ConfigManagementConfig {
|
|
300
|
+
configKey?: string; // 配置键名
|
|
301
|
+
defaultValue?: any; // 默认值
|
|
302
|
+
required?: boolean; // 是否必需
|
|
303
|
+
validationRules?: ValidationRule[]; // 验证规则
|
|
304
|
+
refreshInterval?: number; // 刷新间隔
|
|
305
|
+
environment?: 'development' | 'staging' | 'production'; // 环境
|
|
306
|
+
fallbackConfig?: Record<string, any>; // 备用配置
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
#### 验证规则
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
interface ValidationRule {
|
|
314
|
+
type: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'email' | 'url';
|
|
315
|
+
min?: number; // 最小值/长度
|
|
316
|
+
max?: number; // 最大值/长度
|
|
317
|
+
pattern?: RegExp; // 正则表达式
|
|
318
|
+
custom?: (value: any) => boolean; // 自定义验证
|
|
319
|
+
message?: string; // 错误消息
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### 使用示例
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
import { ConfigManagement } from '@src/annotations/decorators/ConfigManagement';
|
|
327
|
+
|
|
328
|
+
export class ApiController {
|
|
329
|
+
@Get('/api/data')
|
|
330
|
+
@ConfigManagement({
|
|
331
|
+
configKey: 'api.timeout',
|
|
332
|
+
defaultValue: 30000,
|
|
333
|
+
required: true,
|
|
334
|
+
validationRules: [
|
|
335
|
+
{ type: 'number', min: 1000, max: 300000 }
|
|
336
|
+
]
|
|
337
|
+
})
|
|
338
|
+
@ConfigManagement({
|
|
339
|
+
configKey: 'feature.flags',
|
|
340
|
+
defaultValue: { newFeature: false },
|
|
341
|
+
validationRules: [
|
|
342
|
+
{ type: 'object' },
|
|
343
|
+
{
|
|
344
|
+
type: 'object',
|
|
345
|
+
custom: (value) => typeof value.newFeature === 'boolean'
|
|
346
|
+
}
|
|
347
|
+
]
|
|
348
|
+
})
|
|
349
|
+
async getData(@Query() query: any) {
|
|
350
|
+
const config = this.ctx?.state.config;
|
|
351
|
+
const timeout = config['api.timeout'];
|
|
352
|
+
const featureFlags = config['feature.flags'];
|
|
353
|
+
|
|
354
|
+
// 使用配置
|
|
355
|
+
return { data: [], timeout, featureFlags };
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## 📚 使用示例
|
|
361
|
+
|
|
362
|
+
### 基础示例
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
import { Get, Post, Body, Query } from '@src/framework/decorator/controller';
|
|
366
|
+
import { Logging, Permission, RateLimit } from '@src/framework/decorator/processor/AnnotationDecorators';
|
|
367
|
+
import {
|
|
368
|
+
EnterprisePerformance,
|
|
369
|
+
SecurityAudit,
|
|
370
|
+
DistributedTracing,
|
|
371
|
+
ConfigManagement
|
|
372
|
+
} from '@src/annotations/decorators/PerformanceMonitor';
|
|
373
|
+
|
|
374
|
+
export class UserController {
|
|
375
|
+
@Get('/users')
|
|
376
|
+
@EnterprisePerformance({
|
|
377
|
+
maxExecutionTime: 1000,
|
|
378
|
+
enableMetrics: true
|
|
379
|
+
})
|
|
380
|
+
@SecurityAudit({
|
|
381
|
+
enableAudit: true,
|
|
382
|
+
logLevel: 'info'
|
|
383
|
+
})
|
|
384
|
+
@DistributedTracing({
|
|
385
|
+
enableTracing: true
|
|
386
|
+
})
|
|
387
|
+
@Logging()
|
|
388
|
+
async getUsers(@Query() query: any) {
|
|
389
|
+
return { users: [] };
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
@Post('/users')
|
|
393
|
+
@EnterprisePerformance({
|
|
394
|
+
maxExecutionTime: 2000,
|
|
395
|
+
enableAlerts: true
|
|
396
|
+
})
|
|
397
|
+
@SecurityAudit({
|
|
398
|
+
enableAudit: true,
|
|
399
|
+
logLevel: 'warn',
|
|
400
|
+
includeRequestData: true,
|
|
401
|
+
sensitiveFields: ['email', 'phone']
|
|
402
|
+
})
|
|
403
|
+
@Permission({ requiredPermission: 'user:create' })
|
|
404
|
+
@RateLimit({ maxRequests: 10, windowMs: 60000 })
|
|
405
|
+
@Logging()
|
|
406
|
+
async createUser(@Body() user: any) {
|
|
407
|
+
return { success: true };
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### 高级示例
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
export class PaymentController {
|
|
416
|
+
@Post('/payments')
|
|
417
|
+
@EnterprisePerformance({
|
|
418
|
+
maxExecutionTime: 5000,
|
|
419
|
+
maxMemoryUsage: 100,
|
|
420
|
+
enableMetrics: true,
|
|
421
|
+
enableAlerts: true,
|
|
422
|
+
alertThresholds: {
|
|
423
|
+
executionTime: 3000,
|
|
424
|
+
memoryUsage: 80
|
|
425
|
+
}
|
|
426
|
+
})
|
|
427
|
+
@SecurityAudit({
|
|
428
|
+
enableAudit: true,
|
|
429
|
+
logLevel: 'warn',
|
|
430
|
+
includeRequestData: true,
|
|
431
|
+
includeResponseData: true,
|
|
432
|
+
complianceMode: 'PCI-DSS',
|
|
433
|
+
sensitiveFields: ['cardNumber', 'cvv', 'amount', 'account'],
|
|
434
|
+
retentionDays: 2555 // 7年
|
|
435
|
+
})
|
|
436
|
+
@DistributedTracing({
|
|
437
|
+
enableTracing: true,
|
|
438
|
+
samplingRate: 1.0,
|
|
439
|
+
customTags: {
|
|
440
|
+
'service.name': 'payment-service',
|
|
441
|
+
'operation.type': 'financial',
|
|
442
|
+
'security.level': 'high',
|
|
443
|
+
'compliance.standard': 'PCI-DSS'
|
|
444
|
+
}
|
|
445
|
+
})
|
|
446
|
+
@ConfigManagement({
|
|
447
|
+
configKey: 'payment.gateway.url',
|
|
448
|
+
defaultValue: 'https://api.payment.com',
|
|
449
|
+
required: true,
|
|
450
|
+
validationRules: [
|
|
451
|
+
{ type: 'url' }
|
|
452
|
+
]
|
|
453
|
+
})
|
|
454
|
+
@ConfigManagement({
|
|
455
|
+
configKey: 'payment.timeout',
|
|
456
|
+
defaultValue: 30000,
|
|
457
|
+
validationRules: [
|
|
458
|
+
{ type: 'number', min: 5000, max: 60000 }
|
|
459
|
+
]
|
|
460
|
+
})
|
|
461
|
+
@Permission({ requiredPermission: 'payment:process' })
|
|
462
|
+
@RateLimit({ maxRequests: 5, windowMs: 60000 })
|
|
463
|
+
@Logging()
|
|
464
|
+
async processPayment(@Body() payment: any) {
|
|
465
|
+
const config = this.ctx?.state.config;
|
|
466
|
+
const gatewayUrl = config['payment.gateway.url'];
|
|
467
|
+
const timeout = config['payment.timeout'];
|
|
468
|
+
|
|
469
|
+
// 支付处理逻辑
|
|
470
|
+
const result = await this.callPaymentGateway(gatewayUrl, payment, timeout);
|
|
471
|
+
|
|
472
|
+
return { success: true, transactionId: result.id };
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
private async callPaymentGateway(url: string, payment: any, timeout: number): Promise<any> {
|
|
476
|
+
// 模拟支付网关调用
|
|
477
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
478
|
+
return { id: 'txn_' + Date.now() };
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
## 🎯 最佳实践
|
|
484
|
+
|
|
485
|
+
### 1. 注解组合使用
|
|
486
|
+
|
|
487
|
+
```typescript
|
|
488
|
+
// ✅ 推荐:合理的注解组合
|
|
489
|
+
@Get('/api/users')
|
|
490
|
+
@EnterprisePerformance({ maxExecutionTime: 1000 })
|
|
491
|
+
@SecurityAudit({ enableAudit: true })
|
|
492
|
+
@DistributedTracing({ enableTracing: true })
|
|
493
|
+
@Logging()
|
|
494
|
+
async getUsers() { }
|
|
495
|
+
|
|
496
|
+
// ❌ 不推荐:过多的注解
|
|
497
|
+
@Get('/api/users')
|
|
498
|
+
@EnterprisePerformance({ maxExecutionTime: 1000 })
|
|
499
|
+
@SecurityAudit({ enableAudit: true })
|
|
500
|
+
@DistributedTracing({ enableTracing: true })
|
|
501
|
+
@ConfigManagement({ configKey: 'unnecessary' })
|
|
502
|
+
@Permission({ requiredPermission: 'read' })
|
|
503
|
+
@RateLimit({ maxRequests: 100 })
|
|
504
|
+
@Logging()
|
|
505
|
+
async getUsers() { }
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### 2. 性能优化
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
// ✅ 推荐:合理的性能阈值
|
|
512
|
+
@EnterprisePerformance({
|
|
513
|
+
maxExecutionTime: 1000, // 1秒
|
|
514
|
+
maxMemoryUsage: 50, // 50MB
|
|
515
|
+
enableAlerts: true
|
|
516
|
+
})
|
|
517
|
+
|
|
518
|
+
// ❌ 不推荐:过于严格的阈值
|
|
519
|
+
@EnterprisePerformance({
|
|
520
|
+
maxExecutionTime: 100, // 100ms 太严格
|
|
521
|
+
maxMemoryUsage: 5, // 5MB 太小
|
|
522
|
+
enableAlerts: true
|
|
523
|
+
})
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### 3. 安全配置
|
|
527
|
+
|
|
528
|
+
```typescript
|
|
529
|
+
// ✅ 推荐:完整的安全配置
|
|
530
|
+
@SecurityAudit({
|
|
531
|
+
enableAudit: true,
|
|
532
|
+
logLevel: 'warn',
|
|
533
|
+
includeRequestData: true,
|
|
534
|
+
sensitiveFields: ['password', 'ssn', 'creditCard'],
|
|
535
|
+
complianceMode: 'GDPR'
|
|
536
|
+
})
|
|
537
|
+
|
|
538
|
+
// ❌ 不推荐:不完整的安全配置
|
|
539
|
+
@SecurityAudit({
|
|
540
|
+
enableAudit: true
|
|
541
|
+
// 缺少其他重要配置
|
|
542
|
+
})
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### 4. 配置管理
|
|
546
|
+
|
|
547
|
+
```typescript
|
|
548
|
+
// ✅ 推荐:带验证的配置
|
|
549
|
+
@ConfigManagement({
|
|
550
|
+
configKey: 'api.timeout',
|
|
551
|
+
defaultValue: 30000,
|
|
552
|
+
required: true,
|
|
553
|
+
validationRules: [
|
|
554
|
+
{ type: 'number', min: 1000, max: 300000 }
|
|
555
|
+
]
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
// ❌ 不推荐:无验证的配置
|
|
559
|
+
@ConfigManagement({
|
|
560
|
+
configKey: 'api.timeout',
|
|
561
|
+
defaultValue: 30000
|
|
562
|
+
// 缺少验证规则
|
|
563
|
+
})
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
## ⚙️ 配置管理
|
|
567
|
+
|
|
568
|
+
### 环境变量配置
|
|
569
|
+
|
|
570
|
+
```bash
|
|
571
|
+
# 性能监控配置
|
|
572
|
+
PERFORMANCE_ENABLED=true
|
|
573
|
+
PERFORMANCE_SAMPLING_RATE=1.0
|
|
574
|
+
PERFORMANCE_ALERT_THRESHOLD=1000
|
|
575
|
+
|
|
576
|
+
# 安全审计配置
|
|
577
|
+
SECURITY_AUDIT_ENABLED=true
|
|
578
|
+
SECURITY_AUDIT_LOG_LEVEL=warn
|
|
579
|
+
SECURITY_AUDIT_RETENTION_DAYS=90
|
|
580
|
+
|
|
581
|
+
# 分布式追踪配置
|
|
582
|
+
TRACING_ENABLED=true
|
|
583
|
+
TRACING_SAMPLING_RATE=1.0
|
|
584
|
+
JAEGER_ENDPOINT=http://jaeger:14268/api/traces
|
|
585
|
+
ZIPKIN_ENDPOINT=http://zipkin:9411/api/v2/spans
|
|
586
|
+
|
|
587
|
+
# 配置管理
|
|
588
|
+
CONFIG_REFRESH_INTERVAL=60000
|
|
589
|
+
CONFIG_CACHE_TTL=300000
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
### 配置文件
|
|
593
|
+
|
|
594
|
+
```json
|
|
595
|
+
{
|
|
596
|
+
"annotations": {
|
|
597
|
+
"enterprisePerformance": {
|
|
598
|
+
"enabled": true,
|
|
599
|
+
"samplingRate": 1.0,
|
|
600
|
+
"alertThresholds": {
|
|
601
|
+
"executionTime": 1000,
|
|
602
|
+
"memoryUsage": 50
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
"securityAudit": {
|
|
606
|
+
"enabled": true,
|
|
607
|
+
"logLevel": "warn",
|
|
608
|
+
"complianceMode": "GDPR",
|
|
609
|
+
"retentionDays": 90
|
|
610
|
+
},
|
|
611
|
+
"distributedTracing": {
|
|
612
|
+
"enabled": true,
|
|
613
|
+
"samplingRate": 1.0,
|
|
614
|
+
"exportToJaeger": true,
|
|
615
|
+
"exportToZipkin": false
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
## 📊 监控和告警
|
|
622
|
+
|
|
623
|
+
### 性能指标
|
|
624
|
+
|
|
625
|
+
系统会自动收集以下性能指标:
|
|
626
|
+
|
|
627
|
+
- **执行时间统计**: 平均值、最大值、最小值
|
|
628
|
+
- **内存使用统计**: 堆使用、RSS、外部内存
|
|
629
|
+
- **CPU 使用统计**: 用户时间、系统时间
|
|
630
|
+
- **请求/响应大小**: 数据量统计
|
|
631
|
+
- **错误率**: 失败请求比例
|
|
632
|
+
|
|
633
|
+
### 告警规则
|
|
634
|
+
|
|
635
|
+
```typescript
|
|
636
|
+
// 性能告警配置
|
|
637
|
+
const alertRules = {
|
|
638
|
+
executionTime: {
|
|
639
|
+
threshold: 1000, // 1秒
|
|
640
|
+
severity: 'warning'
|
|
641
|
+
},
|
|
642
|
+
memoryUsage: {
|
|
643
|
+
threshold: 50, // 50MB
|
|
644
|
+
severity: 'critical'
|
|
645
|
+
},
|
|
646
|
+
errorRate: {
|
|
647
|
+
threshold: 0.05, // 5%
|
|
648
|
+
severity: 'warning'
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
### 监控面板
|
|
654
|
+
|
|
655
|
+
系统提供内置的监控面板,可以查看:
|
|
656
|
+
|
|
657
|
+
- 实时性能指标
|
|
658
|
+
- 历史趋势分析
|
|
659
|
+
- 告警状态
|
|
660
|
+
- 系统健康度
|
|
661
|
+
|
|
662
|
+
## 🛡️ 安全审计
|
|
663
|
+
|
|
664
|
+
### 审计日志格式
|
|
665
|
+
|
|
666
|
+
```json
|
|
667
|
+
{
|
|
668
|
+
"timestamp": "2024-01-01T12:00:00.000Z",
|
|
669
|
+
"userId": "user123",
|
|
670
|
+
"sessionId": "session456",
|
|
671
|
+
"ipAddress": "192.168.1.100",
|
|
672
|
+
"userAgent": "Mozilla/5.0...",
|
|
673
|
+
"method": "POST",
|
|
674
|
+
"url": "/api/payments",
|
|
675
|
+
"controller": "PaymentController",
|
|
676
|
+
"action": "processPayment",
|
|
677
|
+
"securityLevel": "CRITICAL",
|
|
678
|
+
"eventType": "DATA_MODIFICATION",
|
|
679
|
+
"riskScore": 8,
|
|
680
|
+
"complianceFlags": ["PCI-DSS_FINANCIAL_DATA"],
|
|
681
|
+
"requestData": {
|
|
682
|
+
"amount": 100.00,
|
|
683
|
+
"cardNumber": "[REDACTED]"
|
|
684
|
+
},
|
|
685
|
+
"responseData": {
|
|
686
|
+
"success": true,
|
|
687
|
+
"transactionId": "txn_123"
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
### 合规性检查
|
|
693
|
+
|
|
694
|
+
系统支持多种合规性标准:
|
|
695
|
+
|
|
696
|
+
- **GDPR**: 欧盟通用数据保护条例
|
|
697
|
+
- **SOX**: 萨班斯-奥克斯利法案
|
|
698
|
+
- **HIPAA**: 健康保险可携性和责任法案
|
|
699
|
+
- **PCI-DSS**: 支付卡行业数据安全标准
|
|
700
|
+
|
|
701
|
+
### 风险评估
|
|
702
|
+
|
|
703
|
+
系统会根据以下因素计算风险评分:
|
|
704
|
+
|
|
705
|
+
1. **操作类型**: DELETE > PUT > POST > GET
|
|
706
|
+
2. **用户权限**: 无权限 > 普通用户 > 管理员
|
|
707
|
+
3. **IP 地址**: 可疑IP > 内网IP > 外网IP
|
|
708
|
+
4. **访问时间**: 非工作时间 > 工作时间
|
|
709
|
+
5. **数据敏感性**: 敏感数据 > 普通数据
|
|
710
|
+
|
|
711
|
+
## 🔍 分布式追踪
|
|
712
|
+
|
|
713
|
+
### 追踪上下文
|
|
714
|
+
|
|
715
|
+
每个请求都会生成唯一的追踪上下文:
|
|
716
|
+
|
|
717
|
+
```typescript
|
|
718
|
+
interface TraceContext {
|
|
719
|
+
traceId: string; // 请求的唯一标识
|
|
720
|
+
spanId: string; // 当前操作的标识
|
|
721
|
+
parentSpanId?: string; // 父操作的标识
|
|
722
|
+
baggage?: Record<string, string>; // 跨服务传递的数据
|
|
723
|
+
}
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
### 服务依赖图
|
|
727
|
+
|
|
728
|
+
系统会自动构建服务依赖关系图:
|
|
729
|
+
|
|
730
|
+
```
|
|
731
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
732
|
+
│ Web API │───▶│ User Svc │───▶│ Database │
|
|
733
|
+
│ │ │ │ │ │
|
|
734
|
+
└─────────────┘ └─────────────┘ └─────────────┘
|
|
735
|
+
│ │
|
|
736
|
+
▼ ▼
|
|
737
|
+
┌─────────────┐ ┌─────────────┐
|
|
738
|
+
│ Payment Svc│ │ Email Svc │
|
|
739
|
+
│ │ │ │
|
|
740
|
+
└─────────────┘ └─────────────┘
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
### 性能分析
|
|
744
|
+
|
|
745
|
+
系统提供详细的性能分析:
|
|
746
|
+
|
|
747
|
+
- **服务调用链**: 完整的请求路径
|
|
748
|
+
- **瓶颈识别**: 最慢的服务和操作
|
|
749
|
+
- **依赖分析**: 服务间的调用关系
|
|
750
|
+
- **错误追踪**: 错误在调用链中的传播
|
|
751
|
+
|
|
752
|
+
## 🔧 故障排除
|
|
753
|
+
|
|
754
|
+
### 常见问题
|
|
755
|
+
|
|
756
|
+
#### 1. 注解不生效
|
|
757
|
+
|
|
758
|
+
**问题**: 注解装饰器没有执行
|
|
759
|
+
|
|
760
|
+
**解决方案**:
|
|
761
|
+
```typescript
|
|
762
|
+
// 检查注解系统是否已初始化
|
|
763
|
+
import { AnnotationSystemInitializer } from '@src/framework/decorator/processor/AnnotationSystemInitializer';
|
|
764
|
+
|
|
765
|
+
if (!AnnotationSystemInitializer.isInitialized()) {
|
|
766
|
+
AnnotationSystemInitializer.initialize();
|
|
767
|
+
}
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
#### 2. 性能监控数据不准确
|
|
771
|
+
|
|
772
|
+
**问题**: 性能指标与实际不符
|
|
773
|
+
|
|
774
|
+
**解决方案**:
|
|
775
|
+
```typescript
|
|
776
|
+
// 检查采样率配置
|
|
777
|
+
@EnterprisePerformance({
|
|
778
|
+
enableMetrics: true,
|
|
779
|
+
samplingRate: 1.0 // 确保采样率为1.0
|
|
780
|
+
})
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
#### 3. 安全审计日志过多
|
|
784
|
+
|
|
785
|
+
**问题**: 审计日志产生过多噪音
|
|
786
|
+
|
|
787
|
+
**解决方案**:
|
|
788
|
+
```typescript
|
|
789
|
+
// 调整日志级别和过滤条件
|
|
790
|
+
@SecurityAudit({
|
|
791
|
+
logLevel: 'warn', // 只记录警告和错误
|
|
792
|
+
includeRequestData: false, // 不包含请求数据
|
|
793
|
+
sensitiveFields: ['password', 'ssn'] // 只关注敏感字段
|
|
794
|
+
})
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
#### 4. 分布式追踪数据丢失
|
|
798
|
+
|
|
799
|
+
**问题**: 追踪数据没有正确导出
|
|
800
|
+
|
|
801
|
+
**解决方案**:
|
|
802
|
+
```bash
|
|
803
|
+
# 检查环境变量配置
|
|
804
|
+
export JAEGER_ENDPOINT=http://jaeger:14268/api/traces
|
|
805
|
+
export TRACING_SAMPLING_RATE=1.0
|
|
806
|
+
export TRACING_ENABLED=true
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
### 调试技巧
|
|
810
|
+
|
|
811
|
+
#### 1. 启用调试日志
|
|
812
|
+
|
|
813
|
+
```typescript
|
|
814
|
+
// 在注解处理器中添加调试日志
|
|
815
|
+
console.log(`[${this.name}] 调试信息:`, {
|
|
816
|
+
methodName,
|
|
817
|
+
annotationData,
|
|
818
|
+
callParams
|
|
819
|
+
});
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
#### 2. 检查注解注册状态
|
|
823
|
+
|
|
824
|
+
```typescript
|
|
825
|
+
import { annotationRegistry } from '@src/framework/decorator/processor/AnnotationRegistry';
|
|
826
|
+
|
|
827
|
+
// 检查已注册的处理器
|
|
828
|
+
console.log('已注册的处理器:', annotationRegistry.getRegisteredProcessors());
|
|
829
|
+
|
|
830
|
+
// 检查特定处理器
|
|
831
|
+
const processor = annotationRegistry.getProcessor('EnterprisePerformance');
|
|
832
|
+
console.log('处理器状态:', processor);
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
#### 3. 验证配置
|
|
836
|
+
|
|
837
|
+
```typescript
|
|
838
|
+
// 验证配置是否正确加载
|
|
839
|
+
@ConfigManagement({
|
|
840
|
+
configKey: 'debug.enabled',
|
|
841
|
+
defaultValue: false,
|
|
842
|
+
validationRules: [
|
|
843
|
+
{ type: 'boolean' }
|
|
844
|
+
]
|
|
845
|
+
})
|
|
846
|
+
async debugMethod() {
|
|
847
|
+
const config = this.ctx?.state.config;
|
|
848
|
+
console.log('配置状态:', config);
|
|
849
|
+
}
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
### 性能优化建议
|
|
853
|
+
|
|
854
|
+
#### 1. 合理设置采样率
|
|
855
|
+
|
|
856
|
+
```typescript
|
|
857
|
+
// 生产环境建议采样率
|
|
858
|
+
@DistributedTracing({
|
|
859
|
+
samplingRate: 0.1 // 10% 采样率
|
|
860
|
+
})
|
|
861
|
+
|
|
862
|
+
// 开发环境可以设置更高采样率
|
|
863
|
+
@DistributedTracing({
|
|
864
|
+
samplingRate: 1.0 // 100% 采样率
|
|
865
|
+
})
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
#### 2. 优化内存使用
|
|
869
|
+
|
|
870
|
+
```typescript
|
|
871
|
+
// 定期清理过期数据
|
|
872
|
+
setInterval(() => {
|
|
873
|
+
processor.cleanupExpiredSpans(3600000); // 清理1小时前的数据
|
|
874
|
+
}, 300000); // 每5分钟清理一次
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
#### 3. 异步处理
|
|
878
|
+
|
|
879
|
+
```typescript
|
|
880
|
+
// 对于耗时的操作,使用异步处理
|
|
881
|
+
async postProcess(ctx: Context, controller: any, methodName: string, response: any) {
|
|
882
|
+
// 异步处理,不阻塞响应
|
|
883
|
+
setImmediate(() => {
|
|
884
|
+
this.processAuditLog(ctx, controller, methodName, response);
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
## 📈 自定义注解开发指南
|
|
890
|
+
|
|
891
|
+
### 🎯 开发概述
|
|
892
|
+
|
|
893
|
+
企业级注解系统提供了完整的自定义注解开发框架,支持开发者创建符合业务需求的专用注解。本章节将详细介绍如何从零开始开发自定义注解。
|
|
894
|
+
|
|
895
|
+
### 📋 开发流程
|
|
896
|
+
|
|
897
|
+
#### 1. 确定注解需求
|
|
898
|
+
|
|
899
|
+
在开发自定义注解之前,需要明确以下问题:
|
|
900
|
+
|
|
901
|
+
- **功能目标**: 注解要实现什么功能?
|
|
902
|
+
- **执行时机**: 在方法执行前、后,还是两者都需要?
|
|
903
|
+
- **配置参数**: 需要哪些可配置的参数?
|
|
904
|
+
- **优先级**: 相对于其他注解的执行顺序?
|
|
905
|
+
- **依赖关系**: 是否需要依赖其他服务或组件?
|
|
906
|
+
|
|
907
|
+
#### 2. 设计注解接口
|
|
908
|
+
|
|
909
|
+
```typescript
|
|
910
|
+
// 定义注解配置接口
|
|
911
|
+
export interface CustomAnnotationConfig {
|
|
912
|
+
// 基础配置
|
|
913
|
+
enabled?: boolean;
|
|
914
|
+
logLevel?: 'debug' | 'info' | 'warn' | 'error';
|
|
915
|
+
|
|
916
|
+
// 业务特定配置
|
|
917
|
+
businessParam1?: string;
|
|
918
|
+
businessParam2?: number;
|
|
919
|
+
businessParam3?: boolean;
|
|
920
|
+
|
|
921
|
+
// 高级配置
|
|
922
|
+
timeout?: number;
|
|
923
|
+
retryCount?: number;
|
|
924
|
+
fallbackValue?: any;
|
|
925
|
+
}
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
#### 3. 实现注解处理器
|
|
929
|
+
|
|
930
|
+
```typescript
|
|
931
|
+
import { Context } from 'koa';
|
|
932
|
+
import { AnnotationProcessor } from '@src/framework/decorator/processor/AnnotationProcessor';
|
|
933
|
+
import { logger } from '@src/framework/utils/logger';
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* 自定义注解处理器示例
|
|
937
|
+
* 实现业务特定的功能
|
|
938
|
+
*/
|
|
939
|
+
export class CustomAnnotationProcessor implements AnnotationProcessor {
|
|
940
|
+
readonly name = 'CustomAnnotation';
|
|
941
|
+
readonly priority = 20; // 设置优先级
|
|
942
|
+
|
|
943
|
+
private config: CustomAnnotationConfig = {};
|
|
944
|
+
private metrics: Map<string, any> = new Map();
|
|
945
|
+
|
|
946
|
+
constructor() {
|
|
947
|
+
this.initializeMetrics();
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* 前置处理方法
|
|
952
|
+
* 在控制器方法执行前调用
|
|
953
|
+
*/
|
|
954
|
+
async process(
|
|
955
|
+
ctx: Context,
|
|
956
|
+
controller: any,
|
|
957
|
+
methodName: string,
|
|
958
|
+
annotationData: CustomAnnotationConfig,
|
|
959
|
+
callParams: any[]
|
|
960
|
+
): Promise<boolean> {
|
|
961
|
+
try {
|
|
962
|
+
// 合并配置
|
|
963
|
+
this.config = { ...this.config, ...annotationData };
|
|
964
|
+
|
|
965
|
+
// 检查是否启用
|
|
966
|
+
if (!this.config.enabled) {
|
|
967
|
+
return true;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// 记录开始时间
|
|
971
|
+
const startTime = Date.now();
|
|
972
|
+
ctx.state.customAnnotationStartTime = startTime;
|
|
973
|
+
|
|
974
|
+
// 执行业务逻辑
|
|
975
|
+
await this.executeBusinessLogic(ctx, controller, methodName, callParams);
|
|
976
|
+
|
|
977
|
+
// 记录指标
|
|
978
|
+
this.recordMetrics(methodName, 'start', startTime);
|
|
979
|
+
|
|
980
|
+
logger.info(`[${this.name}] 开始处理: ${controller.constructor.name}.${methodName}`, {
|
|
981
|
+
config: this.config,
|
|
982
|
+
params: callParams
|
|
983
|
+
});
|
|
984
|
+
|
|
985
|
+
return true;
|
|
986
|
+
|
|
987
|
+
} catch (error) {
|
|
988
|
+
logger.error(`[${this.name}] 处理失败: ${controller.constructor.name}.${methodName}`, error);
|
|
989
|
+
|
|
990
|
+
// 根据配置决定是否中断执行
|
|
991
|
+
if (this.config.enabled) {
|
|
992
|
+
ctx.status = 500;
|
|
993
|
+
ctx.body = { error: 'Custom annotation processing failed' };
|
|
994
|
+
return false;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
return true;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
/**
|
|
1002
|
+
* 后置处理方法
|
|
1003
|
+
* 在控制器方法执行后调用
|
|
1004
|
+
*/
|
|
1005
|
+
async postProcess(
|
|
1006
|
+
ctx: Context,
|
|
1007
|
+
controller: any,
|
|
1008
|
+
methodName: string,
|
|
1009
|
+
response: any
|
|
1010
|
+
): Promise<void> {
|
|
1011
|
+
try {
|
|
1012
|
+
if (!this.config.enabled) {
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
const startTime = ctx.state.customAnnotationStartTime;
|
|
1017
|
+
const endTime = Date.now();
|
|
1018
|
+
const duration = startTime ? endTime - startTime : 0;
|
|
1019
|
+
|
|
1020
|
+
// 执行业务后置逻辑
|
|
1021
|
+
await this.executePostBusinessLogic(ctx, controller, methodName, response);
|
|
1022
|
+
|
|
1023
|
+
// 记录指标
|
|
1024
|
+
this.recordMetrics(methodName, 'end', endTime, duration);
|
|
1025
|
+
|
|
1026
|
+
// 记录日志
|
|
1027
|
+
logger.info(`[${this.name}] 完成处理: ${controller.constructor.name}.${methodName}`, {
|
|
1028
|
+
duration: `${duration}ms`,
|
|
1029
|
+
response: this.sanitizeResponse(response)
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
// 清理上下文
|
|
1033
|
+
delete ctx.state.customAnnotationStartTime;
|
|
1034
|
+
|
|
1035
|
+
} catch (error) {
|
|
1036
|
+
logger.error(`[${this.name}] 后置处理失败: ${controller.constructor.name}.${methodName}`, error);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* 执行业务逻辑
|
|
1042
|
+
*/
|
|
1043
|
+
private async executeBusinessLogic(
|
|
1044
|
+
ctx: Context,
|
|
1045
|
+
controller: any,
|
|
1046
|
+
methodName: string,
|
|
1047
|
+
callParams: any[]
|
|
1048
|
+
): Promise<void> {
|
|
1049
|
+
// 示例:数据验证
|
|
1050
|
+
if (this.config.businessParam1) {
|
|
1051
|
+
await this.validateData(ctx, callParams);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
// 示例:权限检查
|
|
1055
|
+
if (this.config.businessParam2) {
|
|
1056
|
+
await this.checkPermissions(ctx, controller, methodName);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// 示例:缓存检查
|
|
1060
|
+
if (this.config.businessParam3) {
|
|
1061
|
+
await this.checkCache(ctx, methodName, callParams);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
// 示例:外部服务调用
|
|
1065
|
+
if (this.config.timeout) {
|
|
1066
|
+
await this.callExternalService(ctx, this.config.timeout);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
/**
|
|
1071
|
+
* 执行后置业务逻辑
|
|
1072
|
+
*/
|
|
1073
|
+
private async executePostBusinessLogic(
|
|
1074
|
+
ctx: Context,
|
|
1075
|
+
controller: any,
|
|
1076
|
+
methodName: string,
|
|
1077
|
+
response: any
|
|
1078
|
+
): Promise<void> {
|
|
1079
|
+
// 示例:结果处理
|
|
1080
|
+
await this.processResult(ctx, response);
|
|
1081
|
+
|
|
1082
|
+
// 示例:缓存更新
|
|
1083
|
+
if (this.config.businessParam3) {
|
|
1084
|
+
await this.updateCache(ctx, methodName, response);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
// 示例:通知发送
|
|
1088
|
+
await this.sendNotification(ctx, controller, methodName, response);
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* 数据验证
|
|
1093
|
+
*/
|
|
1094
|
+
private async validateData(ctx: Context, callParams: any[]): Promise<void> {
|
|
1095
|
+
// 实现数据验证逻辑
|
|
1096
|
+
for (const param of callParams) {
|
|
1097
|
+
if (param && typeof param === 'object') {
|
|
1098
|
+
// 验证逻辑
|
|
1099
|
+
if (!this.isValidData(param)) {
|
|
1100
|
+
throw new Error('Data validation failed');
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* 权限检查
|
|
1108
|
+
*/
|
|
1109
|
+
private async checkPermissions(
|
|
1110
|
+
ctx: Context,
|
|
1111
|
+
controller: any,
|
|
1112
|
+
methodName: string
|
|
1113
|
+
): Promise<void> {
|
|
1114
|
+
// 实现权限检查逻辑
|
|
1115
|
+
const user = ctx.state.user;
|
|
1116
|
+
if (!user || !user.hasPermission(this.config.businessParam2)) {
|
|
1117
|
+
throw new Error('Permission denied');
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
/**
|
|
1122
|
+
* 缓存检查
|
|
1123
|
+
*/
|
|
1124
|
+
private async checkCache(
|
|
1125
|
+
ctx: Context,
|
|
1126
|
+
methodName: string,
|
|
1127
|
+
callParams: any[]
|
|
1128
|
+
): Promise<void> {
|
|
1129
|
+
// 实现缓存检查逻辑
|
|
1130
|
+
const cacheKey = this.generateCacheKey(methodName, callParams);
|
|
1131
|
+
const cached = await this.getFromCache(cacheKey);
|
|
1132
|
+
|
|
1133
|
+
if (cached) {
|
|
1134
|
+
ctx.state.cachedResult = cached;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
/**
|
|
1139
|
+
* 外部服务调用
|
|
1140
|
+
*/
|
|
1141
|
+
private async callExternalService(ctx: Context, timeout: number): Promise<void> {
|
|
1142
|
+
// 实现外部服务调用逻辑
|
|
1143
|
+
const result = await this.callWithTimeout('/api/external', timeout);
|
|
1144
|
+
ctx.state.externalResult = result;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
/**
|
|
1148
|
+
* 结果处理
|
|
1149
|
+
*/
|
|
1150
|
+
private async processResult(ctx: Context, response: any): Promise<void> {
|
|
1151
|
+
// 实现结果处理逻辑
|
|
1152
|
+
if (response && typeof response === 'object') {
|
|
1153
|
+
// 处理响应数据
|
|
1154
|
+
response.processedAt = new Date().toISOString();
|
|
1155
|
+
response.processedBy = this.name;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* 缓存更新
|
|
1161
|
+
*/
|
|
1162
|
+
private async updateCache(
|
|
1163
|
+
ctx: Context,
|
|
1164
|
+
methodName: string,
|
|
1165
|
+
response: any
|
|
1166
|
+
): Promise<void> {
|
|
1167
|
+
// 实现缓存更新逻辑
|
|
1168
|
+
const cacheKey = this.generateCacheKey(methodName, ctx.state.callParams);
|
|
1169
|
+
await this.setCache(cacheKey, response, 300); // 5分钟过期
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
/**
|
|
1173
|
+
* 发送通知
|
|
1174
|
+
*/
|
|
1175
|
+
private async sendNotification(
|
|
1176
|
+
ctx: Context,
|
|
1177
|
+
controller: any,
|
|
1178
|
+
methodName: string,
|
|
1179
|
+
response: any
|
|
1180
|
+
): Promise<void> {
|
|
1181
|
+
// 实现通知发送逻辑
|
|
1182
|
+
const notification = {
|
|
1183
|
+
controller: controller.constructor.name,
|
|
1184
|
+
method: methodName,
|
|
1185
|
+
timestamp: new Date().toISOString(),
|
|
1186
|
+
success: response?.code === 0
|
|
1187
|
+
};
|
|
1188
|
+
|
|
1189
|
+
await this.sendToNotificationService(notification);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
/**
|
|
1193
|
+
* 记录指标
|
|
1194
|
+
*/
|
|
1195
|
+
private recordMetrics(methodName: string, event: string, timestamp: number, duration?: number): void {
|
|
1196
|
+
const key = `${methodName}_${event}`;
|
|
1197
|
+
const metrics = this.metrics.get(key) || { count: 0, totalDuration: 0 };
|
|
1198
|
+
|
|
1199
|
+
metrics.count++;
|
|
1200
|
+
if (duration) {
|
|
1201
|
+
metrics.totalDuration += duration;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
this.metrics.set(key, metrics);
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
/**
|
|
1208
|
+
* 初始化指标
|
|
1209
|
+
*/
|
|
1210
|
+
private initializeMetrics(): void {
|
|
1211
|
+
// 初始化指标收集
|
|
1212
|
+
this.metrics = new Map();
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* 工具方法
|
|
1217
|
+
*/
|
|
1218
|
+
private isValidData(data: any): boolean {
|
|
1219
|
+
// 实现数据验证逻辑
|
|
1220
|
+
return data && typeof data === 'object';
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
private generateCacheKey(methodName: string, params: any[]): string {
|
|
1224
|
+
return `${methodName}_${JSON.stringify(params)}`;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
private async getFromCache(key: string): Promise<any> {
|
|
1228
|
+
// 实现缓存获取逻辑
|
|
1229
|
+
return null;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
private async setCache(key: string, value: any, ttl: number): Promise<void> {
|
|
1233
|
+
// 实现缓存设置逻辑
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
private async callWithTimeout(url: string, timeout: number): Promise<any> {
|
|
1237
|
+
// 实现带超时的服务调用
|
|
1238
|
+
return new Promise((resolve, reject) => {
|
|
1239
|
+
setTimeout(() => resolve({ data: 'external result' }), 100);
|
|
1240
|
+
});
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
private async sendToNotificationService(notification: any): Promise<void> {
|
|
1244
|
+
// 实现通知发送逻辑
|
|
1245
|
+
console.log('Sending notification:', notification);
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
private sanitizeResponse(response: any): any {
|
|
1249
|
+
// 实现响应数据脱敏
|
|
1250
|
+
if (response && typeof response === 'object') {
|
|
1251
|
+
const sanitized = { ...response };
|
|
1252
|
+
// 移除敏感信息
|
|
1253
|
+
delete sanitized.password;
|
|
1254
|
+
delete sanitized.token;
|
|
1255
|
+
return sanitized;
|
|
1256
|
+
}
|
|
1257
|
+
return response;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
/**
|
|
1261
|
+
* 获取指标统计
|
|
1262
|
+
*/
|
|
1263
|
+
getMetrics(): Map<string, any> {
|
|
1264
|
+
return new Map(this.metrics);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
/**
|
|
1268
|
+
* 清理指标
|
|
1269
|
+
*/
|
|
1270
|
+
clearMetrics(): void {
|
|
1271
|
+
this.metrics.clear();
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
```
|
|
1275
|
+
|
|
1276
|
+
#### 4. 创建注解装饰器
|
|
1277
|
+
|
|
1278
|
+
```typescript
|
|
1279
|
+
import { createAnnotationDecorator } from '@src/framework/decorator/processor/AnnotationDecorators';
|
|
1280
|
+
import { CustomAnnotationConfig } from './CustomAnnotationProcessor';
|
|
1281
|
+
|
|
1282
|
+
/**
|
|
1283
|
+
* 自定义注解装饰器
|
|
1284
|
+
* 提供类型安全的配置接口
|
|
1285
|
+
*/
|
|
1286
|
+
export function CustomAnnotation(config?: CustomAnnotationConfig) {
|
|
1287
|
+
return createAnnotationDecorator('CustomAnnotation')(config);
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
/**
|
|
1291
|
+
* 带默认配置的装饰器变体
|
|
1292
|
+
*/
|
|
1293
|
+
export function CustomAnnotationWithDefaults(config?: Partial<CustomAnnotationConfig>) {
|
|
1294
|
+
const defaultConfig: CustomAnnotationConfig = {
|
|
1295
|
+
enabled: true,
|
|
1296
|
+
logLevel: 'info',
|
|
1297
|
+
businessParam1: 'default',
|
|
1298
|
+
businessParam2: 0,
|
|
1299
|
+
businessParam3: false,
|
|
1300
|
+
timeout: 5000,
|
|
1301
|
+
retryCount: 3,
|
|
1302
|
+
fallbackValue: null
|
|
1303
|
+
};
|
|
1304
|
+
|
|
1305
|
+
return CustomAnnotation({ ...defaultConfig, ...config });
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
/**
|
|
1309
|
+
* 简化版装饰器
|
|
1310
|
+
*/
|
|
1311
|
+
export function SimpleCustomAnnotation(enabled: boolean = true) {
|
|
1312
|
+
return CustomAnnotation({ enabled });
|
|
1313
|
+
}
|
|
1314
|
+
```
|
|
1315
|
+
|
|
1316
|
+
#### 5. 注册注解处理器
|
|
1317
|
+
|
|
1318
|
+
```typescript
|
|
1319
|
+
// 方式1: 在注解配置文件中注册
|
|
1320
|
+
// src/framework/decorator/processor/AnnotationProcessorConfig.ts
|
|
1321
|
+
|
|
1322
|
+
import { CustomAnnotationProcessor } from '@src/annotations/processors/CustomAnnotationProcessor';
|
|
1323
|
+
|
|
1324
|
+
export function getAllAnnotationProcessors(): AnnotationProcessor[] {
|
|
1325
|
+
return [
|
|
1326
|
+
// ... 其他处理器
|
|
1327
|
+
new CustomAnnotationProcessor()
|
|
1328
|
+
];
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
// 方式2: 动态注册
|
|
1332
|
+
// src/app.ts 或初始化文件中
|
|
1333
|
+
|
|
1334
|
+
import { annotationRegistry } from '@src/framework/decorator/processor/AnnotationRegistry';
|
|
1335
|
+
import { CustomAnnotationProcessor } from '@src/annotations/processors/CustomAnnotationProcessor';
|
|
1336
|
+
|
|
1337
|
+
// 在应用启动时注册
|
|
1338
|
+
annotationRegistry.registerProcessor(new CustomAnnotationProcessor());
|
|
1339
|
+
```
|
|
1340
|
+
|
|
1341
|
+
#### 6. 使用自定义注解
|
|
1342
|
+
|
|
1343
|
+
```typescript
|
|
1344
|
+
import { Get, Post, Body, Query } from '@src/framework/decorator/controller';
|
|
1345
|
+
import { Logging } from '@src/framework/decorator/processor/AnnotationDecorators';
|
|
1346
|
+
import { CustomAnnotation, CustomAnnotationWithDefaults } from '@src/annotations/decorators/CustomAnnotation';
|
|
1347
|
+
|
|
1348
|
+
export class BusinessController {
|
|
1349
|
+
|
|
1350
|
+
/**
|
|
1351
|
+
* 基础使用
|
|
1352
|
+
*/
|
|
1353
|
+
@Get('/business/basic')
|
|
1354
|
+
@CustomAnnotation({
|
|
1355
|
+
enabled: true,
|
|
1356
|
+
logLevel: 'info',
|
|
1357
|
+
businessParam1: 'test',
|
|
1358
|
+
timeout: 3000
|
|
1359
|
+
})
|
|
1360
|
+
@Logging()
|
|
1361
|
+
async getBasicData(@Query() query: any) {
|
|
1362
|
+
return { data: 'basic data' };
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
/**
|
|
1366
|
+
* 使用默认配置
|
|
1367
|
+
*/
|
|
1368
|
+
@Post('/business/advanced')
|
|
1369
|
+
@CustomAnnotationWithDefaults({
|
|
1370
|
+
businessParam2: 100,
|
|
1371
|
+
retryCount: 5
|
|
1372
|
+
})
|
|
1373
|
+
@Logging()
|
|
1374
|
+
async createAdvancedData(@Body() data: any) {
|
|
1375
|
+
return { success: true, data };
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
/**
|
|
1379
|
+
* 简化使用
|
|
1380
|
+
*/
|
|
1381
|
+
@Get('/business/simple')
|
|
1382
|
+
@SimpleCustomAnnotation(true)
|
|
1383
|
+
@Logging()
|
|
1384
|
+
async getSimpleData() {
|
|
1385
|
+
return { data: 'simple data' };
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
```
|
|
1389
|
+
|
|
1390
|
+
### 🔧 高级开发技巧
|
|
1391
|
+
|
|
1392
|
+
#### 1. 注解组合模式
|
|
1393
|
+
|
|
1394
|
+
```typescript
|
|
1395
|
+
/**
|
|
1396
|
+
* 组合多个注解功能
|
|
1397
|
+
*/
|
|
1398
|
+
export class CompositeAnnotationProcessor implements AnnotationProcessor {
|
|
1399
|
+
readonly name = 'CompositeAnnotation';
|
|
1400
|
+
readonly priority = 1;
|
|
1401
|
+
|
|
1402
|
+
private processors: AnnotationProcessor[] = [];
|
|
1403
|
+
|
|
1404
|
+
constructor() {
|
|
1405
|
+
// 组合多个处理器
|
|
1406
|
+
this.processors.push(new ValidationProcessor());
|
|
1407
|
+
this.processors.push(new CacheProcessor());
|
|
1408
|
+
this.processors.push(new MetricsProcessor());
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
async process(ctx: Context, controller: any, methodName: string, annotationData: any, callParams: any[]): Promise<boolean> {
|
|
1412
|
+
// 按顺序执行所有处理器
|
|
1413
|
+
for (const processor of this.processors) {
|
|
1414
|
+
const result = await processor.process(ctx, controller, methodName, annotationData, callParams);
|
|
1415
|
+
if (!result) {
|
|
1416
|
+
return false; // 任何一个失败就中断
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
return true;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
async postProcess(ctx: Context, controller: any, methodName: string, response: any): Promise<void> {
|
|
1423
|
+
// 按相反顺序执行后置处理
|
|
1424
|
+
for (let i = this.processors.length - 1; i >= 0; i--) {
|
|
1425
|
+
const processor = this.processors[i];
|
|
1426
|
+
if (processor.postProcess) {
|
|
1427
|
+
await processor.postProcess(ctx, controller, methodName, response);
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
```
|
|
1433
|
+
|
|
1434
|
+
#### 2. 条件执行注解
|
|
1435
|
+
|
|
1436
|
+
```typescript
|
|
1437
|
+
/**
|
|
1438
|
+
* 基于条件的注解处理器
|
|
1439
|
+
*/
|
|
1440
|
+
export class ConditionalAnnotationProcessor implements AnnotationProcessor {
|
|
1441
|
+
readonly name = 'ConditionalAnnotation';
|
|
1442
|
+
readonly priority = 15;
|
|
1443
|
+
|
|
1444
|
+
async process(
|
|
1445
|
+
ctx: Context,
|
|
1446
|
+
controller: any,
|
|
1447
|
+
methodName: string,
|
|
1448
|
+
annotationData: { condition: (ctx: Context) => boolean; processor: AnnotationProcessor },
|
|
1449
|
+
callParams: any[]
|
|
1450
|
+
): Promise<boolean> {
|
|
1451
|
+
// 检查条件
|
|
1452
|
+
if (annotationData.condition && annotationData.condition(ctx)) {
|
|
1453
|
+
// 条件满足时执行处理器
|
|
1454
|
+
return await annotationData.processor.process(ctx, controller, methodName, annotationData, callParams);
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
return true; // 条件不满足时跳过
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
// 使用示例
|
|
1462
|
+
@ConditionalAnnotation({
|
|
1463
|
+
condition: (ctx) => ctx.state.user?.isAdmin,
|
|
1464
|
+
processor: new AdminOnlyProcessor()
|
|
1465
|
+
})
|
|
1466
|
+
async adminOnlyMethod() { }
|
|
1467
|
+
```
|
|
1468
|
+
|
|
1469
|
+
#### 3. 异步注解处理器
|
|
1470
|
+
|
|
1471
|
+
```typescript
|
|
1472
|
+
/**
|
|
1473
|
+
* 支持异步操作的注解处理器
|
|
1474
|
+
*/
|
|
1475
|
+
export class AsyncAnnotationProcessor implements AnnotationProcessor {
|
|
1476
|
+
readonly name = 'AsyncAnnotation';
|
|
1477
|
+
readonly priority = 10;
|
|
1478
|
+
|
|
1479
|
+
private asyncOperations: Map<string, Promise<any>> = new Map();
|
|
1480
|
+
|
|
1481
|
+
async process(
|
|
1482
|
+
ctx: Context,
|
|
1483
|
+
controller: any,
|
|
1484
|
+
methodName: string,
|
|
1485
|
+
annotationData: { asyncOperation: () => Promise<any> },
|
|
1486
|
+
callParams: any[]
|
|
1487
|
+
): Promise<boolean> {
|
|
1488
|
+
try {
|
|
1489
|
+
// 启动异步操作
|
|
1490
|
+
const operationKey = `${controller.constructor.name}.${methodName}`;
|
|
1491
|
+
const operation = annotationData.asyncOperation();
|
|
1492
|
+
|
|
1493
|
+
this.asyncOperations.set(operationKey, operation);
|
|
1494
|
+
|
|
1495
|
+
// 不等待完成,继续执行控制器方法
|
|
1496
|
+
return true;
|
|
1497
|
+
|
|
1498
|
+
} catch (error) {
|
|
1499
|
+
logger.error(`[${this.name}] 异步操作启动失败:`, error);
|
|
1500
|
+
return true; // 异步操作失败不影响主流程
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
async postProcess(
|
|
1505
|
+
ctx: Context,
|
|
1506
|
+
controller: any,
|
|
1507
|
+
methodName: string,
|
|
1508
|
+
response: any
|
|
1509
|
+
): Promise<void> {
|
|
1510
|
+
const operationKey = `${controller.constructor.name}.${methodName}`;
|
|
1511
|
+
const operation = this.asyncOperations.get(operationKey);
|
|
1512
|
+
|
|
1513
|
+
if (operation) {
|
|
1514
|
+
try {
|
|
1515
|
+
// 等待异步操作完成
|
|
1516
|
+
const result = await operation;
|
|
1517
|
+
logger.info(`[${this.name}] 异步操作完成:`, result);
|
|
1518
|
+
|
|
1519
|
+
// 清理
|
|
1520
|
+
this.asyncOperations.delete(operationKey);
|
|
1521
|
+
|
|
1522
|
+
} catch (error) {
|
|
1523
|
+
logger.error(`[${this.name}] 异步操作失败:`, error);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
```
|
|
1529
|
+
|
|
1530
|
+
#### 4. 注解链式调用
|
|
1531
|
+
|
|
1532
|
+
```typescript
|
|
1533
|
+
/**
|
|
1534
|
+
* 支持链式调用的注解处理器
|
|
1535
|
+
*/
|
|
1536
|
+
export class ChainableAnnotationProcessor implements AnnotationProcessor {
|
|
1537
|
+
readonly name = 'ChainableAnnotation';
|
|
1538
|
+
readonly priority = 5;
|
|
1539
|
+
|
|
1540
|
+
private chain: AnnotationProcessor[] = [];
|
|
1541
|
+
|
|
1542
|
+
addProcessor(processor: AnnotationProcessor): ChainableAnnotationProcessor {
|
|
1543
|
+
this.chain.push(processor);
|
|
1544
|
+
return this;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
async process(ctx: Context, controller: any, methodName: string, annotationData: any, callParams: any[]): Promise<boolean> {
|
|
1548
|
+
for (const processor of this.chain) {
|
|
1549
|
+
const result = await processor.process(ctx, controller, methodName, annotationData, callParams);
|
|
1550
|
+
if (!result) {
|
|
1551
|
+
return false;
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
return true;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
async postProcess(ctx: Context, controller: any, methodName: string, response: any): Promise<void> {
|
|
1558
|
+
for (let i = this.chain.length - 1; i >= 0; i--) {
|
|
1559
|
+
const processor = this.chain[i];
|
|
1560
|
+
if (processor.postProcess) {
|
|
1561
|
+
await processor.postProcess(ctx, controller, methodName, response);
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
// 使用示例
|
|
1568
|
+
const chainProcessor = new ChainableAnnotationProcessor()
|
|
1569
|
+
.addProcessor(new ValidationProcessor())
|
|
1570
|
+
.addProcessor(new CacheProcessor())
|
|
1571
|
+
.addProcessor(new MetricsProcessor());
|
|
1572
|
+
|
|
1573
|
+
annotationRegistry.registerProcessor(chainProcessor);
|
|
1574
|
+
```
|
|
1575
|
+
|
|
1576
|
+
### 🧪 测试自定义注解
|
|
1577
|
+
|
|
1578
|
+
#### 1. 单元测试
|
|
1579
|
+
|
|
1580
|
+
```typescript
|
|
1581
|
+
import { CustomAnnotationProcessor } from '../CustomAnnotationProcessor';
|
|
1582
|
+
import { Context } from 'koa';
|
|
1583
|
+
|
|
1584
|
+
describe('CustomAnnotationProcessor', () => {
|
|
1585
|
+
let processor: CustomAnnotationProcessor;
|
|
1586
|
+
let mockContext: Partial<Context>;
|
|
1587
|
+
|
|
1588
|
+
beforeEach(() => {
|
|
1589
|
+
processor = new CustomAnnotationProcessor();
|
|
1590
|
+
mockContext = {
|
|
1591
|
+
state: {},
|
|
1592
|
+
status: 200,
|
|
1593
|
+
body: null
|
|
1594
|
+
};
|
|
1595
|
+
});
|
|
1596
|
+
|
|
1597
|
+
it('should process annotation successfully', async () => {
|
|
1598
|
+
const config = {
|
|
1599
|
+
enabled: true,
|
|
1600
|
+
logLevel: 'info',
|
|
1601
|
+
businessParam1: 'test'
|
|
1602
|
+
};
|
|
1603
|
+
|
|
1604
|
+
const result = await processor.process(
|
|
1605
|
+
mockContext as Context,
|
|
1606
|
+
{},
|
|
1607
|
+
'testMethod',
|
|
1608
|
+
config,
|
|
1609
|
+
[{ test: 'data' }]
|
|
1610
|
+
);
|
|
1611
|
+
|
|
1612
|
+
expect(result).toBe(true);
|
|
1613
|
+
expect(mockContext.state.customAnnotationStartTime).toBeDefined();
|
|
1614
|
+
});
|
|
1615
|
+
|
|
1616
|
+
it('should handle disabled annotation', async () => {
|
|
1617
|
+
const config = { enabled: false };
|
|
1618
|
+
|
|
1619
|
+
const result = await processor.process(
|
|
1620
|
+
mockContext as Context,
|
|
1621
|
+
{},
|
|
1622
|
+
'testMethod',
|
|
1623
|
+
config,
|
|
1624
|
+
[]
|
|
1625
|
+
);
|
|
1626
|
+
|
|
1627
|
+
expect(result).toBe(true);
|
|
1628
|
+
expect(mockContext.state.customAnnotationStartTime).toBeUndefined();
|
|
1629
|
+
});
|
|
1630
|
+
|
|
1631
|
+
it('should record metrics correctly', async () => {
|
|
1632
|
+
const config = { enabled: true };
|
|
1633
|
+
|
|
1634
|
+
await processor.process(mockContext as Context, {}, 'testMethod', config, []);
|
|
1635
|
+
await processor.postProcess(mockContext as Context, {}, 'testMethod', {});
|
|
1636
|
+
|
|
1637
|
+
const metrics = processor.getMetrics();
|
|
1638
|
+
expect(metrics.has('testMethod_start')).toBe(true);
|
|
1639
|
+
expect(metrics.has('testMethod_end')).toBe(true);
|
|
1640
|
+
});
|
|
1641
|
+
});
|
|
1642
|
+
```
|
|
1643
|
+
|
|
1644
|
+
#### 2. 集成测试
|
|
1645
|
+
|
|
1646
|
+
```typescript
|
|
1647
|
+
import request from 'supertest';
|
|
1648
|
+
import { app } from '../app';
|
|
1649
|
+
|
|
1650
|
+
describe('Custom Annotation Integration', () => {
|
|
1651
|
+
it('should work with custom annotation', async () => {
|
|
1652
|
+
const response = await request(app)
|
|
1653
|
+
.get('/business/basic')
|
|
1654
|
+
.query({ test: 'data' })
|
|
1655
|
+
.expect(200);
|
|
1656
|
+
|
|
1657
|
+
expect(response.body.data).toBeDefined();
|
|
1658
|
+
});
|
|
1659
|
+
|
|
1660
|
+
it('should handle annotation errors gracefully', async () => {
|
|
1661
|
+
const response = await request(app)
|
|
1662
|
+
.post('/business/error')
|
|
1663
|
+
.send({ invalid: 'data' })
|
|
1664
|
+
.expect(500);
|
|
1665
|
+
|
|
1666
|
+
expect(response.body.error).toBeDefined();
|
|
1667
|
+
});
|
|
1668
|
+
});
|
|
1669
|
+
```
|
|
1670
|
+
|
|
1671
|
+
### 📚 最佳实践
|
|
1672
|
+
|
|
1673
|
+
#### 1. 命名规范
|
|
1674
|
+
|
|
1675
|
+
```typescript
|
|
1676
|
+
// ✅ 好的命名
|
|
1677
|
+
export class UserValidationProcessor implements AnnotationProcessor {
|
|
1678
|
+
readonly name = 'UserValidation';
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
export function UserValidation(config?: UserValidationConfig) {
|
|
1682
|
+
return createAnnotationDecorator('UserValidation')(config);
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
// ❌ 不好的命名
|
|
1686
|
+
export class Processor1 implements AnnotationProcessor {
|
|
1687
|
+
readonly name = 'proc1';
|
|
1688
|
+
}
|
|
1689
|
+
```
|
|
1690
|
+
|
|
1691
|
+
#### 2. 错误处理
|
|
1692
|
+
|
|
1693
|
+
```typescript
|
|
1694
|
+
export class RobustAnnotationProcessor implements AnnotationProcessor {
|
|
1695
|
+
readonly name = 'RobustAnnotation';
|
|
1696
|
+
readonly priority = 10;
|
|
1697
|
+
|
|
1698
|
+
async process(
|
|
1699
|
+
ctx: Context,
|
|
1700
|
+
controller: any,
|
|
1701
|
+
methodName: string,
|
|
1702
|
+
annotationData: any,
|
|
1703
|
+
callParams: any[]
|
|
1704
|
+
): Promise<boolean> {
|
|
1705
|
+
try {
|
|
1706
|
+
// 主要逻辑
|
|
1707
|
+
return await this.executeMainLogic(ctx, controller, methodName, annotationData, callParams);
|
|
1708
|
+
|
|
1709
|
+
} catch (error) {
|
|
1710
|
+
// 记录错误但不中断流程
|
|
1711
|
+
logger.error(`[${this.name}] 处理失败:`, error);
|
|
1712
|
+
|
|
1713
|
+
// 根据配置决定是否中断
|
|
1714
|
+
if (annotationData?.strictMode) {
|
|
1715
|
+
ctx.status = 500;
|
|
1716
|
+
ctx.body = { error: 'Annotation processing failed' };
|
|
1717
|
+
return false;
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
return true; // 非严格模式下继续执行
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
private async executeMainLogic(
|
|
1725
|
+
ctx: Context,
|
|
1726
|
+
controller: any,
|
|
1727
|
+
methodName: string,
|
|
1728
|
+
annotationData: any,
|
|
1729
|
+
callParams: any[]
|
|
1730
|
+
): Promise<boolean> {
|
|
1731
|
+
// 实现主要逻辑
|
|
1732
|
+
return true;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
```
|
|
1736
|
+
|
|
1737
|
+
#### 3. 性能优化
|
|
1738
|
+
|
|
1739
|
+
```typescript
|
|
1740
|
+
export class OptimizedAnnotationProcessor implements AnnotationProcessor {
|
|
1741
|
+
readonly name = 'OptimizedAnnotation';
|
|
1742
|
+
readonly priority = 10;
|
|
1743
|
+
|
|
1744
|
+
private cache = new Map<string, any>();
|
|
1745
|
+
private metrics = new Map<string, number>();
|
|
1746
|
+
|
|
1747
|
+
async process(
|
|
1748
|
+
ctx: Context,
|
|
1749
|
+
controller: any,
|
|
1750
|
+
methodName: string,
|
|
1751
|
+
annotationData: any,
|
|
1752
|
+
callParams: any[]
|
|
1753
|
+
): Promise<boolean> {
|
|
1754
|
+
const startTime = Date.now();
|
|
1755
|
+
|
|
1756
|
+
try {
|
|
1757
|
+
// 使用缓存避免重复计算
|
|
1758
|
+
const cacheKey = this.generateCacheKey(methodName, annotationData);
|
|
1759
|
+
let result = this.cache.get(cacheKey);
|
|
1760
|
+
|
|
1761
|
+
if (!result) {
|
|
1762
|
+
result = await this.computeResult(annotationData);
|
|
1763
|
+
this.cache.set(cacheKey, result);
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
// 记录性能指标
|
|
1767
|
+
const duration = Date.now() - startTime;
|
|
1768
|
+
this.recordMetric(methodName, duration);
|
|
1769
|
+
|
|
1770
|
+
return result;
|
|
1771
|
+
|
|
1772
|
+
} catch (error) {
|
|
1773
|
+
logger.error(`[${this.name}] 处理失败:`, error);
|
|
1774
|
+
return true;
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
private generateCacheKey(methodName: string, data: any): string {
|
|
1779
|
+
return `${methodName}_${JSON.stringify(data)}`;
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
private async computeResult(data: any): Promise<boolean> {
|
|
1783
|
+
// 模拟计算密集型操作
|
|
1784
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
1785
|
+
return true;
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
private recordMetric(methodName: string, duration: number): void {
|
|
1789
|
+
const current = this.metrics.get(methodName) || 0;
|
|
1790
|
+
this.metrics.set(methodName, current + duration);
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
// 定期清理缓存
|
|
1794
|
+
startCleanupTimer(): void {
|
|
1795
|
+
setInterval(() => {
|
|
1796
|
+
this.cache.clear();
|
|
1797
|
+
logger.info(`[${this.name}] 缓存已清理`);
|
|
1798
|
+
}, 300000); // 5分钟
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
```
|
|
1802
|
+
|
|
1803
|
+
### 🔍 调试技巧
|
|
1804
|
+
|
|
1805
|
+
#### 1. 启用调试模式
|
|
1806
|
+
|
|
1807
|
+
```typescript
|
|
1808
|
+
export class DebuggableAnnotationProcessor implements AnnotationProcessor {
|
|
1809
|
+
readonly name = 'DebuggableAnnotation';
|
|
1810
|
+
readonly priority = 10;
|
|
1811
|
+
|
|
1812
|
+
private debugMode = process.env.ANNOTATION_DEBUG === 'true';
|
|
1813
|
+
|
|
1814
|
+
async process(
|
|
1815
|
+
ctx: Context,
|
|
1816
|
+
controller: any,
|
|
1817
|
+
methodName: string,
|
|
1818
|
+
annotationData: any,
|
|
1819
|
+
callParams: any[]
|
|
1820
|
+
): Promise<boolean> {
|
|
1821
|
+
if (this.debugMode) {
|
|
1822
|
+
console.log(`[DEBUG] ${this.name} 开始处理:`, {
|
|
1823
|
+
controller: controller.constructor.name,
|
|
1824
|
+
method: methodName,
|
|
1825
|
+
data: annotationData,
|
|
1826
|
+
params: callParams
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
// 主要逻辑
|
|
1831
|
+
const result = await this.executeLogic(ctx, controller, methodName, annotationData, callParams);
|
|
1832
|
+
|
|
1833
|
+
if (this.debugMode) {
|
|
1834
|
+
console.log(`[DEBUG] ${this.name} 处理完成:`, { result });
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
return result;
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
private async executeLogic(
|
|
1841
|
+
ctx: Context,
|
|
1842
|
+
controller: any,
|
|
1843
|
+
methodName: string,
|
|
1844
|
+
annotationData: any,
|
|
1845
|
+
callParams: any[]
|
|
1846
|
+
): Promise<boolean> {
|
|
1847
|
+
// 实现逻辑
|
|
1848
|
+
return true;
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
```
|
|
1852
|
+
|
|
1853
|
+
#### 2. 性能分析
|
|
1854
|
+
|
|
1855
|
+
```typescript
|
|
1856
|
+
export class ProfiledAnnotationProcessor implements AnnotationProcessor {
|
|
1857
|
+
readonly name = 'ProfiledAnnotation';
|
|
1858
|
+
readonly priority = 10;
|
|
1859
|
+
|
|
1860
|
+
private profileData: Map<string, { count: number; totalTime: number; avgTime: number }> = new Map();
|
|
1861
|
+
|
|
1862
|
+
async process(
|
|
1863
|
+
ctx: Context,
|
|
1864
|
+
controller: any,
|
|
1865
|
+
methodName: string,
|
|
1866
|
+
annotationData: any,
|
|
1867
|
+
callParams: any[]
|
|
1868
|
+
): Promise<boolean> {
|
|
1869
|
+
const startTime = process.hrtime.bigint();
|
|
1870
|
+
|
|
1871
|
+
try {
|
|
1872
|
+
const result = await this.executeLogic(ctx, controller, methodName, annotationData, callParams);
|
|
1873
|
+
|
|
1874
|
+
// 记录性能数据
|
|
1875
|
+
const endTime = process.hrtime.bigint();
|
|
1876
|
+
const duration = Number(endTime - startTime) / 1000000; // 转换为毫秒
|
|
1877
|
+
|
|
1878
|
+
this.recordProfile(methodName, duration);
|
|
1879
|
+
|
|
1880
|
+
return result;
|
|
1881
|
+
|
|
1882
|
+
} catch (error) {
|
|
1883
|
+
logger.error(`[${this.name}] 处理失败:`, error);
|
|
1884
|
+
return true;
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
private recordProfile(methodName: string, duration: number): void {
|
|
1889
|
+
const current = this.profileData.get(methodName) || { count: 0, totalTime: 0, avgTime: 0 };
|
|
1890
|
+
|
|
1891
|
+
current.count++;
|
|
1892
|
+
current.totalTime += duration;
|
|
1893
|
+
current.avgTime = current.totalTime / current.count;
|
|
1894
|
+
|
|
1895
|
+
this.profileData.set(methodName, current);
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
getProfileData(): Map<string, any> {
|
|
1899
|
+
return new Map(this.profileData);
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
printProfileReport(): void {
|
|
1903
|
+
console.log('\n=== 注解性能分析报告 ===');
|
|
1904
|
+
this.profileData.forEach((data, methodName) => {
|
|
1905
|
+
console.log(`${methodName}:`, {
|
|
1906
|
+
调用次数: data.count,
|
|
1907
|
+
总耗时: `${data.totalTime.toFixed(2)}ms`,
|
|
1908
|
+
平均耗时: `${data.avgTime.toFixed(2)}ms`
|
|
1909
|
+
});
|
|
1910
|
+
});
|
|
1911
|
+
console.log('========================\n');
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
```
|
|
1915
|
+
|
|
1916
|
+
### 📖 完整示例
|
|
1917
|
+
|
|
1918
|
+
#### 业务注解示例:数据加密注解
|
|
1919
|
+
|
|
1920
|
+
```typescript
|
|
1921
|
+
// 1. 配置接口
|
|
1922
|
+
export interface DataEncryptionConfig {
|
|
1923
|
+
enabled?: boolean;
|
|
1924
|
+
algorithm?: 'AES' | 'RSA' | 'DES';
|
|
1925
|
+
key?: string;
|
|
1926
|
+
fields?: string[];
|
|
1927
|
+
encryptRequest?: boolean;
|
|
1928
|
+
encryptResponse?: boolean;
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
// 2. 注解处理器
|
|
1932
|
+
export class DataEncryptionProcessor implements AnnotationProcessor {
|
|
1933
|
+
readonly name = 'DataEncryption';
|
|
1934
|
+
readonly priority = 5;
|
|
1935
|
+
|
|
1936
|
+
private encryptionService: EncryptionService;
|
|
1937
|
+
|
|
1938
|
+
constructor() {
|
|
1939
|
+
this.encryptionService = new EncryptionService();
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
async process(
|
|
1943
|
+
ctx: Context,
|
|
1944
|
+
controller: any,
|
|
1945
|
+
methodName: string,
|
|
1946
|
+
annotationData: DataEncryptionConfig,
|
|
1947
|
+
callParams: any[]
|
|
1948
|
+
): Promise<boolean> {
|
|
1949
|
+
if (!annotationData.enabled) return true;
|
|
1950
|
+
|
|
1951
|
+
try {
|
|
1952
|
+
// 加密请求数据
|
|
1953
|
+
if (annotationData.encryptRequest) {
|
|
1954
|
+
await this.encryptRequestData(ctx, annotationData);
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
return true;
|
|
1958
|
+
} catch (error) {
|
|
1959
|
+
logger.error(`[${this.name}] 加密失败:`, error);
|
|
1960
|
+
return false;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
async postProcess(
|
|
1965
|
+
ctx: Context,
|
|
1966
|
+
controller: any,
|
|
1967
|
+
methodName: string,
|
|
1968
|
+
response: any
|
|
1969
|
+
): Promise<void> {
|
|
1970
|
+
const annotationData = this.getAnnotationData(ctx);
|
|
1971
|
+
if (!annotationData?.enabled) return;
|
|
1972
|
+
|
|
1973
|
+
try {
|
|
1974
|
+
// 加密响应数据
|
|
1975
|
+
if (annotationData.encryptResponse) {
|
|
1976
|
+
await this.encryptResponseData(ctx, response, annotationData);
|
|
1977
|
+
}
|
|
1978
|
+
} catch (error) {
|
|
1979
|
+
logger.error(`[${this.name}] 响应加密失败:`, error);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
private async encryptRequestData(ctx: Context, config: DataEncryptionConfig): Promise<void> {
|
|
1984
|
+
if (ctx.request.body && config.fields) {
|
|
1985
|
+
for (const field of config.fields) {
|
|
1986
|
+
if (ctx.request.body[field]) {
|
|
1987
|
+
ctx.request.body[field] = await this.encryptionService.encrypt(
|
|
1988
|
+
ctx.request.body[field],
|
|
1989
|
+
config.algorithm || 'AES',
|
|
1990
|
+
config.key
|
|
1991
|
+
);
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
private async encryptResponseData(
|
|
1998
|
+
ctx: Context,
|
|
1999
|
+
response: any,
|
|
2000
|
+
config: DataEncryptionConfig
|
|
2001
|
+
): Promise<void> {
|
|
2002
|
+
if (response && config.fields) {
|
|
2003
|
+
for (const field of config.fields) {
|
|
2004
|
+
if (response[field]) {
|
|
2005
|
+
response[field] = await this.encryptionService.encrypt(
|
|
2006
|
+
response[field],
|
|
2007
|
+
config.algorithm || 'AES',
|
|
2008
|
+
config.key
|
|
2009
|
+
);
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
private getAnnotationData(ctx: Context): DataEncryptionConfig | null {
|
|
2016
|
+
// 从上下文中获取注解数据
|
|
2017
|
+
return ctx.state.annotationData || null;
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
// 3. 装饰器
|
|
2022
|
+
export function DataEncryption(config?: DataEncryptionConfig) {
|
|
2023
|
+
return createAnnotationDecorator('DataEncryption')(config);
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
// 4. 使用示例
|
|
2027
|
+
export class SecureController {
|
|
2028
|
+
@Post('/secure/data')
|
|
2029
|
+
@DataEncryption({
|
|
2030
|
+
enabled: true,
|
|
2031
|
+
algorithm: 'AES',
|
|
2032
|
+
fields: ['password', 'ssn'],
|
|
2033
|
+
encryptRequest: true,
|
|
2034
|
+
encryptResponse: true
|
|
2035
|
+
})
|
|
2036
|
+
@Logging()
|
|
2037
|
+
async handleSecureData(@Body() data: any) {
|
|
2038
|
+
return {
|
|
2039
|
+
message: 'Data processed securely',
|
|
2040
|
+
data: data
|
|
2041
|
+
};
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
```
|
|
2045
|
+
|
|
2046
|
+
通过以上完整的自定义注解开发指南,开发者可以:
|
|
2047
|
+
|
|
2048
|
+
1. **理解注解系统架构**:掌握注解处理器的工作原理
|
|
2049
|
+
2. **开发自定义注解**:从需求分析到实现部署的完整流程
|
|
2050
|
+
3. **应用最佳实践**:性能优化、错误处理、测试等
|
|
2051
|
+
4. **解决实际问题**:通过实际业务场景的注解开发
|
|
2052
|
+
|
|
2053
|
+
这套开发指南为企业级注解系统的扩展提供了坚实的基础!
|
|
2054
|
+
|
|
2055
|
+
## 🎉 总结
|
|
2056
|
+
|
|
2057
|
+
企业级注解系统提供了完整的企业级应用支持,包括:
|
|
2058
|
+
|
|
2059
|
+
- **🔧 完整的监控体系**: 性能、安全、追踪、配置
|
|
2060
|
+
- **🛡️ 企业级安全**: 审计、合规、风险评估
|
|
2061
|
+
- **📊 可观测性**: 指标、日志、追踪三位一体
|
|
2062
|
+
- **⚙️ 配置管理**: 动态配置、环境管理、验证
|
|
2063
|
+
- **🚀 高性能**: 优化的执行性能和资源使用
|
|
2064
|
+
- **📝 类型安全**: 完整的 TypeScript 支持
|
|
2065
|
+
- **🔍 易于调试**: 丰富的调试工具和日志
|
|
2066
|
+
|
|
2067
|
+
通过合理使用这些注解,可以构建出符合企业级标准的应用程序,满足现代企业对可观测性、安全性和可维护性的要求。
|
|
2068
|
+
|
|
2069
|
+
|