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.
Files changed (235) hide show
  1. package/README.md +50 -0
  2. package/index.mjs +97 -0
  3. package/package.json +33 -0
  4. package/template/.env.development +9 -0
  5. package/template/.env.production +12 -0
  6. package/template/.github/workflows/ci-cd.yml +182 -0
  7. package/template/.trae/documents/controller_development_plan.md +386 -0
  8. package/template/.trae/skills/00-backend-core.skill.md +50 -0
  9. package/template/.trae/skills/01-backend-skill-router.skill.md +55 -0
  10. package/template/.trae/skills/10-backend-api.skill.md +54 -0
  11. package/template/.trae/skills/11-backend-controller-recipes.skill.md +107 -0
  12. package/template/.trae/skills/20-backend-repository.skill.md +25 -0
  13. package/template/.trae/skills/21-backend-service.skill.md +135 -0
  14. package/template/.trae/skills/25-backend-comments-and-doc.skill.md +97 -0
  15. package/template/.trae/skills/30-backend-validation.skill.md +320 -0
  16. package/template/.trae/skills/40-backend-error-logging.skill.md +21 -0
  17. package/template/.trae/skills/50-backend-bootstrap-lifecycle.skill.md +90 -0
  18. package/template/.trae/skills/60-backend-router-registration.skill.md +71 -0
  19. package/template/.trae/skills/70-backend-middleware.skill.md +98 -0
  20. package/template/.trae/skills/80-backend-utils-and-libs.skill.md +90 -0
  21. package/template/.trae/skills/85-backend-plugins.rule.md +64 -0
  22. package/template/.trae/skills/90-backend-testing.skill.md +29 -0
  23. package/template/.trae/skills/README.md +49 -0
  24. package/template/.vscode/launch.json +38 -0
  25. package/template/.vscode/settings.json +1 -0
  26. package/template/Dockerfile +36 -0
  27. package/template/README.md +229 -0
  28. package/template/docker-compose.yml +135 -0
  29. package/template/docs/API_DOCUMENTATION.md +837 -0
  30. package/template/docs/ARCHITECTURE_REFACTOR.md +109 -0
  31. package/template/docs/CACHE_MIGRATION_GUIDE.md +142 -0
  32. package/template/docs/DEPLOYMENT_GUIDE.md +1062 -0
  33. package/template/docs/DEVELOPMENT_GUIDE.md +1097 -0
  34. package/template/docs/DOCUMENTATION_CLEANUP_REPORT.md +166 -0
  35. package/template/docs/DOCUMENTATION_COMPLETION_REPORT.md +223 -0
  36. package/template/docs/DOCUMENTATION_INDEX.md +294 -0
  37. package/template/docs/DOCUMENTATION_STRUCTURE.md +221 -0
  38. package/template/docs/ENTERPRISE_ANNOTATION_SYSTEM_GUIDE.md +2069 -0
  39. package/template/docs/ENTERPRISE_DATABASE_ARCHITECTURE.md +318 -0
  40. package/template/docs/ENTERPRISE_DEPLOYMENT_GUIDE.md +547 -0
  41. package/template/docs/ENTERPRISE_ERROR_HANDLING_GUIDE.md +357 -0
  42. package/template/docs/ENTERPRISE_LOGGING_SYSTEM_GUIDE.md +494 -0
  43. package/template/docs/ENVIRONMENT_CONFIG_EXAMPLE.md +69 -0
  44. package/template/docs/FINAL_IMPLEMENTATION_SUMMARY.md +206 -0
  45. package/template/docs/HEALTH_CHECK_ROUTE_FIX.md +134 -0
  46. package/template/docs/IMPLEMENTATION_CHECKLIST.md +204 -0
  47. package/template/docs/INSTALLATION_GUIDE.md +611 -0
  48. package/template/docs/INTERCEPTOR_TESTING_REPORT.md +226 -0
  49. package/template/docs/INTERCEPTOR_TESTING_SCRIPTS.md +143 -0
  50. package/template/docs/LOGGING_OPTIMIZATION_GUIDE.md +126 -0
  51. package/template/docs/MEMORY_DATABASE_GUIDE.md +212 -0
  52. package/template/docs/NEW_ROUTER_INTEGRATION_GUIDE.md +345 -0
  53. package/template/docs/NEW_ROUTER_INTEGRATION_SUMMARY.md +259 -0
  54. package/template/docs/NEW_ROUTER_USAGE_GUIDE.md +364 -0
  55. package/template/docs/QUICK_START.md +268 -0
  56. package/template/docs/ROUTE_SLASH_COMPATIBILITY_FIX.md +191 -0
  57. package/template/docs/SERVICE_INTERCEPTOR_GUIDE.md +243 -0
  58. package/template/docs/SERVICE_LAYER_INDEX.md +205 -0
  59. package/template/docs/SERVICE_PATTERN_GUIDE.md +270 -0
  60. package/template/docs/SERVICE_RETURN_VALUE_SPECIFICATION.md +466 -0
  61. package/template/docs/SWAGGER_DEBUG_MODE_GUIDE.md +80 -0
  62. package/template/docs/SWAGGER_INTEGRATION_GUIDE.md +416 -0
  63. package/template/docs/TRANSACTION_MANAGER_USAGE.md +360 -0
  64. package/template/docs/TROUBLESHOOTING.md +869 -0
  65. package/template/env.production.example +62 -0
  66. package/template/jest.config.js +34 -0
  67. package/template/package-lock.json +13240 -0
  68. package/template/package.json +119 -0
  69. package/template/patches/typeorm+0.3.25.patch +22 -0
  70. package/template/scripts/sync-template.mjs +84 -0
  71. package/template/scripts/test-annotation-system.sh +48 -0
  72. package/template/scripts/test-core-functionality.sh +28 -0
  73. package/template/src/annotations/decorators/ConfigManagement.ts +9 -0
  74. package/template/src/annotations/decorators/DistributedTracing.ts +9 -0
  75. package/template/src/annotations/decorators/EnterprisePerformance.ts +9 -0
  76. package/template/src/annotations/decorators/PerformanceMonitor.ts +32 -0
  77. package/template/src/annotations/decorators/SecurityAudit.ts +9 -0
  78. package/template/src/annotations/index.ts +50 -0
  79. package/template/src/annotations/processors/ConfigManagementProcessor.ts +369 -0
  80. package/template/src/annotations/processors/DistributedTracingProcessor.ts +288 -0
  81. package/template/src/annotations/processors/EnterprisePerformanceProcessor.ts +189 -0
  82. package/template/src/annotations/processors/PerformanceMonitorProcessor.ts +101 -0
  83. package/template/src/annotations/processors/SecurityAuditProcessor.ts +345 -0
  84. package/template/src/annotations/processors/SwaggerProcessor.ts +612 -0
  85. package/template/src/annotations/processors/index.ts +10 -0
  86. package/template/src/app.ts +123 -0
  87. package/template/src/controllers/base.controller.ts +41 -0
  88. package/template/src/controllers/cacheManagement.controller.ts +131 -0
  89. package/template/src/controllers/captcha.controller.ts +57 -0
  90. package/template/src/controllers/demo/AnnotationDemoController.ts +118 -0
  91. package/template/src/controllers/example/EnterpriseExampleController.ts +297 -0
  92. package/template/src/controllers/example/ExampleController.ts +110 -0
  93. package/template/src/controllers/example/NewAnnotationExampleController.ts +159 -0
  94. package/template/src/controllers/example/SwaggerExampleController.ts +205 -0
  95. package/template/src/controllers/example/TransactionExample.controller.ts +336 -0
  96. package/template/src/controllers/health.controller.ts +235 -0
  97. package/template/src/controllers/home/register.controller.ts +58 -0
  98. package/template/src/controllers/home/ytGoods.controller.ts +92 -0
  99. package/template/src/controllers/home/ytShop.controller.ts +135 -0
  100. package/template/src/controllers/home/ytUser.controller.ts +89 -0
  101. package/template/src/controllers/logManagement.controller.ts +396 -0
  102. package/template/src/controllers/public/emailSend.controller.ts +65 -0
  103. package/template/src/controllers/public/ytUserAuth.controller.ts +174 -0
  104. package/template/src/controllers/testData.controller.ts +253 -0
  105. package/template/src/dto/controller/example/NewAnnotationExampleController.dto.ts +73 -0
  106. package/template/src/dto/controller/home/emailSend.controller.dto.ts +40 -0
  107. package/template/src/dto/controller/home/register.controller.dto.ts +45 -0
  108. package/template/src/dto/controller/home/ytGoods.controller.dto.ts +55 -0
  109. package/template/src/dto/controller/home/ytShop.controller.dto.ts +69 -0
  110. package/template/src/dto/controller/home/ytUser.controller.dto.ts +44 -0
  111. package/template/src/dto/controller/public/ytUserAuth.controller.dto.ts +63 -0
  112. package/template/src/dto/goods.dto.ts +212 -0
  113. package/template/src/dto/service/ytService.dto.ts +13 -0
  114. package/template/src/dto/user.dto.ts +177 -0
  115. package/template/src/entity/base.entity.ts +13 -0
  116. package/template/src/entity/columnTypes.ts +13 -0
  117. package/template/src/entity/goodsImagesUnlockKey.entity.ts +33 -0
  118. package/template/src/entity/goodsUnlocker.entity.ts +34 -0
  119. package/template/src/entity/index.ts +15 -0
  120. package/template/src/entity/shop.entity.ts +52 -0
  121. package/template/src/entity/shopUser.entity.ts +41 -0
  122. package/template/src/entity/ytGoods.entity.ts +94 -0
  123. package/template/src/entity/ytUser.entity.ts +96 -0
  124. package/template/src/examples/InterceptorExampleRunner.ts +284 -0
  125. package/template/src/examples/ServiceInterceptorExample.ts +214 -0
  126. package/template/src/examples/SwaggerProcessorExample.ts +169 -0
  127. package/template/src/examples/TransactionManagerDemo.ts +377 -0
  128. package/template/src/examples/cacheExamples.ts +155 -0
  129. package/template/src/framework/decorator/controller.ts +311 -0
  130. package/template/src/framework/decorator/processor/AnnotationDecorators.ts +100 -0
  131. package/template/src/framework/decorator/processor/AnnotationProcessor.ts +156 -0
  132. package/template/src/framework/decorator/processor/AnnotationProcessorConfig.ts +45 -0
  133. package/template/src/framework/decorator/processor/AnnotationRegistry.ts +117 -0
  134. package/template/src/framework/decorator/processor/AnnotationSystemInitializer.ts +95 -0
  135. package/template/src/framework/decorator/processor/ProcessorManager.ts +76 -0
  136. package/template/src/framework/decorator/processor/processors/CustomProcessors.ts +126 -0
  137. package/template/src/framework/decorator/processor/processors/DefaultProcessors.ts +207 -0
  138. package/template/src/framework/decorator/refactored/DecoratorFactory.ts +99 -0
  139. package/template/src/framework/decorator/refactored/DecoratorMetadataManager.ts +125 -0
  140. package/template/src/framework/decorator/refactored/DecoratorValidator.ts +128 -0
  141. package/template/src/framework/decorator/refactored/TypeSafeDecorators.ts +139 -0
  142. package/template/src/framework/decorator/refactored/index.ts +98 -0
  143. package/template/src/framework/decorator/swagger.ts +150 -0
  144. package/template/src/framework/interceptors/AdvancedServiceCallInterceptor.ts +375 -0
  145. package/template/src/framework/interceptors/ServiceCallInterceptor.ts +348 -0
  146. package/template/src/framework/interceptors/index.ts +19 -0
  147. package/template/src/framework/plugins/registry.ts +63 -0
  148. package/template/src/framework/plugins/types.ts +15 -0
  149. package/template/src/framework/types/ServiceResult.ts +151 -0
  150. package/template/src/framework/types/index.ts +16 -0
  151. package/template/src/framework/utils/CacheManager.ts +430 -0
  152. package/template/src/framework/utils/CacheService.ts +248 -0
  153. package/template/src/framework/utils/DtoValidator.ts +164 -0
  154. package/template/src/framework/utils/MigrationHelper.ts +179 -0
  155. package/template/src/framework/utils/MigrationManager.ts +256 -0
  156. package/template/src/framework/utils/NewRouter.ts +207 -0
  157. package/template/src/framework/utils/TransactionManager.ts +172 -0
  158. package/template/src/framework/utils/bootstrap.ts +445 -0
  159. package/template/src/framework/utils/cache.ts +269 -0
  160. package/template/src/framework/utils/databaseConfig.ts +148 -0
  161. package/template/src/framework/utils/db.ts +39 -0
  162. package/template/src/framework/utils/dbMonitor.ts +106 -0
  163. package/template/src/framework/utils/dynamicSwagger.ts +410 -0
  164. package/template/src/framework/utils/function.ts +61 -0
  165. package/template/src/framework/utils/gracefulShutdown.ts +131 -0
  166. package/template/src/framework/utils/logger.ts +388 -0
  167. package/template/src/framework/utils/metrics.ts +182 -0
  168. package/template/src/framework/utils/router.ts +417 -0
  169. package/template/src/framework/utils/swagger.ts +184 -0
  170. package/template/src/framework/utils/testDb.ts +19 -0
  171. package/template/src/framework/utils/token.ts +23 -0
  172. package/template/src/framework/utils/transform.ts +17 -0
  173. package/template/src/libs/aokEmailSender.ts +42 -0
  174. package/template/src/libs/captcha.ts +37 -0
  175. package/template/src/libs/cos.ts +45 -0
  176. package/template/src/libs/mCache.ts +7 -0
  177. package/template/src/libs/serviceValidate.ts +3 -0
  178. package/template/src/libs/tecentSms.ts +51 -0
  179. package/template/src/middlewares/a.middleware.ts +6 -0
  180. package/template/src/middlewares/error.middleware.ts +14 -0
  181. package/template/src/middlewares/logging.middleware.ts +187 -0
  182. package/template/src/middlewares/static.middleware.ts +79 -0
  183. package/template/src/middlewares/swagger.middleware.ts +70 -0
  184. package/template/src/middlewares/token.middleware.ts +32 -0
  185. package/template/src/migrations/1700000000000-InitialDatabaseStructure.ts +172 -0
  186. package/template/src/migrations/index.ts +6 -0
  187. package/template/src/plugins/weboffice/core/context.ts +47 -0
  188. package/template/src/plugins/weboffice/core/errors.ts +51 -0
  189. package/template/src/plugins/weboffice/core/types.ts +63 -0
  190. package/template/src/plugins/weboffice/core/utils.ts +7 -0
  191. package/template/src/plugins/weboffice/entities/index.ts +3 -0
  192. package/template/src/plugins/weboffice/entities/webofficeFile.entity.ts +28 -0
  193. package/template/src/plugins/weboffice/entities/webofficeFileVersion.entity.ts +29 -0
  194. package/template/src/plugins/weboffice/http/routes.ts +179 -0
  195. package/template/src/plugins/weboffice/index.ts +23 -0
  196. package/template/src/plugins/weboffice/services/webofficeCallback.service.ts +274 -0
  197. package/template/src/repository/UserRepository.ts +122 -0
  198. package/template/src/repository/base/BaseRepository.ts +124 -0
  199. package/template/src/repository/interfaces/IBaseRepository.ts +67 -0
  200. package/template/src/routers/index.ts +49 -0
  201. package/template/src/service/base.service.ts +116 -0
  202. package/template/src/service/paramValidateTest.service.ts +139 -0
  203. package/template/src/service/ytGoods.service.ts +42 -0
  204. package/template/src/service/ytShop.service.ts +90 -0
  205. package/template/src/service/ytUser.service.ts +451 -0
  206. package/template/src/test/swaggerParameterTest.ts +90 -0
  207. package/template/src/utils/testDataInitializer.ts +296 -0
  208. package/template/static/output.json +15203 -0
  209. package/template/test/controllers/controllers.test.ts +173 -0
  210. package/template/test/controllers/example/ExampleController.test.ts +222 -0
  211. package/template/test/controllers/example/NewAnnotationExampleController.test.ts +200 -0
  212. package/template/test/framework/TransactionManagerDemo.test.ts +363 -0
  213. package/template/test/framework/annotation/AnnotationDecorators.test.ts +222 -0
  214. package/template/test/framework/annotation/AnnotationExecutor.test.ts +246 -0
  215. package/template/test/framework/annotation/AnnotationProcessor.test.ts +179 -0
  216. package/template/test/framework/annotation/CustomProcessors.test.ts +313 -0
  217. package/template/test/framework/annotation/DefaultProcessors.test.ts +371 -0
  218. package/template/test/framework/annotation/NewRouter.test.ts +272 -0
  219. package/template/test/framework/annotation/ProcessorManager.test.ts +248 -0
  220. package/template/test/framework/annotation/setup.ts +26 -0
  221. package/template/test/framework/cache.test.ts +101 -0
  222. package/template/test/framework/databaseConfig.test.ts +142 -0
  223. package/template/test/integration/integration.test.ts +153 -0
  224. package/template/test/plugins/weboffice/http.routes.int.test.ts +61 -0
  225. package/template/test/service/business.test.ts +87 -0
  226. package/template/test/service/paramValidateTest.service.test.ts +184 -0
  227. package/template/test/service/ytUser.service.test.ts +566 -0
  228. package/template/test/setup.ts +20 -0
  229. package/template/test/setupAfterEnv.ts +14 -0
  230. package/template/test/utils/testHelpers.ts +220 -0
  231. package/template/test_output.txt +0 -0
  232. package/template/tsconfig.build.json +17 -0
  233. package/template/tsconfig.json +31 -0
  234. package/template/webpack.config.js +71 -0
  235. package/template/yarn.lock +7354 -0
