create-dp-koa 1.1.2 → 1.1.4

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 (104) hide show
  1. package/package.json +1 -1
  2. package/template/.cursor/rules/00-backend-core.skill.md +1 -1
  3. package/template/.cursor/rules/01-backend-skill-router.skill.md +8 -2
  4. package/template/.cursor/rules/10-backend-api.skill.md +8 -0
  5. package/template/.cursor/rules/11-backend-controller-recipes.skill.md +12 -9
  6. package/template/.cursor/rules/21-backend-service.skill.md +14 -0
  7. package/template/.cursor/rules/30-backend-validation.skill.md +1 -1
  8. package/template/.cursor/rules/40-backend-error-logging.skill.md +9 -5
  9. package/template/.cursor/rules/50-backend-bootstrap-lifecycle.skill.md +4 -4
  10. package/template/.cursor/rules/60-backend-router-registration.skill.md +16 -6
  11. package/template/.cursor/rules/70-backend-middleware.skill.md +2 -2
  12. package/template/.cursor/rules/80-backend-utils-and-libs.skill.md +71 -14
  13. package/template/.cursor/rules/85-backend-plugins.rule.md +4 -4
  14. package/template/.cursor/rules/90-backend-testing.skill.md +26 -0
  15. package/template/.cursor/rules/README.md +2 -2
  16. package/template/.trae/skills/11-backend-controller-recipes.skill.md +12 -9
  17. package/template/.trae/skills/21-backend-service.skill.md +15 -1
  18. package/template/.trae/skills/40-backend-error-logging.skill.md +9 -5
  19. package/template/.trae/skills/80-backend-utils-and-libs.skill.md +77 -8
  20. package/template/.trae/skills/90-backend-testing.skill.md +26 -0
  21. package/template/scripts/sync-template.mjs +20 -0
  22. package/template/src/app.ts +1 -2
  23. package/template/src/{framework/plugins → plugins}/registry.ts +2 -2
  24. package/template/src/plugins/weboffice/http/routes.ts +1 -1
  25. package/template/src/plugins/weboffice/index.ts +3 -3
  26. package/template/src/plugins/weboffice/services/webofficeCallback.service.ts +3 -4
  27. package/template/src/types/ctxState.ts +9 -0
  28. package/template/src/utils/testDataInitializer.ts +1 -1
  29. package/template/tsconfig.json +6 -0
  30. package/template/src/annotations/decorators/ConfigManagement.ts +0 -9
  31. package/template/src/annotations/decorators/DistributedTracing.ts +0 -9
  32. package/template/src/annotations/decorators/EnterprisePerformance.ts +0 -9
  33. package/template/src/annotations/decorators/PerformanceMonitor.ts +0 -32
  34. package/template/src/annotations/decorators/SecurityAudit.ts +0 -9
  35. package/template/src/annotations/index.ts +0 -50
  36. package/template/src/annotations/processors/ConfigManagementProcessor.ts +0 -369
  37. package/template/src/annotations/processors/DistributedTracingProcessor.ts +0 -288
  38. package/template/src/annotations/processors/EnterprisePerformanceProcessor.ts +0 -189
  39. package/template/src/annotations/processors/PerformanceMonitorProcessor.ts +0 -101
  40. package/template/src/annotations/processors/SecurityAuditProcessor.ts +0 -345
  41. package/template/src/annotations/processors/SwaggerProcessor.ts +0 -612
  42. package/template/src/annotations/processors/index.ts +0 -10
  43. package/template/src/examples/InterceptorExampleRunner.ts +0 -284
  44. package/template/src/examples/ServiceInterceptorExample.ts +0 -214
  45. package/template/src/examples/cacheExamples.ts +0 -155
  46. package/template/src/framework/decorator/controller.ts +0 -311
  47. package/template/src/framework/decorator/processor/AnnotationDecorators.ts +0 -100
  48. package/template/src/framework/decorator/processor/AnnotationProcessor.ts +0 -160
  49. package/template/src/framework/decorator/processor/AnnotationProcessorConfig.ts +0 -45
  50. package/template/src/framework/decorator/processor/AnnotationRegistry.ts +0 -117
  51. package/template/src/framework/decorator/processor/AnnotationSystemInitializer.ts +0 -95
  52. package/template/src/framework/decorator/processor/ProcessorManager.ts +0 -76
  53. package/template/src/framework/decorator/processor/processors/CustomProcessors.ts +0 -126
  54. package/template/src/framework/decorator/processor/processors/DefaultProcessors.ts +0 -207
  55. package/template/src/framework/decorator/refactored/DecoratorFactory.ts +0 -99
  56. package/template/src/framework/decorator/refactored/DecoratorMetadataManager.ts +0 -125
  57. package/template/src/framework/decorator/refactored/DecoratorValidator.ts +0 -128
  58. package/template/src/framework/decorator/refactored/TypeSafeDecorators.ts +0 -139
  59. package/template/src/framework/decorator/refactored/index.ts +0 -98
  60. package/template/src/framework/decorator/swagger.ts +0 -150
  61. package/template/src/framework/interceptors/AdvancedServiceCallInterceptor.ts +0 -375
  62. package/template/src/framework/interceptors/ServiceCallInterceptor.ts +0 -348
  63. package/template/src/framework/interceptors/index.ts +0 -19
  64. package/template/src/framework/plugins/types.ts +0 -15
  65. package/template/src/framework/types/ServiceResult.ts +0 -151
  66. package/template/src/framework/types/index.ts +0 -16
  67. package/template/src/framework/utils/CacheManager.ts +0 -430
  68. package/template/src/framework/utils/CacheService.ts +0 -248
  69. package/template/src/framework/utils/DtoValidator.ts +0 -164
  70. package/template/src/framework/utils/MigrationHelper.ts +0 -179
  71. package/template/src/framework/utils/MigrationManager.ts +0 -256
  72. package/template/src/framework/utils/NewRouter.ts +0 -207
  73. package/template/src/framework/utils/TransactionManager.ts +0 -172
  74. package/template/src/framework/utils/bootstrap.ts +0 -445
  75. package/template/src/framework/utils/cache.ts +0 -269
  76. package/template/src/framework/utils/databaseConfig.ts +0 -148
  77. package/template/src/framework/utils/db.ts +0 -39
  78. package/template/src/framework/utils/dbMonitor.ts +0 -106
  79. package/template/src/framework/utils/function.ts +0 -61
  80. package/template/src/framework/utils/gracefulShutdown.ts +0 -131
  81. package/template/src/framework/utils/logger.ts +0 -388
  82. package/template/src/framework/utils/metrics.ts +0 -182
  83. package/template/src/framework/utils/router.ts +0 -417
  84. package/template/src/framework/utils/swagger.ts +0 -184
  85. package/template/src/framework/utils/testDb.ts +0 -19
  86. package/template/src/framework/utils/token.ts +0 -23
  87. package/template/src/framework/utils/transform.ts +0 -17
  88. package/template/src/libs/aokEmailSender.ts +0 -42
  89. package/template/src/libs/captcha.ts +0 -37
  90. package/template/src/libs/cos.ts +0 -45
  91. package/template/src/libs/mCache.ts +0 -7
  92. package/template/src/libs/serviceValidate.ts +0 -3
  93. package/template/src/libs/tecentSms.ts +0 -51
  94. package/template/src/middlewares/a.middleware.ts +0 -6
  95. package/template/src/middlewares/error.middleware.ts +0 -14
  96. package/template/src/middlewares/logging.middleware.ts +0 -187
  97. package/template/src/middlewares/static.middleware.ts +0 -79
  98. package/template/src/middlewares/swagger.middleware.ts +0 -70
  99. package/template/src/middlewares/token.middleware.ts +0 -32
  100. package/template/src/migrations/1700000000000-InitialDatabaseStructure.ts +0 -172
  101. package/template/src/migrations/index.ts +0 -6
  102. package/template/src/repository/base/BaseRepository.ts +0 -124
  103. package/template/src/repository/interfaces/IBaseRepository.ts +0 -67
  104. package/template/src/service/base.service.ts +0 -116
