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,466 @@
|
|
|
1
|
+
# Service 层返回值规范
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
本文档定义了 Service 层的标准返回值规范,确保所有 Service 方法遵循统一的返回格式。
|
|
6
|
+
|
|
7
|
+
## 核心返回类型:CommonServiceResult<T>
|
|
8
|
+
|
|
9
|
+
所有 Service 方法必须返回 `CommonServiceResult<T>` 对象,其中 `T` 是实际返回的数据类型。
|
|
10
|
+
|
|
11
|
+
### 结构定义
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
class CommonServiceResult<T> {
|
|
15
|
+
code: CommonServiceResultCode; // 状态码
|
|
16
|
+
data: T | null; // 返回数据
|
|
17
|
+
message?: string; // 提示消息
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 状态码枚举
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
enum CommonServiceResultCode {
|
|
25
|
+
SUCCESS = "SUCCESS", // 成功
|
|
26
|
+
FAIL = "FAIL", // 失败
|
|
27
|
+
ERROR = "ERROR", // 错误
|
|
28
|
+
NOT_FOUND = "NOT_FOUND", // 未找到
|
|
29
|
+
VALIDATION_ERROR = "VALIDATION_ERROR", // 验证错误
|
|
30
|
+
UNAUTHORIZED = "UNAUTHORIZED", // 未授权
|
|
31
|
+
FORBIDDEN = "FORBIDDEN", // 禁止访问
|
|
32
|
+
CONFLICT = "CONFLICT", // 冲突
|
|
33
|
+
TIMEOUT = "TIMEOUT", // 超时
|
|
34
|
+
RATE_LIMITED = "RATE_LIMITED", // 限流
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 使用方式
|
|
39
|
+
|
|
40
|
+
### 1. 静态工厂方法(推荐)
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { CommonServiceResult, CommonServiceResultCode } from '@src/framework/types/ServiceResult';
|
|
44
|
+
|
|
45
|
+
// 创建成功结果
|
|
46
|
+
const result = CommonServiceResult.success(user, "用户创建成功");
|
|
47
|
+
|
|
48
|
+
// 创建失败结果
|
|
49
|
+
const result = CommonServiceResult.fail(
|
|
50
|
+
CommonServiceResultCode.NOT_FOUND,
|
|
51
|
+
"用户不存在"
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
// 创建验证错误
|
|
55
|
+
const result = CommonServiceResult.validationError("邮箱格式不正确");
|
|
56
|
+
|
|
57
|
+
// 创建未找到结果
|
|
58
|
+
const result = CommonServiceResult.notFound("用户不存在");
|
|
59
|
+
|
|
60
|
+
// 创建未授权结果
|
|
61
|
+
const result = CommonServiceResult.unauthorized("密码错误");
|
|
62
|
+
|
|
63
|
+
// 创建禁止访问结果
|
|
64
|
+
const result = CommonServiceResult.forbidden("用户已被禁用");
|
|
65
|
+
|
|
66
|
+
// 创建冲突结果
|
|
67
|
+
const result = CommonServiceResult.conflict("邮箱已被使用");
|
|
68
|
+
|
|
69
|
+
// 创建服务器错误
|
|
70
|
+
const result = CommonServiceResult.error("创建用户时发生错误");
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 2. 构造方法
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// 使用构造函数
|
|
77
|
+
const result = new CommonServiceResult(
|
|
78
|
+
CommonServiceResultCode.SUCCESS,
|
|
79
|
+
user,
|
|
80
|
+
"用户创建成功"
|
|
81
|
+
);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 3. 常用结果类型
|
|
85
|
+
|
|
86
|
+
#### 成功结果
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
// 成功返回数据
|
|
90
|
+
return CommonServiceResult.success(user);
|
|
91
|
+
// 或
|
|
92
|
+
return CommonServiceResult.success(user, "操作成功");
|
|
93
|
+
|
|
94
|
+
// 返回类型
|
|
95
|
+
Promise<CommonServiceResult<UserEntity>>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### 验证错误
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
return CommonServiceResult.validationError("邮箱格式不正确");
|
|
102
|
+
return CommonServiceResult.validationError("密码长度不能少于6个字符", null);
|
|
103
|
+
|
|
104
|
+
// 返回类型
|
|
105
|
+
Promise<CommonServiceResult<UserEntity | null>>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### 资源未找到
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
return CommonServiceResult.notFound("用户不存在");
|
|
112
|
+
return CommonServiceResult.notFound("订单不存在", null);
|
|
113
|
+
|
|
114
|
+
// 返回类型
|
|
115
|
+
Promise<CommonServiceResult<UserEntity | null>>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### 权限错误
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// 未授权
|
|
122
|
+
return CommonServiceResult.unauthorized("密码错误");
|
|
123
|
+
|
|
124
|
+
// 禁止访问
|
|
125
|
+
return CommonServiceResult.forbidden("账户已被禁用");
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### 资源冲突
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
return CommonServiceResult.conflict("邮箱已被使用");
|
|
132
|
+
return CommonServiceResult.conflict("手机号已被注册");
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### 服务器错误
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
return CommonServiceResult.error("创建用户时发生错误");
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## 完整示例
|
|
142
|
+
|
|
143
|
+
### 示例 1:创建用户 Service
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { Injectable } from "dp-ioc";
|
|
147
|
+
import { CommonServiceResult } from '@src/framework/types/ServiceResult';
|
|
148
|
+
import { CreateUserDto } from '@src/dto/user.dto';
|
|
149
|
+
|
|
150
|
+
@Injectable()
|
|
151
|
+
export class YtUserService extends BaseService {
|
|
152
|
+
async createUser(dto: CreateUserDto): Promise<CommonServiceResult<UserEntity>> {
|
|
153
|
+
try {
|
|
154
|
+
// 1. 验证数据
|
|
155
|
+
if (!dto.email) {
|
|
156
|
+
return CommonServiceResult.validationError("邮箱不能为空");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// 2. 检查业务规则
|
|
160
|
+
const existingUser = await this.userRepository.findByEmail(dto.email);
|
|
161
|
+
if (existingUser) {
|
|
162
|
+
return CommonServiceResult.conflict("邮箱已被使用");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 3. 执行业务逻辑
|
|
166
|
+
const user = await this.userRepository.save({
|
|
167
|
+
...dto,
|
|
168
|
+
password: await bcrypt.hash(dto.password, 10)
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// 4. 返回成功
|
|
172
|
+
return CommonServiceResult.success(user, "用户创建成功");
|
|
173
|
+
|
|
174
|
+
} catch (error) {
|
|
175
|
+
logger.error("创建用户失败:", error);
|
|
176
|
+
return CommonServiceResult.error("创建用户时发生错误");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 示例 2:查找用户 Service
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
async getUserById(id: number): Promise<CommonServiceResult<UserEntity | null>> {
|
|
186
|
+
try {
|
|
187
|
+
const user = await this.userRepository.findById(id);
|
|
188
|
+
|
|
189
|
+
if (!user) {
|
|
190
|
+
return CommonServiceResult.notFound("用户不存在");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return CommonServiceResult.success(user);
|
|
194
|
+
} catch (error) {
|
|
195
|
+
logger.error("获取用户失败:", error);
|
|
196
|
+
return CommonServiceResult.error("获取用户时发生错误");
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 示例 3:更新用户 Service
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
async updateUser(
|
|
205
|
+
id: number,
|
|
206
|
+
dto: UpdateUserDto
|
|
207
|
+
): Promise<CommonServiceResult<UserEntity | null>> {
|
|
208
|
+
try {
|
|
209
|
+
// 检查用户是否存在
|
|
210
|
+
const existingUser = await this.userRepository.findById(id);
|
|
211
|
+
if (!existingUser) {
|
|
212
|
+
return CommonServiceResult.notFound("用户不存在");
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// 检查业务冲突
|
|
216
|
+
if (dto.email && dto.email !== existingUser.email) {
|
|
217
|
+
const userWithEmail = await this.userRepository.findByEmail(dto.email);
|
|
218
|
+
if (userWithEmail) {
|
|
219
|
+
return CommonServiceResult.conflict("邮箱已被其他用户使用");
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// 执行更新
|
|
224
|
+
await this.userRepository.update(id, dto);
|
|
225
|
+
const updatedUser = await this.userRepository.findById(id);
|
|
226
|
+
|
|
227
|
+
return CommonServiceResult.success(updatedUser, "用户更新成功");
|
|
228
|
+
} catch (error) {
|
|
229
|
+
logger.error("更新用户失败:", error);
|
|
230
|
+
return CommonServiceResult.error("更新用户时发生错误");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 示例 4:查询列表 Service
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
async getUsers(query: QueryUserDto): Promise<CommonServiceResult<[UserEntity[], number]>> {
|
|
239
|
+
try {
|
|
240
|
+
const [users, total] = await this.userRepository.findAndCount(query);
|
|
241
|
+
|
|
242
|
+
return CommonServiceResult.success([users, total]);
|
|
243
|
+
} catch (error) {
|
|
244
|
+
logger.error("查询用户列表失败:", error);
|
|
245
|
+
return CommonServiceResult.error("查询用户列表时发生错误");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Controller 层的处理
|
|
251
|
+
|
|
252
|
+
### 标准处理模式
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
@Post('/users')
|
|
256
|
+
async createUser(ctx: Context) {
|
|
257
|
+
const dto = ctx.request.body;
|
|
258
|
+
const result = await userService.createUser(dto);
|
|
259
|
+
|
|
260
|
+
if (result.isSuccess()) {
|
|
261
|
+
ctx.status = 200;
|
|
262
|
+
ctx.body = {
|
|
263
|
+
code: 0,
|
|
264
|
+
message: result.message,
|
|
265
|
+
data: result.data
|
|
266
|
+
};
|
|
267
|
+
} else {
|
|
268
|
+
// 根据不同的错误码返回不同的 HTTP 状态码
|
|
269
|
+
ctx.status = this.getHttpStatus(result.code);
|
|
270
|
+
ctx.body = {
|
|
271
|
+
code: this.getHttpCode(result.code),
|
|
272
|
+
message: result.message || result.getErrorMessage(),
|
|
273
|
+
data: result.data
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
private getHttpStatus(code: CommonServiceResultCode): number {
|
|
279
|
+
const statusMap = {
|
|
280
|
+
[CommonServiceResultCode.SUCCESS]: 200,
|
|
281
|
+
[CommonServiceResultCode.VALIDATION_ERROR]: 400,
|
|
282
|
+
[CommonServiceResultCode.UNAUTHORIZED]: 401,
|
|
283
|
+
[CommonServiceResultCode.FORBIDDEN]: 403,
|
|
284
|
+
[CommonServiceResultCode.NOT_FOUND]: 404,
|
|
285
|
+
[CommonServiceResultCode.CONFLICT]: 409,
|
|
286
|
+
[CommonServiceResultCode.ERROR]: 500,
|
|
287
|
+
};
|
|
288
|
+
return statusMap[code] || 500;
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### 简化处理模式
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
@Post('/users')
|
|
296
|
+
async createUser(ctx: Context) {
|
|
297
|
+
const dto = ctx.request.body;
|
|
298
|
+
const result = await userService.createUser(dto);
|
|
299
|
+
|
|
300
|
+
// 统一处理
|
|
301
|
+
ctx.status = result.isSuccess() ? 200 : 400;
|
|
302
|
+
ctx.body = {
|
|
303
|
+
success: result.isSuccess(),
|
|
304
|
+
data: result.data,
|
|
305
|
+
message: result.message
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## 状态码映射表
|
|
311
|
+
|
|
312
|
+
| Service 状态码 | HTTP 状态码 | 说明 |
|
|
313
|
+
|---------------|------------|------|
|
|
314
|
+
| SUCCESS | 200 | 操作成功 |
|
|
315
|
+
| VALIDATION_ERROR | 400 | 数据验证失败 |
|
|
316
|
+
| UNAUTHORIZED | 401 | 未授权 |
|
|
317
|
+
| FORBIDDEN | 403 | 禁止访问 |
|
|
318
|
+
| NOT_FOUND | 404 | 资源不存在 |
|
|
319
|
+
| CONFLICT | 409 | 资源冲突 |
|
|
320
|
+
| ERROR | 500 | 服务器错误 |
|
|
321
|
+
| TIMEOUT | 504 | 请求超时 |
|
|
322
|
+
| RATE_LIMITED | 429 | 请求过频 |
|
|
323
|
+
|
|
324
|
+
## 辅助方法
|
|
325
|
+
|
|
326
|
+
### isSuccess() / isFailure()
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
const result = await userService.createUser(dto);
|
|
330
|
+
|
|
331
|
+
if (result.isSuccess()) {
|
|
332
|
+
// 处理成功情况
|
|
333
|
+
console.log(result.data);
|
|
334
|
+
} else {
|
|
335
|
+
// 处理失败情况
|
|
336
|
+
console.error(result.message);
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### getErrorMessage()
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
const result = await userService.createUser(dto);
|
|
344
|
+
|
|
345
|
+
if (result.isFailure()) {
|
|
346
|
+
const errorMsg = result.getErrorMessage();
|
|
347
|
+
// 返回默认错误消息或自定义消息
|
|
348
|
+
console.error(errorMsg);
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## 最佳实践
|
|
353
|
+
|
|
354
|
+
### ✅ 推荐做法
|
|
355
|
+
|
|
356
|
+
1. **总是返回 CommonServiceResult**
|
|
357
|
+
```typescript
|
|
358
|
+
async createUser(dto: CreateUserDto): Promise<CommonServiceResult<UserEntity>> {
|
|
359
|
+
// ...
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
2. **使用工厂方法创建结果**
|
|
364
|
+
```typescript
|
|
365
|
+
return CommonServiceResult.success(user);
|
|
366
|
+
return CommonServiceResult.validationError("邮箱不能为空");
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
3. **提供有意义的错误消息**
|
|
370
|
+
```typescript
|
|
371
|
+
return CommonServiceResult.notFound("用户不存在");
|
|
372
|
+
// 而不是
|
|
373
|
+
return CommonServiceResult.notFound();
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
4. **统一处理异常**
|
|
377
|
+
```typescript
|
|
378
|
+
try {
|
|
379
|
+
// 业务逻辑
|
|
380
|
+
} catch (error) {
|
|
381
|
+
logger.error("操作失败:", error);
|
|
382
|
+
return CommonServiceResult.error("操作失败");
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### ❌ 避免的做法
|
|
387
|
+
|
|
388
|
+
1. **不要直接抛出异常**
|
|
389
|
+
```typescript
|
|
390
|
+
// 不好的做法
|
|
391
|
+
async createUser(dto: CreateUserDto) {
|
|
392
|
+
throw new Error("用户创建失败");
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// 好的做法
|
|
396
|
+
async createUser(dto: CreateUserDto): Promise<CommonServiceResult<UserEntity>> {
|
|
397
|
+
return CommonServiceResult.error("用户创建失败");
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
2. **不要返回 null 或 undefined**
|
|
402
|
+
```typescript
|
|
403
|
+
// 不好的做法
|
|
404
|
+
async getUser(id: number) {
|
|
405
|
+
const user = await this.repository.findById(id);
|
|
406
|
+
return user; // 可能返回 null
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// 好的做法
|
|
410
|
+
async getUser(id: number): Promise<CommonServiceResult<UserEntity | null>> {
|
|
411
|
+
const user = await this.repository.findById(id);
|
|
412
|
+
if (!user) {
|
|
413
|
+
return CommonServiceResult.notFound("用户不存在");
|
|
414
|
+
}
|
|
415
|
+
return CommonServiceResult.success(user);
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
3. **不要混合不同的返回类型**
|
|
420
|
+
```typescript
|
|
421
|
+
// 不好的做法
|
|
422
|
+
async getUser(id: number) {
|
|
423
|
+
if (!id) return null;
|
|
424
|
+
const user = await this.repository.findById(id);
|
|
425
|
+
return user;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// 好的做法
|
|
429
|
+
async getUser(id: number): Promise<CommonServiceResult<UserEntity | null>> {
|
|
430
|
+
// 所有路径都返回 CommonServiceResult
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
## 类型安全
|
|
435
|
+
|
|
436
|
+
使用泛型确保类型安全:
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
// 返回单个实体
|
|
440
|
+
Promise<CommonServiceResult<UserEntity>>
|
|
441
|
+
|
|
442
|
+
// 返回实体或 null
|
|
443
|
+
Promise<CommonServiceResult<UserEntity | null>>
|
|
444
|
+
|
|
445
|
+
// 返回列表
|
|
446
|
+
Promise<CommonServiceResult<UserEntity[]>>
|
|
447
|
+
|
|
448
|
+
// 返回元组 [data, total]
|
|
449
|
+
Promise<CommonServiceResult<[UserEntity[], number]>>
|
|
450
|
+
|
|
451
|
+
// 返回布尔值
|
|
452
|
+
Promise<CommonServiceResult<boolean>>
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## 总结
|
|
456
|
+
|
|
457
|
+
- ✅ 所有 Service 方法必须返回 `CommonServiceResult<T>`
|
|
458
|
+
- ✅ 使用静态工厂方法创建结果(推荐)
|
|
459
|
+
- ✅ 提供有意义的错误消息
|
|
460
|
+
- ✅ 正确处理异常
|
|
461
|
+
- ✅ Controller 层统一处理返回结果
|
|
462
|
+
- ✅ 保持类型安全
|
|
463
|
+
|
|
464
|
+
遵循这些规范可以确保代码的一致性、可维护性和可读性。
|
|
465
|
+
|
|
466
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Swagger 调试模式配置指南
|
|
2
|
+
|
|
3
|
+
## 🎯 调试模式特点
|
|
4
|
+
|
|
5
|
+
当你使用 VS Code 调试模式时:
|
|
6
|
+
- 使用 `ts-node` 直接运行 TypeScript 源码
|
|
7
|
+
- 不需要编译步骤
|
|
8
|
+
- 支持热重载和断点调试
|
|
9
|
+
- 环境变量在 `launch.json` 中配置
|
|
10
|
+
|
|
11
|
+
## 🔧 当前配置
|
|
12
|
+
|
|
13
|
+
### VS Code 调试配置
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"name": "Debug TS Server",
|
|
17
|
+
"env": {
|
|
18
|
+
"NODE_ENV": "development",
|
|
19
|
+
"USE_NEW_ANNOTATION_SYSTEM": "1",
|
|
20
|
+
"db_memory": "1",
|
|
21
|
+
"db_enable": "1",
|
|
22
|
+
"SWAGGER_ROUTE_PREFIX": "/swagger/b" // 新增
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Swagger 路径检测逻辑
|
|
28
|
+
1. **优先使用环境变量** - `SWAGGER_ROUTE_PREFIX`
|
|
29
|
+
2. **自动检测路由前缀** - 从实际路由注册中获取
|
|
30
|
+
3. **默认值回退** - `/swagger/b`
|
|
31
|
+
|
|
32
|
+
## 📋 修改 bindRouter 路径的调试模式流程
|
|
33
|
+
|
|
34
|
+
### 方法1:修改环境变量(推荐)
|
|
35
|
+
1. **修改 `.vscode/launch.json`**:
|
|
36
|
+
```json
|
|
37
|
+
"SWAGGER_ROUTE_PREFIX": "/your/new/path"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. **重新启动调试**:
|
|
41
|
+
- 停止当前调试会话
|
|
42
|
+
- 重新启动调试(F5)
|
|
43
|
+
|
|
44
|
+
3. **验证更新**:
|
|
45
|
+
- 访问 http://127.0.0.1:3000/swagger.json
|
|
46
|
+
- 检查路径是否已更新
|
|
47
|
+
|
|
48
|
+
### 方法2:修改默认值
|
|
49
|
+
1. **修改 `src/framework/utils/dynamicSwagger.ts`**:
|
|
50
|
+
```typescript
|
|
51
|
+
const defaultPrefix = '/your/new/path';
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
2. **重新启动调试**
|
|
55
|
+
|
|
56
|
+
## 🎯 当前 Swagger 路径
|
|
57
|
+
|
|
58
|
+
基于当前配置,Swagger UI 应该显示:
|
|
59
|
+
- **GET** `/swagger/b/user/list` - 获取用户列表
|
|
60
|
+
- **GET** `/swagger/b/user/{id}` - 获取用户详情
|
|
61
|
+
- **POST** `/swagger/b/user` - 创建用户
|
|
62
|
+
- **PUT** `/swagger/b/user/{id}` - 更新用户
|
|
63
|
+
- **DELETE** `/swagger/b/user/{id}` - 删除用户
|
|
64
|
+
|
|
65
|
+
## 🔍 调试信息
|
|
66
|
+
|
|
67
|
+
启动调试时,查看控制台日志:
|
|
68
|
+
```
|
|
69
|
+
使用环境变量中的 Swagger 路径前缀: /swagger/b
|
|
70
|
+
动态生成 Swagger 规范成功,包含 5 个路由
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 💡 最佳实践
|
|
74
|
+
|
|
75
|
+
1. **使用环境变量** - 便于不同环境配置
|
|
76
|
+
2. **保持同步** - 确保 `bindRouter` 路径与环境变量一致
|
|
77
|
+
3. **验证更新** - 每次修改后检查 Swagger UI
|
|
78
|
+
4. **日志监控** - 关注控制台的 Swagger 相关日志
|
|
79
|
+
|
|
80
|
+
|