create-dp-koa 1.1.2 → 1.1.3

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 (84) hide show
  1. package/package.json +1 -1
  2. package/template/scripts/sync-template.mjs +20 -0
  3. package/template/src/app.ts +1 -2
  4. package/template/src/{framework/plugins → plugins}/registry.ts +2 -2
  5. package/template/src/plugins/weboffice/http/routes.ts +1 -1
  6. package/template/src/plugins/weboffice/index.ts +3 -3
  7. package/template/src/plugins/weboffice/services/webofficeCallback.service.ts +3 -4
  8. package/template/src/utils/testDataInitializer.ts +1 -1
  9. package/template/tsconfig.json +6 -0
  10. package/template/src/annotations/decorators/ConfigManagement.ts +0 -9
  11. package/template/src/annotations/decorators/DistributedTracing.ts +0 -9
  12. package/template/src/annotations/decorators/EnterprisePerformance.ts +0 -9
  13. package/template/src/annotations/decorators/PerformanceMonitor.ts +0 -32
  14. package/template/src/annotations/decorators/SecurityAudit.ts +0 -9
  15. package/template/src/annotations/index.ts +0 -50
  16. package/template/src/annotations/processors/ConfigManagementProcessor.ts +0 -369
  17. package/template/src/annotations/processors/DistributedTracingProcessor.ts +0 -288
  18. package/template/src/annotations/processors/EnterprisePerformanceProcessor.ts +0 -189
  19. package/template/src/annotations/processors/PerformanceMonitorProcessor.ts +0 -101
  20. package/template/src/annotations/processors/SecurityAuditProcessor.ts +0 -345
  21. package/template/src/annotations/processors/SwaggerProcessor.ts +0 -612
  22. package/template/src/annotations/processors/index.ts +0 -10
  23. package/template/src/examples/InterceptorExampleRunner.ts +0 -284
  24. package/template/src/examples/ServiceInterceptorExample.ts +0 -214
  25. package/template/src/examples/cacheExamples.ts +0 -155
  26. package/template/src/framework/decorator/controller.ts +0 -311
  27. package/template/src/framework/decorator/processor/AnnotationDecorators.ts +0 -100
  28. package/template/src/framework/decorator/processor/AnnotationProcessor.ts +0 -160
  29. package/template/src/framework/decorator/processor/AnnotationProcessorConfig.ts +0 -45
  30. package/template/src/framework/decorator/processor/AnnotationRegistry.ts +0 -117
  31. package/template/src/framework/decorator/processor/AnnotationSystemInitializer.ts +0 -95
  32. package/template/src/framework/decorator/processor/ProcessorManager.ts +0 -76
  33. package/template/src/framework/decorator/processor/processors/CustomProcessors.ts +0 -126
  34. package/template/src/framework/decorator/processor/processors/DefaultProcessors.ts +0 -207
  35. package/template/src/framework/decorator/refactored/DecoratorFactory.ts +0 -99
  36. package/template/src/framework/decorator/refactored/DecoratorMetadataManager.ts +0 -125
  37. package/template/src/framework/decorator/refactored/DecoratorValidator.ts +0 -128
  38. package/template/src/framework/decorator/refactored/TypeSafeDecorators.ts +0 -139
  39. package/template/src/framework/decorator/refactored/index.ts +0 -98
  40. package/template/src/framework/decorator/swagger.ts +0 -150
  41. package/template/src/framework/interceptors/AdvancedServiceCallInterceptor.ts +0 -375
  42. package/template/src/framework/interceptors/ServiceCallInterceptor.ts +0 -348
  43. package/template/src/framework/interceptors/index.ts +0 -19
  44. package/template/src/framework/plugins/types.ts +0 -15
  45. package/template/src/framework/types/ServiceResult.ts +0 -151
  46. package/template/src/framework/types/index.ts +0 -16
  47. package/template/src/framework/utils/CacheManager.ts +0 -430
  48. package/template/src/framework/utils/CacheService.ts +0 -248
  49. package/template/src/framework/utils/DtoValidator.ts +0 -164
  50. package/template/src/framework/utils/MigrationHelper.ts +0 -179
  51. package/template/src/framework/utils/MigrationManager.ts +0 -256
  52. package/template/src/framework/utils/NewRouter.ts +0 -207
  53. package/template/src/framework/utils/TransactionManager.ts +0 -172
  54. package/template/src/framework/utils/bootstrap.ts +0 -445
  55. package/template/src/framework/utils/cache.ts +0 -269
  56. package/template/src/framework/utils/databaseConfig.ts +0 -148
  57. package/template/src/framework/utils/db.ts +0 -39
  58. package/template/src/framework/utils/dbMonitor.ts +0 -106
  59. package/template/src/framework/utils/function.ts +0 -61
  60. package/template/src/framework/utils/gracefulShutdown.ts +0 -131
  61. package/template/src/framework/utils/logger.ts +0 -388
  62. package/template/src/framework/utils/metrics.ts +0 -182
  63. package/template/src/framework/utils/router.ts +0 -417
  64. package/template/src/framework/utils/swagger.ts +0 -184
  65. package/template/src/framework/utils/testDb.ts +0 -19
  66. package/template/src/framework/utils/token.ts +0 -23
  67. package/template/src/framework/utils/transform.ts +0 -17
  68. package/template/src/libs/aokEmailSender.ts +0 -42
  69. package/template/src/libs/captcha.ts +0 -37
  70. package/template/src/libs/cos.ts +0 -45
  71. package/template/src/libs/mCache.ts +0 -7
  72. package/template/src/libs/serviceValidate.ts +0 -3
  73. package/template/src/libs/tecentSms.ts +0 -51
  74. package/template/src/middlewares/a.middleware.ts +0 -6
  75. package/template/src/middlewares/error.middleware.ts +0 -14
  76. package/template/src/middlewares/logging.middleware.ts +0 -187
  77. package/template/src/middlewares/static.middleware.ts +0 -79
  78. package/template/src/middlewares/swagger.middleware.ts +0 -70
  79. package/template/src/middlewares/token.middleware.ts +0 -32
  80. package/template/src/migrations/1700000000000-InitialDatabaseStructure.ts +0 -172
  81. package/template/src/migrations/index.ts +0 -6
  82. package/template/src/repository/base/BaseRepository.ts +0 -124
  83. package/template/src/repository/interfaces/IBaseRepository.ts +0 -67
  84. package/template/src/service/base.service.ts +0 -116