@@ -1,37 +0,0 @@
1
- import svgCaptcha from 'svg-captcha';
2
- import jwt from 'jsonwebtoken';
3
-
4
- export class CaptchaGenerator {
5
- private static readonly JWT_SECRET = process.env.CAPTCHA_JWT_SECRET || 'captcha_secret';
6
- private static readonly JWT_EXPIRES_IN = '5m';
7
-
8
- static generate() {
9
- const captcha = svgCaptcha.create({
10
- size: 4,
11
- ignoreChars: '0o1i',
12
- noise: 2,
13
- color: true,
14
- background: '#f0f0f0'
15
- });
16
-
17
- const token = jwt.sign(
18
- { captcha: captcha.text.toLowerCase() },
19
- this.JWT_SECRET,
20
- { expiresIn: this.JWT_EXPIRES_IN }
21
- );
22
-
23
- return {
24
- image: captcha.data,
25
- token
26
- };
27
- }
28
-
29
- static verify(token: string, input: string): boolean {
30
- try {
31
- const decoded = jwt.verify(token, this.JWT_SECRET) as { captcha: string };
32
- return decoded.captcha === input?.toLowerCase();
33
- } catch {
34
- return false;
35
- }
36
- }
37
- }
@@ -1,45 +0,0 @@
1
- import COS from "cos-nodejs-sdk-v5";
2
- import fs from "fs";
3
-
4
- const SECRET_ID = process.env.COS_SECRET_ID || "";
5
- const SECRET_KEY = process.env.COS_SECRET_KEY || "";
6
- const BUCKET = process.env.COS_BUCKET || "";
7
- const REGION = process.env.COS_REGION || "";
8
- const FILES_HOST =
9
- process.env.WEBOFFICE_FILES_HOST || process.env.FILES_HOST || "";
10
-
11
- function getCosClient(): COS | null {
12
- if (!SECRET_ID || !SECRET_KEY) return null;
13
- return new COS({
14
- SecretId: SECRET_ID,
15
- SecretKey: SECRET_KEY,
16
- });
17
- }
18
-
19
- export function isCosConfigured(): boolean {
20
- return !!(SECRET_ID && SECRET_KEY && BUCKET && REGION);
21
- }
22
-
23
- export async function uploadToCos(localFilePath: string, key: string): Promise<void> {
24
- const client = getCosClient();
25
- if (!client) throw new Error("COS client not configured");
26
- if (!BUCKET || !REGION) throw new Error("COS bucket/region not configured");
27
- await client.putObject({
28
- Bucket: BUCKET,
29
- Region: REGION,
30
- Key: key,
31
- Body: fs.createReadStream(localFilePath),
32
- });
33
- }
34
-
35
- export function getFilePublicUrl(key: string): string {
36
- if (!FILES_HOST) return "";
37
- const host = FILES_HOST.replace(/\/$/, "");
38
- const k = key.replace(/^\//, "");
39
- return `${host}/${k}`;
40
- }
41
-
42
- export function webofficeCosKey(fileId: string, version: number): string {
43
- return `weboffice/files/${fileId}/v${version}`;
44
- }
45
-
@@ -1,7 +0,0 @@
1
- import { createCache, CacheType } from "@src/framework/utils/cache";
2
-
3
- // 使用统一的缓存管理创建用户缓存
4
- export const ytUserCache = createCache('yt-user', CacheType.USER, {
5
- stdTTL: 600, // 10分钟过期
6
- maxKeys: 500 // 用户缓存限制500个
7
- });
@@ -1,3 +0,0 @@
1
- export const ServiceValidate = (params: any, instance: any, fn: Function, done: (err: any, param: any) => void) => {
2
- console.log(params, instance, fn, done, "seravice拦截器");
3
- }
@@ -1,51 +0,0 @@
1
- import * as tencentcloud from 'tencentcloud-sdk-nodejs';
2
- import { config } from 'dotenv';
3
-
4
- type SmsParams = {
5
- PhoneNumberSet: string[];
6
- TemplateId: string;
7
- SignName: string;
8
- TemplateParamSet?: string[];
9
- SmsSdkAppId: string;
10
- };
11
-
12
- export class TencentSms {
13
- private client: any;
14
-
15
- constructor() {
16
- config();
17
- const SmsClient = tencentcloud.sms.v20210111.Client;
18
-
19
- this.client = new SmsClient({
20
- credential: {
21
- secretId: process.env.TENCENT_SMS_SECRET_ID,
22
- secretKey: process.env.TENCENT_SMS_SECRET_KEY,
23
- },
24
- region: process.env.TENCENT_SMS_REGION || 'ap-guangzhou',
25
- profile: {
26
- httpProfile: {
27
- endpoint: 'sms.tencentcloudapi.com',
28
- },
29
- },
30
- });
31
- }
32
-
33
- async sendSms(params: SmsParams): Promise<any> {
34
- try {
35
- const request = {
36
- PhoneNumberSet: params.PhoneNumberSet,
37
- TemplateId: params.TemplateId,
38
- SignName: params.SignName,
39
- TemplateParamSet: params.TemplateParamSet || [],
40
- SmsSdkAppId: params.SmsSdkAppId,
41
- };
42
-
43
- return await this.client.SendSms(request);
44
- } catch (error) {
45
- throw error;
46
- // throw new Error(`Failed to send SMS: ${error.message}`);
47
- }
48
- }
49
- }
50
-
51
- export const tencentSms = new TencentSms();
@@ -1,6 +0,0 @@
1
- export default function () {
2
- return async (ctx: any, next: Function) => {
3
- // console.log("a middleware ");
4
- await next()
5
- }
6
- }
@@ -1,14 +0,0 @@
1
- import { logger } from "@src/framework/utils/logger";
2
-
3
- export default function () {
4
- return async (ctx: any, next: Function) => {
5
- try {
6
- await next();
7
- } catch (err) {
8
- const error = err as any;
9
- ctx.status = 500;
10
- logger.error((err as Error).message || 'Unknown error');
11
- return ctx.body = error;
12
- }
13
- }
14
- }
@@ -1,187 +0,0 @@
1
- import { Context, Next } from 'koa'
2
- import { logger, createRequestLogger } from '@src/framework/utils/logger'
3
- import { isDebug } from '@src/framework/utils/function'
4
-
5
- /**
6
- * 企业级日志中间件
7
- * 提供请求追踪、性能监控、安全审计等功能
8
- */
9
- export const loggingMiddleware = () => {
10
- return async (ctx: Context, next: Next) => {
11
- const startTime = Date.now()
12
- const requestId = logger.generateRequestId()
13
-
14
- // 创建请求专用的日志器
15
- const requestLogger = createRequestLogger(requestId)
16
-
17
- // 设置请求上下文
18
- requestLogger.setRequestContext(
19
- requestId,
20
- ctx.state.user?.id,
21
- ctx.session?.id
22
- )
23
-
24
- // 设置追踪上下文(如果存在)
25
- const traceId = ctx.get('X-Trace-ID') || ctx.get('X-Request-ID')
26
- if (traceId) {
27
- requestLogger.setTraceContext(traceId, requestId)
28
- }
29
-
30
- // 记录请求开始 - 只在调试模式下记录详细信息
31
- if (isDebug()) {
32
- requestLogger.debug('Request started', {
33
- method: ctx.method,
34
- url: ctx.url,
35
- userAgent: ctx.get('User-Agent'),
36
- ip: ctx.ip,
37
- headers: sanitizeHeaders(ctx.headers)
38
- })
39
- }
40
-
41
- // 审计日志 - 请求访问(只在调试模式下输出到控制台)
42
- if (isDebug()) {
43
- requestLogger.audit('REQUEST_ACCESS', ctx.url, {
44
- method: ctx.method,
45
- ip: ctx.ip,
46
- userAgent: ctx.get('User-Agent'),
47
- userId: ctx.state.user?.id
48
- })
49
- }
50
-
51
- // 将日志器添加到上下文
52
- ctx.logger = requestLogger
53
- ctx.requestId = requestId
54
-
55
- try {
56
- await next()
57
-
58
- const duration = Date.now() - startTime
59
-
60
- // 记录请求完成 - 只在调试模式或慢请求时记录
61
- if (isDebug() || duration > 1000) {
62
- requestLogger.info('Request completed', {
63
- method: ctx.method,
64
- url: ctx.url,
65
- status: ctx.status,
66
- duration: `${duration}ms`,
67
- responseSize: ctx.response.length || 0
68
- })
69
- }
70
-
71
- // 性能监控日志 - 只在调试模式下输出到控制台
72
- if (isDebug()) {
73
- requestLogger.performance('HTTP_REQUEST', duration, {
74
- method: ctx.method,
75
- url: ctx.url,
76
- status: ctx.status,
77
- responseSize: ctx.response.length || 0
78
- })
79
- }
80
-
81
- // 安全审计 - 响应状态
82
- if (ctx.status >= 400) {
83
- requestLogger.security('HTTP_ERROR_RESPONSE',
84
- ctx.status >= 500 ? 'high' : 'medium',
85
- {
86
- status: ctx.status,
87
- method: ctx.method,
88
- url: ctx.url,
89
- userId: ctx.state.user?.id
90
- }
91
- )
92
- }
93
-
94
- } catch (error) {
95
- const duration = Date.now() - startTime
96
-
97
- // 记录错误
98
- requestLogger.error('Request failed', error as Error, {
99
- method: ctx.method,
100
- url: ctx.url,
101
- duration: `${duration}ms`
102
- })
103
-
104
- // 安全审计 - 错误事件
105
- requestLogger.security('REQUEST_ERROR', 'high', {
106
- error: error instanceof Error ? error.message : 'Unknown error',
107
- method: ctx.method,
108
- url: ctx.url,
109
- userId: ctx.state.user?.id
110
- })
111
-
112
- throw error
113
- } finally {
114
- // 清理上下文
115
- requestLogger.clearContext()
116
- }
117
- }
118
- }
119
-
120
- /**
121
- * 脱敏请求头
122
- */
123
- function sanitizeHeaders(headers: any): any {
124
- const sanitized = { ...headers }
125
- const sensitiveHeaders = ['authorization', 'cookie', 'x-api-key', 'x-auth-token']
126
-
127
- sensitiveHeaders.forEach(header => {
128
- if (sanitized[header]) {
129
- sanitized[header] = '***REDACTED***'
130
- }
131
- })
132
-
133
- return sanitized
134
- }
135
-
136
- /**
137
- * 业务日志中间件
138
- * 用于记录业务操作
139
- */
140
- export const businessLoggingMiddleware = () => {
141
- return async (ctx: Context, next: Next) => {
142
- const originalBody = ctx.body
143
-
144
- await next()
145
-
146
- // 记录业务操作 - 注释掉,不在控制台输出
147
- // 如果需要查看业务日志,请查看 logs/structured.log 文件
148
- // if (ctx.logger && ctx.status < 400 && isDebug()) {
149
- // ctx.logger.business('API_CALL', {
150
- // method: ctx.method,
151
- // url: ctx.url,
152
- // status: ctx.status,
153
- // userId: ctx.state.user?.id,
154
- // timestamp: new Date().toISOString()
155
- // })
156
- // }
157
- }
158
- }
159
-
160
- /**
161
- * 数据库操作日志中间件
162
- */
163
- export const databaseLoggingMiddleware = () => {
164
- return async (ctx: Context, next: Next) => {
165
- const startTime = Date.now()
166
-
167
- await next()
168
-
169
- const duration = Date.now() - startTime
170
-
171
- if (ctx.logger && duration > 100) { // 只记录超过100ms的数据库操作
172
- ctx.logger.performance('DATABASE_OPERATION', duration, {
173
- method: ctx.method,
174
- url: ctx.url,
175
- userId: ctx.state.user?.id
176
- })
177
- }
178
- }
179
- }
180
-
181
- // 扩展Context类型
182
- declare module 'koa' {
183
- interface Context {
184
- logger: any
185
- requestId: string
186
- }
187
- }
@@ -1,79 +0,0 @@
1
- import path from "path";
2
- import mount from "koa-mount";
3
- import serve from "koa-static";
4
- import { isDebug } from "@src/framework/utils/function";
5
-
6
- export interface StaticMiddlewareOptions {
7
- /**
8
- * URL 前缀,例如:/static
9
- * - 不建议以 / 结尾
10
- */
11
- urlPrefix?: string;
12
- /**
13
- * 本地目录(相对项目根目录 process.cwd()),例如:assets / uploads
14
- */
15
- dir?: string;
16
- /**
17
- * 生产环境缓存秒数(Cache-Control max-age)
18
- */
19
- maxAgeSeconds?: number;
20
- /**
21
- * 访问前缀根路径时的默认文件,例如:index.html
22
- * - false 表示不提供默认文件
23
- */
24
- index?: string | false;
25
- /**
26
- * 是否在 next() 之后再尝试提供静态文件(默认 false,优先静态)
27
- */
28
- defer?: boolean;
29
- /**
30
- * 是否允许访问隐藏文件(默认 false)
31
- */
32
- hidden?: boolean;
33
- }
34
-
35
- function normalizePrefix(prefix: string): string {
36
- let p = prefix.trim();
37
- if (!p.startsWith("/")) p = `/${p}`;
38
- // 只保留末尾非根路径的前缀(避免 /static/ 和 /static 产生差异)
39
- if (p.length > 1 && p.endsWith("/")) p = p.slice(0, -1);
40
- return p;
41
- }
42
-
43
- /**
44
- * 静态文件映射中间件(基于 koa-static + koa-mount)
45
- * - 默认:/static -> ./static
46
- * - 支持环境变量覆盖:STATIC_URL_PREFIX、STATIC_DIR、STATIC_MAX_AGE_SECONDS、STATIC_INDEX
47
- */
48
- export default function staticMiddleware(options: StaticMiddlewareOptions = {}) {
49
- const urlPrefix = normalizePrefix(
50
- options.urlPrefix ?? process.env.STATIC_URL_PREFIX ?? "/static"
51
- );
52
- const dir = options.dir ?? process.env.STATIC_DIR ?? "static";
53
- const root = path.resolve(process.cwd(), dir);
54
- const index =
55
- options.index ??
56
- (typeof process.env.STATIC_INDEX === "string"
57
- ? process.env.STATIC_INDEX
58
- : false);
59
-
60
- const maxAgeSeconds =
61
- options.maxAgeSeconds ??
62
- (process.env.STATIC_MAX_AGE_SECONDS
63
- ? Number(process.env.STATIC_MAX_AGE_SECONDS)
64
- : !isDebug()
65
- ? 86400
66
- : 0);
67
-
68
- return mount(
69
- urlPrefix,
70
- serve(root, {
71
- maxage: Math.max(0, maxAgeSeconds) * 1000,
72
- index,
73
- defer: options.defer ?? false,
74
- hidden: options.hidden ?? false,
75
- })
76
- );
77
- }
78
-
79
-
@@ -1,70 +0,0 @@
1
- import { getSwaggerSpec } from '@src/framework/utils/swagger';
2
- import { logger } from '@src/framework/utils/logger';
3
-
4
- /**
5
- * Swagger UI中间件 - 简化版本
6
- */
7
- export function swaggerMiddleware() {
8
- logger.info('Swagger UI已配置');
9
-
10
- return async (ctx: any, next: any) => {
11
- if (ctx.path === '/swagger') {
12
- ctx.set('Content-Type', 'text/html');
13
- ctx.body = `
14
- <!DOCTYPE html>
15
- <html>
16
- <head>
17
- <title>DP Koa Framework API文档</title>
18
- <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3.25.0/swagger-ui.css" />
19
- <style>
20
- .topbar { display: none !important; }
21
- .swagger-ui .info { margin: 20px 0; }
22
- </style>
23
- </head>
24
- <body>
25
- <div id="swagger-ui"></div>
26
- <script src="https://unpkg.com/swagger-ui-dist@3.25.0/swagger-ui-bundle.js"></script>
27
- <script>
28
- SwaggerUIBundle({
29
- url: '/swagger.json',
30
- dom_id: '#swagger-ui',
31
- presets: [
32
- SwaggerUIBundle.presets.apis,
33
- SwaggerUIBundle.presets.standalone
34
- ],
35
- layout: "StandaloneLayout"
36
- });
37
- </script>
38
- </body>
39
- </html>
40
- `;
41
- return;
42
- }
43
- await next();
44
- };
45
- }
46
-
47
- /**
48
- * Swagger JSON端点
49
- */
50
- export async function swaggerJson(ctx: any, next: any) {
51
- if (ctx.path === '/swagger.json') {
52
- try {
53
- const swaggerSpec = getSwaggerSpec();
54
-
55
- // 动态从Controller中提取Swagger信息
56
- // 这里可以集成现有的路由系统来生成完整的文档
57
-
58
- ctx.set('Content-Type', 'application/json');
59
- ctx.body = swaggerSpec;
60
- } catch (error) {
61
- logger.error('生成Swagger文档失败:', error as Error);
62
- ctx.status = 500;
63
- ctx.body = { error: '无法生成Swagger文档' };
64
- }
65
- return;
66
- }
67
-
68
- await next();
69
- }
70
-
@@ -1,32 +0,0 @@
1
- import * as jwt from "jsonwebtoken";
2
- import { Context } from "koa";
3
- import { getTokenFromHeader } from "@src/framework/utils/token";
4
-
5
- export default function tokenMiddleware() {
6
-
7
- return async (ctx: Context, next: Function) => {
8
- // 1. 从请求头获取token
9
- const token = getTokenFromHeader(ctx);
10
- if (!token) {
11
- ctx.status = 401;
12
- ctx.body = { code: -1, message: "未提供认证token" };
13
- return;
14
- }
15
-
16
- try {
17
- // 2. 验证token
18
- const decoded = jwt.verify(token, process.env.jwt_secret ?? "123456") as any;
19
-
20
- // 3. 将用户信息挂载到ctx.state
21
- ctx.state.user = {
22
- userId: decoded.userId,
23
- type: decoded.type,
24
- };
25
-
26
- await next();
27
- } catch (err) {
28
- ctx.status = 401;
29
- ctx.body = { code: -1, message: "无效或过期的token" };
30
- }
31
- };
32
- }