chanjs 2.6.4 → 2.6.6
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/App.js +1 -1
- package/base/Container.js +6 -3
- package/base/Controller.js +2 -1
- package/base/Service.js +20 -1
- package/common/index.js +0 -2
- package/doc/Aop.md +269 -0
- package/doc/Cache.md +160 -0
- package/doc/Common.md +182 -0
- package/doc/Controller.md +152 -0
- package/doc/Email.md +114 -0
- package/doc/Event.md +232 -0
- package/doc/Help.md +789 -0
- package/doc/Service.md +566 -0
- package/helper/cache.js +1 -0
- package/helper/index.js +71 -22
- package/index.js +0 -1
- package/middleware/waf.js +5 -6
- package/package.json +1 -1
- package//345/275/222/346/241/243.zip +0 -0
- package/utils/index.js +0 -4
- /package/{utils → helper}/checker.js +0 -0
- /package/{utils → helper}/keywords.js +0 -0
- /package/{utils → helper}/rate-limit.js +0 -0
- /package/{utils → helper}/response.js +0 -0
- /package/{utils → helper}/xss-filter.js +0 -0
package/doc/Help.md
ADDED
|
@@ -0,0 +1,789 @@
|
|
|
1
|
+
# chanjs/helper/index.js 工具函数使用文档
|
|
2
|
+
本文档详细说明 `chanjs/helper/index.js` 导出的所有工具函数的调用方式、参数说明及使用示例,帮助开发者快速集成和使用这些工具。
|
|
3
|
+
|
|
4
|
+
## 一、加载器相关(loader.js)
|
|
5
|
+
### 1. loaderSort
|
|
6
|
+
**功能**:对加载的模块/配置进行排序处理
|
|
7
|
+
**调用方式**:
|
|
8
|
+
```javascript
|
|
9
|
+
import { loaderSort } from 'chanjs/helper/index.js';
|
|
10
|
+
|
|
11
|
+
// 示例:对加载的控制器列表排序
|
|
12
|
+
const loadList = [{ name: 'user', order: 2 }, { name: 'auth', order: 1 }];
|
|
13
|
+
const sortedList = loaderSort(loadList); // 按order升序排列
|
|
14
|
+
console.log(sortedList); // [{ name: 'auth', order: 1 }, { name: 'user', order: 2 }]
|
|
15
|
+
```
|
|
16
|
+
**参数说明**:
|
|
17
|
+
- `list` (Array):需要排序的加载项数组,数组项需包含排序字段(如`order`,具体字段由内部逻辑定义)
|
|
18
|
+
- 返回值:排序后的数组
|
|
19
|
+
|
|
20
|
+
### 2. loadConfig
|
|
21
|
+
**功能**:加载项目配置文件(如JSON/JS配置)
|
|
22
|
+
**调用方式**:
|
|
23
|
+
```javascript
|
|
24
|
+
import { loadConfig } from 'chanjs/helper/index.js';
|
|
25
|
+
|
|
26
|
+
// 示例:加载指定路径的配置
|
|
27
|
+
const config = loadConfig('config/app.js');
|
|
28
|
+
console.log(config); // 配置文件导出的内容
|
|
29
|
+
```
|
|
30
|
+
**参数说明**:
|
|
31
|
+
- `path` (String):配置文件路径(相对/绝对)
|
|
32
|
+
- 返回值:配置文件的导出内容
|
|
33
|
+
|
|
34
|
+
### 3. clearConfigCache
|
|
35
|
+
**功能**:清除配置加载的缓存(避免配置修改后读取旧值)
|
|
36
|
+
**调用方式**:
|
|
37
|
+
```javascript
|
|
38
|
+
import { clearConfigCache } from 'chanjs/helper/index.js';
|
|
39
|
+
|
|
40
|
+
// 示例:修改配置后清除缓存
|
|
41
|
+
clearConfigCache(); // 无参数,直接调用
|
|
42
|
+
```
|
|
43
|
+
**参数说明**:无参数
|
|
44
|
+
**返回值**:无
|
|
45
|
+
|
|
46
|
+
### 4. loadController
|
|
47
|
+
**功能**:加载指定目录下的控制器文件
|
|
48
|
+
**调用方式**:
|
|
49
|
+
```javascript
|
|
50
|
+
import { loadController } from 'chanjs/helper/index.js';
|
|
51
|
+
|
|
52
|
+
// 示例:加载controllers目录下的所有控制器
|
|
53
|
+
const controllers = loadController('app/controllers');
|
|
54
|
+
console.log(controllers); // 控制器实例/映射对象
|
|
55
|
+
```
|
|
56
|
+
**参数说明**:
|
|
57
|
+
- `dir` (String):控制器目录路径
|
|
58
|
+
- 返回值:加载后的控制器集合(对象/数组,具体格式由内部逻辑定义)
|
|
59
|
+
|
|
60
|
+
## 二、时间处理(time.js)
|
|
61
|
+
### 1. formatTime
|
|
62
|
+
**功能**:格式化时间戳/日期对象为指定格式的字符串
|
|
63
|
+
**调用方式**:
|
|
64
|
+
```javascript
|
|
65
|
+
import { formatTime } from 'chanjs/helper/index.js';
|
|
66
|
+
|
|
67
|
+
// 示例1:格式化当前时间
|
|
68
|
+
const now = new Date();
|
|
69
|
+
const timeStr1 = formatTime(now, 'YYYY-MM-DD HH:mm:ss'); // 2024-05-20 14:30:00
|
|
70
|
+
|
|
71
|
+
// 示例2:格式化时间戳
|
|
72
|
+
const timestamp = 1716205800000;
|
|
73
|
+
const timeStr2 = formatTime(timestamp, 'YYYY/MM/DD'); // 2024/05/20
|
|
74
|
+
```
|
|
75
|
+
**参数说明**:
|
|
76
|
+
- `time` (Date/Number/String):待格式化的时间(日期对象/时间戳/时间字符串)
|
|
77
|
+
- `format` (String):格式模板,支持 `YYYY`(年)、`MM`(月)、`DD`(日)、`HH`(时)、`mm`(分)、`ss`(秒)
|
|
78
|
+
- 返回值:格式化后的时间字符串
|
|
79
|
+
|
|
80
|
+
### 2. formatDateFields
|
|
81
|
+
**功能**:批量格式化对象中的日期字段(如将时间戳字段转为格式化字符串)
|
|
82
|
+
**调用方式**:
|
|
83
|
+
```javascript
|
|
84
|
+
import { formatDateFields } from 'chanjs/helper/index.js';
|
|
85
|
+
|
|
86
|
+
// 示例:格式化对象中的createTime和updateTime字段
|
|
87
|
+
const data = {
|
|
88
|
+
id: 1,
|
|
89
|
+
createTime: 1716205800000,
|
|
90
|
+
updateTime: 1716206800000
|
|
91
|
+
};
|
|
92
|
+
const formattedData = formatDateFields(data, ['createTime', 'updateTime'], 'YYYY-MM-DD');
|
|
93
|
+
// { id: 1, createTime: '2024-05-20', updateTime: '2024-05-20' }
|
|
94
|
+
```
|
|
95
|
+
**参数说明**:
|
|
96
|
+
- `obj` (Object):需要处理的对象
|
|
97
|
+
- `fields` (Array):需要格式化的日期字段名数组
|
|
98
|
+
- `format` (String):时间格式模板(同formatTime)
|
|
99
|
+
- 返回值:格式化后的新对象
|
|
100
|
+
|
|
101
|
+
## 三、缓存相关(cache.js)
|
|
102
|
+
### 1. Cache(默认导出类)
|
|
103
|
+
**功能**:缓存操作类(支持设置、获取、删除缓存等)
|
|
104
|
+
**调用方式**:
|
|
105
|
+
```javascript
|
|
106
|
+
import { Cache } from 'chanjs/helper/index.js';
|
|
107
|
+
|
|
108
|
+
// 示例:实例化并使用缓存
|
|
109
|
+
const cache = new Cache();
|
|
110
|
+
|
|
111
|
+
// 设置缓存(key, value, 过期时间(秒))
|
|
112
|
+
cache.set('user_1', { name: '张三' }, 3600);
|
|
113
|
+
|
|
114
|
+
// 获取缓存
|
|
115
|
+
const user = cache.get('user_1');
|
|
116
|
+
console.log(user); // { name: '张三' }
|
|
117
|
+
|
|
118
|
+
// 删除缓存
|
|
119
|
+
cache.del('user_1');
|
|
120
|
+
|
|
121
|
+
// 清空所有缓存
|
|
122
|
+
cache.clear();
|
|
123
|
+
```
|
|
124
|
+
**核心方法**:
|
|
125
|
+
- `set(key, value, expire)`:设置缓存,`expire` 为过期时间(秒),可选
|
|
126
|
+
- `get(key)`:获取缓存,返回缓存值(无则返回null)
|
|
127
|
+
- `del(key)`:删除指定key的缓存
|
|
128
|
+
- `clear()`:清空所有缓存
|
|
129
|
+
|
|
130
|
+
## 四、文件操作(file.js)
|
|
131
|
+
### 1. dirname
|
|
132
|
+
**功能**:获取文件/路径的目录名(兼容不同系统路径)
|
|
133
|
+
**调用方式**:
|
|
134
|
+
```javascript
|
|
135
|
+
import { dirname } from 'chanjs/helper/index.js';
|
|
136
|
+
|
|
137
|
+
// 示例:获取文件的目录路径
|
|
138
|
+
const filePath = '/app/controllers/user.js';
|
|
139
|
+
const dir = dirname(filePath);
|
|
140
|
+
console.log(dir); // /app/controllers
|
|
141
|
+
```
|
|
142
|
+
**参数说明**:
|
|
143
|
+
- `path` (String):文件/路径字符串
|
|
144
|
+
- 返回值:目录名字符串
|
|
145
|
+
|
|
146
|
+
### 2. delImg
|
|
147
|
+
**功能**:删除指定路径的图片文件
|
|
148
|
+
**调用方式**:
|
|
149
|
+
```javascript
|
|
150
|
+
import { delImg } from 'chanjs/helper/index.js';
|
|
151
|
+
|
|
152
|
+
// 示例:删除上传的图片
|
|
153
|
+
const imgPath = '/uploads/2024/05/avatar.png';
|
|
154
|
+
const isDel = delImg(imgPath);
|
|
155
|
+
console.log(isDel); // true(删除成功)/false(删除失败)
|
|
156
|
+
```
|
|
157
|
+
**参数说明**:
|
|
158
|
+
- `imgPath` (String):图片文件路径
|
|
159
|
+
- 返回值:Boolean,是否删除成功
|
|
160
|
+
|
|
161
|
+
### 3. getFileTree
|
|
162
|
+
**功能**:生成指定目录的文件树结构(递归遍历)
|
|
163
|
+
**调用方式**:
|
|
164
|
+
```javascript
|
|
165
|
+
import { getFileTree } from 'chanjs/helper/index.js';
|
|
166
|
+
|
|
167
|
+
// 示例:生成src目录的文件树
|
|
168
|
+
const tree = getFileTree('/app/src');
|
|
169
|
+
console.log(tree);
|
|
170
|
+
// 输出示例:{ name: 'src', type: 'dir', children: [{ name: 'utils', type: 'dir', children: [...] }, ...] }
|
|
171
|
+
```
|
|
172
|
+
**参数说明**:
|
|
173
|
+
- `dir` (String):目标目录路径
|
|
174
|
+
- 返回值:Object,文件树结构(包含name、type、children等字段)
|
|
175
|
+
|
|
176
|
+
### 4. readFileContent
|
|
177
|
+
**功能**:读取文件内容(支持文本/JSON格式)
|
|
178
|
+
**调用方式**:
|
|
179
|
+
```javascript
|
|
180
|
+
import { readFileContent } from 'chanjs/helper/index.js';
|
|
181
|
+
|
|
182
|
+
// 示例1:读取文本文件
|
|
183
|
+
const text = readFileContent('/app/config.txt', 'utf8');
|
|
184
|
+
console.log(text); // 文件文本内容
|
|
185
|
+
|
|
186
|
+
// 示例2:读取JSON文件
|
|
187
|
+
const json = readFileContent('/app/config.json', 'json');
|
|
188
|
+
console.log(json); // 解析后的JSON对象
|
|
189
|
+
```
|
|
190
|
+
**参数说明**:
|
|
191
|
+
- `filePath` (String):文件路径
|
|
192
|
+
- `type` (String):读取类型,可选 `utf8`(文本)/`json`(JSON),默认`utf8`
|
|
193
|
+
- 返回值:String/Object,文件内容(JSON类型返回解析后的对象)
|
|
194
|
+
|
|
195
|
+
### 5. saveFileContent
|
|
196
|
+
**功能**:写入内容到文件(支持覆盖/追加)
|
|
197
|
+
**调用方式**:
|
|
198
|
+
```javascript
|
|
199
|
+
import { saveFileContent } from 'chanjs/helper/index.js';
|
|
200
|
+
|
|
201
|
+
// 示例1:覆盖写入文本
|
|
202
|
+
saveFileContent('/app/log.txt', '操作日志:用户登录', 'overwrite');
|
|
203
|
+
|
|
204
|
+
// 示例2:追加写入文本
|
|
205
|
+
saveFileContent('/app/log.txt', '\n操作日志:用户退出', 'append');
|
|
206
|
+
|
|
207
|
+
// 示例3:写入JSON对象
|
|
208
|
+
saveFileContent('/app/data.json', { list: [1,2,3] }, 'json');
|
|
209
|
+
```
|
|
210
|
+
**参数说明**:
|
|
211
|
+
- `filePath` (String):文件路径
|
|
212
|
+
- `content` (String/Object):写入内容(JSON类型自动序列化)
|
|
213
|
+
- `mode` (String):写入模式,可选 `overwrite`(覆盖)/`append`(追加)/`json`(JSON写入),默认`overwrite`
|
|
214
|
+
- 返回值:Boolean,是否写入成功
|
|
215
|
+
|
|
216
|
+
### 6. isPathSafe
|
|
217
|
+
**功能**:校验路径是否安全(防止路径遍历攻击)
|
|
218
|
+
**调用方式**:
|
|
219
|
+
```javascript
|
|
220
|
+
import { isPathSafe } from 'chanjs/helper/index.js';
|
|
221
|
+
|
|
222
|
+
// 示例1:安全路径
|
|
223
|
+
const safe = isPathSafe('/app/uploads/avatar.png', '/app/uploads');
|
|
224
|
+
console.log(safe); // true
|
|
225
|
+
|
|
226
|
+
// 示例2:危险路径(路径遍历)
|
|
227
|
+
const unsafe = isPathSafe('/app/uploads/../config.js', '/app/uploads');
|
|
228
|
+
console.log(unsafe); // false
|
|
229
|
+
```
|
|
230
|
+
**参数说明**:
|
|
231
|
+
- `path` (String):待校验的路径
|
|
232
|
+
- `root` (String):允许的根目录
|
|
233
|
+
- 返回值:Boolean,路径是否安全
|
|
234
|
+
|
|
235
|
+
### 7. getFolders
|
|
236
|
+
**功能**:获取指定目录下的所有子目录
|
|
237
|
+
**调用方式**:
|
|
238
|
+
```javascript
|
|
239
|
+
import { getFolders } from 'chanjs/helper/index.js';
|
|
240
|
+
|
|
241
|
+
// 示例:获取src目录下的所有子目录
|
|
242
|
+
const folders = getFolders('/app/src');
|
|
243
|
+
console.log(folders); // ['utils', 'controllers', 'models']
|
|
244
|
+
```
|
|
245
|
+
**参数说明**:
|
|
246
|
+
- `dir` (String):目标目录路径
|
|
247
|
+
- 返回值:Array,子目录名称数组
|
|
248
|
+
|
|
249
|
+
## 五、HTML处理(html.js)
|
|
250
|
+
### 1. htmlDecode
|
|
251
|
+
**功能**:HTML实体解码(将`&`/`<`等转为原字符)
|
|
252
|
+
**调用方式**:
|
|
253
|
+
```javascript
|
|
254
|
+
import { htmlDecode } from 'chanjs/helper/index.js';
|
|
255
|
+
|
|
256
|
+
// 示例:解码HTML实体
|
|
257
|
+
const htmlStr = '<div>张三&李四</div>';
|
|
258
|
+
const rawStr = htmlDecode(htmlStr);
|
|
259
|
+
console.log(rawStr); // <div>张三&李四</div>
|
|
260
|
+
```
|
|
261
|
+
**参数说明**:
|
|
262
|
+
- `str` (String):包含HTML实体的字符串
|
|
263
|
+
- 返回值:String,解码后的原始字符串
|
|
264
|
+
|
|
265
|
+
## 六、IP相关(ip.js)
|
|
266
|
+
### 1. getIp
|
|
267
|
+
**功能**:从请求对象中获取客户端真实IP(兼容反向代理)
|
|
268
|
+
**调用方式**:
|
|
269
|
+
```javascript
|
|
270
|
+
import { getIp } from 'chanjs/helper/index.js';
|
|
271
|
+
// 示例(Express/Koa框架)
|
|
272
|
+
app.get('/', (req, res) => {
|
|
273
|
+
const ip = getIp(req); // Koa需传req.req
|
|
274
|
+
console.log(ip); // 客户端IP,如 192.168.1.100
|
|
275
|
+
res.send(`你的IP:${ip}`);
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
**参数说明**:
|
|
279
|
+
- `req` (Object):HTTP请求对象(Express/Koa的req)
|
|
280
|
+
- 返回值:String,客户端真实IP
|
|
281
|
+
|
|
282
|
+
## 七、JWT令牌(jwt.js)
|
|
283
|
+
### 1. verifyToken
|
|
284
|
+
**功能**:验证JWT令牌的有效性
|
|
285
|
+
**调用方式**:
|
|
286
|
+
```javascript
|
|
287
|
+
import { verifyToken } from 'chanjs/helper/index.js';
|
|
288
|
+
|
|
289
|
+
// 示例:验证令牌
|
|
290
|
+
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
|
|
291
|
+
try {
|
|
292
|
+
const payload = verifyToken(token); // 内部已配置密钥
|
|
293
|
+
console.log(payload); // 令牌解析后的载荷,如 { userId: 1, exp: 1716300000 }
|
|
294
|
+
} catch (err) {
|
|
295
|
+
console.error('令牌无效:', err.message);
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
**参数说明**:
|
|
299
|
+
- `token` (String):JWT令牌字符串
|
|
300
|
+
- 返回值:Object,令牌载荷(验证失败抛出异常)
|
|
301
|
+
|
|
302
|
+
### 2. generateToken
|
|
303
|
+
**功能**:生成JWT令牌
|
|
304
|
+
**调用方式**:
|
|
305
|
+
```javascript
|
|
306
|
+
import { generateToken } from 'chanjs/helper/index.js';
|
|
307
|
+
|
|
308
|
+
// 示例:生成令牌(有效期1小时)
|
|
309
|
+
const payload = { userId: 1, username: '张三' };
|
|
310
|
+
const token = generateToken(payload, 3600); // 过期时间3600秒
|
|
311
|
+
console.log(token); // 生成的JWT字符串
|
|
312
|
+
```
|
|
313
|
+
**参数说明**:
|
|
314
|
+
- `payload` (Object):令牌载荷(需包含非敏感信息)
|
|
315
|
+
- `expire` (Number):过期时间(秒),默认3600
|
|
316
|
+
- 返回值:String,JWT令牌
|
|
317
|
+
|
|
318
|
+
### 3. setToken
|
|
319
|
+
**功能**:设置令牌到响应头/客户端存储(如Cookie)
|
|
320
|
+
**调用方式**:
|
|
321
|
+
```javascript
|
|
322
|
+
import { setToken } from 'chanjs/helper/index.js';
|
|
323
|
+
// 示例(Express框架)
|
|
324
|
+
app.post('/login', (req, res) => {
|
|
325
|
+
const token = generateToken({ userId: 1 });
|
|
326
|
+
setToken(res, token); // 将令牌设置到Cookie/响应头
|
|
327
|
+
res.send({ code: 200, msg: '登录成功' });
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
**参数说明**:
|
|
331
|
+
- `res` (Object):HTTP响应对象(Express/Koa的res)
|
|
332
|
+
- `token` (String):JWT令牌
|
|
333
|
+
- 返回值:无
|
|
334
|
+
|
|
335
|
+
### 4. getToken
|
|
336
|
+
**功能**:从请求中获取JWT令牌(从Header/Cookie)
|
|
337
|
+
**调用方式**:
|
|
338
|
+
```javascript
|
|
339
|
+
import { getToken } from 'chanjs/helper/index.js';
|
|
340
|
+
// 示例(Express框架)
|
|
341
|
+
app.get('/profile', (req, res) => {
|
|
342
|
+
const token = getToken(req); // 从Authorization头/Cookie获取
|
|
343
|
+
if (!token) {
|
|
344
|
+
return res.send({ code: 401, msg: '未登录' });
|
|
345
|
+
}
|
|
346
|
+
// 验证令牌...
|
|
347
|
+
});
|
|
348
|
+
```
|
|
349
|
+
**参数说明**:
|
|
350
|
+
- `req` (Object):HTTP请求对象(Express/Koa的req)
|
|
351
|
+
- 返回值:String/null,获取到的令牌(无则返回null)
|
|
352
|
+
|
|
353
|
+
## 八、签名/加密(sign.js)
|
|
354
|
+
### 1. signData
|
|
355
|
+
**功能**:对数据进行签名(防止篡改)
|
|
356
|
+
**调用方式**:
|
|
357
|
+
```javascript
|
|
358
|
+
import { signData } from 'chanjs/helper/index.js';
|
|
359
|
+
|
|
360
|
+
// 示例:对数据签名
|
|
361
|
+
const data = { userId: 1, amount: 100 };
|
|
362
|
+
const sign = signData(data, 'your-secret-key'); // 传入数据和密钥
|
|
363
|
+
console.log(sign); // 生成的签名字符串
|
|
364
|
+
```
|
|
365
|
+
**参数说明**:
|
|
366
|
+
- `data` (Object):待签名的数据
|
|
367
|
+
- `secret` (String):签名密钥(内部可配置默认密钥)
|
|
368
|
+
- 返回值:String,签名字符串
|
|
369
|
+
|
|
370
|
+
### 2. verifySign
|
|
371
|
+
**功能**:验证数据签名的有效性
|
|
372
|
+
**调用方式**:
|
|
373
|
+
```javascript
|
|
374
|
+
import { verifySign } from 'chanjs/helper/index.js';
|
|
375
|
+
|
|
376
|
+
// 示例:验证签名
|
|
377
|
+
const data = { userId: 1, amount: 100 };
|
|
378
|
+
const sign = 'xxx...'; // 前端传入的签名
|
|
379
|
+
const isValid = verifySign(data, sign, 'your-secret-key');
|
|
380
|
+
console.log(isValid); // true(签名有效)/false(无效)
|
|
381
|
+
```
|
|
382
|
+
**参数说明**:
|
|
383
|
+
- `data` (Object):原始数据
|
|
384
|
+
- `sign` (String):待验证的签名
|
|
385
|
+
- `secret` (String):签名密钥(需与签名时一致)
|
|
386
|
+
- 返回值:Boolean,签名是否有效
|
|
387
|
+
|
|
388
|
+
### 3. aesEncrypt
|
|
389
|
+
**功能**:AES加密数据
|
|
390
|
+
**调用方式**:
|
|
391
|
+
```javascript
|
|
392
|
+
import { aesEncrypt } from 'chanjs/helper/index.js';
|
|
393
|
+
|
|
394
|
+
// 示例:加密字符串
|
|
395
|
+
const rawData = '敏感信息:123456';
|
|
396
|
+
const encrypted = aesEncrypt(rawData, 'aes-secret-key', 'aes-iv'); // 密钥+向量
|
|
397
|
+
console.log(encrypted); // 加密后的Base64字符串
|
|
398
|
+
```
|
|
399
|
+
**参数说明**:
|
|
400
|
+
- `data` (String):待加密数据
|
|
401
|
+
- `key` (String):AES密钥(内部可配置默认)
|
|
402
|
+
- `iv` (String):AES向量(内部可配置默认)
|
|
403
|
+
- 返回值:String,加密后的Base64字符串
|
|
404
|
+
|
|
405
|
+
### 4. aesDecrypt
|
|
406
|
+
**功能**:AES解密数据
|
|
407
|
+
**调用方式**:
|
|
408
|
+
```javascript
|
|
409
|
+
import { aesDecrypt } from 'chanjs/helper/index.js';
|
|
410
|
+
|
|
411
|
+
// 示例:解密
|
|
412
|
+
const encrypted = 'xxx...'; // 加密后的字符串
|
|
413
|
+
const decrypted = aesDecrypt(encrypted, 'aes-secret-key', 'aes-iv');
|
|
414
|
+
console.log(decrypted); // 原始敏感信息:123456
|
|
415
|
+
```
|
|
416
|
+
**参数说明**:
|
|
417
|
+
- `data` (String):加密后的Base64字符串
|
|
418
|
+
- `key` (String):AES密钥(需与加密时一致)
|
|
419
|
+
- `iv` (String):AES向量(需与加密时一致)
|
|
420
|
+
- 返回值:String,解密后的原始数据
|
|
421
|
+
|
|
422
|
+
## 九、网络请求(request.js)
|
|
423
|
+
### 1. request
|
|
424
|
+
**功能**:封装的HTTP请求方法(支持GET/POST等)
|
|
425
|
+
**调用方式**:
|
|
426
|
+
```javascript
|
|
427
|
+
import { request } from 'chanjs/helper/index.js';
|
|
428
|
+
|
|
429
|
+
// 示例1:GET请求
|
|
430
|
+
request({
|
|
431
|
+
url: 'https://api.example.com/user',
|
|
432
|
+
method: 'GET',
|
|
433
|
+
params: { id: 1 } // URL参数
|
|
434
|
+
}).then(res => {
|
|
435
|
+
console.log(res); // 响应数据
|
|
436
|
+
}).catch(err => {
|
|
437
|
+
console.error(err);
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
// 示例2:POST请求(JSON数据)
|
|
441
|
+
request({
|
|
442
|
+
url: 'https://api.example.com/user',
|
|
443
|
+
method: 'POST',
|
|
444
|
+
data: { name: '张三', age: 20 }, // 请求体
|
|
445
|
+
headers: { 'Content-Type': 'application/json' }
|
|
446
|
+
}).then(res => {
|
|
447
|
+
console.log(res);
|
|
448
|
+
});
|
|
449
|
+
```
|
|
450
|
+
**参数说明**:
|
|
451
|
+
- `options` (Object):请求配置
|
|
452
|
+
- `url` (String):请求地址(必传)
|
|
453
|
+
- `method` (String):请求方法,默认GET
|
|
454
|
+
- `params` (Object):URL查询参数
|
|
455
|
+
- `data` (Object/String):请求体数据
|
|
456
|
+
- `headers` (Object):请求头
|
|
457
|
+
- `timeout` (Number):超时时间(毫秒),默认5000
|
|
458
|
+
- 返回值:Promise,解析后为响应数据
|
|
459
|
+
|
|
460
|
+
## 十、数据解析(data-parse.js)
|
|
461
|
+
### 1. dataParse
|
|
462
|
+
**功能**:通用数据解析(如表单数据/JSON字符串转对象)
|
|
463
|
+
**调用方式**:
|
|
464
|
+
```javascript
|
|
465
|
+
import { dataParse } from 'chanjs/helper/index.js';
|
|
466
|
+
|
|
467
|
+
// 示例1:解析JSON字符串
|
|
468
|
+
const jsonStr = '{"name":"张三","age":20}';
|
|
469
|
+
const obj1 = dataParse(jsonStr, 'json');
|
|
470
|
+
console.log(obj1); // { name: '张三', age: 20 }
|
|
471
|
+
|
|
472
|
+
// 示例2:解析表单字符串
|
|
473
|
+
const formStr = 'name=张三&age=20';
|
|
474
|
+
const obj2 = dataParse(formStr, 'form');
|
|
475
|
+
console.log(obj2); // { name: '张三', age: '20' }
|
|
476
|
+
```
|
|
477
|
+
**参数说明**:
|
|
478
|
+
- `data` (String):待解析的数据
|
|
479
|
+
- `type` (String):解析类型,可选 `json`/`form`,默认`json`
|
|
480
|
+
- 返回值:Object,解析后的对象
|
|
481
|
+
|
|
482
|
+
### 2. arrToObj
|
|
483
|
+
**功能**:将数组转为对象(指定key为属性名)
|
|
484
|
+
**调用方式**:
|
|
485
|
+
```javascript
|
|
486
|
+
import { arrToObj } from 'chanjs/helper/index.js';
|
|
487
|
+
|
|
488
|
+
// 示例:将用户数组转为以id为key的对象
|
|
489
|
+
const userArr = [{ id: 1, name: '张三' }, { id: 2, name: '李四' }];
|
|
490
|
+
const userObj = arrToObj(userArr, 'id');
|
|
491
|
+
console.log(userObj);
|
|
492
|
+
// { 1: { id: 1, name: '张三' }, 2: { id: 2, name: '李四' } }
|
|
493
|
+
```
|
|
494
|
+
**参数说明**:
|
|
495
|
+
- `arr` (Array):源数组
|
|
496
|
+
- `key` (String):作为对象属性名的字段
|
|
497
|
+
- 返回值:Object,转换后的对象
|
|
498
|
+
|
|
499
|
+
### 3. parseJsonFields
|
|
500
|
+
**功能**:解析对象中的JSON字符串字段为对象
|
|
501
|
+
**调用方式**:
|
|
502
|
+
```javascript
|
|
503
|
+
import { parseJsonFields } from 'chanjs/helper/index.js';
|
|
504
|
+
|
|
505
|
+
// 示例:解析userInfo字段(JSON字符串)
|
|
506
|
+
const data = {
|
|
507
|
+
id: 1,
|
|
508
|
+
userInfo: '{"name":"张三","age":20}'
|
|
509
|
+
};
|
|
510
|
+
const parsedData = parseJsonFields(data, ['userInfo']);
|
|
511
|
+
console.log(parsedData.userInfo); // { name: '张三', age: 20 }
|
|
512
|
+
```
|
|
513
|
+
**参数说明**:
|
|
514
|
+
- `obj` (Object):源对象
|
|
515
|
+
- `fields` (Array):需要解析的字段名数组
|
|
516
|
+
- 返回值:Object,解析后的新对象
|
|
517
|
+
|
|
518
|
+
### 4. buildTree
|
|
519
|
+
**功能**:将扁平数组转为树形结构(如分类/菜单)
|
|
520
|
+
**调用方式**:
|
|
521
|
+
```javascript
|
|
522
|
+
import { buildTree } from 'chanjs/helper/index.js';
|
|
523
|
+
|
|
524
|
+
// 示例:构建菜单树
|
|
525
|
+
const menuArr = [
|
|
526
|
+
{ id: 1, name: '系统管理', parentId: 0 },
|
|
527
|
+
{ id: 2, name: '用户管理', parentId: 1 },
|
|
528
|
+
{ id: 3, name: '角色管理', parentId: 1 }
|
|
529
|
+
];
|
|
530
|
+
const menuTree = buildTree(menuArr, 'id', 'parentId', 'children');
|
|
531
|
+
console.log(menuTree);
|
|
532
|
+
// 输出:[{ id: 1, name: '系统管理', parentId: 0, children: [{ id: 2, ... }, { id: 3, ... }] }]
|
|
533
|
+
```
|
|
534
|
+
**参数说明**:
|
|
535
|
+
- `arr` (Array):扁平数组
|
|
536
|
+
- `idKey` (String):ID字段名,默认'id'
|
|
537
|
+
- `parentKey` (String):父ID字段名,默认'parentId'
|
|
538
|
+
- `childrenKey` (String):子节点字段名,默认'children'
|
|
539
|
+
- 返回值:Array,树形结构数组
|
|
540
|
+
|
|
541
|
+
## 十一、树形结构(tree.js)
|
|
542
|
+
### 1. tree
|
|
543
|
+
**功能**:通用树形结构生成(简化版buildTree)
|
|
544
|
+
**调用方式**:
|
|
545
|
+
```javascript
|
|
546
|
+
import { tree } from 'chanjs/helper/index.js';
|
|
547
|
+
|
|
548
|
+
// 示例:生成分类树
|
|
549
|
+
const cateArr = [
|
|
550
|
+
{ id: 1, name: '电子产品', parentId: 0 },
|
|
551
|
+
{ id: 2, name: '手机', parentId: 1 }
|
|
552
|
+
];
|
|
553
|
+
const cateTree = tree(cateArr);
|
|
554
|
+
console.log(cateTree); // 树形结构数组
|
|
555
|
+
```
|
|
556
|
+
**参数说明**:
|
|
557
|
+
- `arr` (Array):扁平数组(默认id/parentId字段)
|
|
558
|
+
- 返回值:Array,树形结构数组
|
|
559
|
+
|
|
560
|
+
### 2. treeById
|
|
561
|
+
**功能**:根据ID查找树形结构中的节点
|
|
562
|
+
**调用方式**:
|
|
563
|
+
```javascript
|
|
564
|
+
import { treeById } from 'chanjs/helper/index.js';
|
|
565
|
+
|
|
566
|
+
// 示例:查找ID为2的节点
|
|
567
|
+
const cateTree = [/* 树形结构数组 */];
|
|
568
|
+
const node = treeById(cateTree, 2);
|
|
569
|
+
console.log(node); // { id: 2, name: '手机', parentId: 1 }
|
|
570
|
+
```
|
|
571
|
+
**参数说明**:
|
|
572
|
+
- `tree` (Array):树形结构数组
|
|
573
|
+
- `id` (Number/String):节点ID
|
|
574
|
+
- 返回值:Object/null,找到的节点(无则返回null)
|
|
575
|
+
|
|
576
|
+
## 十二、字段过滤(filter.js)
|
|
577
|
+
### 1. filterFields
|
|
578
|
+
**功能**:过滤对象中的字段(保留/排除指定字段)
|
|
579
|
+
**调用方式**:
|
|
580
|
+
```javascript
|
|
581
|
+
import { filterFields } from 'chanjs/helper/index.js';
|
|
582
|
+
|
|
583
|
+
// 示例1:保留指定字段
|
|
584
|
+
const user = { id: 1, name: '张三', password: '123456', age: 20 };
|
|
585
|
+
const userSafe = filterFields(user, ['id', 'name', 'age'], 'keep');
|
|
586
|
+
console.log(userSafe); // { id: 1, name: '张三', age: 20 }
|
|
587
|
+
|
|
588
|
+
// 示例2:排除指定字段
|
|
589
|
+
const userNoPwd = filterFields(user, ['password'], 'exclude');
|
|
590
|
+
console.log(userNoPwd); // { id: 1, name: '张三', age: 20 }
|
|
591
|
+
```
|
|
592
|
+
**参数说明**:
|
|
593
|
+
- `obj` (Object):源对象
|
|
594
|
+
- `fields` (Array):字段名数组
|
|
595
|
+
- `mode` (String):过滤模式,`keep`(保留)/`exclude`(排除),默认'keep'
|
|
596
|
+
- 返回值:Object,过滤后的新对象
|
|
597
|
+
|
|
598
|
+
## 十三、响应格式化(response.js)
|
|
599
|
+
### 1. success
|
|
600
|
+
**功能**:生成成功响应格式
|
|
601
|
+
**调用方式**:
|
|
602
|
+
```javascript
|
|
603
|
+
import { success } from 'chanjs/helper/index.js';
|
|
604
|
+
|
|
605
|
+
// 示例:返回成功响应
|
|
606
|
+
const resData = success({ data: { list: [1,2,3] }, msg: '操作成功' });
|
|
607
|
+
console.log(resData);
|
|
608
|
+
// 输出:{ code: 200, msg: '操作成功', data: { list: [1,2,3] } }
|
|
609
|
+
```
|
|
610
|
+
**参数说明**:
|
|
611
|
+
- `options` (Object):
|
|
612
|
+
- `data` (Any):响应数据,默认{}
|
|
613
|
+
- `msg` (String):提示信息,默认'操作成功'
|
|
614
|
+
- `code` (Number):状态码,默认200
|
|
615
|
+
- 返回值:Object,成功响应对象
|
|
616
|
+
|
|
617
|
+
### 2. fail
|
|
618
|
+
**功能**:生成失败响应格式
|
|
619
|
+
**调用方式**:
|
|
620
|
+
```javascript
|
|
621
|
+
import { fail } from 'chanjs/helper/index.js';
|
|
622
|
+
|
|
623
|
+
// 示例:返回失败响应
|
|
624
|
+
const resData = fail({ msg: '参数错误', code: 400 });
|
|
625
|
+
console.log(resData);
|
|
626
|
+
// 输出:{ code: 400, msg: '参数错误', data: {} }
|
|
627
|
+
```
|
|
628
|
+
**参数说明**:
|
|
629
|
+
- `options` (Object):
|
|
630
|
+
- `msg` (String):错误提示,默认'操作失败'
|
|
631
|
+
- `data` (Any):附加数据,默认{}
|
|
632
|
+
- `code` (Number):错误码,默认201
|
|
633
|
+
- 返回值:Object,失败响应对象
|
|
634
|
+
|
|
635
|
+
### 3. error
|
|
636
|
+
**功能**:生成服务器错误响应格式
|
|
637
|
+
**调用方式**:
|
|
638
|
+
```javascript
|
|
639
|
+
import { error } from 'chanjs/helper/index.js';
|
|
640
|
+
|
|
641
|
+
// 示例:返回服务器错误响应
|
|
642
|
+
const resData = error({ msg: '数据库查询失败' });
|
|
643
|
+
console.log(resData);
|
|
644
|
+
// 输出:{ code: 500, msg: '数据库查询失败', data: {} }
|
|
645
|
+
```
|
|
646
|
+
**参数说明**:
|
|
647
|
+
- `options` (Object):
|
|
648
|
+
- `msg` (String):错误提示,默认'服务器内部错误'
|
|
649
|
+
- `data` (Any):附加数据,默认{}
|
|
650
|
+
- 返回值:Object,错误响应对象(默认code=500)
|
|
651
|
+
|
|
652
|
+
### 4. parseDatabaseError
|
|
653
|
+
**功能**:解析数据库错误信息(格式化报错)
|
|
654
|
+
**调用方式**:
|
|
655
|
+
```javascript
|
|
656
|
+
import { parseDatabaseError } from 'chanjs/helper/index.js';
|
|
657
|
+
|
|
658
|
+
// 示例:解析数据库异常
|
|
659
|
+
try {
|
|
660
|
+
// 数据库操作...
|
|
661
|
+
} catch (err) {
|
|
662
|
+
const errInfo = parseDatabaseError(err);
|
|
663
|
+
console.log(errInfo); // { msg: '主键冲突', code: 'ER_DUP_ENTRY' }
|
|
664
|
+
}
|
|
665
|
+
```
|
|
666
|
+
**参数说明**:
|
|
667
|
+
- `err` (Error):数据库抛出的异常对象
|
|
668
|
+
- 返回值:Object,解析后的错误信息(msg/code)
|
|
669
|
+
|
|
670
|
+
### 5. notFoundResponse
|
|
671
|
+
**功能**:生成404响应格式
|
|
672
|
+
**调用方式**:
|
|
673
|
+
```javascript
|
|
674
|
+
import { notFoundResponse } from 'chanjs/helper/index.js';
|
|
675
|
+
|
|
676
|
+
// 示例:返回404响应
|
|
677
|
+
const resData = notFoundResponse({ msg: '资源不存在' });
|
|
678
|
+
console.log(resData);
|
|
679
|
+
// 输出:{ code: 404, msg: '资源不存在', data: {} }
|
|
680
|
+
```
|
|
681
|
+
**参数说明**:
|
|
682
|
+
- `options` (Object):
|
|
683
|
+
- `msg` (String):提示信息,默认'请求资源不存在'
|
|
684
|
+
- 返回值:Object,404响应对象
|
|
685
|
+
|
|
686
|
+
### 6. errorResponse
|
|
687
|
+
**功能**:通用错误响应生成(自定义码和信息)
|
|
688
|
+
**调用方式**:
|
|
689
|
+
```javascript
|
|
690
|
+
import { errorResponse } from 'chanjs/helper/index.js';
|
|
691
|
+
|
|
692
|
+
// 示例:生成自定义错误响应
|
|
693
|
+
const resData = errorResponse(403, '无访问权限', { userId: 1 });
|
|
694
|
+
console.log(resData);
|
|
695
|
+
// 输出:{ code: 403, msg: '无访问权限', data: { userId: 1 } }
|
|
696
|
+
```
|
|
697
|
+
**参数说明**:
|
|
698
|
+
- `code` (Number):错误码
|
|
699
|
+
- `msg` (String):错误提示
|
|
700
|
+
- `data` (Any):附加数据,默认{}
|
|
701
|
+
- 返回值:Object,自定义错误响应对象
|
|
702
|
+
|
|
703
|
+
## 十四、内容检查(checker.js)
|
|
704
|
+
### 1. checkKeywords
|
|
705
|
+
**功能**:检查文本中是否包含敏感关键词
|
|
706
|
+
**调用方式**:
|
|
707
|
+
```javascript
|
|
708
|
+
import { checkKeywords } from 'chanjs/helper/index.js';
|
|
709
|
+
|
|
710
|
+
// 示例:检查内容是否含敏感词
|
|
711
|
+
const content = '这是一条包含敏感词的内容';
|
|
712
|
+
const { isIllegal, keywords } = checkKeywords(content);
|
|
713
|
+
console.log(isIllegal); // true(包含敏感词)/false
|
|
714
|
+
console.log(keywords); // ['敏感词'](检测到的敏感词)
|
|
715
|
+
```
|
|
716
|
+
**参数说明**:
|
|
717
|
+
- `text` (String):待检查的文本
|
|
718
|
+
- 返回值:Object,{ isIllegal: Boolean, keywords: Array }
|
|
719
|
+
|
|
720
|
+
### 2. isIgnored
|
|
721
|
+
**功能**:检查内容是否属于忽略项(如白名单/过滤规则)
|
|
722
|
+
**调用方式**:
|
|
723
|
+
```javascript
|
|
724
|
+
import { isIgnored } from 'chanjs/helper/index.js';
|
|
725
|
+
|
|
726
|
+
// 示例:检查用户ID是否在忽略列表
|
|
727
|
+
const userId = 1;
|
|
728
|
+
const isIgnore = isIgnored(userId, 'user_ignore_list'); // 指定忽略规则名称
|
|
729
|
+
console.log(isIgnore); // true(忽略)/false(不忽略)
|
|
730
|
+
```
|
|
731
|
+
**参数说明**:
|
|
732
|
+
- `value` (Any):待检查的值
|
|
733
|
+
- `rule` (String):忽略规则名称(内部配置的规则标识)
|
|
734
|
+
- 返回值:Boolean,是否忽略
|
|
735
|
+
|
|
736
|
+
## 十五、XSS过滤(xss-filter.js)
|
|
737
|
+
### 1. filterXSS
|
|
738
|
+
**功能**:过滤文本中的XSS攻击脚本
|
|
739
|
+
**调用方式**:
|
|
740
|
+
```javascript
|
|
741
|
+
import { filterXSS } from 'chanjs/helper/index.js';
|
|
742
|
+
|
|
743
|
+
// 示例:过滤XSS脚本
|
|
744
|
+
const unsafeText = '<script>alert("xss")</script> <div>正常内容</div>';
|
|
745
|
+
const safeText = filterXSS(unsafeText);
|
|
746
|
+
console.log(safeText); // <script>alert("xss")</script> <div>正常内容</div>
|
|
747
|
+
```
|
|
748
|
+
**参数说明**:
|
|
749
|
+
- `text` (String):待过滤的文本
|
|
750
|
+
- 返回值:String,过滤后的安全文本
|
|
751
|
+
|
|
752
|
+
## 十六、限流中间件(rate-limit.js)
|
|
753
|
+
### 1. createRateLimitMiddleware
|
|
754
|
+
**功能**:创建接口限流中间件(防止高频请求)
|
|
755
|
+
**调用方式**:
|
|
756
|
+
```javascript
|
|
757
|
+
import { createRateLimitMiddleware } from 'chanjs/helper/index.js';
|
|
758
|
+
import express from 'express';
|
|
759
|
+
const app = express();
|
|
760
|
+
|
|
761
|
+
// 示例:创建限流中间件(每分钟最多100次请求)
|
|
762
|
+
const rateLimit = createRateLimitMiddleware({
|
|
763
|
+
windowMs: 60 * 1000, // 时间窗口(毫秒)
|
|
764
|
+
max: 100, // 窗口内最大请求数
|
|
765
|
+
message: { code: 429, msg: '请求过于频繁,请稍后再试' }
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
// 应用到所有接口
|
|
769
|
+
app.use(rateLimit);
|
|
770
|
+
|
|
771
|
+
// 或应用到单个接口
|
|
772
|
+
app.get('/api/user', rateLimit, (req, res) => {
|
|
773
|
+
res.send('用户信息');
|
|
774
|
+
});
|
|
775
|
+
```
|
|
776
|
+
**参数说明**:
|
|
777
|
+
- `options` (Object):限流配置
|
|
778
|
+
- `windowMs` (Number):时间窗口(毫秒),默认60000
|
|
779
|
+
- `max` (Number):窗口内最大请求数,默认100
|
|
780
|
+
- `message` (Object):限流提示响应,默认{ code: 429, msg: '请求频繁' }
|
|
781
|
+
- `keyGenerator` (Function):生成限流标识的函数(默认取IP)
|
|
782
|
+
- 返回值:Function,中间件函数(适配Express/Koa)
|
|
783
|
+
|
|
784
|
+
## 注意事项
|
|
785
|
+
1. 所有工具函数的默认配置(如密钥、超时时间等)可在对应子文件(如jwt.js、sign.js)中调整;
|
|
786
|
+
2. 涉及加密/签名的函数,建议使用项目自定义密钥,避免使用默认值;
|
|
787
|
+
3. 中间件类函数(如createRateLimitMiddleware)需适配对应Web框架(Express/Koa);
|
|
788
|
+
4. 文件操作函数需注意路径权限,避免因权限问题导致读写失败;
|
|
789
|
+
5. 所有异步函数(如request)返回Promise,需使用async/await或.then()处理。
|