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,205 @@
1
+ import { Get, Post, Put, Del, Body, Query, Params } from '@src/framework/decorator/controller';
2
+ import { BaseController } from '@src/controllers/base.controller';
3
+ import { Api, ApiTags, ApiResponse, ApiBody, ApiParam } from '@src/framework/decorator/swagger';
4
+ import { logger } from '@src/framework/utils/logger';
5
+
6
+ /**
7
+ * Swagger示例控制器 - 展示完整的Swagger注解用法
8
+ */
9
+ @ApiTags('Swagger示例', 'API文档完整示例')
10
+ export class SwaggerExampleController extends BaseController {
11
+
12
+ /**
13
+ * GET请求 - 带查询参数
14
+ */
15
+ @Get('/user/list')
16
+ @Api({
17
+ tags: ['用户管理'],
18
+ summary: '获取用户列表',
19
+ description: '根据查询参数获取用户列表',
20
+ operationId: 'getUserList',
21
+ })
22
+ @ApiResponse({
23
+ status: 200,
24
+ description: '成功返回用户列表',
25
+ schema: {
26
+ type: 'object',
27
+ properties: {
28
+ code: { type: 'number', example: 0 },
29
+ data: {
30
+ type: 'array',
31
+ items: {
32
+ type: 'object',
33
+ properties: {
34
+ id: { type: 'number' },
35
+ name: { type: 'string' },
36
+ email: { type: 'string' },
37
+ },
38
+ },
39
+ },
40
+ message: { type: 'string' },
41
+ },
42
+ },
43
+ })
44
+ async getUserList(@Query() query: { page: number; pageSize: number; keyword?: string }) {
45
+ return this.success({
46
+ users: [
47
+ { id: 1, name: '张三', email: 'zhang@example.com' },
48
+ { id: 2, name: '李四', email: 'li@example.com' },
49
+ ],
50
+ total: 2,
51
+ page: query.page || 1,
52
+ pageSize: query.pageSize || 10,
53
+ }, '获取用户列表成功');
54
+ }
55
+
56
+ /**
57
+ * GET请求 - 带路径参数
58
+ */
59
+ @Get('/user/:id')
60
+ @Api({
61
+ tags: ['用户管理'],
62
+ summary: '获取用户详情',
63
+ description: '根据用户ID获取用户详细信息',
64
+ })
65
+ @ApiResponse({
66
+ status: 200,
67
+ description: '成功返回用户详情',
68
+ })
69
+ @ApiResponse({
70
+ status: 404,
71
+ description: '用户不存在',
72
+ })
73
+ async getUserById(@Params() params: { id: number }) {
74
+ return this.success({
75
+ id: params.id,
76
+ name: '张三',
77
+ email: 'zhang@example.com',
78
+ avatar: 'https://example.com/avatar.jpg',
79
+ }, '获取用户详情成功');
80
+ }
81
+
82
+ /**
83
+ * POST请求 - 带请求体
84
+ */
85
+ @Post('/user')
86
+ @Api({
87
+ tags: ['用户管理'],
88
+ summary: '创建新用户',
89
+ description: '创建新用户并返回用户信息',
90
+ })
91
+ @ApiBody({
92
+ description: '用户信息',
93
+ required: true,
94
+ schema: {
95
+ type: 'object',
96
+ required: ['name', 'email'],
97
+ properties: {
98
+ name: { type: 'string', description: '用户名', example: '张三' },
99
+ email: { type: 'string', format: 'email', description: '邮箱', example: 'zhang@example.com' },
100
+ age: { type: 'number', description: '年龄', example: 25 },
101
+ },
102
+ },
103
+ examples: {
104
+ example1: {
105
+ summary: '示例数据1',
106
+ value: {
107
+ name: '张三',
108
+ email: 'zhang@example.com',
109
+ age: 25,
110
+ },
111
+ },
112
+ },
113
+ })
114
+ @ApiResponse({
115
+ status: 200,
116
+ description: '成功创建用户',
117
+ schema: {
118
+ type: 'object',
119
+ properties: {
120
+ code: { type: 'number' },
121
+ data: {
122
+ type: 'object',
123
+ properties: {
124
+ id: { type: 'number' },
125
+ name: { type: 'string' },
126
+ email: { type: 'string' },
127
+ },
128
+ },
129
+ message: { type: 'string' },
130
+ },
131
+ },
132
+ })
133
+ @ApiResponse({
134
+ status: 400,
135
+ description: '参数验证失败',
136
+ })
137
+ async createUser(@Body() body: { name: string; email: string; age?: number }) {
138
+ return this.success({
139
+ id: Math.floor(Math.random() * 1000),
140
+ name: body.name,
141
+ email: body.email,
142
+ age: body.age,
143
+ }, '创建用户成功');
144
+ }
145
+
146
+ /**
147
+ * PUT请求 - 更新资源
148
+ */
149
+ @Put('/user/:id')
150
+ @Api({
151
+ tags: ['用户管理'],
152
+ summary: '更新用户信息',
153
+ description: '根据用户ID更新用户信息',
154
+ })
155
+ @ApiBody({
156
+ description: '更新的用户信息',
157
+ required: true,
158
+ schema: {
159
+ type: 'object',
160
+ properties: {
161
+ name: { type: 'string', description: '用户名' },
162
+ email: { type: 'string', format: 'email', description: '邮箱' },
163
+ age: { type: 'number', description: '年龄' },
164
+ },
165
+ },
166
+ })
167
+ @ApiResponse({
168
+ status: 200,
169
+ description: '成功更新用户信息',
170
+ })
171
+ @ApiResponse({
172
+ status: 404,
173
+ description: '用户不存在',
174
+ })
175
+ async updateUser(@Params() params: { id: number }, @Body() body: { name?: string; email?: string; age?: number }) {
176
+ return this.success({
177
+ id: params.id,
178
+ ...body,
179
+ }, '更新用户成功');
180
+ }
181
+
182
+ /**
183
+ * DELETE请求 - 删除资源
184
+ */
185
+ @Del('/user/:id')
186
+ @Api({
187
+ tags: ['用户管理'],
188
+ summary: '删除用户',
189
+ description: '根据用户ID删除用户',
190
+ })
191
+ @ApiResponse({
192
+ status: 200,
193
+ description: '成功删除用户',
194
+ })
195
+ @ApiResponse({
196
+ status: 404,
197
+ description: '用户不存在',
198
+ })
199
+ async deleteUser(@Params() params: { id: number }) {
200
+ logger.debug('🔍 deleteUser 方法被调用');
201
+ logger.debug('📋 参数:', params);
202
+ return this.success(null, '删除用户成功');
203
+ }
204
+ }
205
+
@@ -0,0 +1,336 @@
1
+ /**
2
+ * 事务管理器使用示例控制器
3
+ * 演示在实际 API 中如何使用 TransactionManager
4
+ */
5
+
6
+ import { Post, Get, Put, Del } from '@src/framework/decorator/controller';
7
+ import { Context } from 'koa';
8
+ import { transactionManager } from '@src/framework/utils/TransactionManager';
9
+ import { YtUserEntity } from '@src/entity/ytUser.entity';
10
+ import { logger } from '@src/framework/utils/logger';
11
+ import * as bcrypt from 'bcryptjs';
12
+
13
+ export class TransactionExampleController {
14
+
15
+ /**
16
+ * 示例 1: 基本事务 - 创建用户
17
+ * POST /api/example/transaction/create-user
18
+ */
19
+ @Post('/create-user')
20
+ async createUser(ctx: Context) {
21
+ const { email, telnumber, password } = ctx.request.body;
22
+
23
+ try {
24
+ const result = await transactionManager.executeInTransaction(async (manager) => {
25
+ // 检查用户是否已存在
26
+ const existingUser = await manager.findOne(YtUserEntity, {
27
+ where: [{ email }, { telnumber }] as any
28
+ });
29
+
30
+ if (existingUser) {
31
+ throw new Error('用户已存在');
32
+ }
33
+
34
+ // 创建新用户
35
+ const user = new YtUserEntity();
36
+ user.email = email;
37
+ user.telnumber = telnumber;
38
+ user.password = await bcrypt.hash(password, 10);
39
+ user.createDate = new Date();
40
+ user.updateDate = new Date();
41
+
42
+ return await manager.save(user);
43
+ });
44
+
45
+ ctx.body = {
46
+ success: true,
47
+ message: '用户创建成功',
48
+ data: result
49
+ };
50
+ ctx.status = 200;
51
+
52
+ } catch (error) {
53
+ logger.error('创建用户失败:', error as Error);
54
+ ctx.body = {
55
+ success: false,
56
+ message: error instanceof Error ? error.message : '创建用户失败',
57
+ error: '事务已回滚'
58
+ };
59
+ ctx.status = 500;
60
+ }
61
+ }
62
+
63
+ /**
64
+ * 示例 2: 更新用户信息(使用隔离级别)
65
+ * PUT /api/example/transaction/update-user/:id
66
+ */
67
+ @Put('/update-user/:id')
68
+ async updateUser(ctx: Context) {
69
+ const id = parseInt(ctx.params.id);
70
+ const { email, telnumber } = ctx.request.body;
71
+
72
+ try {
73
+ const result = await transactionManager.executeInTransaction(
74
+ async (manager) => {
75
+ // 查找用户
76
+ const user = await manager.findOne(YtUserEntity, {
77
+ where: { id } as any
78
+ });
79
+
80
+ if (!user) {
81
+ throw new Error('用户不存在');
82
+ }
83
+
84
+ // 更新用户信息
85
+ if (email) {
86
+ // 检查邮箱是否被其他用户使用
87
+ const existingUser = await manager.findOne(YtUserEntity, {
88
+ where: { email } as any
89
+ });
90
+ if (existingUser && existingUser.id !== id) {
91
+ throw new Error('邮箱已被其他用户使用');
92
+ }
93
+ user.email = email;
94
+ }
95
+
96
+ if (telnumber) {
97
+ // 检查手机号是否被其他用户使用
98
+ const existingUser = await manager.findOne(YtUserEntity, {
99
+ where: { telnumber } as any
100
+ });
101
+ if (existingUser && existingUser.id !== id) {
102
+ throw new Error('手机号已被其他用户使用');
103
+ }
104
+ user.telnumber = telnumber;
105
+ }
106
+
107
+ user.updateDate = new Date();
108
+ return await manager.save(user);
109
+ },
110
+ 'SERIALIZABLE' // 使用最高隔离级别,防止并发更新冲突
111
+ );
112
+
113
+ ctx.body = {
114
+ success: true,
115
+ message: '用户更新成功',
116
+ data: result
117
+ };
118
+ ctx.status = 200;
119
+
120
+ } catch (error) {
121
+ logger.error('更新用户失败:', error as Error);
122
+ ctx.body = {
123
+ success: false,
124
+ message: error instanceof Error ? error.message : '更新用户失败',
125
+ error: '事务已回滚'
126
+ };
127
+ ctx.status = 500;
128
+ }
129
+ }
130
+
131
+ /**
132
+ * 示例 3: 批量创建用户
133
+ * POST /api/example/transaction/batch-create
134
+ */
135
+ @Post('/batch-create')
136
+ async batchCreateUsers(ctx: Context) {
137
+ const { users } = ctx.request.body; // [{ email, telnumber, password }, ...]
138
+
139
+ try {
140
+ const operations = users.map((userData: any) => {
141
+ return async (manager: any) => {
142
+ // 验证数据
143
+ if (!userData.email || !userData.password) {
144
+ throw new Error('邮箱和密码不能为空');
145
+ }
146
+
147
+ // 加密密码
148
+ const hashedPassword = await bcrypt.hash(userData.password, 10);
149
+
150
+ // 创建用户
151
+ const user = new YtUserEntity();
152
+ user.email = userData.email;
153
+ user.telnumber = userData.telnumber;
154
+ user.password = hashedPassword;
155
+ user.createDate = new Date();
156
+ user.updateDate = new Date();
157
+
158
+ return await manager.save(user);
159
+ };
160
+ });
161
+
162
+ const results = await transactionManager.executeBatchTransaction(operations);
163
+
164
+ ctx.body = {
165
+ success: true,
166
+ message: `成功创建 ${results.length} 个用户`,
167
+ data: results
168
+ };
169
+ ctx.status = 200;
170
+
171
+ } catch (error) {
172
+ logger.error('批量创建用户失败:', error as Error);
173
+ ctx.body = {
174
+ success: false,
175
+ message: '批量创建用户失败,所有更改已回滚',
176
+ error: error instanceof Error ? error.message : '未知错误'
177
+ };
178
+ ctx.status = 500;
179
+ }
180
+ }
181
+
182
+ /**
183
+ * 示例 4: 删除用户(演示事务回滚)
184
+ * DELETE /api/example/transaction/delete-user/:id
185
+ */
186
+ @Del('/delete-user/:id')
187
+ async deleteUser(ctx: Context) {
188
+ const id = parseInt(ctx.params.id);
189
+
190
+ try {
191
+ await transactionManager.executeInTransaction(async (manager) => {
192
+ // 查找用户
193
+ const user = await manager.findOne(YtUserEntity, {
194
+ where: { id } as any
195
+ });
196
+
197
+ if (!user) {
198
+ throw new Error('用户不存在');
199
+ }
200
+
201
+ // 模拟业务规则:不允许删除管理员用户
202
+ if (user.userType && String(user.userType) === 'admin') {
203
+ throw new Error('不能删除管理员用户');
204
+ }
205
+
206
+ // 删除用户
207
+ await manager.remove(user);
208
+
209
+ // 模拟额外操作(如果有的话)
210
+ // await manager.save(DeleteLog, { userId: id });
211
+ });
212
+
213
+ ctx.body = {
214
+ success: true,
215
+ message: '用户删除成功'
216
+ };
217
+ ctx.status = 200;
218
+
219
+ } catch (error) {
220
+ logger.error('删除用户失败:', error as Error);
221
+ ctx.body = {
222
+ success: false,
223
+ message: error instanceof Error ? error.message : '删除用户失败',
224
+ error: '事务已回滚'
225
+ };
226
+ ctx.status = 500;
227
+ }
228
+ }
229
+
230
+ /**
231
+ * 示例 5: 查询统计(使用只读事务)
232
+ * GET /api/example/transaction/stats
233
+ */
234
+ @Get('/stats')
235
+ async getStats(ctx: Context) {
236
+ try {
237
+ const stats = await transactionManager.executeInReadOnlyTransaction(async (manager) => {
238
+ // 只读事务,不会产生任何写操作
239
+ const totalUsers = await manager.count(YtUserEntity);
240
+ const activeUsers = await manager.count(YtUserEntity, {
241
+ where: { status: 'normal' } as any
242
+ });
243
+
244
+ const users = await manager.find(YtUserEntity, {
245
+ take: 10,
246
+ order: { createDate: 'DESC' } as any
247
+ });
248
+
249
+ return {
250
+ total: totalUsers,
251
+ active: activeUsers,
252
+ inactive: totalUsers - activeUsers,
253
+ recentUsers: users
254
+ };
255
+ });
256
+
257
+ ctx.body = {
258
+ success: true,
259
+ data: stats
260
+ };
261
+ ctx.status = 200;
262
+
263
+ } catch (error) {
264
+ logger.error('获取统计信息失败:', error as Error);
265
+ ctx.body = {
266
+ success: false,
267
+ message: '获取统计信息失败'
268
+ };
269
+ ctx.status = 500;
270
+ }
271
+ }
272
+
273
+ /**
274
+ * 示例 6: 复杂业务场景 - 用户迁移
275
+ * POST /api/example/transaction/migrate-user
276
+ */
277
+ @Post('/migrate-user')
278
+ async migrateUser(ctx: Context) {
279
+ const { fromUserId, toEmail } = ctx.request.body;
280
+
281
+ try {
282
+ const result = await transactionManager.executeInTransaction(async (manager) => {
283
+ // 步骤 1: 查找原用户
284
+ const fromUser = await manager.findOne(YtUserEntity, {
285
+ where: { id: fromUserId } as any
286
+ });
287
+
288
+ if (!fromUser) {
289
+ throw new Error('原用户不存在');
290
+ }
291
+
292
+ // 步骤 2: 检查新邮箱是否已使用
293
+ const existingUser = await manager.findOne(YtUserEntity, {
294
+ where: { email: toEmail } as any
295
+ });
296
+
297
+ if (existingUser) {
298
+ throw new Error('新邮箱已被使用');
299
+ }
300
+
301
+ // 步骤 3: 创建新用户(复制数据)
302
+ const newUser = new YtUserEntity();
303
+ newUser.email = toEmail;
304
+ newUser.telnumber = fromUser.telnumber;
305
+ newUser.password = fromUser.password;
306
+ newUser.createDate = new Date();
307
+ newUser.updateDate = new Date();
308
+ const savedNewUser = await manager.save(newUser);
309
+
310
+ // 步骤 4: 删除原用户
311
+ await manager.remove(fromUser);
312
+
313
+ return {
314
+ oldUser: fromUser,
315
+ newUser: savedNewUser
316
+ };
317
+ });
318
+
319
+ ctx.body = {
320
+ success: true,
321
+ message: '用户迁移成功',
322
+ data: result
323
+ };
324
+ ctx.status = 200;
325
+
326
+ } catch (error) {
327
+ logger.error('用户迁移失败:', error as Error);
328
+ ctx.body = {
329
+ success: false,
330
+ message: error instanceof Error ? error.message : '用户迁移失败',
331
+ error: '所有操作已回滚'
332
+ };
333
+ ctx.status = 500;
334
+ }
335
+ }
336
+ }