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/doc/Service.md ADDED
@@ -0,0 +1,566 @@
1
+ # Service 数据库服务基类文档
2
+ ## 一、模块概述
3
+ `Service` 类是基于 `Container` 扩展的数据库服务基类,封装了常用的数据库操作方法,包括增删改查、分页查询、事务处理、软删除、关联查询等核心能力。该类自动处理日期字段格式化、数据库连接校验,并提供统一的返回格式,简化业务层数据库操作逻辑。
4
+
5
+ ## 二、依赖说明
6
+ - 继承自 `Container` 基类(`./Container.js`)
7
+ - 引入日期字段格式化工具 `formatDateFields`(`../helper/time.js`)
8
+ - 依赖全局对象 `Chan`:
9
+ - `Chan.db`/`Chan.dbManager`:数据库连接实例/连接管理器
10
+ - `Chan.config`:系统配置(包含分页、限制条数等配置项)
11
+
12
+ ## 三、类构造与初始化
13
+ ### 3.1 构造函数
14
+ #### 函数签名
15
+ ```javascript
16
+ constructor(tableName = null, dbName = null)
17
+ ```
18
+ #### 参数说明
19
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
20
+ |--------|------|------|--------|------|
21
+ | tableName | string | 否 | null | 数据库表名,子类实例化时指定 |
22
+ | dbName | string | 否 | null | 数据库连接名称,不传则使用默认数据库连接 |
23
+
24
+ #### 初始化逻辑
25
+ 1. 调用父类 `Container` 构造函数,指定组件类型为 `service`;
26
+ 2. 根据 `dbName` 获取对应数据库连接(优先),否则使用默认连接 `Chan.db`;
27
+ 3. 初始化日期字段列表 `_dateFields`,用于自动格式化日期字符串;
28
+ 4. 若子类定义 `on` 方法,自动执行以注册事件监听器。
29
+
30
+ ### 3.2 内置属性
31
+ | 属性名 | 类型 | 说明 |
32
+ |--------|------|------|
33
+ | _dateFields | Array<string> | 需自动格式化的日期字段列表(包含下划线/驼峰命名的常见日期字段) |
34
+ | pageSize(getter) | number | 每页默认记录数,优先读取 `Chan.config.PAGE_SIZE`,默认20 |
35
+ | limit(getter) | number | 查询最大限制条数,优先读取 `Chan.config.LIMIT_MAX`,默认300 |
36
+
37
+ ## 四、私有方法
38
+ ### 4.1 _checkDB
39
+ #### 功能描述
40
+ 校验数据库连接是否可用,不可用时抛出异常。
41
+ #### 函数签名
42
+ ```javascript
43
+ _checkDB()
44
+ ```
45
+ #### 异常抛出
46
+ - 类型:`Error`
47
+ - 消息:`Database connection not available`
48
+
49
+ ### 4.2 _formatDateFields
50
+ #### 功能描述
51
+ 自动将日期字符串转换为数据库可识别的 `Date` 类型,仅处理 `_dateFields` 中的字段。
52
+ #### 函数签名
53
+ ```javascript
54
+ _formatDateFields(data) => Object
55
+ ```
56
+ #### 参数说明
57
+ | 参数名 | 类型 | 必填 | 说明 |
58
+ |--------|------|------|------|
59
+ | data | Object | 是 | 待格式化的数据对象 |
60
+
61
+ #### 返回值
62
+ | 类型 | 说明 |
63
+ |------|------|
64
+ | Object | 格式化后的数据对象(原对象深拷贝,避免修改源数据) |
65
+
66
+ #### 处理逻辑
67
+ 1. 非对象类型直接返回;
68
+ 2. 遍历 `_dateFields` 中的字段,若字段值为有效日期字符串,转换为 `Date` 对象;
69
+ 3. 转换失败时打印错误日志,不中断流程。
70
+
71
+ ### 4.3 _buildBaseQuery
72
+ #### 功能描述
73
+ 构建基础查询器(Knex 查询构建器),整合查询条件、排序、字段筛选。
74
+ #### 函数签名
75
+ ```javascript
76
+ _buildBaseQuery({ query = {}, sort = {}, fields = [] } = {}) => Object
77
+ ```
78
+ #### 参数说明
79
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
80
+ |--------|------|------|--------|------|
81
+ | query | Object | 否 | {} | 查询条件(Knex `where` 格式) |
82
+ | sort | Object | 否 | {} | 排序条件(键:字段名,值:asc/desc) |
83
+ | fields | Array<string> | 否 | [] | 查询字段列表(为空则查询所有字段) |
84
+
85
+ #### 返回值
86
+ | 类型 | 说明 |
87
+ |------|------|
88
+ | Object | Knex 查询构建器实例 |
89
+
90
+ #### 处理逻辑
91
+ 1. 先调用 `_checkDB` 校验连接;
92
+ 2. 初始化查询器,指定操作表名;
93
+ 3. 依次添加 `where` 条件、字段筛选、排序规则(排序方向自动兼容大小写,默认升序)。
94
+
95
+ ## 五、核心操作方法
96
+ ### 5.1 all - 查询所有记录
97
+ #### 功能描述
98
+ 查询符合条件的所有记录,自动格式化日期字段。
99
+ #### 函数签名
100
+ ```javascript
101
+ async all({ query = {}, sort = {}, fields = [] } = {}) => Promise<Array>
102
+ ```
103
+ #### 参数说明
104
+ 同 `_buildBaseQuery` 方法参数。
105
+ #### 返回值
106
+ | 类型 | 说明 |
107
+ |------|------|
108
+ | Promise<Array> | 查询结果数组,日期字段已格式化 |
109
+
110
+ ### 5.2 find - 分页查询(偏移量模式)
111
+ #### 功能描述
112
+ 基于偏移量和限制条数的分页查询,返回结构化结果。
113
+ #### 函数签名
114
+ ```javascript
115
+ async find({ query = {}, sort = {}, fields = [], limit, offset } = {}) => Promise<Object>
116
+ ```
117
+ #### 参数说明
118
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
119
+ |--------|------|------|--------|------|
120
+ | query | Object | 否 | {} | 查询条件 |
121
+ | sort | Object | 否 | {} | 排序条件 |
122
+ | fields | Array<string> | 否 | [] | 查询字段 |
123
+ | limit | number | 否 | - | 限制返回条数 |
124
+ | offset | number | 否 | - | 偏移量(从0开始) |
125
+
126
+ #### 返回值
127
+ | 类型 | 结构 | 说明 |
128
+ |------|------|------|
129
+ | Promise<Object> | `{ success: true, code: 200, msg: '查询成功', data: Array }` | data 为查询结果数组,日期字段已格式化 |
130
+
131
+ ### 5.3 findOne - 查询单条记录
132
+ #### 功能描述
133
+ 根据条件查询单条记录,无结果时返回明确的失败状态。
134
+ #### 函数签名
135
+ ```javascript
136
+ async findOne({ query = {}, fields = [] } = {}) => Promise<Object>
137
+ ```
138
+ #### 参数说明
139
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
140
+ |--------|------|------|--------|------|
141
+ | query | Object | 否 | {} | 查询条件(建议唯一条件) |
142
+ | fields | Array<string> | 否 | [] | 查询字段 |
143
+
144
+ #### 返回值
145
+ | 场景 | 返回结构 |
146
+ |------|----------|
147
+ | 有结果 | `{ success: true, code: 200, msg: '查询成功', data: Object }` |
148
+ | 无结果 | `{ success: false, code: 404, msg: '记录不存在', data: null }` |
149
+
150
+ ### 5.4 findById - 根据ID查询单条记录
151
+ #### 功能描述
152
+ 简化根据主键ID查询单条记录的逻辑,参数更简洁。
153
+ #### 函数签名
154
+ ```javascript
155
+ async findById(id, { fields = [] } = {}) => Promise<Object>
156
+ ```
157
+ #### 参数说明
158
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
159
+ |--------|------|------|--------|------|
160
+ | id | number/string | 是 | - | 记录主键ID |
161
+ | fields | Array<string> | 否 | [] | 查询字段 |
162
+
163
+ #### 返回值
164
+ 同 `findOne` 方法。
165
+
166
+ ### 5.5 insert - 插入单条记录
167
+ #### 功能描述
168
+ 插入单条记录,自动格式化日期字段,返回插入结果。
169
+ #### 函数签名
170
+ ```javascript
171
+ async insert(data = {}) => Promise<Object>
172
+ ```
173
+ #### 参数说明
174
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
175
+ |--------|------|------|--------|------|
176
+ | data | Object | 否 | {} | 插入的数据对象 |
177
+
178
+ #### 返回值
179
+ | 场景 | 返回结构 |
180
+ |------|----------|
181
+ | 参数为空 | `{ success: false, code: 400, msg: '参数缺失', data: {} }` |
182
+ | 插入成功 | `{ success: true, code: 200, msg: '插入成功', data: { insertId: number, affectedRows: number } }` |
183
+
184
+ ### 5.6 insertMany - 批量插入记录
185
+ #### 功能描述
186
+ 批量插入多条记录,自动格式化每条记录的日期字段。
187
+ #### 函数签名
188
+ ```javascript
189
+ async insertMany(records = []) => Promise<Object>
190
+ ```
191
+ #### 参数说明
192
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
193
+ |--------|------|------|--------|------|
194
+ | records | Array<Object> | 否 | [] | 待插入的记录数组 |
195
+
196
+ #### 返回值
197
+ | 场景 | 返回结构 |
198
+ |------|----------|
199
+ | 参数为空 | `{ success: false, code: 400, msg: '参数缺失', data: {} }` |
200
+ | 插入成功 | `{ success: true, code: 200, msg: '批量插入成功', data: { insertIds: Array<number>, affectedRows: number } }` |
201
+
202
+ ### 5.7 delete - 根据条件删除记录
203
+ #### 功能描述
204
+ 根据自定义条件删除记录,返回受影响行数。
205
+ #### 函数签名
206
+ ```javascript
207
+ async delete(query = {}) => Promise<Object>
208
+ ```
209
+ #### 参数说明
210
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
211
+ |--------|------|------|--------|------|
212
+ | query | Object | 否 | {} | 删除条件(Knex `where` 格式) |
213
+
214
+ #### 返回值
215
+ | 场景 | 返回结构 |
216
+ |------|----------|
217
+ | 条件为空 | `{ success: false, code: 400, msg: '参数缺失', data: {} }` |
218
+ | 删除成功 | `{ success: true, code: 200, msg: '删除成功', data: { affectedRows: number } }` |
219
+
220
+ ### 5.8 deleteById - 根据ID删除记录
221
+ #### 功能描述
222
+ 简化根据主键ID删除记录的逻辑。
223
+ #### 函数签名
224
+ ```javascript
225
+ async deleteById(id) => Promise<Object>
226
+ ```
227
+ #### 参数说明
228
+ | 参数名 | 类型 | 必填 | 说明 |
229
+ |--------|------|------|------|
230
+ | id | number/string | 是 | 记录主键ID |
231
+
232
+ #### 返回值
233
+ 同 `delete` 方法。
234
+
235
+ ### 5.9 updateByQuery - 根据条件更新记录
236
+ #### 功能描述
237
+ 根据自定义条件更新记录,自动格式化日期字段,返回受影响行数。
238
+ #### 函数签名
239
+ ```javascript
240
+ async updateByQuery({ query, data } = {}) => Promise<Object>
241
+ ```
242
+ #### 参数说明
243
+ | 参数名 | 类型 | 必填 | 说明 |
244
+ |--------|------|------|------|
245
+ | query | Object | 是 | 更新条件(Knex `where` 格式) |
246
+ | data | Object | 是 | 更新的数据对象 |
247
+
248
+ #### 返回值
249
+ | 场景 | 返回结构 |
250
+ |------|----------|
251
+ | 参数无效(条件/数据为空) | `{ success: false, code: 400, msg: '参数无效', data: {} }` |
252
+ | 更新成功 | `{ success: true, code: 200, msg: '更新成功', data: { affectedRows: number } }` |
253
+
254
+ ### 5.10 updateById - 根据ID更新记录
255
+ #### 功能描述
256
+ 根据主键ID更新记录,返回更新后的完整记录。
257
+ #### 函数签名
258
+ ```javascript
259
+ async updateById(id, data = {}) => Promise<Object>
260
+ ```
261
+ #### 参数说明
262
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
263
+ |--------|------|------|--------|------|
264
+ | id | number/string | 是 | - | 记录主键ID |
265
+ | data | Object | 否 | {} | 更新的数据对象 |
266
+
267
+ #### 返回值
268
+ | 场景 | 返回结构 |
269
+ |------|----------|
270
+ | 参数无效(ID/数据为空) | `{ success: false, code: 400, msg: '参数无效', data: {} }` |
271
+ | 更新成功 | `{ success: true, code: 200, msg: '更新成功', data: Object }` |
272
+
273
+ ### 5.11 updateMany - 批量更新记录(事务)
274
+ #### 功能描述
275
+ 基于事务的批量更新,确保所有更新操作原子性(要么全部成功,要么全部回滚)。
276
+ #### 函数签名
277
+ ```javascript
278
+ async updateMany(updates = []) => Promise<Object>
279
+ ```
280
+ #### 参数说明
281
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
282
+ |--------|------|------|--------|------|
283
+ | updates | Array<Object> | 否 | [] | 批量更新配置,每项结构:`{ query: Object, data: Object }` |
284
+
285
+ #### 返回值
286
+ | 场景 | 返回结构 |
287
+ |------|----------|
288
+ | 参数无效(非数组/空数组) | `{ success: false, code: 400, msg: '参数缺失', data: {} }` |
289
+ | 单条条件为空 | `{ success: false, code: 400, msg: '参数无效:批量更新不允许空条件', data: {} }` |
290
+ | 更新成功 | `{ success: true, code: 200, msg: '批量更新成功', data: { affectedRows: number } }` |
291
+
292
+ #### 事务逻辑
293
+ 1. 开启数据库事务;
294
+ 2. 遍历更新配置,逐条执行更新;
295
+ 3. 任意一条更新条件为空时,回滚事务并返回失败;
296
+ 4. 全部执行完成后提交事务,返回总受影响行数。
297
+
298
+ ### 5.12 query - 分页查询(页码模式)
299
+ #### 功能描述
300
+ 基于页码的分页查询,自动计算偏移量,返回包含分页信息的结构化结果。
301
+ #### 函数签名
302
+ ```javascript
303
+ async query({ current = 1, pageSize = 10, query = {}, sort = {}, field = [] }) => Promise<Object>
304
+ ```
305
+ #### 参数说明
306
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
307
+ |--------|------|------|--------|------|
308
+ | current | number | 否 | 1 | 当前页码 |
309
+ | pageSize | number | 否 | 10 | 每页条数(自动限制在1~limit之间) |
310
+ | query | Object | 否 | {} | 查询条件 |
311
+ | sort | Object | 否 | {} | 排序条件 |
312
+ | field | Array<string> | 否 | [] | 查询字段 |
313
+
314
+ #### 返回值
315
+ ```javascript
316
+ {
317
+ success: true,
318
+ code: 200,
319
+ msg: '查询成功',
320
+ data: {
321
+ list: Array, // 查询结果列表
322
+ total: number, // 总记录数
323
+ current: number, // 当前页码
324
+ pageSize: number, // 实际每页条数
325
+ totalPages: number // 总页数
326
+ }
327
+ }
328
+ ```
329
+
330
+ ### 5.13 count - 统计记录数
331
+ #### 功能描述
332
+ 根据条件统计记录总数。
333
+ #### 函数签名
334
+ ```javascript
335
+ async count(query = {}) => Promise<Object>
336
+ ```
337
+ #### 参数说明
338
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
339
+ |--------|------|------|--------|------|
340
+ | query | Object | 否 | {} | 统计条件 |
341
+
342
+ #### 返回值
343
+ ```javascript
344
+ {
345
+ success: true,
346
+ code: 200,
347
+ msg: '统计成功',
348
+ data: { count: number } // 统计结果
349
+ }
350
+ ```
351
+
352
+ ### 5.14 exists - 检查记录是否存在
353
+ #### 功能描述
354
+ 根据条件检查是否存在匹配记录。
355
+ #### 函数签名
356
+ ```javascript
357
+ async exists(query = {}) => Promise<Object>
358
+ ```
359
+ #### 参数说明
360
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
361
+ |--------|------|------|--------|------|
362
+ | query | Object | 否 | {} | 检查条件 |
363
+
364
+ #### 返回值
365
+ ```javascript
366
+ {
367
+ success: true,
368
+ code: 200,
369
+ msg: '检查成功',
370
+ data: { exists: boolean } // 是否存在匹配记录
371
+ }
372
+ ```
373
+
374
+ ### 5.15 join - 关联查询
375
+ #### 功能描述
376
+ 实现两表内连接查询,支持条件、排序、字段筛选。
377
+ #### 函数签名
378
+ ```javascript
379
+ async join({ joinTable, localField, foreignField, fields = ["*"], query = {}, sort = {} }) => Promise<Object>
380
+ ```
381
+ #### 参数说明
382
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
383
+ |--------|------|------|--------|------|
384
+ | joinTable | string | 是 | - | 关联表名 |
385
+ | localField | string | 是 | - | 主表关联字段 |
386
+ | foreignField | string | 是 | - | 关联表关联字段 |
387
+ | fields | Array<string> | 否 | ["*"] | 查询字段(可指定表别名,如 `table1.field1`) |
388
+ | query | Object | 否 | {} | 查询条件 |
389
+ | sort | Object | 否 | {} | 排序条件 |
390
+
391
+ #### 返回值
392
+ ```javascript
393
+ {
394
+ success: true,
395
+ code: 200,
396
+ msg: '查询成功',
397
+ data: Array // 关联查询结果列表
398
+ }
399
+ ```
400
+
401
+ ### 5.16 deleteMany - 批量删除(ID数组)
402
+ #### 功能描述
403
+ 根据ID数组批量删除记录。
404
+ #### 函数签名
405
+ ```javascript
406
+ async deleteMany(ids = []) => Promise<Object>
407
+ ```
408
+ #### 参数说明
409
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
410
+ |--------|------|------|--------|------|
411
+ | ids | Array<number/string> | 否 | [] | 待删除记录的ID数组 |
412
+
413
+ #### 返回值
414
+ | 场景 | 返回结构 |
415
+ |------|----------|
416
+ | ID数组为空 | `{ success: false, code: 400, msg: '参数缺失', data: {} }` |
417
+ | 删除成功 | `{ success: true, code: 200, msg: '删除成功', data: { affectedRows: number } }` |
418
+
419
+ ### 5.17 softDelete - 软删除
420
+ #### 功能描述
421
+ 设置 `deleted_at` 字段为当前时间,实现逻辑删除(非物理删除)。
422
+ #### 函数签名
423
+ ```javascript
424
+ async softDelete(id) => Promise<Object>
425
+ ```
426
+ #### 参数说明
427
+ | 参数名 | 类型 | 必填 | 说明 |
428
+ |--------|------|------|------|
429
+ | id | number/string | 是 | 记录主键ID |
430
+
431
+ #### 返回值
432
+ | 场景 | 返回结构 |
433
+ |------|----------|
434
+ | 参数为空 | `{ msg: '参数缺失' }` |
435
+ | 删除成功 | `{ affectedRows: number }` |
436
+
437
+ ### 5.18 restore - 恢复软删除记录
438
+ #### 功能描述
439
+ 将 `deleted_at` 字段置为 `null`,恢复软删除的记录。
440
+ #### 函数签名
441
+ ```javascript
442
+ async restore(id) => Promise<Object>
443
+ ```
444
+ #### 参数说明
445
+ | 参数名 | 类型 | 必填 | 说明 |
446
+ |--------|------|------|------|
447
+ | id | number/string | 是 | 记录主键ID |
448
+
449
+ #### 返回值
450
+ | 场景 | 返回结构 |
451
+ |------|----------|
452
+ | 参数为空 | `{ msg: '参数缺失' }` |
453
+ | 恢复成功 | `{ affectedRows: number }` |
454
+
455
+ ### 5.19 findTrashed - 查询软删除记录
456
+ #### 功能描述
457
+ 查询已被软删除的记录(`deleted_at` 不为空)。
458
+ #### 函数签名
459
+ ```javascript
460
+ async findTrashed({ query = {}, fields = [], limit = 20, offset = 0 } = {}) => Promise<Array>
461
+ ```
462
+ #### 参数说明
463
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
464
+ |--------|------|------|--------|------|
465
+ | query | Object | 否 | {} | 额外查询条件 |
466
+ | fields | Array<string> | 否 | [] | 查询字段 |
467
+ | limit | number | 否 | 20 | 限制条数 |
468
+ | offset | number | 否 | 0 | 偏移量 |
469
+
470
+ #### 返回值
471
+ | 类型 | 说明 |
472
+ |------|------|
473
+ | Promise<Array> | 软删除记录列表,按 `deleted_at` 降序排列 |
474
+
475
+ ### 5.20 forceDelete - 强制删除软删除记录
476
+ #### 功能描述
477
+ 物理删除指定天数前被软删除的记录,用于清理历史数据。
478
+ #### 函数签名
479
+ ```javascript
480
+ async forceDelete(days = 30) => Promise<Object>
481
+ ```
482
+ #### 参数说明
483
+ | 参数名 | 类型 | 必填 | 默认值 | 说明 |
484
+ |--------|------|------|--------|------|
485
+ | days | number | 否 | 30 | 天数(删除N天前的软删除记录) |
486
+
487
+ #### 返回值
488
+ | 类型 | 说明 |
489
+ |------|------|
490
+ | Promise<Object> | `{ affectedRows: number }` - 受影响的行数 |
491
+
492
+ ### 5.21 stats - 统计总数与今日新增
493
+ #### 功能描述
494
+ 统计表中总记录数和今日新增记录数(按 `created_at` 字段)。
495
+ #### 函数签名
496
+ ```javascript
497
+ async stats() => Promise<Object>
498
+ ```
499
+ #### 返回值
500
+ | 类型 | 结构 |
501
+ |------|------|
502
+ | Promise<Object> | `{ total: number, today: number }` - total为总记录数,today为今日新增数 |
503
+
504
+ ## 六、使用示例
505
+ ### 6.1 基础使用(子类继承)
506
+ ```javascript
507
+ // UserService.js
508
+ import Service from './Service.js';
509
+
510
+ class UserService extends Service {
511
+ constructor() {
512
+ // 指定表名和数据库连接名
513
+ super('user', 'default');
514
+ }
515
+
516
+ // 自定义业务方法
517
+ async findByUsername(username) {
518
+ return this.findOne({ query: { username } });
519
+ }
520
+ }
521
+
522
+ export default new UserService();
523
+ ```
524
+
525
+ ### 6.2 调用示例
526
+ ```javascript
527
+ import userService from './UserService.js';
528
+
529
+ // 1. 查询用户列表(分页)
530
+ const userPage = await userService.query({
531
+ current: 1,
532
+ pageSize: 10,
533
+ query: { status: 1 },
534
+ sort: { create_at: 'desc' },
535
+ field: ['id', 'username', 'email']
536
+ });
537
+
538
+ // 2. 新增用户
539
+ const insertRes = await userService.insert({
540
+ username: 'test',
541
+ email: 'test@example.com',
542
+ created_at: '2024-01-01 12:00:00'
543
+ });
544
+
545
+ // 3. 软删除用户
546
+ await userService.softDelete(1);
547
+
548
+ // 4. 恢复软删除用户
549
+ await userService.restore(1);
550
+
551
+ // 5. 关联查询(用户-订单)
552
+ const userOrder = await userService.join({
553
+ joinTable: 'order',
554
+ localField: 'id',
555
+ foreignField: 'user_id',
556
+ fields: ['user.username', 'order.order_no'],
557
+ query: { user.status: 1 }
558
+ });
559
+ ```
560
+
561
+ ## 七、注意事项
562
+ 1. 所有方法均依赖 `Chan` 全局对象,需确保初始化时已配置数据库连接和相关配置项;
563
+ 2. 日期字段格式化仅处理 `_dateFields` 中的字段,若需扩展可在子类中重写该属性;
564
+ 3. 事务操作(`updateMany`)需数据库支持事务,否则会抛出异常;
565
+ 4. 分页查询 `query` 方法会自动限制 `pageSize` 不超过 `limit`,避免大数据量查询;
566
+ 5. 软删除相关方法依赖 `deleted_at` 字段,需确保表结构中包含该字段。
package/helper/cache.js CHANGED
@@ -179,4 +179,5 @@ class Cache {
179
179
  }