@@ -1,445 +0,0 @@
1
- import Koa from 'koa';
2
- const app = new Koa();
3
- import dotenv from 'dotenv';
4
- import "reflect-metadata";
5
- import koaBody from 'koa-body';
6
- const moduleAlias = require("module-alias");//路径别名
7
- import path from 'path';
8
- import type { Server } from 'http';
9
-
10
- // 首先设置路径别名
11
- moduleAlias.addAliases({
12
- "@src": path.join(process.cwd(), "./src"),
13
- });
14
-
15
- // import koaCros from "@koa/cors"
16
- const koaCros = require("@koa/cors")
17
- import { logger } from '@src/framework/utils/logger';
18
- import { isDebug } from '@src/framework/utils/function';
19
- import { router } from '@src/framework/utils/router';
20
- import { loggingMiddleware, businessLoggingMiddleware, databaseLoggingMiddleware } from '@src/middlewares/logging.middleware';
21
-
22
- // 开发/调试用 .env.development,生产用 .env.production(与 NODE_ENV 解耦:仅 `--env=debug` 走 development)
23
- const envFile = isDebug() ? '.env.development' : '.env.production';
24
- dotenv.config({ path: envFile });
25
-
26
- let beforeBootstraps: Function | null = null;
27
- let afterBootstraps: Function | null = null;
28
- let server: Server | null = null;
29
-
30
- /**
31
- * 企业级错误分类枚举
32
- */
33
- enum ErrorCategory {
34
- VALIDATION = 'VALIDATION_ERROR',
35
- AUTHENTICATION = 'AUTH_ERROR',
36
- AUTHORIZATION = 'AUTHZ_ERROR',
37
- BUSINESS_LOGIC = 'BUSINESS_ERROR',
38
- DATABASE = 'DATABASE_ERROR',
39
- EXTERNAL_SERVICE = 'EXTERNAL_SERVICE_ERROR',
40
- SYSTEM = 'SYSTEM_ERROR',
41
- NETWORK = 'NETWORK_ERROR',
42
- UNKNOWN = 'UNKNOWN_ERROR'
43
- }
44
-
45
- /**
46
- * 企业级错误码定义
47
- */
48
- enum ErrorCode {
49
- // 4xx 客户端错误
50
- INVALID_REQUEST = 'E400001',
51
- VALIDATION_FAILED = 'E400002',
52
- UNAUTHORIZED = 'E401001',
53
- FORBIDDEN = 'E403001',
54
- NOT_FOUND = 'E404001',
55
- METHOD_NOT_ALLOWED = 'E405001',
56
- CONFLICT = 'E409001',
57
-
58
- // 5xx 服务器错误
59
- INTERNAL_ERROR = 'E500001',
60
- DATABASE_ERROR = 'E500002',
61
- EXTERNAL_SERVICE_ERROR = 'E500003',
62
- SERVICE_UNAVAILABLE = 'E503001',
63
- TIMEOUT = 'E504001'
64
- }
65
-
66
- /**
67
- * 企业级错误处理中间件
68
- * 符合企业开发规范:错误分类、标准化错误码、安全防护、监控告警
69
- */
70
- const frameworkErrorMiddleware = () => {
71
- return async (ctx: any, next: Function) => {
72
- try {
73
- await next();
74
- } catch (err) {
75
- const error = err as any;
76
-
77
- // 1. 错误分类和标准化处理
78
- const errorInfo = classifyAndStandardizeError(error);
79
-
80
- // 2. 设置响应状态码
81
- ctx.status = errorInfo.statusCode;
82
-
83
- // 3. 安全信息过滤
84
- const sanitizedError = sanitizeErrorForLogging(error, ctx);
85
-
86
- // 4. 记录结构化错误日志
87
- logger.error('企业级异常处理', error as Error, {
88
- error: {
89
- category: errorInfo.category,
90
- code: errorInfo.code,
91
- message: sanitizedError.message,
92
- stack: sanitizedError.stack,
93
- statusCode: errorInfo.statusCode,
94
- severity: errorInfo.severity
95
- },
96
- request: {
97
- method: ctx.method,
98
- url: sanitizeUrl(ctx.url),
99
- userAgent: ctx.headers['user-agent'],
100
- ip: ctx.ip,
101
- requestId: ctx.requestId || 'unknown',
102
- userId: ctx.userId || 'anonymous'
103
- },
104
- context: {
105
- timestamp: new Date().toISOString(),
106
- environment: isDebug() ? 'development' : 'production',
107
- service: 'dp-koa-framework',
108
- version: process.env.npm_package_version || '1.0.0'
109
- }
110
- });
111
-
112
- // 5. 错误监控和告警(严重错误)
113
- if (errorInfo.severity === 'critical' || errorInfo.severity === 'high') {
114
- triggerErrorAlert(errorInfo, sanitizedError, ctx);
115
- }
116
-
117
- // 6. 标准化错误响应
118
- ctx.body = buildStandardErrorResponse(errorInfo, ctx);
119
-
120
- // 7. 设置安全响应头
121
- setSecurityHeaders(ctx);
122
- }
123
- };
124
- };
125
-
126
- /**
127
- * 错误分类和标准化处理
128
- */
129
- function classifyAndStandardizeError(error: any): {
130
- category: ErrorCategory;
131
- code: ErrorCode;
132
- statusCode: number;
133
- severity: 'low' | 'medium' | 'high' | 'critical';
134
- message: string;
135
- } {
136
- // 根据错误类型进行分类
137
- if (error.name === 'ValidationError' || error.name === 'CastError') {
138
- return {
139
- category: ErrorCategory.VALIDATION,
140
- code: ErrorCode.VALIDATION_FAILED,
141
- statusCode: 400,
142
- severity: 'low',
143
- message: '请求参数验证失败'
144
- };
145
- }
146
-
147
- if (error.name === 'UnauthorizedError' || error.status === 401) {
148
- return {
149
- category: ErrorCategory.AUTHENTICATION,
150
- code: ErrorCode.UNAUTHORIZED,
151
- statusCode: 401,
152
- severity: 'medium',
153
- message: '身份验证失败'
154
- };
155
- }
156
-
157
- if (error.name === 'ForbiddenError' || error.status === 403) {
158
- return {
159
- category: ErrorCategory.AUTHORIZATION,
160
- code: ErrorCode.FORBIDDEN,
161
- statusCode: 403,
162
- severity: 'medium',
163
- message: '访问权限不足'
164
- };
165
- }
166
-
167
- if (error.name === 'NotFoundError' || error.status === 404) {
168
- return {
169
- category: ErrorCategory.BUSINESS_LOGIC,
170
- code: ErrorCode.NOT_FOUND,
171
- statusCode: 404,
172
- severity: 'low',
173
- message: '请求的资源不存在'
174
- };
175
- }
176
-
177
- if (error.code && error.code.startsWith('ER_')) {
178
- return {
179
- category: ErrorCategory.DATABASE,
180
- code: ErrorCode.DATABASE_ERROR,
181
- statusCode: 500,
182
- severity: 'high',
183
- message: '数据库操作失败'
184
- };
185
- }
186
-
187
- if (error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT') {
188
- return {
189
- category: ErrorCategory.NETWORK,
190
- code: ErrorCode.EXTERNAL_SERVICE_ERROR,
191
- statusCode: 503,
192
- severity: 'high',
193
- message: '外部服务不可用'
194
- };
195
- }
196
-
197
- // 默认系统错误
198
- return {
199
- category: ErrorCategory.SYSTEM,
200
- code: ErrorCode.INTERNAL_ERROR,
201
- statusCode: error.status || error.statusCode || 500,
202
- severity: error.status >= 500 ? 'critical' : 'medium',
203
- message: error.message || '系统内部错误'
204
- };
205
- }
206
-
207
- /**
208
- * 安全信息过滤
209
- */
210
- function sanitizeErrorForLogging(error: any, ctx: any): any {
211
- const sensitiveFields = ['password', 'token', 'secret', 'key', 'auth', 'credential'];
212
-
213
- const sanitize = (obj: any): any => {
214
- if (typeof obj !== 'object' || obj === null) return obj;
215
-
216
- const sanitized = { ...obj };
217
- for (const [key, value] of Object.entries(sanitized)) {
218
- if (sensitiveFields.some(field => key.toLowerCase().includes(field))) {
219
- sanitized[key] = '***REDACTED***';
220
- } else if (typeof value === 'object') {
221
- sanitized[key] = sanitize(value);
222
- }
223
- }
224
- return sanitized;
225
- };
226
-
227
- return {
228
- message: error.message || 'Unknown error',
229
- stack: isDebug() ? error.stack : undefined,
230
- ...sanitize(error)
231
- };
232
- }
233
-
234
- /**
235
- * URL 安全过滤
236
- */
237
- function sanitizeUrl(url: string): string {
238
- // 移除查询参数中的敏感信息
239
- try {
240
- // 如果URL是相对路径,则直接处理查询参数
241
- if (!url.startsWith('http://') && !url.startsWith('https://')) {
242
- // 处理相对路径,如 /api/users?token=xxx
243
- const [pathname, search] = url.split('?');
244
- if (!search) return pathname;
245
-
246
- const params = new URLSearchParams(search);
247
- const sensitiveParams = ['password', 'token', 'secret', 'key'];
248
-
249
- sensitiveParams.forEach(param => {
250
- if (params.has(param)) {
251
- params.set(param, '***REDACTED***');
252
- }
253
- });
254
-
255
- return pathname + '?' + params.toString();
256
- }
257
-
258
- // 处理完整URL
259
- const urlObj = new URL(url);
260
- const sensitiveParams = ['password', 'token', 'secret', 'key'];
261
-
262
- sensitiveParams.forEach(param => {
263
- if (urlObj.searchParams.has(param)) {
264
- urlObj.searchParams.set(param, '***REDACTED***');
265
- }
266
- });
267
-
268
- return urlObj.pathname + urlObj.search;
269
- } catch {
270
- // 如果URL解析失败,至少移除明显的敏感参数
271
- return url.replace(/([?&])(password|token|secret|key)=[^&]*/gi, '$1$2=***REDACTED***');
272
- }
273
- }
274
-
275
- /**
276
- * 错误告警触发
277
- */
278
- function triggerErrorAlert(errorInfo: any, error: any, ctx: any): void {
279
- // 这里可以集成告警系统,如钉钉、企业微信、邮件等
280
- logger.warn('触发错误告警', {
281
- alert: {
282
- level: errorInfo.severity,
283
- category: errorInfo.category,
284
- code: errorInfo.code,
285
- message: errorInfo.message,
286
- timestamp: new Date().toISOString()
287
- },
288
- request: {
289
- method: ctx.method,
290
- url: sanitizeUrl(ctx.url),
291
- ip: ctx.ip,
292
- requestId: ctx.requestId
293
- }
294
- });
295
- }
296
-
297
- /**
298
- * 构建标准化错误响应
299
- */
300
- function buildStandardErrorResponse(errorInfo: any, ctx: any): any {
301
- const baseResponse = {
302
- success: false,
303
- error: {
304
- code: errorInfo.code,
305
- category: errorInfo.category,
306
- message: errorInfo.message,
307
- timestamp: new Date().toISOString(),
308
- requestId: ctx.requestId || 'unknown'
309
- }
310
- };
311
-
312
- // 开发环境添加调试信息
313
- if (isDebug()) {
314
- return {
315
- ...baseResponse,
316
- debug: {
317
- stack: errorInfo.stack,
318
- originalError: errorInfo.originalError
319
- }
320
- };
321
- }
322
-
323
- return baseResponse;
324
- }
325
-
326
- /**
327
- * 设置安全响应头
328
- */
329
- function setSecurityHeaders(ctx: any): void {
330
- // 防止信息泄露
331
- ctx.set('X-Content-Type-Options', 'nosniff');
332
- ctx.set('X-Frame-Options', 'DENY');
333
- ctx.set('X-XSS-Protection', '1; mode=block');
334
-
335
- // 移除可能泄露信息的头
336
- ctx.remove('X-Powered-By');
337
- ctx.remove('Server');
338
- }
339
-
340
- /**
341
- * 启动应用
342
- * @param fn 启动函数,该函数会在应用启动前执行,所以可以在该函数中执行耗时操作,比如数据库连接、日志初始化等。
343
- * @param port 应用端口,默认为3000
344
- /**
345
- * 启动前执行,用户可以在这里执行一些初始化操作,比如数据库连接、日志初始化等。
346
- * 注意:该函数会在应用启动前执行,所以不要在该函数中执行耗时操作,否则会影响应用启动速度。
347
- * 注意:该函数是异步函数,所以需要使用await关键字来等待执行完成。
348
- * @param fn
349
- */
350
- export const setBeforeBootstrap = async (fn: Function) => {
351
- beforeBootstraps = fn;
352
- }
353
-
354
- /**
355
- * 启动后执行,用户可以在这里执行一些初始化操作,比如数据库连接、日志初始化等。
356
- * 注意:该函数会在应用启动后执行,所以可以在该函数中执行耗时操作,比如数据库连接、日志初始化等。
357
- * 注意:该函数是异步函数,所以需要使用await关键字来等待执行完成。
358
- * @param fn
359
- */
360
- export const setAfterBootstrap = async (fn: Function) => {
361
- afterBootstraps = fn;
362
- }
363
-
364
-
365
- export const bootstrap = async () => {
366
- if (beforeBootstraps) {
367
- await beforeBootstraps(app);
368
- }
369
-
370
- app.use(koaCros({
371
- origin: '*', //允许所有域名访问
372
- maxAge: 5,
373
- credentials: true, //允许携带cookie
374
- allowMethods: ['GET', 'POST', 'PUT', 'DELETE'], //允许的请求方法
375
- allowHeaders: ['Content-Type', 'Authorization', 'Accept'], //允许的请求头
376
- }));
377
-
378
- // 企业级日志中间件
379
- app.use(loggingMiddleware());
380
- app.use(businessLoggingMiddleware());
381
- app.use(databaseLoggingMiddleware());
382
-
383
- // 框架层错误处理中间件
384
- app.use(frameworkErrorMiddleware())
385
- app.use(koaBody());
386
-
387
- // Swagger文档和UI(仅开发环境启用)
388
- // if (isDebug()) {
389
- // app.use(swaggerJson);
390
- // app.use(swaggerMiddleware());
391
- // }
392
-
393
- // 添加路由调试中间件
394
- // app.use(async (ctx, next) => {
395
- // logger.info(`收到请求: ${ctx.method} ${ctx.path}`);
396
- // await next();
397
- // });
398
-
399
- // 启用路由
400
- app.use(router.routes()).use(router.allowedMethods());
401
-
402
- // 启动应用
403
- const port = Number(process.env.port) || 3000;
404
- const host = process.env.host || '0.0.0.0';
405
-
406
- await new Promise<void>((resolve, reject) => {
407
- try {
408
- server = app.listen(port, host, () => {
409
- logger.info(`Server is running on ${host}:${port}`);
410
- resolve();
411
- })
412
- server.on('error', (err) => reject(err));
413
- } catch (error) {
414
- reject(error)
415
- }
416
- })
417
-
418
- if (afterBootstraps) {
419
- await afterBootstraps(app);
420
- }
421
- }
422
-
423
- // 导出app 对象
424
- export const App = app;
425
-
426
- /**
427
- * 获取当前 HTTP Server(如果已启动)
428
- */
429
- export const getServer = (): Server | null => server;
430
-
431
- /**
432
- * 关闭 HTTP Server(幂等)
433
- */
434
- export const closeServer = async (): Promise<void> => {
435
- if (!server) return;
436
- const s = server;
437
- server = null;
438
-
439
- await new Promise<void>((resolve, reject) => {
440
- s.close((err?: Error) => {
441
- if (err) return reject(err);
442
- resolve();
443
- });
444
- });
445
- }
@@ -1,269 +0,0 @@
1
- import { logger } from "@src/framework/utils/logger";
2
-
3
- const NodeCache = require("node-cache");
4
-
5
- /**
6
- * 缓存配置接口
7
- */
8
- export interface CacheConfig {
9
- /** 默认TTL时间(秒) */
10
- stdTTL?: number;
11
- /** 最大缓存条目数 */
12
- maxKeys?: number;
13
- /** 检查过期时间间隔(秒) */
14
- checkperiod?: number;
15
- /** 是否使用克隆模式 */
16
- useClones?: boolean;
17
- /** 是否删除过期键 */
18
- deleteOnExpire?: boolean;
19
- }
20
-
21
- /**
22
- * 默认缓存配置
23
- * 统一管理所有缓存的默认参数,防止内存泄露
24
- */
25
- const DEFAULT_CACHE_CONFIG: Required<CacheConfig> = {
26
- stdTTL: 300, // 默认5分钟过期
27
- maxKeys: 1000, // 最大1000个缓存条目
28
- checkperiod: 120, // 每2分钟检查一次过期
29
- useClones: false, // 不使用克隆,提高性能
30
- deleteOnExpire: true // 自动删除过期键
31
- };
32
-
33
- /**
34
- * 缓存类型枚举
35
- */
36
- export enum CacheType {
37
- /** 用户缓存 */
38
- USER = 'user',
39
- /** 控制器结果缓存 */
40
- CONTROLLER = 'controller',
41
- /** 会话缓存 */
42
- SESSION = 'session',
43
- /** 验证码缓存 */
44
- CAPTCHA = 'captcha',
45
- /** 临时缓存 */
46
- TEMP = 'temp'
47
- }
48
-
49
- /**
50
- * 不同类型缓存的特定配置
51
- */
52
- const CACHE_TYPE_CONFIGS: Record<CacheType, Partial<CacheConfig>> = {
53
- [CacheType.USER]: {
54
- stdTTL: 1800, // 30分钟
55
- maxKeys: 500
56
- },
57
- [CacheType.CONTROLLER]: {
58
- stdTTL: 60, // 1分钟
59
- maxKeys: 2000
60
- },
61
- [CacheType.SESSION]: {
62
- stdTTL: 3600, // 1小时
63
- maxKeys: 1000
64
- },
65
- [CacheType.CAPTCHA]: {
66
- stdTTL: 300, // 5分钟
67
- maxKeys: 100
68
- },
69
- [CacheType.TEMP]: {
70
- stdTTL: 60, // 1分钟
71
- maxKeys: 100
72
- }
73
- };
74
-
75
- /**
76
- * 缓存管理器类
77
- */
78
- class CacheManager {
79
- private caches: Map<string, any> = new Map();
80
- private stats: Map<string, { hits: number; misses: number; keys: number }> = new Map();
81
-
82
- /**
83
- * 创建缓存实例
84
- * @param name 缓存名称
85
- * @param type 缓存类型
86
- * @param customConfig 自定义配置
87
- */
88
- createCache(name: string, type: CacheType = CacheType.TEMP, customConfig?: Partial<CacheConfig>) {
89
- if (this.caches.has(name)) {
90
- logger.warn(`缓存 ${name} 已存在,返回现有实例`);
91
- return this.caches.get(name);
92
- }
93
-
94
- // 合并配置
95
- const typeConfig = CACHE_TYPE_CONFIGS[type] || {};
96
- const finalConfig = { ...DEFAULT_CACHE_CONFIG, ...typeConfig, ...customConfig };
97
-
98
- // 创建缓存实例
99
- const cache = new NodeCache(finalConfig);
100
-
101
- // 添加统计信息
102
- this.stats.set(name, { hits: 0, misses: 0, keys: 0 });
103
-
104
- // 监听缓存事件
105
- cache.on('set', (key: string, value: any) => {
106
- const stats = this.stats.get(name);
107
- if (stats) {
108
- stats.keys = cache.keys().length;
109
- }
110
- logger.debug(`缓存 ${name} 设置键: ${key}`);
111
- });
112
-
113
- cache.on('del', (key: string, value: any) => {
114
- const stats = this.stats.get(name);
115
- if (stats) {
116
- stats.keys = cache.keys().length;
117
- }
118
- logger.debug(`缓存 ${name} 删除键: ${key}`);
119
- });
120
-
121
- cache.on('expired', (key: string, value: any) => {
122
- const stats = this.stats.get(name);
123
- if (stats) {
124
- stats.keys = cache.keys().length;
125
- }
126
- logger.debug(`缓存 ${name} 键过期: ${key}`);
127
- });
128
-
129
- // 包装get方法以添加统计
130
- const originalGet = cache.get.bind(cache);
131
- cache.get = (key: string) => {
132
- const result = originalGet(key);
133
- const stats = this.stats.get(name);
134
- if (stats) {
135
- if (result !== undefined) {
136
- stats.hits++;
137
- } else {
138
- stats.misses++;
139
- }
140
- }
141
- return result;
142
- };
143
-
144
- this.caches.set(name, cache);
145
- logger.debug(`创建缓存 ${name},类型: ${type},配置:`, finalConfig);
146
-
147
- return cache;
148
- }
149
-
150
- /**
151
- * 获取缓存实例
152
- * @param name 缓存名称
153
- */
154
- getCache(name: string) {
155
- return this.caches.get(name);
156
- }
157
-
158
- /**
159
- * 删除缓存实例
160
- * @param name 缓存名称
161
- */
162
- deleteCache(name: string) {
163
- const cache = this.caches.get(name);
164
- if (cache) {
165
- cache.close();
166
- this.caches.delete(name);
167
- this.stats.delete(name);
168
- logger.info(`删除缓存 ${name}`);
169
- }
170
- }
171
-
172
- /**
173
- * 清空所有缓存
174
- */
175
- clearAllCaches() {
176
- this.caches.forEach((cache, name) => {
177
- cache.flushAll();
178
- logger.info(`清空缓存 ${name}`);
179
- });
180
- }
181
-
182
- /**
183
- * 获取缓存统计信息
184
- */
185
- getStats() {
186
- const result: Record<string, any> = {};
187
- this.stats.forEach((stats, name) => {
188
- const cache = this.caches.get(name);
189
- result[name] = {
190
- ...stats,
191
- hitRate: stats.hits + stats.misses > 0 ? (stats.hits / (stats.hits + stats.misses) * 100).toFixed(2) + '%' : '0%',
192
- config: cache ? cache.options : null
193
- };
194
- });
195
- return result;
196
- }
197
-
198
- /**
199
- * 获取所有缓存的内存使用情况
200
- */
201
- getMemoryUsage() {
202
- const result: Record<string, any> = {};
203
- this.caches.forEach((cache, name) => {
204
- const keys = cache.keys();
205
- result[name] = {
206
- keyCount: keys.length,
207
- maxKeys: cache.options.maxKeys,
208
- usage: ((keys.length / cache.options.maxKeys) * 100).toFixed(2) + '%'
209
- };
210
- });
211
- return result;
212
- }
213
- }
214
-
215
- // 创建全局缓存管理器实例
216
- const cacheManager = new CacheManager();
217
-
218
- /**
219
- * 创建缓存的便捷函数
220
- * @param name 缓存名称
221
- * @param type 缓存类型
222
- * @param customConfig 自定义配置
223
- */
224
- export const createCache = (name: string, type: CacheType = CacheType.TEMP, customConfig?: Partial<CacheConfig>) => {
225
- return cacheManager.createCache(name, type, customConfig);
226
- };
227
-
228
- /**
229
- * 获取缓存实例
230
- * @param name 缓存名称
231
- */
232
- export const getCache = (name: string) => {
233
- return cacheManager.getCache(name);
234
- };
235
-
236
- /**
237
- * 删除缓存实例
238
- * @param name 缓存名称
239
- */
240
- export const deleteCache = (name: string) => {
241
- return cacheManager.deleteCache(name);
242
- };
243
-
244
- /**
245
- * 清空所有缓存
246
- */
247
- export const clearAllCaches = () => {
248
- return cacheManager.clearAllCaches();
249
- };
250
-
251
- /**
252
- * 获取缓存统计信息
253
- */
254
- export const getCacheStats = () => {
255
- return cacheManager.getStats();
256
- };
257
-
258
- /**
259
- * 获取缓存内存使用情况
260
- */
261
- export const getCacheMemoryUsage = () => {
262
- return cacheManager.getMemoryUsage();
263
- };
264
-
265
- // 导出缓存管理器实例(用于高级操作)
266
- export { cacheManager };
267
-
268
- // 导出默认配置(用于参考)
269
- export { DEFAULT_CACHE_CONFIG, CACHE_TYPE_CONFIGS };