@@ -0,0 +1,1097 @@
1
+ # 开发指南
2
+
3
+ 本指南提供 DP-Koa Framework 的详细开发规范和最佳实践,帮助开发者快速上手并遵循统一的开发标准。
4
+
5
+ ## 📋 目录
6
+
7
+ - [项目架构](#项目架构)
8
+ - [开发环境设置](#开发环境设置)
9
+ - [代码规范](#代码规范)
10
+ - [注解系统使用](#注解系统使用)
11
+ - [控制器开发](#控制器开发)
12
+ - [服务层开发](#服务层开发)
13
+ - [数据实体设计](#数据实体设计)
14
+ - [拦截器使用](#拦截器使用)
15
+ - [测试开发](#测试开发)
16
+ - [调试技巧](#调试技巧)
17
+ - [性能优化](#性能优化)
18
+ - [最佳实践](#最佳实践)
19
+
20
+ ## 🏗️ 项目架构
21
+
22
+ ### 整体架构
23
+
24
+ ```
25
+ src/
26
+ ├── app.ts # 应用入口
27
+ ├── controllers/ # 控制器层
28
+ │ ├── base.controller.ts # 基础控制器
29
+ │ └── example/ # 示例控制器
30
+ ├── service/ # 服务层
31
+ │ ├── base.service.ts # 基础服务
32
+ │ └── *.service.ts # 业务服务
33
+ ├── entity/ # 数据实体
34
+ ├── framework/ # 框架核心
35
+ │ ├── decorator/ # 装饰器系统
36
+ │ ├── interceptors/ # 拦截器
37
+ │ └── utils/ # 工具函数
38
+ ├── middlewares/ # 中间件
39
+ ├── repository/ # 数据仓库
40
+ └── utils/ # 业务工具
41
+ ```
42
+
43
+ ### 分层架构
44
+
45
+ ```
46
+ ┌─────────────────┐
47
+ │ Controllers │ ← HTTP 请求处理
48
+ ├─────────────────┤
49
+ │ Services │ ← 业务逻辑
50
+ ├─────────────────┤
51
+ │ Repository │ ← 数据访问
52
+ ├─────────────────┤
53
+ │ Entities │ ← 数据模型
54
+ └─────────────────┘
55
+ ```
56
+
57
+ ## 🔧 开发环境设置
58
+
59
+ ### 1. IDE 配置
60
+
61
+ 推荐使用 **VS Code** 并安装以下插件:
62
+
63
+ ```json
64
+ {
65
+ "recommendations": [
66
+ "ms-vscode.vscode-typescript-next",
67
+ "bradlc.vscode-tailwindcss",
68
+ "esbenp.prettier-vscode",
69
+ "ms-vscode.vscode-eslint",
70
+ "ms-vscode.vscode-jest"
71
+ ]
72
+ }
73
+ ```
74
+
75
+ ### 2. VS Code 设置
76
+
77
+ 创建 `.vscode/settings.json`:
78
+
79
+ ```json
80
+ {
81
+ "typescript.preferences.importModuleSpecifier": "relative",
82
+ "editor.formatOnSave": true,
83
+ "editor.codeActionsOnSave": {
84
+ "source.fixAll.eslint": true
85
+ },
86
+ "typescript.suggest.autoImports": true,
87
+ "files.exclude": {
88
+ "**/node_modules": true,
89
+ "**/dist": true,
90
+ "**/coverage": true
91
+ }
92
+ }
93
+ ```
94
+
95
+ ### 3. 调试配置
96
+
97
+ 创建 `.vscode/launch.json`:
98
+
99
+ ```json
100
+ {
101
+ "version": "0.2.0",
102
+ "configurations": [
103
+ {
104
+ "name": "启动应用",
105
+ "type": "node",
106
+ "request": "launch",
107
+ "program": "${workspaceFolder}/src/app.ts",
108
+ "outFiles": ["${workspaceFolder}/dist/**/*.js"],
109
+ "env": {
110
+ "NODE_ENV": "development"
111
+ },
112
+ "console": "integratedTerminal",
113
+ "restart": true,
114
+ "protocol": "inspector"
115
+ },
116
+ {
117
+ "name": "运行测试",
118
+ "type": "node",
119
+ "request": "launch",
120
+ "program": "${workspaceFolder}/node_modules/.bin/jest",
121
+ "args": ["--runInBand"],
122
+ "console": "integratedTerminal",
123
+ "internalConsoleOptions": "neverOpen"
124
+ }
125
+ ]
126
+ }
127
+ ```
128
+
129
+ ## 📝 代码规范
130
+
131
+ ### 1. TypeScript 规范
132
+
133
+ #### 命名规范
134
+
135
+ ```typescript
136
+ // 类名:PascalCase
137
+ export class UserService extends BaseService {}
138
+
139
+ // 接口名:PascalCase,以 I 开头
140
+ export interface IUserRepository {}
141
+
142
+ // 枚举名:PascalCase
143
+ export enum UserStatus {
144
+ ACTIVE = 'active',
145
+ INACTIVE = 'inactive'
146
+ }
147
+
148
+ // 变量和函数:camelCase
149
+ const userName = 'john';
150
+ function getUserById(id: number) {}
151
+
152
+ // 常量:UPPER_SNAKE_CASE
153
+ const MAX_RETRY_COUNT = 3;
154
+ const API_BASE_URL = 'https://api.example.com';
155
+
156
+ // 文件名:kebab-case
157
+ // user-service.ts
158
+ // user-controller.ts
159
+ ```
160
+
161
+ #### 类型定义
162
+
163
+ ```typescript
164
+ // 使用接口定义对象结构
165
+ interface UserCreateRequest {
166
+ name: string;
167
+ email: string;
168
+ age?: number; // 可选属性
169
+ }
170
+
171
+ // 使用类型别名
172
+ type UserId = number;
173
+ type UserStatus = 'active' | 'inactive' | 'pending';
174
+
175
+ // 泛型约束
176
+ interface Repository<T extends BaseEntity> {
177
+ findById(id: number): Promise<T | null>;
178
+ save(entity: T): Promise<T>;
179
+ }
180
+ ```
181
+
182
+ #### 错误处理
183
+
184
+ ```typescript
185
+ // 使用 Result 模式
186
+ export class ServiceResult<T> {
187
+ constructor(
188
+ public success: boolean,
189
+ public data?: T,
190
+ public error?: string,
191
+ public code?: number
192
+ ) {}
193
+ }
194
+
195
+ // 在服务中使用
196
+ async getUserById(id: number): Promise<ServiceResult<User>> {
197
+ try {
198
+ const user = await this.userRepository.findById(id);
199
+ if (!user) {
200
+ return new ServiceResult(false, undefined, '用户不存在', 404);
201
+ }
202
+ return new ServiceResult(true, user);
203
+ } catch (error) {
204
+ return new ServiceResult(false, undefined, error.message, 500);
205
+ }
206
+ }
207
+ ```
208
+
209
+ ### 2. 注释规范
210
+
211
+ ```typescript
212
+ /**
213
+ * 用户服务类
214
+ * 提供用户相关的业务逻辑处理
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * const userService = new UserService();
219
+ * const result = await userService.createUser(userData);
220
+ * ```
221
+ */
222
+ export class UserService extends BaseService {
223
+
224
+ /**
225
+ * 根据ID获取用户信息
226
+ *
227
+ * @param id 用户ID
228
+ * @returns Promise<ServiceResult<User>> 用户信息或错误
229
+ *
230
+ * @example
231
+ * ```typescript
232
+ * const result = await userService.getUserById(1);
233
+ * if (result.success) {
234
+ * console.log(result.data);
235
+ * }
236
+ * ```
237
+ */
238
+ async getUserById(id: number): Promise<ServiceResult<User>> {
239
+ // 实现逻辑
240
+ }
241
+ }
242
+ ```
243
+
244
+ ### 3. 导入规范
245
+
246
+ ```typescript
247
+ // 1. Node.js 内置模块
248
+ import { readFileSync } from 'fs';
249
+ import { join } from 'path';
250
+
251
+ // 2. 第三方库
252
+ import { Injectable } from 'dp-ioc';
253
+ import { Entity, Column } from 'typeorm';
254
+
255
+ // 3. 项目内部模块(按路径排序)
256
+ import { BaseService } from '@src/service/base.service';
257
+ import { UserEntity } from '@src/entity/user.entity';
258
+ import { UserRepository } from '@src/repository/user.repository';
259
+
260
+ // 4. 相对路径导入
261
+ import { UserDto } from './user.dto';
262
+ import { UserValidator } from './user.validator';
263
+ ```
264
+
265
+ ## 🎯 注解系统使用
266
+
267
+ ### 1. 控制器注解
268
+
269
+ ```typescript
270
+ import { Get, Post, Put, Delete, Body, Query, Params } from '@src/framework/decorator';
271
+ import { Api, ApiTags, ApiResponse } from '@src/framework/decorator/swagger';
272
+
273
+ @ApiTags('用户管理')
274
+ export class UserController extends BaseController {
275
+
276
+ /**
277
+ * 获取用户列表
278
+ */
279
+ @Get('/users')
280
+ @Api({
281
+ summary: '获取用户列表',
282
+ description: '分页获取用户列表,支持搜索和过滤'
283
+ })
284
+ @ApiResponse({
285
+ status: 200,
286
+ description: '成功返回用户列表'
287
+ })
288
+ async getUsers(
289
+ @Query() query: { page?: number; size?: number; search?: string }
290
+ ) {
291
+ // 实现逻辑
292
+ }
293
+
294
+ /**
295
+ * 创建用户
296
+ */
297
+ @Post('/users')
298
+ @Api({
299
+ summary: '创建用户',
300
+ description: '创建新用户'
301
+ })
302
+ @ApiResponse({
303
+ status: 201,
304
+ description: '用户创建成功'
305
+ })
306
+ async createUser(@Body() userData: UserCreateRequest) {
307
+ // 实现逻辑
308
+ }
309
+ }
310
+ ```
311
+
312
+ ### 2. 服务注解
313
+
314
+ ```typescript
315
+ import { Injectable } from 'dp-ioc';
316
+ import { Logging, PerformanceMonitor } from '@src/annotations/decorators';
317
+
318
+ @Injectable()
319
+ export class UserService extends BaseService {
320
+
321
+ /**
322
+ * 获取用户信息(带性能监控)
323
+ */
324
+ @PerformanceMonitor({ maxExecutionTime: 100 })
325
+ @Logging()
326
+ async getUserById(id: number): Promise<ServiceResult<User>> {
327
+ // 实现逻辑
328
+ }
329
+ }
330
+ ```
331
+
332
+ ### 3. 权限注解
333
+
334
+ ```typescript
335
+ import { Permission, RateLimit } from '@src/framework/decorator/processor/AnnotationDecorators';
336
+
337
+ export class AdminController extends BaseController {
338
+
339
+ @Get('/admin/users')
340
+ @Permission({ requiredPermission: 'admin:read' })
341
+ @RateLimit({ maxRequests: 10, windowMs: 60000 })
342
+ async getAdminUsers() {
343
+ // 管理员专用接口
344
+ }
345
+ }
346
+ ```
347
+
348
+ ## 🎮 控制器开发
349
+
350
+ ### 1. 基础控制器结构
351
+
352
+ ```typescript
353
+ import { Get, Post, Body, Query, Params } from '@src/framework/decorator';
354
+ import { Api, ApiTags } from '@src/framework/decorator/swagger';
355
+ import { BaseController } from '@src/controllers/base.controller';
356
+ import { UserService } from '@src/service/user.service';
357
+ import { Injectable } from 'dp-ioc';
358
+
359
+ @ApiTags('用户管理')
360
+ @Injectable()
361
+ export class UserController extends BaseController {
362
+
363
+ constructor(private userService: UserService) {
364
+ super();
365
+ }
366
+
367
+ @Get('/users')
368
+ @Api({ summary: '获取用户列表' })
369
+ async getUsers(@Query() query: any) {
370
+ try {
371
+ const result = await this.userService.getUsers(query);
372
+ return this.success(result.data, '获取用户列表成功');
373
+ } catch (error) {
374
+ return this.fail(500, error.message);
375
+ }
376
+ }
377
+
378
+ @Post('/users')
379
+ @Api({ summary: '创建用户' })
380
+ async createUser(@Body() userData: any) {
381
+ try {
382
+ const result = await this.userService.createUser(userData);
383
+ if (result.success) {
384
+ return this.success(result.data, '用户创建成功');
385
+ } else {
386
+ return this.fail(result.code || 400, result.error);
387
+ }
388
+ } catch (error) {
389
+ return this.fail(500, error.message);
390
+ }
391
+ }
392
+ }
393
+ ```
394
+
395
+ ### 2. 参数验证
396
+
397
+ ```typescript
398
+ import { IsString, IsEmail, IsOptional, IsNumber } from 'class-validator';
399
+
400
+ export class CreateUserDto {
401
+ @IsString()
402
+ @IsOptional()
403
+ name?: string;
404
+
405
+ @IsEmail()
406
+ email: string;
407
+
408
+ @IsString()
409
+ password: string;
410
+
411
+ @IsNumber()
412
+ @IsOptional()
413
+ age?: number;
414
+ }
415
+
416
+ export class UserController extends BaseController {
417
+
418
+ @Post('/users')
419
+ async createUser(@Body() userData: CreateUserDto) {
420
+ // userData 已经过验证
421
+ }
422
+ }
423
+ ```
424
+
425
+ ### 3. 错误处理
426
+
427
+ ```typescript
428
+ export class UserController extends BaseController {
429
+
430
+ @Get('/users/:id')
431
+ async getUserById(@Params() params: { id: string }) {
432
+ try {
433
+ const id = parseInt(params.id);
434
+ if (isNaN(id)) {
435
+ return this.fail(400, '无效的用户ID');
436
+ }
437
+
438
+ const result = await this.userService.getUserById(id);
439
+ if (!result.success) {
440
+ return this.fail(result.code || 404, result.error);
441
+ }
442
+
443
+ return this.success(result.data);
444
+ } catch (error) {
445
+ this.logger.error('获取用户失败', error);
446
+ return this.fail(500, '服务器内部错误');
447
+ }
448
+ }
449
+ }
450
+ ```
451
+
452
+ ## 🔧 服务层开发
453
+
454
+ ### 1. 基础服务结构
455
+
456
+ ```typescript
457
+ import { Injectable } from 'dp-ioc';
458
+ import { BaseService } from '@src/service/base.service';
459
+ import { UserEntity } from '@src/entity/user.entity';
460
+ import { UserRepository } from '@src/repository/user.repository';
461
+ import { ServiceResult } from '@src/framework/types/ServiceResult';
462
+
463
+ @Injectable()
464
+ export class UserService extends BaseService {
465
+ private repositoryCache = new Map<string, any>();
466
+
467
+ private get userRepository(): UserRepository {
468
+ return this.createLazyRepository(
469
+ UserEntity,
470
+ UserRepository,
471
+ this.repositoryCache
472
+ );
473
+ }
474
+
475
+ async getUserById(id: number): Promise<ServiceResult<UserEntity>> {
476
+ try {
477
+ const user = await this.userRepository.findById(id);
478
+ if (!user) {
479
+ return new ServiceResult(false, undefined, '用户不存在', 404);
480
+ }
481
+ return new ServiceResult(true, user);
482
+ } catch (error) {
483
+ return new ServiceResult(false, undefined, error.message, 500);
484
+ }
485
+ }
486
+
487
+ async createUser(userData: Partial<UserEntity>): Promise<ServiceResult<UserEntity>> {
488
+ try {
489
+ // 验证数据
490
+ const validationResult = this.validateUserData(userData);
491
+ if (!validationResult.valid) {
492
+ return new ServiceResult(false, undefined, validationResult.error, 400);
493
+ }
494
+
495
+ // 检查邮箱是否已存在
496
+ const existingUser = await this.userRepository.findByEmail(userData.email);
497
+ if (existingUser) {
498
+ return new ServiceResult(false, undefined, '邮箱已存在', 409);
499
+ }
500
+
501
+ // 创建用户
502
+ const user = await this.userRepository.create(userData);
503
+ return new ServiceResult(true, user);
504
+ } catch (error) {
505
+ return new ServiceResult(false, undefined, error.message, 500);
506
+ }
507
+ }
508
+
509
+ private validateUserData(userData: Partial<UserEntity>): { valid: boolean; error?: string } {
510
+ if (!userData.email) {
511
+ return { valid: false, error: '邮箱不能为空' };
512
+ }
513
+ if (!userData.password) {
514
+ return { valid: false, error: '密码不能为空' };
515
+ }
516
+ return { valid: true };
517
+ }
518
+ }
519
+ ```
520
+
521
+ ### 2. 事务处理
522
+
523
+ ```typescript
524
+ import { transactionManager } from '@src/framework/utils/TransactionManager';
525
+
526
+ export class UserService extends BaseService {
527
+
528
+ async createUserWithProfile(userData: any, profileData: any): Promise<ServiceResult<any>> {
529
+ return await transactionManager.runTransaction(async (manager) => {
530
+ try {
531
+ // 创建用户
532
+ const user = await manager.save(UserEntity, userData);
533
+
534
+ // 创建用户资料
535
+ const profile = await manager.save(UserProfileEntity, {
536
+ ...profileData,
537
+ userId: user.id
538
+ });
539
+
540
+ return new ServiceResult(true, { user, profile });
541
+ } catch (error) {
542
+ throw error; // 事务会自动回滚
543
+ }
544
+ });
545
+ }
546
+ }
547
+ ```
548
+
549
+ ### 3. 缓存使用
550
+
551
+ ```typescript
552
+ import { cacheManager } from '@src/framework/utils/CacheManager';
553
+
554
+ export class UserService extends BaseService {
555
+
556
+ async getUserById(id: number): Promise<ServiceResult<UserEntity>> {
557
+ // 尝试从缓存获取
558
+ const cacheKey = `user:${id}`;
559
+ const cachedUser = await cacheManager.get<UserEntity>(cacheKey);
560
+
561
+ if (cachedUser) {
562
+ return new ServiceResult(true, cachedUser);
563
+ }
564
+
565
+ // 从数据库获取
566
+ const result = await this.userRepository.findById(id);
567
+ if (result.success && result.data) {
568
+ // 缓存结果
569
+ await cacheManager.set(cacheKey, result.data, 3600); // 1小时
570
+ }
571
+
572
+ return result;
573
+ }
574
+ }
575
+ ```
576
+
577
+ ## 🗄️ 数据实体设计
578
+
579
+ ### 1. 基础实体
580
+
581
+ ```typescript
582
+ import { Entity, Column, CreateDateColumn, UpdateDateColumn, PrimaryGeneratedColumn } from 'typeorm';
583
+
584
+ @Entity()
585
+ export class BaseEntity {
586
+ @PrimaryGeneratedColumn()
587
+ id: number;
588
+
589
+ @CreateDateColumn()
590
+ createdAt: Date;
591
+
592
+ @UpdateDateColumn()
593
+ updatedAt: Date;
594
+
595
+ @Column({ default: true })
596
+ isActive: boolean;
597
+ }
598
+ ```
599
+
600
+ ### 2. 业务实体
601
+
602
+ ```typescript
603
+ import { Entity, Column, OneToMany, OneToOne, JoinColumn } from 'typeorm';
604
+ import { BaseEntity } from '@src/entity/base.entity';
605
+
606
+ @Entity('users')
607
+ export class UserEntity extends BaseEntity {
608
+
609
+ @Column({ length: 100 })
610
+ name: string;
611
+
612
+ @Column({ unique: true })
613
+ email: string;
614
+
615
+ @Column()
616
+ password: string;
617
+
618
+ @Column({ nullable: true })
619
+ avatar?: string;
620
+
621
+ @Column({ default: 'active' })
622
+ status: string;
623
+
624
+ // 关系定义
625
+ @OneToOne(() => UserProfileEntity, profile => profile.user)
626
+ @JoinColumn()
627
+ profile: UserProfileEntity;
628
+
629
+ @OneToMany(() => OrderEntity, order => order.user)
630
+ orders: OrderEntity[];
631
+ }
632
+ ```
633
+
634
+ ### 3. 枚举使用
635
+
636
+ ```typescript
637
+ export enum UserStatus {
638
+ ACTIVE = 'active',
639
+ INACTIVE = 'inactive',
640
+ PENDING = 'pending',
641
+ SUSPENDED = 'suspended'
642
+ }
643
+
644
+ export enum UserRole {
645
+ ADMIN = 'admin',
646
+ USER = 'user',
647
+ MODERATOR = 'moderator'
648
+ }
649
+
650
+ @Entity('users')
651
+ export class UserEntity extends BaseEntity {
652
+
653
+ @Column({
654
+ type: 'enum',
655
+ enum: UserStatus,
656
+ default: UserStatus.ACTIVE
657
+ })
658
+ status: UserStatus;
659
+
660
+ @Column({
661
+ type: 'enum',
662
+ enum: UserRole,
663
+ default: UserRole.USER
664
+ })
665
+ role: UserRole;
666
+ }
667
+ ```
668
+
669
+ ## 🔄 拦截器使用
670
+
671
+ ### 1. 服务调用拦截器
672
+
673
+ ```typescript
674
+ import { ServiceCallInterceptor } from '@src/framework/interceptors';
675
+
676
+ export class UserService extends BaseService {
677
+
678
+ @ServiceCallInterceptor({
679
+ logCalls: true,
680
+ measurePerformance: true,
681
+ retryOnFailure: true,
682
+ maxRetries: 3
683
+ })
684
+ async getUserById(id: number): Promise<ServiceResult<UserEntity>> {
685
+ // 服务实现
686
+ }
687
+ }
688
+ ```
689
+
690
+ ### 2. 自定义拦截器
691
+
692
+ ```typescript
693
+ import { Interceptor, InterceptorContext, InterceptorResult } from '@src/framework/interceptors';
694
+
695
+ export class LoggingInterceptor implements Interceptor {
696
+ async intercept(context: InterceptorContext, next: () => Promise<InterceptorResult>): Promise<InterceptorResult> {
697
+ const startTime = Date.now();
698
+
699
+ try {
700
+ const result = await next();
701
+ const duration = Date.now() - startTime;
702
+
703
+ console.log(`方法 ${context.methodName} 执行成功,耗时: ${duration}ms`);
704
+ return result;
705
+ } catch (error) {
706
+ const duration = Date.now() - startTime;
707
+ console.error(`方法 ${context.methodName} 执行失败,耗时: ${duration}ms`, error);
708
+ throw error;
709
+ }
710
+ }
711
+ }
712
+ ```
713
+
714
+ ## 🧪 测试开发
715
+
716
+ ### 1. 单元测试
717
+
718
+ ```typescript
719
+ import { UserService } from '@src/service/user.service';
720
+ import { UserRepository } from '@src/repository/user.repository';
721
+
722
+ describe('UserService', () => {
723
+ let userService: UserService;
724
+ let mockUserRepository: jest.Mocked<UserRepository>;
725
+
726
+ beforeEach(() => {
727
+ mockUserRepository = {
728
+ findById: jest.fn(),
729
+ create: jest.fn(),
730
+ update: jest.fn(),
731
+ delete: jest.fn()
732
+ } as any;
733
+
734
+ userService = new UserService();
735
+ // 注入 mock repository
736
+ });
737
+
738
+ describe('getUserById', () => {
739
+ it('应该返回用户信息', async () => {
740
+ // Arrange
741
+ const userId = 1;
742
+ const mockUser = { id: 1, name: 'John', email: 'john@example.com' };
743
+ mockUserRepository.findById.mockResolvedValue(mockUser);
744
+
745
+ // Act
746
+ const result = await userService.getUserById(userId);
747
+
748
+ // Assert
749
+ expect(result.success).toBe(true);
750
+ expect(result.data).toEqual(mockUser);
751
+ expect(mockUserRepository.findById).toHaveBeenCalledWith(userId);
752
+ });
753
+
754
+ it('应该处理用户不存在的情况', async () => {
755
+ // Arrange
756
+ const userId = 999;
757
+ mockUserRepository.findById.mockResolvedValue(null);
758
+
759
+ // Act
760
+ const result = await userService.getUserById(userId);
761
+
762
+ // Assert
763
+ expect(result.success).toBe(false);
764
+ expect(result.error).toBe('用户不存在');
765
+ expect(result.code).toBe(404);
766
+ });
767
+ });
768
+ });
769
+ ```
770
+
771
+ ### 2. 集成测试
772
+
773
+ ```typescript
774
+ import request from 'supertest';
775
+ import { app } from '@src/app';
776
+
777
+ describe('User API', () => {
778
+ describe('GET /api/users/:id', () => {
779
+ it('应该返回用户信息', async () => {
780
+ const response = await request(app)
781
+ .get('/api/users/1')
782
+ .expect(200);
783
+
784
+ expect(response.body.success).toBe(true);
785
+ expect(response.body.data).toHaveProperty('id');
786
+ expect(response.body.data).toHaveProperty('name');
787
+ });
788
+
789
+ it('应该处理无效的用户ID', async () => {
790
+ const response = await request(app)
791
+ .get('/api/users/invalid')
792
+ .expect(400);
793
+
794
+ expect(response.body.success).toBe(false);
795
+ expect(response.body.error).toBe('无效的用户ID');
796
+ });
797
+ });
798
+ });
799
+ ```
800
+
801
+ ### 3. 测试工具
802
+
803
+ ```typescript
804
+ // test/utils/test-helpers.ts
805
+ export class TestHelpers {
806
+ static async createTestUser(userData: Partial<UserEntity> = {}): Promise<UserEntity> {
807
+ const defaultData = {
808
+ name: 'Test User',
809
+ email: `test-${Date.now()}@example.com`,
810
+ password: 'password123',
811
+ ...userData
812
+ };
813
+
814
+ return await userRepository.create(defaultData);
815
+ }
816
+
817
+ static async cleanupTestData(): Promise<void> {
818
+ await userRepository.delete({ email: /test-.*@example\.com/ });
819
+ }
820
+ }
821
+ ```
822
+
823
+ ## 🐛 调试技巧
824
+
825
+ ### 1. 日志调试
826
+
827
+ ```typescript
828
+ import { logger } from '@src/framework/utils/logger';
829
+
830
+ export class UserService extends BaseService {
831
+
832
+ async getUserById(id: number): Promise<ServiceResult<UserEntity>> {
833
+ logger.debug('开始获取用户信息', { userId: id });
834
+
835
+ try {
836
+ const user = await this.userRepository.findById(id);
837
+
838
+ if (!user) {
839
+ logger.warn('用户不存在', { userId: id });
840
+ return new ServiceResult(false, undefined, '用户不存在', 404);
841
+ }
842
+
843
+ logger.info('用户信息获取成功', { userId: id, userName: user.name });
844
+ return new ServiceResult(true, user);
845
+ } catch (error) {
846
+ logger.error('获取用户信息失败', { userId: id, error: error.message });
847
+ return new ServiceResult(false, undefined, error.message, 500);
848
+ }
849
+ }
850
+ }
851
+ ```
852
+
853
+ ### 2. 性能调试
854
+
855
+ ```typescript
856
+ import { PerformanceMonitor } from '@src/annotations/decorators';
857
+
858
+ export class UserService extends BaseService {
859
+
860
+ @PerformanceMonitor({
861
+ maxExecutionTime: 1000, // 1秒
862
+ logSlowQueries: true
863
+ })
864
+ async getUsersWithComplexQuery(query: any): Promise<ServiceResult<UserEntity[]>> {
865
+ // 复杂查询逻辑
866
+ }
867
+ }
868
+ ```
869
+
870
+ ### 3. 断点调试
871
+
872
+ ```typescript
873
+ // 在 VS Code 中设置断点
874
+ export class UserService extends BaseService {
875
+
876
+ async getUserById(id: number): Promise<ServiceResult<UserEntity>> {
877
+ debugger; // 断点
878
+
879
+ const user = await this.userRepository.findById(id);
880
+ // 在这里可以检查变量值
881
+
882
+ return new ServiceResult(true, user);
883
+ }
884
+ }
885
+ ```
886
+
887
+ ## ⚡ 性能优化
888
+
889
+ ### 1. 数据库优化
890
+
891
+ ```typescript
892
+ // 使用索引
893
+ @Entity('users')
894
+ export class UserEntity extends BaseEntity {
895
+
896
+ @Column()
897
+ @Index() // 添加索引
898
+ email: string;
899
+
900
+ @Column()
901
+ @Index(['status', 'createdAt']) // 复合索引
902
+ status: string;
903
+ }
904
+
905
+ // 使用查询优化
906
+ export class UserService extends BaseService {
907
+
908
+ async getUsersWithPagination(page: number, size: number): Promise<ServiceResult<UserEntity[]>> {
909
+ const users = await this.userRepository
910
+ .createQueryBuilder('user')
911
+ .select(['user.id', 'user.name', 'user.email']) // 只选择需要的字段
912
+ .where('user.status = :status', { status: 'active' })
913
+ .orderBy('user.createdAt', 'DESC')
914
+ .skip((page - 1) * size)
915
+ .take(size)
916
+ .getMany();
917
+
918
+ return new ServiceResult(true, users);
919
+ }
920
+ }
921
+ ```
922
+
923
+ ### 2. 缓存优化
924
+
925
+ ```typescript
926
+ import { cacheManager } from '@src/framework/utils/CacheManager';
927
+
928
+ export class UserService extends BaseService {
929
+
930
+ async getUserById(id: number): Promise<ServiceResult<UserEntity>> {
931
+ const cacheKey = `user:${id}`;
932
+
933
+ // 尝试从缓存获取
934
+ let user = await cacheManager.get<UserEntity>(cacheKey);
935
+
936
+ if (!user) {
937
+ // 从数据库获取
938
+ const result = await this.userRepository.findById(id);
939
+ if (result.success && result.data) {
940
+ user = result.data;
941
+ // 缓存1小时
942
+ await cacheManager.set(cacheKey, user, 3600);
943
+ }
944
+ }
945
+
946
+ return new ServiceResult(true, user);
947
+ }
948
+ }
949
+ ```
950
+
951
+ ### 3. 内存优化
952
+
953
+ ```typescript
954
+ export class UserService extends BaseService {
955
+ private repositoryCache = new Map<string, any>();
956
+
957
+ // 定期清理缓存
958
+ private cleanupCache(): void {
959
+ if (this.repositoryCache.size > 100) {
960
+ this.repositoryCache.clear();
961
+ }
962
+ }
963
+
964
+ // 在服务销毁时清理资源
965
+ cleanup(): void {
966
+ this.repositoryCache.clear();
967
+ }
968
+ }
969
+ ```
970
+
971
+ ## 🎯 最佳实践
972
+
973
+ ### 1. 错误处理
974
+
975
+ ```typescript
976
+ // 统一的错误处理
977
+ export class BaseService {
978
+ protected handleError(error: Error, context: string): ServiceResult<any> {
979
+ this.logger.error(`${context} 执行失败`, { error: error.message });
980
+
981
+ if (error instanceof ValidationError) {
982
+ return new ServiceResult(false, undefined, error.message, 400);
983
+ }
984
+
985
+ if (error instanceof DatabaseError) {
986
+ return new ServiceResult(false, undefined, '数据库操作失败', 500);
987
+ }
988
+
989
+ return new ServiceResult(false, undefined, '服务器内部错误', 500);
990
+ }
991
+ }
992
+ ```
993
+
994
+ ### 2. 数据验证
995
+
996
+ ```typescript
997
+ import { validate } from 'class-validator';
998
+
999
+ export class UserService extends BaseService {
1000
+
1001
+ async createUser(userData: any): Promise<ServiceResult<UserEntity>> {
1002
+ // 验证输入数据
1003
+ const validationErrors = await validate(userData);
1004
+ if (validationErrors.length > 0) {
1005
+ const errorMessages = validationErrors.map(error =>
1006
+ Object.values(error.constraints || {}).join(', ')
1007
+ );
1008
+ return new ServiceResult(false, undefined, errorMessages.join('; '), 400);
1009
+ }
1010
+
1011
+ // 业务逻辑验证
1012
+ const existingUser = await this.userRepository.findByEmail(userData.email);
1013
+ if (existingUser) {
1014
+ return new ServiceResult(false, undefined, '邮箱已存在', 409);
1015
+ }
1016
+
1017
+ // 创建用户
1018
+ const user = await this.userRepository.create(userData);
1019
+ return new ServiceResult(true, user);
1020
+ }
1021
+ }
1022
+ ```
1023
+
1024
+ ### 3. 安全实践
1025
+
1026
+ ```typescript
1027
+ import bcrypt from 'bcryptjs';
1028
+
1029
+ export class UserService extends BaseService {
1030
+
1031
+ async createUser(userData: any): Promise<ServiceResult<UserEntity>> {
1032
+ // 密码加密
1033
+ const saltRounds = parseInt(process.env.BCRYPT_ROUNDS || '12');
1034
+ const hashedPassword = await bcrypt.hash(userData.password, saltRounds);
1035
+
1036
+ const userDataWithHashedPassword = {
1037
+ ...userData,
1038
+ password: hashedPassword
1039
+ };
1040
+
1041
+ const user = await this.userRepository.create(userDataWithHashedPassword);
1042
+
1043
+ // 返回时移除密码
1044
+ const { password, ...userWithoutPassword } = user;
1045
+ return new ServiceResult(true, userWithoutPassword);
1046
+ }
1047
+ }
1048
+ ```
1049
+
1050
+ ### 4. 代码复用
1051
+
1052
+ ```typescript
1053
+ // 通用分页服务
1054
+ export class PaginationService {
1055
+ static async paginate<T>(
1056
+ repository: Repository<T>,
1057
+ page: number,
1058
+ size: number,
1059
+ where?: any,
1060
+ order?: any
1061
+ ): Promise<{ data: T[]; total: number; page: number; size: number }> {
1062
+ const queryBuilder = repository.createQueryBuilder();
1063
+
1064
+ if (where) {
1065
+ queryBuilder.where(where);
1066
+ }
1067
+
1068
+ if (order) {
1069
+ queryBuilder.orderBy(order);
1070
+ }
1071
+
1072
+ const [data, total] = await queryBuilder
1073
+ .skip((page - 1) * size)
1074
+ .take(size)
1075
+ .getManyAndCount();
1076
+
1077
+ return { data, total, page, size };
1078
+ }
1079
+ }
1080
+ ```
1081
+
1082
+ ## 📚 相关文档
1083
+
1084
+ - [注解系统指南](ENTERPRISE_ANNOTATION_SYSTEM_GUIDE.md) - 详细注解使用说明
1085
+ - [服务层指南](SERVICE_PATTERN_GUIDE.md) - 服务层设计模式
1086
+ - [拦截器指南](SERVICE_INTERCEPTOR_GUIDE.md) - 拦截器使用
1087
+ - [测试指南](TESTING_GUIDE.md) - 测试策略和工具
1088
+ - [API 文档](API_DOCUMENTATION.md) - API 参考
1089
+
1090
+ ---
1091
+
1092
+ **相关链接**:
1093
+ - [快速开始指南](QUICK_START.md) - 5分钟快速上手
1094
+ - [安装配置指南](INSTALLATION_GUIDE.md) - 详细安装步骤
1095
+ - [故障排除指南](TROUBLESHOOTING.md) - 常见问题解决
1096
+
1097
+