@cicctencent/midwayjs-base 1.0.38 → 1.0.40
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/README.md +582 -347
- package/dist/config/config.default.js +5 -1
- package/dist/config/env.js +6 -3
- package/dist/constants/error-code.d.ts +27 -0
- package/dist/constants/error-code.js +53 -0
- package/dist/filter/default.filter.d.ts +4 -3
- package/dist/filter/default.filter.js +12 -2
- package/dist/guard/api.js +12 -6
- package/dist/guard/auth.d.ts +7 -3
- package/dist/guard/auth.js +46 -53
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/lib/decorator.d.ts +1 -1
- package/dist/lib/decorator.js +2 -3
- package/dist/middleware/apiResultFormatter.js +6 -6
- package/dist/types/base.model.service.d.ts +1 -1
- package/dist/types/base.model.service.js +11 -5
- package/dist/types/base.service.js +1 -1
- package/package.json +30 -30
- package/typings/midway.d.ts +54 -54
package/README.md
CHANGED
|
@@ -1,347 +1,582 @@
|
|
|
1
|
-
# @cicctencent/midwayjs-base
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
#
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
@
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
1
|
+
# @cicctencent/midwayjs-base
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@cicctencent/midwayjs-base)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
MidwayJS 企业级基础组件 - 集成公司常用基础服务能力,快速构建后端应用。
|
|
7
|
+
|
|
8
|
+
## 简介
|
|
9
|
+
|
|
10
|
+
`@cicctencent/midwayjs-base` 是一个基于 [MidwayJS 3.x](https://midwayjs.org/) 框架的企业级基础组件,封装了公司内部常用的基础服务能力,包括认证授权、文件存储、API 网关、会话管理等功能,帮助开发者快速搭建稳定可靠的后端服务。
|
|
11
|
+
|
|
12
|
+
## 功能特性
|
|
13
|
+
|
|
14
|
+
### 🔐 认证授权
|
|
15
|
+
- JWT Token 认证(支持 HS256 算法)
|
|
16
|
+
- 单点登录 (SSO) 集成
|
|
17
|
+
- 接口权限守卫(AuthGuard)
|
|
18
|
+
- 管理员账号验证
|
|
19
|
+
|
|
20
|
+
### 📁 文件存储
|
|
21
|
+
- 腾讯云 COS 文件上传/下载
|
|
22
|
+
- 文件访问 URL 生成(带临时签名)
|
|
23
|
+
- 多存储桶配置支持
|
|
24
|
+
- 支持流式上传
|
|
25
|
+
|
|
26
|
+
### 🔌 API 网关
|
|
27
|
+
- 统一 API 响应格式 `{ ret, msg, data }`
|
|
28
|
+
- 请求参数校验
|
|
29
|
+
- IP 白名单控制
|
|
30
|
+
- API Token 验证(带时间戳防重放)
|
|
31
|
+
|
|
32
|
+
### 💾 会话管理
|
|
33
|
+
- 分布式会话存储(基于 Midway Cache)
|
|
34
|
+
- 会话超时配置
|
|
35
|
+
- 自定义会话服务接口(ISessionService)
|
|
36
|
+
|
|
37
|
+
### 🛡️ 安全防护
|
|
38
|
+
- 请求检测中间件(DetectMiddleware)
|
|
39
|
+
- 统一异常过滤器
|
|
40
|
+
- 404 处理
|
|
41
|
+
- XSS 防护
|
|
42
|
+
|
|
43
|
+
### 📝 日志系统
|
|
44
|
+
- 结构化日志输出
|
|
45
|
+
- 远程日志上报
|
|
46
|
+
- 请求 ID 追踪
|
|
47
|
+
- 自动注入用户信息
|
|
48
|
+
|
|
49
|
+
## 目录结构
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
src/
|
|
53
|
+
├── config/ # 配置文件
|
|
54
|
+
│ ├── config.default.ts # 默认配置
|
|
55
|
+
│ └── env.ts # 环境变量加载
|
|
56
|
+
├── filter/ # 异常过滤器
|
|
57
|
+
│ ├── default.filter.ts # 默认异常处理
|
|
58
|
+
│ └── notfound.filter.ts # 404 处理
|
|
59
|
+
├── guard/ # 守卫器
|
|
60
|
+
│ ├── api.ts # API Token 验证守卫
|
|
61
|
+
│ └── auth.ts # 登录态验证守卫
|
|
62
|
+
├── lib/ # 工具库
|
|
63
|
+
│ ├── decorator.ts # 自定义装饰器
|
|
64
|
+
│ ├── jwt.ts # JWT 工具函数
|
|
65
|
+
│ ├── request.ts # 请求工具
|
|
66
|
+
│ └── utils.ts # 通用工具函数
|
|
67
|
+
├── middleware/ # 中间件
|
|
68
|
+
│ ├── apiResultFormatter.ts # API 响应格式化
|
|
69
|
+
│ ├── detect.middleware.ts # 客户端检测
|
|
70
|
+
│ └── requestInit.ts # 请求初始化
|
|
71
|
+
├── service/ # 服务类
|
|
72
|
+
│ ├── session.service.ts # 会话服务
|
|
73
|
+
│ └── tencent.service.ts # 腾讯云服务
|
|
74
|
+
├── types/ # 类型定义
|
|
75
|
+
│ ├── base.controller.ts # 控制器基类
|
|
76
|
+
│ ├── base.model.service.ts # 模型服务基类
|
|
77
|
+
│ ├── base.service.ts # 服务基类
|
|
78
|
+
│ └── session.service.interface.ts # 会话服务接口
|
|
79
|
+
├── configuration.ts # 组件配置
|
|
80
|
+
└── index.ts # 入口文件
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## 快速开始
|
|
84
|
+
|
|
85
|
+
### 安装
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm install @cicctencent/midwayjs-base
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 基础配置
|
|
92
|
+
|
|
93
|
+
在 `src/configuration.ts` 中引入组件:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { Configuration } from '@midwayjs/core';
|
|
97
|
+
import * as base from '@cicctencent/midwayjs-base';
|
|
98
|
+
|
|
99
|
+
@Configuration({
|
|
100
|
+
imports: [
|
|
101
|
+
base // 引入基础组件
|
|
102
|
+
],
|
|
103
|
+
importConfigs: [
|
|
104
|
+
// 你的业务配置
|
|
105
|
+
]
|
|
106
|
+
})
|
|
107
|
+
export class MainConfiguration {
|
|
108
|
+
// 配置
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 环境变量配置
|
|
113
|
+
|
|
114
|
+
创建 `.env` 文件:
|
|
115
|
+
|
|
116
|
+
```env
|
|
117
|
+
# 应用配置
|
|
118
|
+
APP_ID=1001
|
|
119
|
+
SERVICE_NAME=your-service-name
|
|
120
|
+
|
|
121
|
+
# API 配置
|
|
122
|
+
API_KEY=your-api-key
|
|
123
|
+
|
|
124
|
+
# SSO 配置
|
|
125
|
+
SSO_URL=https://sso.example.com
|
|
126
|
+
|
|
127
|
+
# 基础服务地址
|
|
128
|
+
BASE_SERVER_URL=https://base-service.example.com
|
|
129
|
+
|
|
130
|
+
# 腾讯云配置
|
|
131
|
+
TENCENT_CREDENTIAL_SECRETID=your-secret-id
|
|
132
|
+
TENCENT_CREDENTIAL_SECRETKEY=your-secret-key
|
|
133
|
+
|
|
134
|
+
# 会话配置
|
|
135
|
+
SESSION_TIMEOUT=1200000
|
|
136
|
+
|
|
137
|
+
# 日志配置
|
|
138
|
+
LOG_LEVEL=info
|
|
139
|
+
REMOTE_LOGGER_URL=https://log.example.com/api/report
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## 核心功能使用
|
|
143
|
+
|
|
144
|
+
### 1. 基础服务类 (BaseService)
|
|
145
|
+
|
|
146
|
+
继承 `BaseService` 获取基础能力:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { Provide } from '@midwayjs/core';
|
|
150
|
+
import { BaseService } from '@cicctencent/midwayjs-base';
|
|
151
|
+
import { GetUserInfoReq, GetUserInfoRes } from '@fefeding/common/dist/models/user/request';
|
|
152
|
+
|
|
153
|
+
@Provide()
|
|
154
|
+
export class UserService extends BaseService {
|
|
155
|
+
/**
|
|
156
|
+
* 获取用户信息
|
|
157
|
+
* @param userId 用户ID
|
|
158
|
+
*/
|
|
159
|
+
async getUserInfo(userId: number) {
|
|
160
|
+
// 检查是否为管理员
|
|
161
|
+
const isManager = await this.checkManager();
|
|
162
|
+
|
|
163
|
+
// 方式1:使用请求对象(推荐)
|
|
164
|
+
const req = new GetUserInfoReq();
|
|
165
|
+
req.userId = userId;
|
|
166
|
+
const result = await this.requestBaseApi<GetUserInfoRes>(req);
|
|
167
|
+
|
|
168
|
+
// 方式2:使用 URL 路径
|
|
169
|
+
// const result = await this.requestBaseApi('/api/user/getInfo', {
|
|
170
|
+
// data: { userId }
|
|
171
|
+
// });
|
|
172
|
+
|
|
173
|
+
return result?.data || null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**BaseService 提供的能力:**
|
|
179
|
+
- `checkManager(account?)` - 检查是否为管理员账号
|
|
180
|
+
- `requestBaseApi(req, option)` - 请求基础服务(返回 data)
|
|
181
|
+
- `requestBaseServer(req, option)` - 请求基础服务(返回完整响应)
|
|
182
|
+
|
|
183
|
+
### 2. 会话服务类 (SessionService)
|
|
184
|
+
|
|
185
|
+
继承 `ISessionService` 实现自定义会话管理:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import { Provide, Scope, ScopeEnum, Config, Inject } from '@midwayjs/core';
|
|
189
|
+
import { ISessionService, TencentService } from '@cicctencent/midwayjs-base';
|
|
190
|
+
import { Session, GetLoginSessionReq } from '@fefeding/common/dist/models/account/session';
|
|
191
|
+
|
|
192
|
+
@Provide('session:service')
|
|
193
|
+
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
|
194
|
+
export class SessionService extends ISessionService {
|
|
195
|
+
@Config('loginOption')
|
|
196
|
+
loginOption: any;
|
|
197
|
+
|
|
198
|
+
@Inject()
|
|
199
|
+
tencentService: TencentService;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* 根据Token获取会话信息
|
|
203
|
+
* @param id 会话Token
|
|
204
|
+
*/
|
|
205
|
+
async getLoginSession(id: string): Promise<Session | null> {
|
|
206
|
+
const req = new GetLoginSessionReq();
|
|
207
|
+
req.id = id;
|
|
208
|
+
const res = await this.requestBaseApi(req);
|
|
209
|
+
return res?.data || null;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* 用户登出
|
|
214
|
+
* @param id 会话Token
|
|
215
|
+
*/
|
|
216
|
+
async logout(id: string): Promise<any> {
|
|
217
|
+
this.ctx.currentSession = null;
|
|
218
|
+
return { success: true };
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* 通过临时授权码登录
|
|
223
|
+
* @param code 授权码
|
|
224
|
+
*/
|
|
225
|
+
async loginByCode(code: string): Promise<Session | null> {
|
|
226
|
+
const res = await this.requestBaseApi('/api/session/loginByAuthCode', {
|
|
227
|
+
data: { code }
|
|
228
|
+
});
|
|
229
|
+
return res?.data || null;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### 3. 控制器基类 (BaseController)
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
import { Controller, Get, Post } from '@midwayjs/core';
|
|
238
|
+
import { BaseController } from '@cicctencent/midwayjs-base';
|
|
239
|
+
|
|
240
|
+
@Controller('/api/user')
|
|
241
|
+
export class UserController extends BaseController {
|
|
242
|
+
|
|
243
|
+
@Get('/info')
|
|
244
|
+
async getUserInfo() {
|
|
245
|
+
// 获取当前会话信息
|
|
246
|
+
const session = this.ctx.currentSession;
|
|
247
|
+
|
|
248
|
+
return {
|
|
249
|
+
userId: session.userId,
|
|
250
|
+
account: session.account
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### 4. 装饰器使用
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
import { Controller, Get, Post } from '@midwayjs/core';
|
|
260
|
+
import { checkLogin, checkApiToken, checkIP } from '@cicctencent/midwayjs-base';
|
|
261
|
+
|
|
262
|
+
@Controller('/api')
|
|
263
|
+
export class ApiController {
|
|
264
|
+
|
|
265
|
+
@Get('/public')
|
|
266
|
+
async publicApi() {
|
|
267
|
+
// 公开接口,无需认证
|
|
268
|
+
return { message: 'public' };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
@Get('/user/info')
|
|
272
|
+
@checkLogin() // 需要登录态
|
|
273
|
+
async getUserInfo() {
|
|
274
|
+
return this.ctx.currentSession;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
@Post('/admin/action')
|
|
278
|
+
@checkLogin()
|
|
279
|
+
@checkIP() // 检查IP白名单
|
|
280
|
+
async adminAction() {
|
|
281
|
+
// 仅允许白名单IP访问
|
|
282
|
+
return { success: true };
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@Post('/internal/sync')
|
|
286
|
+
@checkApiToken() // 验证API Token
|
|
287
|
+
async syncData() {
|
|
288
|
+
// 需要携带有效的 api_token 和 timestamp
|
|
289
|
+
return { success: true };
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### 5. 腾讯云 COS 服务
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
import { Provide, Inject } from '@midwayjs/core';
|
|
298
|
+
import { TencentService } from '@cicctencent/midwayjs-base';
|
|
299
|
+
|
|
300
|
+
@Provide()
|
|
301
|
+
export class FileService {
|
|
302
|
+
|
|
303
|
+
@Inject()
|
|
304
|
+
tencentService: TencentService;
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* 上传文件到 COS
|
|
308
|
+
* @param filePath 本地文件路径
|
|
309
|
+
* @param key COS对象键
|
|
310
|
+
*/
|
|
311
|
+
async uploadFile(filePath: string, key: string) {
|
|
312
|
+
// 上传文件
|
|
313
|
+
const result = await this.tencentService.uploadCosFile(key, filePath);
|
|
314
|
+
|
|
315
|
+
// 获取带签名的访问URL
|
|
316
|
+
const url = await this.tencentService.getCosFileUrl(key);
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
...result,
|
|
320
|
+
url
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* 上传数据到 COS
|
|
326
|
+
* @param key COS对象键
|
|
327
|
+
* @param data 数据内容(字符串、Buffer、ReadStream等)
|
|
328
|
+
*/
|
|
329
|
+
async uploadData(key: string, data: any) {
|
|
330
|
+
return await this.tencentService.uploadCosData(key, data);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* 获取文件内容
|
|
335
|
+
* @param key COS对象键
|
|
336
|
+
*/
|
|
337
|
+
async getFile(key: string) {
|
|
338
|
+
return await this.tencentService.getFile(key);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### 6. JWT 工具
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
import { jwt } from '@cicctencent/midwayjs-base';
|
|
347
|
+
|
|
348
|
+
// 生成 JWT Token
|
|
349
|
+
const token = jwt.encodeJWT(
|
|
350
|
+
{ userId: 123, loginId: 'user001' },
|
|
351
|
+
'your-secret-key',
|
|
352
|
+
{ expiresIn: '7d' } // 可选:过期时间
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
// 解码 JWT Token
|
|
356
|
+
const payload = jwt.decodeJWT(token, 'your-secret-key');
|
|
357
|
+
if (payload) {
|
|
358
|
+
console.log('用户ID:', payload.userId);
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### 7. 通用工具函数
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
import { utils } from '@cicctencent/midwayjs-base';
|
|
366
|
+
|
|
367
|
+
// 检查URL是否属于指定域名
|
|
368
|
+
const isValid = utils.checkUrlHost('https://example.com/path', 'example.com');
|
|
369
|
+
|
|
370
|
+
// 获取/设置认证Token
|
|
371
|
+
const token = utils.getAuthToken(ctx);
|
|
372
|
+
utils.setAuthToken(ctx, 'new-token');
|
|
373
|
+
|
|
374
|
+
// 渲染模板
|
|
375
|
+
await utils.getDefaultTemplate(ctx, 'index.html', { title: '首页' });
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## 配置说明
|
|
379
|
+
|
|
380
|
+
### 完整配置项
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
// config/config.default.ts
|
|
384
|
+
export default {
|
|
385
|
+
// Cookie 签名密钥
|
|
386
|
+
keys: 'your-app-keys',
|
|
387
|
+
|
|
388
|
+
// Cookie 配置
|
|
389
|
+
cookies: {
|
|
390
|
+
secret: '', // 空字符串表示关闭加密
|
|
391
|
+
},
|
|
392
|
+
|
|
393
|
+
// 视图配置(Nunjucks)
|
|
394
|
+
view: {
|
|
395
|
+
defaultViewEngine: 'nunjucks',
|
|
396
|
+
rootDir: {
|
|
397
|
+
default: path.join(appInfo.webDist, 'view/'),
|
|
398
|
+
},
|
|
399
|
+
mapping: {
|
|
400
|
+
'.html': 'nunjucks',
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
|
|
404
|
+
// 文件上传配置
|
|
405
|
+
upload: {
|
|
406
|
+
mode: 'file',
|
|
407
|
+
fileSize: '10mb',
|
|
408
|
+
whitelist: ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx'],
|
|
409
|
+
},
|
|
410
|
+
|
|
411
|
+
// 静态文件服务
|
|
412
|
+
staticFile: {
|
|
413
|
+
dirs: {
|
|
414
|
+
default: {
|
|
415
|
+
dir: appInfo.webPublic,
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
|
|
420
|
+
// API 配置
|
|
421
|
+
apiOption: {
|
|
422
|
+
key: 'your-api-key', // API Token 密钥
|
|
423
|
+
reg: /^\/([^/]+\/)?api\//i, // API 路径匹配正则
|
|
424
|
+
ignore: ['/'], // 忽略路径
|
|
425
|
+
},
|
|
426
|
+
|
|
427
|
+
// IP 白名单
|
|
428
|
+
ipOption: {
|
|
429
|
+
whiteList: ['127.0.0.1', '::1', '0.0.0.0'],
|
|
430
|
+
},
|
|
431
|
+
|
|
432
|
+
// 基础服务配置
|
|
433
|
+
baseService: {
|
|
434
|
+
manager: ['admin'], // 管理员账号列表
|
|
435
|
+
appId: 1001, // 应用ID
|
|
436
|
+
url: 'https://base-service.example.com',
|
|
437
|
+
},
|
|
438
|
+
|
|
439
|
+
// 会话配置
|
|
440
|
+
session: {
|
|
441
|
+
timeout: 1200000, // 过期时间(毫秒),默认20分钟
|
|
442
|
+
secretKey: 'your-session-secret',
|
|
443
|
+
},
|
|
444
|
+
|
|
445
|
+
// 登录态校验配置
|
|
446
|
+
auth: {
|
|
447
|
+
ignores: [/\/api\/test\//i], // 忽略登录态校验的路径
|
|
448
|
+
},
|
|
449
|
+
|
|
450
|
+
// SSO 配置
|
|
451
|
+
sso: {
|
|
452
|
+
baseUrl: 'https://sso.example.com',
|
|
453
|
+
appId: 1001,
|
|
454
|
+
},
|
|
455
|
+
|
|
456
|
+
// 腾讯云凭证
|
|
457
|
+
tencentCredential: {
|
|
458
|
+
secretId: 'your-secret-id',
|
|
459
|
+
secretKey: 'your-secret-key',
|
|
460
|
+
},
|
|
461
|
+
|
|
462
|
+
// 请求体解析配置
|
|
463
|
+
bodyParser: {
|
|
464
|
+
formLimit: '30mb',
|
|
465
|
+
jsonLimit: '30mb',
|
|
466
|
+
},
|
|
467
|
+
|
|
468
|
+
// 缓存配置
|
|
469
|
+
cacheManager: {
|
|
470
|
+
clients: {
|
|
471
|
+
default: {
|
|
472
|
+
store: 'memory',
|
|
473
|
+
options: {
|
|
474
|
+
max: 10000, // 最大缓存key数量
|
|
475
|
+
ttl: 600000, // 过期时间(毫秒)
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
|
|
481
|
+
// 日志配置
|
|
482
|
+
logger: {
|
|
483
|
+
level: 'info',
|
|
484
|
+
consoleLevel: 'info',
|
|
485
|
+
remoteUrl: '', // 远程日志上报地址
|
|
486
|
+
},
|
|
487
|
+
};
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
## 中间件说明
|
|
491
|
+
|
|
492
|
+
### 内置中间件执行顺序
|
|
493
|
+
|
|
494
|
+
```
|
|
495
|
+
请求 → RequestInitMiddleware → DetectMiddleware → ApiResultFormatterMiddleware → Guard → Controller
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
1. **RequestInitMiddleware**: 请求初始化
|
|
499
|
+
- 生成请求 ID
|
|
500
|
+
- 初始化日志器
|
|
501
|
+
- 记录请求耗时
|
|
502
|
+
|
|
503
|
+
2. **DetectMiddleware**: 客户端检测
|
|
504
|
+
- 检测移动端/PC端
|
|
505
|
+
- 检测微信/QQ环境
|
|
506
|
+
- 获取客户端IP
|
|
507
|
+
|
|
508
|
+
3. **ApiResultFormatterMiddleware**: API 响应格式化
|
|
509
|
+
- 统一响应格式 `{ ret, msg, data }`
|
|
510
|
+
- 异常处理
|
|
511
|
+
|
|
512
|
+
### 守卫器
|
|
513
|
+
|
|
514
|
+
1. **ApiGuard**: API 接口守卫
|
|
515
|
+
- `@checkApiToken()` - 验证 API Token
|
|
516
|
+
- `@checkIP()` - IP 白名单检查
|
|
517
|
+
|
|
518
|
+
2. **AuthGuard**: 认证守卫
|
|
519
|
+
- `@checkLogin()` - 登录态验证
|
|
520
|
+
- 支持 SSO 回调处理
|
|
521
|
+
- 支持 JWT Token 认证
|
|
522
|
+
|
|
523
|
+
## 开发指南
|
|
524
|
+
|
|
525
|
+
### 本地开发
|
|
526
|
+
|
|
527
|
+
```bash
|
|
528
|
+
# 安装依赖
|
|
529
|
+
npm install
|
|
530
|
+
|
|
531
|
+
# 构建
|
|
532
|
+
npm run build
|
|
533
|
+
|
|
534
|
+
# 测试
|
|
535
|
+
npm test
|
|
536
|
+
|
|
537
|
+
# 代码检查
|
|
538
|
+
npm run lint
|
|
539
|
+
npm run lint:fix
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### 发布
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
# 构建
|
|
546
|
+
npm run build
|
|
547
|
+
|
|
548
|
+
# 发布
|
|
549
|
+
npm publish --access public
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
## 依赖说明
|
|
553
|
+
|
|
554
|
+
### 核心依赖
|
|
555
|
+
- `@midwayjs/core` - MidwayJS 核心框架
|
|
556
|
+
- `@midwayjs/koa` - Koa 适配器
|
|
557
|
+
- `@fefeding/common` - 公共模型和工具库
|
|
558
|
+
|
|
559
|
+
### 功能依赖
|
|
560
|
+
- `jsonwebtoken` - JWT 处理
|
|
561
|
+
- `axios` - HTTP 客户端
|
|
562
|
+
- `typeorm` - ORM 支持
|
|
563
|
+
- `dayjs` - 日期处理
|
|
564
|
+
|
|
565
|
+
## 版本历史
|
|
566
|
+
|
|
567
|
+
### v1.0.38 (当前版本)
|
|
568
|
+
- 优化请求初始化中间件
|
|
569
|
+
- 增强错误处理机制
|
|
570
|
+
|
|
571
|
+
### v1.0.35+
|
|
572
|
+
- 基础功能稳定版本
|
|
573
|
+
- 完整的认证授权体系
|
|
574
|
+
- 腾讯云 COS 集成
|
|
575
|
+
|
|
576
|
+
## 技术支持
|
|
577
|
+
|
|
578
|
+
如有问题或建议,请联系开发团队。
|
|
579
|
+
|
|
580
|
+
## 许可证
|
|
581
|
+
|
|
582
|
+
MIT License
|