180
180
  }
181
181
 
182
+ export const cache = new Cache();
182
183
  export default Cache;
package/helper/index.js CHANGED
@@ -1,28 +1,77 @@
1
+ // 加载器相关
1
2
  export { loaderSort, loadConfig, clearConfigCache, loadController } from "./loader.js";
2
- export { formatTime } from "./time.js";
3
- export { formatDateFields } from "./time.js";
4
- export { default as Cache } from "./cache.js";
5
- export { dirname } from "./file.js";
6
- export { delImg } from "./file.js";
7
- export { getFileTree } from "./file.js";
8
- export { readFileContent } from "./file.js";
9
- export { saveFileContent } from "./file.js";
10
- export { isPathSafe } from "./file.js";
11
- export { getFolders } from "./file.js";
3
+
4
+ // 时间处理
5
+ export { formatTime, formatDateFields } from "./time.js";
6
+
7
+ // 缓存相关
8
+ export { cache } from "./cache.js";
9
+
10
+ // 文件操作
11
+ export {
12
+ dirname,
13
+ delImg,
14
+ getFileTree,
15
+ readFileContent,
16
+ saveFileContent,
17
+ isPathSafe,
18
+ getFolders
19
+ } from "./file.js";
20
+
21
+ // HTML处理
12
22
  export { htmlDecode } from "./html.js";
