create-dp-koa 1.0.1 → 1.0.2
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/package.json +1 -1
- package/template/.cursor/commands/cheatsheet-backend-controller.md +2 -2
- package/template/.cursor/commands/implement-backend-api-controller.md +6 -4
- package/template/.cursor/rules/11-backend-controller-recipes.skill.md +89 -10
- package/template/.trae/skills/11-backend-controller-recipes.skill.md +91 -10
- package/template/src/controllers/example/ExampleController.ts +14 -0
- package/template/src/entity/index.ts +1 -15
- package/template/src/framework/decorator/processor/AnnotationProcessor.ts +5 -1
- package/template/src/routers/index.ts +0 -35
- package/template/src/utils/testDataInitializer.ts +2 -269
- package/template/test/controllers/example/ExampleController.test.ts +29 -31
- package/template/test/framework/annotation/AnnotationDecorators.test.ts +15 -15
- package/template/test/framework/annotation/AnnotationExecutor.test.ts +27 -32
- package/template/test/framework/annotation/AnnotationProcessor.test.ts +25 -24
- package/template/test/framework/annotation/CustomProcessors.test.ts +15 -25
- package/template/test/framework/annotation/NewRouter.test.ts +9 -7
- package/template/test/framework/annotation/ProcessorManager.test.ts +14 -27
- package/template/test/framework/databaseConfig.test.ts +2 -2
- package/template/test/integration/integration.test.ts +15 -72
- package/template/src/controllers/cacheManagement.controller.ts +0 -131
- package/template/src/controllers/captcha.controller.ts +0 -57
- package/template/src/controllers/example/NewAnnotationExampleController.ts +0 -159
- package/template/src/controllers/example/SwaggerExampleController.ts +0 -205
- package/template/src/controllers/example/TransactionExample.controller.ts +0 -336
- package/template/src/controllers/health.controller.ts +0 -235
- package/template/src/controllers/home/register.controller.ts +0 -58
- package/template/src/controllers/home/ytGoods.controller.ts +0 -92
- package/template/src/controllers/home/ytShop.controller.ts +0 -135
- package/template/src/controllers/home/ytUser.controller.ts +0 -89
- package/template/src/controllers/logManagement.controller.ts +0 -396
- package/template/src/controllers/public/emailSend.controller.ts +0 -65
- package/template/src/controllers/public/ytUserAuth.controller.ts +0 -174
- package/template/src/controllers/testData.controller.ts +0 -253
- package/template/src/dto/controller/example/NewAnnotationExampleController.dto.ts +0 -73
- package/template/src/dto/controller/home/emailSend.controller.dto.ts +0 -40
- package/template/src/dto/controller/home/register.controller.dto.ts +0 -45
- package/template/src/dto/controller/home/ytGoods.controller.dto.ts +0 -55
- package/template/src/dto/controller/home/ytShop.controller.dto.ts +0 -69
- package/template/src/dto/controller/home/ytUser.controller.dto.ts +0 -44
- package/template/src/dto/controller/public/ytUserAuth.controller.dto.ts +0 -63
- package/template/src/dto/goods.dto.ts +0 -212
- package/template/src/dto/service/ytService.dto.ts +0 -13
- package/template/src/dto/user.dto.ts +0 -177
- package/template/src/entity/columnTypes.ts +0 -13
- package/template/src/entity/goodsImagesUnlockKey.entity.ts +0 -33
- package/template/src/entity/goodsUnlocker.entity.ts +0 -34
- package/template/src/entity/shop.entity.ts +0 -52
- package/template/src/entity/shopUser.entity.ts +0 -41
- package/template/src/entity/ytGoods.entity.ts +0 -94
- package/template/src/entity/ytUser.entity.ts +0 -96
- package/template/src/examples/SwaggerProcessorExample.ts +0 -169
- package/template/src/examples/TransactionManagerDemo.ts +0 -377
- package/template/src/framework/utils/dynamicSwagger.ts +0 -410
- package/template/src/repository/UserRepository.ts +0 -122
- package/template/src/service/paramValidateTest.service.ts +0 -139
- package/template/src/service/ytGoods.service.ts +0 -42
- package/template/src/service/ytShop.service.ts +0 -90
- package/template/src/service/ytUser.service.ts +0 -451
- package/template/src/test/swaggerParameterTest.ts +0 -90
- package/template/test/controllers/controllers.test.ts +0 -173
- package/template/test/controllers/example/NewAnnotationExampleController.test.ts +0 -200
- package/template/test/framework/TransactionManagerDemo.test.ts +0 -363
- package/template/test/service/business.test.ts +0 -87
- package/template/test/service/paramValidateTest.service.test.ts +0 -184
- package/template/test/service/ytUser.service.test.ts +0 -566
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import { Get } from '@src/framework/decorator/controller';
|
|
2
|
-
import { BaseController } from '@src/controllers/base.controller';
|
|
3
|
-
import { dbMonitor } from '@src/framework/utils/dbMonitor';
|
|
4
|
-
import { isDbConnected, getDataSource } from '@src/framework/utils/db';
|
|
5
|
-
import { getCacheStats, getCacheMemoryUsage } from '@src/framework/utils/cache';
|
|
6
|
-
import { metricsCollector } from '@src/framework/utils/metrics';
|
|
7
|
-
import { logger } from '@src/framework/utils/logger';
|
|
8
|
-
import { getRuntimeEnvironmentLabel } from '@src/framework/utils/function';
|
|
9
|
-
|
|
10
|
-
export class HealthController extends BaseController {
|
|
11
|
-
|
|
12
|
-
@Get("/")
|
|
13
|
-
async healthCheck() {
|
|
14
|
-
const dbStatus = isDbConnected();
|
|
15
|
-
const poolStatus = await dbMonitor.getConnectionPoolStatus();
|
|
16
|
-
const cacheStats = getCacheStats();
|
|
17
|
-
const cacheMemory = getCacheMemoryUsage();
|
|
18
|
-
|
|
19
|
-
return this.success({
|
|
20
|
-
status: 'ok',
|
|
21
|
-
timestamp: new Date().toISOString(),
|
|
22
|
-
database: {
|
|
23
|
-
connected: dbStatus,
|
|
24
|
-
pool: poolStatus
|
|
25
|
-
},
|
|
26
|
-
cache: {
|
|
27
|
-
stats: cacheStats,
|
|
28
|
-
memory: cacheMemory
|
|
29
|
-
},
|
|
30
|
-
uptime: process.uptime(),
|
|
31
|
-
memory: {
|
|
32
|
-
used: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
|
|
33
|
-
total: Math.round(process.memoryUsage().heapTotal / 1024 / 1024),
|
|
34
|
-
rss: Math.round(process.memoryUsage().rss / 1024 / 1024)
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
@Get('/db')
|
|
40
|
-
async dbHealthCheck() {
|
|
41
|
-
const dbStatus = isDbConnected();
|
|
42
|
-
const poolStatus = await dbMonitor.getConnectionPoolStatus();
|
|
43
|
-
|
|
44
|
-
if (!dbStatus) {
|
|
45
|
-
return this.fail(500, '数据库连接异常');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return this.success({
|
|
49
|
-
connected: dbStatus,
|
|
50
|
-
pool: poolStatus
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
@Get('/cache')
|
|
55
|
-
async cacheHealthCheck() {
|
|
56
|
-
const cacheStats = getCacheStats();
|
|
57
|
-
const cacheMemory = getCacheMemoryUsage();
|
|
58
|
-
|
|
59
|
-
// 检查是否有缓存使用率过高
|
|
60
|
-
const highUsageCaches = Object.entries(cacheMemory).filter(([name, info]: [string, any]) => {
|
|
61
|
-
return parseFloat(info.usage) > 80; // 使用率超过80%
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
if (highUsageCaches.length > 0) {
|
|
65
|
-
return this.fail(500, `缓存使用率过高: ${highUsageCaches.map(([name]) => name).join(', ')}`);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return this.success({
|
|
69
|
-
stats: cacheStats,
|
|
70
|
-
memory: cacheMemory,
|
|
71
|
-
status: 'healthy'
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* 企业级详细健康检查
|
|
77
|
-
*/
|
|
78
|
-
@Get('/detailed')
|
|
79
|
-
async detailedHealthCheck() {
|
|
80
|
-
const health = {
|
|
81
|
-
status: 'healthy',
|
|
82
|
-
timestamp: new Date().toISOString(),
|
|
83
|
-
uptime: process.uptime(),
|
|
84
|
-
pid: process.pid,
|
|
85
|
-
version: process.env.npm_package_version || '1.0.0',
|
|
86
|
-
environment: getRuntimeEnvironmentLabel(),
|
|
87
|
-
checks: {
|
|
88
|
-
database: await this.checkDatabase(),
|
|
89
|
-
memory: this.checkMemory(),
|
|
90
|
-
cache: await this.checkCache()
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
// 检查是否有任何检查失败
|
|
95
|
-
const failedChecks = Object.values(health.checks).filter((check: any) => check.status !== 'healthy');
|
|
96
|
-
if (failedChecks.length > 0) {
|
|
97
|
-
health.status = 'unhealthy';
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return this.success(health);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* 就绪检查
|
|
105
|
-
*/
|
|
106
|
-
@Get('/ready')
|
|
107
|
-
async readinessCheck() {
|
|
108
|
-
const checks = {
|
|
109
|
-
database: await this.checkDatabase()
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const isReady = Object.values(checks).every((check: any) => check.status === 'healthy');
|
|
113
|
-
|
|
114
|
-
return this.success({
|
|
115
|
-
status: isReady ? 'ready' : 'not_ready',
|
|
116
|
-
timestamp: new Date().toISOString(),
|
|
117
|
-
checks
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* 存活检查
|
|
123
|
-
*/
|
|
124
|
-
@Get('/live')
|
|
125
|
-
async livenessCheck() {
|
|
126
|
-
return this.success({
|
|
127
|
-
status: 'alive',
|
|
128
|
-
timestamp: new Date().toISOString(),
|
|
129
|
-
pid: process.pid,
|
|
130
|
-
uptime: process.uptime()
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* 指标端点
|
|
136
|
-
*/
|
|
137
|
-
@Get('/metrics')
|
|
138
|
-
async metrics() {
|
|
139
|
-
return this.success({
|
|
140
|
-
prometheus: metricsCollector.generatePrometheusMetrics(),
|
|
141
|
-
json: metricsCollector.getSystemMetrics()
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* 检查数据库连接
|
|
147
|
-
*/
|
|
148
|
-
private async checkDatabase(): Promise<any> {
|
|
149
|
-
try {
|
|
150
|
-
const dataSource = getDataSource();
|
|
151
|
-
if (!dataSource) {
|
|
152
|
-
return {
|
|
153
|
-
status: 'unhealthy',
|
|
154
|
-
message: 'Database not initialized'
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (!dataSource.isInitialized) {
|
|
159
|
-
return {
|
|
160
|
-
status: 'unhealthy',
|
|
161
|
-
message: 'Database not connected'
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// 执行简单查询测试连接
|
|
166
|
-
await dataSource.query('SELECT 1');
|
|
167
|
-
|
|
168
|
-
return {
|
|
169
|
-
status: 'healthy',
|
|
170
|
-
message: 'Database connection OK',
|
|
171
|
-
type: dataSource.options.type
|
|
172
|
-
};
|
|
173
|
-
} catch (error) {
|
|
174
|
-
logger.error('Database health check failed', error as Error);
|
|
175
|
-
return {
|
|
176
|
-
status: 'unhealthy',
|
|
177
|
-
message: 'Database connection failed',
|
|
178
|
-
error: (error as Error).message
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* 检查内存使用
|
|
185
|
-
*/
|
|
186
|
-
private checkMemory(): any {
|
|
187
|
-
const memUsage = process.memoryUsage();
|
|
188
|
-
const maxMemory = 500 * 1024 * 1024; // 500MB
|
|
189
|
-
const isHealthy = memUsage.heapUsed < maxMemory;
|
|
190
|
-
|
|
191
|
-
return {
|
|
192
|
-
status: isHealthy ? 'healthy' : 'unhealthy',
|
|
193
|
-
message: isHealthy ? 'Memory usage OK' : 'Memory usage high',
|
|
194
|
-
details: {
|
|
195
|
-
heapUsed: memUsage.heapUsed,
|
|
196
|
-
heapTotal: memUsage.heapTotal,
|
|
197
|
-
rss: memUsage.rss,
|
|
198
|
-
external: memUsage.external
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* 检查缓存状态
|
|
205
|
-
*/
|
|
206
|
-
private async checkCache(): Promise<any> {
|
|
207
|
-
try {
|
|
208
|
-
const cacheStats = getCacheStats();
|
|
209
|
-
const cacheMemory = getCacheMemoryUsage();
|
|
210
|
-
|
|
211
|
-
// 检查是否有缓存使用率过高
|
|
212
|
-
const highUsageCaches = Object.entries(cacheMemory).filter(([name, info]: [string, any]) => {
|
|
213
|
-
return parseFloat(info.usage) > 80;
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
const isHealthy = highUsageCaches.length === 0;
|
|
217
|
-
|
|
218
|
-
return {
|
|
219
|
-
status: isHealthy ? 'healthy' : 'unhealthy',
|
|
220
|
-
message: isHealthy ? 'Cache status OK' : 'Cache usage high',
|
|
221
|
-
details: {
|
|
222
|
-
stats: cacheStats,
|
|
223
|
-
memory: cacheMemory,
|
|
224
|
-
highUsageCaches: highUsageCaches.map(([name]) => name)
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
} catch (error) {
|
|
228
|
-
return {
|
|
229
|
-
status: 'unhealthy',
|
|
230
|
-
message: 'Cache check failed',
|
|
231
|
-
error: (error as Error).message
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { BaseController, ControllerResponse } from "@src/controllers/base.controller";
|
|
2
|
-
import { Body, Post } from "@src/framework/decorator/controller";
|
|
3
|
-
import { YtUserRegisterDto } from "@src/dto/controller/home/register.controller.dto";
|
|
4
|
-
import * as jwt from "jsonwebtoken";
|
|
5
|
-
import { Inject } from "dp-ioc2";
|
|
6
|
-
import md5 from "md5"
|
|
7
|
-
import { YtUserService } from "@src/service/ytUser.service";
|
|
8
|
-
import { YtUserEntity } from "@src/entity/ytUser.entity";
|
|
9
|
-
import { logger } from "@src/framework/utils/logger";
|
|
10
|
-
|
|
11
|
-
interface IvcodeInfo {
|
|
12
|
-
vcode: string
|
|
13
|
-
expire: number
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export class YtUserRegisterController extends BaseController {
|
|
17
|
-
|
|
18
|
-
@Inject(YtUserService)
|
|
19
|
-
ytUserService: YtUserService;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@Post()
|
|
23
|
-
async register(
|
|
24
|
-
@Body(YtUserRegisterDto) body: YtUserRegisterDto
|
|
25
|
-
): Promise<ControllerResponse<boolean>> {
|
|
26
|
-
|
|
27
|
-
let vcodeInfo: IvcodeInfo | null = null;
|
|
28
|
-
try {
|
|
29
|
-
vcodeInfo = jwt.verify(body.vcodeToken, process.env.jwt_secret ?? "123456") as any;
|
|
30
|
-
} catch (err) {
|
|
31
|
-
throw "验证码解析异常";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!vcodeInfo) {
|
|
35
|
-
return this.fail(-1, "验证码解析失败");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (vcodeInfo?.expire < new Date().getTime()) {
|
|
39
|
-
return this.fail(-1, "验证码过期");
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// 验证是否已经完成注册
|
|
43
|
-
const exist = await this.ytUserService.findByEmail(body.email);
|
|
44
|
-
if (exist) {
|
|
45
|
-
|
|
46
|
-
// return this.fail(-1, "邮箱已经注册");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// 开始注册
|
|
50
|
-
const ytUser = new YtUserEntity();
|
|
51
|
-
ytUser.nickName = '新用户';
|
|
52
|
-
ytUser.email = body.email;
|
|
53
|
-
ytUser.password = md5(body.password);
|
|
54
|
-
await this.ytUserService.add(ytUser);
|
|
55
|
-
|
|
56
|
-
return this.success(true, "注册成功")
|
|
57
|
-
}
|
|
58
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { Body, ControllerCache, Get, Post, Query, State } from "@src/framework/decorator/controller";
|
|
2
|
-
import { BaseController, ControllerResponse } from "@src/controllers/base.controller";
|
|
3
|
-
import { GetGoodsInfoDto, GetGoodsInfoResultDto, GetGoodsUnlockInfoDto, UnlockGoodsImageDto } from "@src/dto/controller/home/ytGoods.controller.dto";
|
|
4
|
-
import { Inject } from "dp-ioc2";
|
|
5
|
-
import { YtGoodsService } from "@src/service/ytGoods.service";
|
|
6
|
-
import { YtGoodsEntity } from "@src/entity/ytGoods.entity";
|
|
7
|
-
import { CommonServiceResultCode } from "@src/framework/types/ServiceResult";
|
|
8
|
-
import { isDebug } from "@src/framework/utils/function";
|
|
9
|
-
import { YtGoodsUnlockerEntity } from "@src/entity/goodsUnlocker.entity";
|
|
10
|
-
|
|
11
|
-
export class YtGoodsController extends BaseController {
|
|
12
|
-
|
|
13
|
-
@Inject(YtGoodsService)
|
|
14
|
-
goodsService: YtGoodsService;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 解锁商品图片
|
|
18
|
-
* @param body
|
|
19
|
-
*/
|
|
20
|
-
@Post()
|
|
21
|
-
async unlockGoodsImage(
|
|
22
|
-
@Body(UnlockGoodsImageDto) body: UnlockGoodsImageDto,
|
|
23
|
-
@State() state: any
|
|
24
|
-
): Promise<ControllerResponse<boolean>> {
|
|
25
|
-
|
|
26
|
-
const result = await this.goodsService.unlockGoodsImage(
|
|
27
|
-
body.goodsId,
|
|
28
|
-
state.user.userId,
|
|
29
|
-
body.key
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
if (result.code !== CommonServiceResultCode.SUCCESS) {
|
|
33
|
-
return this.fail(-1, result.message || "解锁失败");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return this.success(true);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
@ControllerCache((query: GetGoodsInfoDto) => `YtGoodsController-getGoodsInfo-${query.id}`, {
|
|
40
|
-
ttl: {
|
|
41
|
-
max: 60 * 5,
|
|
42
|
-
min: 30,
|
|
43
|
-
},
|
|
44
|
-
enable: !isDebug()
|
|
45
|
-
})
|
|
46
|
-
@Get()
|
|
47
|
-
async getGoodsInfo(
|
|
48
|
-
@Query(GetGoodsInfoDto) query: GetGoodsInfoDto
|
|
49
|
-
): Promise<ControllerResponse<GetGoodsInfoResultDto>> {
|
|
50
|
-
|
|
51
|
-
const goods = await this.goodsService.getById(YtGoodsEntity, query.id);
|
|
52
|
-
if (!goods) {
|
|
53
|
-
return this.fail(-1, "查询商品失败");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return this.success({
|
|
57
|
-
id: goods.id,
|
|
58
|
-
name: goods.name,
|
|
59
|
-
albums: goods.albums,
|
|
60
|
-
tags: goods.tags,
|
|
61
|
-
price: goods.price,
|
|
62
|
-
description: goods.description,
|
|
63
|
-
content: goods.content,
|
|
64
|
-
imagesContent: goods.imagesContent
|
|
65
|
-
})
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// @ControllerCache((query: GetGoodsUnlockInfoDto) => `YtGoodsController-getGoodsUnlockInfo-${query.goodsId}`, {
|
|
69
|
-
// ttl: {
|
|
70
|
-
// max: 60 * 2,
|
|
71
|
-
// min: 30,
|
|
72
|
-
// },
|
|
73
|
-
// enable: !isDebug()
|
|
74
|
-
// })
|
|
75
|
-
@Get()
|
|
76
|
-
async getGoodsUnlockInfo(
|
|
77
|
-
@Query(GetGoodsUnlockInfoDto) query: GetGoodsUnlockInfoDto,
|
|
78
|
-
@State() state: any,
|
|
79
|
-
): Promise<ControllerResponse<boolean | null>> {
|
|
80
|
-
|
|
81
|
-
const result = await this.goodsService.getDataRepository(YtGoodsUnlockerEntity).findOne({
|
|
82
|
-
where: {
|
|
83
|
-
ytUserId: state.user.userId,
|
|
84
|
-
goodsId: query.goodsId,
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
if (result) {
|
|
88
|
-
return this.success(true);
|
|
89
|
-
}
|
|
90
|
-
return this.success(false);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { Inject } from "dp-ioc2"
|
|
2
|
-
import { BaseController, ControllerResponse } from "@src/controllers/base.controller"
|
|
3
|
-
import { YtShopService } from "@src/service/ytShop.service"
|
|
4
|
-
import { Get, Query, ResponseValidateIf, State } from "@src/framework/decorator/controller";
|
|
5
|
-
import { GetShopGoodsListQueryDto, GetShopGoodsListResultDto, GetShopInfoByIdQueryDto, GetShopInfoByIdResultDto, GetShopUserInfoDto } from "@src/dto/controller/home/ytShop.controller.dto";
|
|
6
|
-
import { ShopEntity, ShopStatusEnum } from "@src/entity/shop.entity";
|
|
7
|
-
import { CommonServiceResultCode } from "@src/framework/types/ServiceResult";
|
|
8
|
-
import { getUserInfoByIdDto, GetUserInfoResponseDto } from "@src/dto/controller/home/ytUser.controller.dto";
|
|
9
|
-
import { createCache, CacheType } from "@src/framework/utils/cache";
|
|
10
|
-
import { YtUserService } from "@src/service/ytUser.service";
|
|
11
|
-
import { YtUserEntity } from "@src/entity/ytUser.entity";
|
|
12
|
-
|
|
13
|
-
// 创建店铺用户缓存实例
|
|
14
|
-
const shopUserCache = createCache('yt-shop-user-controller', CacheType.USER, {
|
|
15
|
-
stdTTL: 1800, // 30分钟过期
|
|
16
|
-
maxKeys: 500
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export class YtShopController extends BaseController {
|
|
21
|
-
|
|
22
|
-
@Inject(YtShopService)
|
|
23
|
-
ytShopService: YtShopService;
|
|
24
|
-
|
|
25
|
-
@Inject(YtUserService)
|
|
26
|
-
ytUserService: YtUserService
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* 读取店铺的基本信息
|
|
31
|
-
* @param state
|
|
32
|
-
* @returns
|
|
33
|
-
*/
|
|
34
|
-
@ResponseValidateIf(GetShopInfoByIdResultDto, (data) => data && data.data)
|
|
35
|
-
@Get()
|
|
36
|
-
async getShopInfoById(
|
|
37
|
-
@Query(GetShopInfoByIdQueryDto) query: GetShopInfoByIdQueryDto
|
|
38
|
-
): Promise<ControllerResponse<GetShopInfoByIdResultDto | null>> {
|
|
39
|
-
|
|
40
|
-
const shop = await this.ytShopService.getById(ShopEntity, query.id);
|
|
41
|
-
if (!shop) {
|
|
42
|
-
return this.fail(-1, "店铺不存在");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (shop.status == ShopStatusEnum.FORBIDDEN) {
|
|
46
|
-
return this.fail(-1, "店铺已被禁用");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// 读取 店铺用户的基本信息
|
|
50
|
-
const shopUserResult = await this.ytShopService.getShopUserInfo(shop.id);
|
|
51
|
-
if (shopUserResult.code != CommonServiceResultCode.SUCCESS) {
|
|
52
|
-
return this.fail(-1, "店铺用户信息加载失败");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return this.success({
|
|
56
|
-
id: shop.id,
|
|
57
|
-
name: shop.name,
|
|
58
|
-
description: shop.description,
|
|
59
|
-
userId: shopUserResult.data?.id ?? 0,
|
|
60
|
-
// avatar: shopUserResult.data?.avatar ?? "",
|
|
61
|
-
status: shop.status,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 获取店铺的商品列表
|
|
67
|
-
* @param query
|
|
68
|
-
*/
|
|
69
|
-
@Get()
|
|
70
|
-
async getShopGoodsList(
|
|
71
|
-
@Query(GetShopGoodsListQueryDto) query: GetShopGoodsListQueryDto
|
|
72
|
-
): Promise<ControllerResponse<[GetShopGoodsListResultDto[], number]>> {
|
|
73
|
-
const { id, page = 1, pageSize = 10 } = query;
|
|
74
|
-
const result = await this.ytShopService.getGoodsListByShopId(id, page, pageSize);
|
|
75
|
-
if (result.code != CommonServiceResultCode.SUCCESS) {
|
|
76
|
-
return this.fail(-1, result.message);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// 过滤出精简信息
|
|
80
|
-
const responseData = result.data?.[0].map(item => {
|
|
81
|
-
return {
|
|
82
|
-
id: item.id,
|
|
83
|
-
name: item.name,
|
|
84
|
-
description: item.description,
|
|
85
|
-
price: item.price,
|
|
86
|
-
albums: item.albums,
|
|
87
|
-
}
|
|
88
|
-
}) ?? []
|
|
89
|
-
return this.success([responseData, result.data?.[1] ?? 0]);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
@ResponseValidateIf(GetUserInfoResponseDto, (data) => data && data.data)
|
|
93
|
-
@Get()
|
|
94
|
-
async getShopUserInfo(
|
|
95
|
-
@Query(GetShopUserInfoDto) query: GetShopUserInfoDto
|
|
96
|
-
)
|
|
97
|
-
: Promise<ControllerResponse<null | GetUserInfoResponseDto>> {
|
|
98
|
-
|
|
99
|
-
const cacheKey = `shop_user_${query.shopId}`;
|
|
100
|
-
const user = shopUserCache.get(cacheKey);
|
|
101
|
-
if (user) {
|
|
102
|
-
return this.success({
|
|
103
|
-
id: user.id,
|
|
104
|
-
nickName: user.nickName,
|
|
105
|
-
status: user.status,
|
|
106
|
-
email: user.email,
|
|
107
|
-
type: user.userType,
|
|
108
|
-
avatar: user.avatar,
|
|
109
|
-
gender: user.gender,
|
|
110
|
-
age: user.age,
|
|
111
|
-
constellation: user.constellation,
|
|
112
|
-
})
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const getUserResult = await this.ytShopService.getShopUserInfo(query.shopId);
|
|
116
|
-
if (getUserResult.code != CommonServiceResultCode.SUCCESS) {
|
|
117
|
-
return this.fail(-1, getUserResult.message)
|
|
118
|
-
}
|
|
119
|
-
const _user = getUserResult.data as YtUserEntity;
|
|
120
|
-
shopUserCache.set(cacheKey, _user);
|
|
121
|
-
|
|
122
|
-
return this.success({
|
|
123
|
-
id: _user.id,
|
|
124
|
-
nickName: _user.nickName,
|
|
125
|
-
status: _user.status,
|
|
126
|
-
email: _user.email,
|
|
127
|
-
type: _user.userType,
|
|
128
|
-
avatar: _user.avatar,
|
|
129
|
-
gender: _user.gender,
|
|
130
|
-
age: _user.age,
|
|
131
|
-
constellation: _user.constellation,
|
|
132
|
-
})
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { Get, Query, ResponseValidateIf, ResponseValidator, State } from "@src/framework/decorator/controller";
|
|
2
|
-
import { BaseController, ControllerResponse } from "@src/controllers/base.controller";
|
|
3
|
-
import { logger } from "@src/framework/utils/logger";
|
|
4
|
-
import { Inject } from "dp-ioc2";
|
|
5
|
-
import { YtUserService } from "@src/service/ytUser.service";
|
|
6
|
-
import { YtUserEntity } from "@src/entity/ytUser.entity";
|
|
7
|
-
import { createCache, CacheType } from "@src/framework/utils/cache";
|
|
8
|
-
import { CommonServiceResultCode } from "@src/framework/types/ServiceResult";
|
|
9
|
-
import { getUserInfoByIdDto, GetUserInfoResponseDto } from "@src/dto/controller/home/ytUser.controller.dto";
|
|
10
|
-
import { YtShopService } from "@src/service/ytShop.service";
|
|
11
|
-
|
|
12
|
-
// 创建用户缓存实例
|
|
13
|
-
const userCache = createCache('yt-user-controller', CacheType.USER, {
|
|
14
|
-
stdTTL: 1800, // 30分钟过期
|
|
15
|
-
maxKeys: 500
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export class YtUserController extends BaseController {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@Inject(YtUserService)
|
|
24
|
-
ytUserService: YtUserService;
|
|
25
|
-
|
|
26
|
-
@Inject(YtShopService)
|
|
27
|
-
ytShopService: YtShopService;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@ResponseValidateIf(GetUserInfoResponseDto, (data) => data && data.data)
|
|
31
|
-
@Get()
|
|
32
|
-
async getUserInfo(@State() state: any)
|
|
33
|
-
: Promise<ControllerResponse<null | GetUserInfoResponseDto>> {
|
|
34
|
-
|
|
35
|
-
const cacheKey = `user_${state.user.userId}`;
|
|
36
|
-
const user = userCache.get(cacheKey);
|
|
37
|
-
if (user) {
|
|
38
|
-
return this.success({
|
|
39
|
-
id: user.id,
|
|
40
|
-
nickName: user.nickName,
|
|
41
|
-
status: user.status,
|
|
42
|
-
email: user.email,
|
|
43
|
-
type: user.userType,
|
|
44
|
-
avatar: user.avatar,
|
|
45
|
-
gender: user.gender,
|
|
46
|
-
age: user.age,
|
|
47
|
-
constellation: user.constellation,
|
|
48
|
-
})
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const _user = await this.ytUserService.getById(YtUserEntity, state.user.userId);
|
|
52
|
-
if (!_user) {
|
|
53
|
-
return this.fail(-1, '用户不存在')
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
userCache.set(cacheKey, _user);
|
|
57
|
-
|
|
58
|
-
return this.success({
|
|
59
|
-
id: _user.id,
|
|
60
|
-
nickName: _user.nickName,
|
|
61
|
-
status: _user.status,
|
|
62
|
-
email: _user.email,
|
|
63
|
-
type: _user.userType,
|
|
64
|
-
avatar: _user.avatar,
|
|
65
|
-
gender: _user.gender,
|
|
66
|
-
age: _user.age,
|
|
67
|
-
constellation: _user.constellation,
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* 检查当前用户是否有店铺
|
|
74
|
-
* @param state
|
|
75
|
-
* @returns
|
|
76
|
-
*/
|
|
77
|
-
@Get()
|
|
78
|
-
async hasShop(
|
|
79
|
-
@State() state: any
|
|
80
|
-
): Promise<ControllerResponse<number | null>> {
|
|
81
|
-
|
|
82
|
-
const result = await this.ytShopService.checkHasShop(state.user.userId);
|
|
83
|
-
if (result.code != CommonServiceResultCode.SUCCESS) {
|
|
84
|
-
return this.fail(-1, result.message);
|
|
85
|
-
}
|
|
86
|
-
return this.success(result.data);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
}
|