23
+
24
+ // IP相关
13
25
  export { getIp } from "./ip.js";
14
- export { verifyToken } from "./jwt.js";
15
- export { generateToken } from "./jwt.js";
16
- export { setToken } from "./jwt.js";
17
- export { getToken } from "./jwt.js";
18
- export { signData } from "./sign.js";
19
- export { verifySign } from "./sign.js";
20
- export { aesEncrypt } from "./sign.js";
21
- export { aesDecrypt } from "./sign.js";
26
+
27
+ // JWT令牌
28
+ export {
29
+ verifyToken,
30
+ generateToken,
31
+ setToken,
32
+ getToken
33
+ } from "./jwt.js";
34
+
35
+ // 签名/加密
36
+ export {
37
+ signData,
38
+ verifySign,
39
+ aesEncrypt,
40
+ aesDecrypt
41
+ } from "./sign.js";
42
+
43
+ // 网络请求
22
44
  export { request } from "./request.js";
23
- export { dataParse } from "./data-parse.js";
24
- export { arrToObj } from "./data-parse.js";
25
- export { parseJsonFields } from "./data-parse.js";
26
- export { buildTree } from "./data-parse.js";
45
+
46
+ // 数据解析
47
+ export {
48
+ dataParse,
49
+ arrToObj,
50
+ parseJsonFields,
51
+ buildTree
52
+ } from "./data-parse.js";
53
+
54
+ // 树形结构
27
55
  export { tree, treeById } from "./tree.js";
56
+
57
+ // 字段过滤
28
58
  export { filterFields } from "./filter.js";
59
+
60
+ // 响应格式化
61
+ export {
62
+ success,
63
+ fail,
64
+ error,
65
+ parseDatabaseError,
66
+ notFoundResponse,
67
+ errorResponse
68
+ } from "./response.js";
69
+
70
+ // 内容检查
71
+ export { checkKeywords, isIgnored } from "./checker.js";
72
+
73
+ // XSS过滤
74
+ export { filterXSS } from "./xss-filter.js";
75
+
76
+ // 限流中间件
77
+ export { createRateLimitMiddleware } from "./rate-limit.js";
package/index.js CHANGED
@@ -8,7 +8,6 @@ export { Event, event } from "./base/Event.js";
8
8
 
9
9
  // 工具模块导出
10
10
  export * as helper from "./helper/index.js";
11
- export * as utils from "./utils/index.js";
12
11
  export * as middleware from "./middleware/index.js";
13
12
  export * as config from "./config/index.js";
14
13
  export * as common from "./common/index.js";