mm_mongodb 1.5.1 → 1.5.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 (4) hide show
  1. package/README.md +353 -612
  2. package/index.js +673 -430
  3. package/package.json +3 -3
  4. package/test.js +4 -5
package/index.js CHANGED
@@ -4,21 +4,22 @@
4
4
  * @version 1.2.1
5
5
  */
6
6
  const {
7
- BaseService
8
- } = require('mm_base_service');
7
+ Base
8
+ } = require('mm_expand');
9
9
  const MongoClient = require('mongodb').MongoClient;
10
10
 
11
11
  /**
12
12
  * @description MongoDB帮助类
13
13
  */
14
- class MongoDB extends BaseService {
14
+ class MongoDB extends Base {
15
15
  /**
16
16
  * @description 创建MongoDB帮助类函数 (构造函数)
17
17
  * @param {Object} config 配置参数
18
18
  * @constructor
19
19
  */
20
20
  constructor(config) {
21
- super(Object.assign({
21
+ super();
22
+ this.config = {
22
23
  // 服务器地址
23
24
  host: "localhost",
24
25
  // 端口号
@@ -26,26 +27,17 @@ class MongoDB extends BaseService {
26
27
  // 数据库名
27
28
  database: "mm",
28
29
  // 用户名
29
- user: "admin",
30
+ user: "",
30
31
  // 密码
31
32
  password: "",
32
- // 连接选项
33
- options: {
34
- minPoolSize: 10,
35
- maxPoolSize: 100,
36
- connectTimeoutMS: 10000,
37
- serverSelectionTimeoutMS: 5000,
38
- retryWrites: true
39
- },
40
- // 重试配置
41
- retry: {
42
- maxAttempts: 3,
43
- delayMS: 1000
44
- }
45
- }, config));
33
+ // 连接选项 (MongoDB驱动7.x版本支持的参数)
34
+ min_pool_size: 10,
35
+ max_pool_size: 100,
36
+ connect_timeout_ms: 10000,
37
+ server_selection_timeout_ms: 5000,
38
+ retry_writes: true
39
+ };
46
40
 
47
- // 连接地址
48
- this.url = null;
49
41
  // 数据库连接器
50
42
  this.conn = null;
51
43
  // 操作的数据库
@@ -81,15 +73,15 @@ class MongoDB extends BaseService {
81
73
  */
82
74
  MongoDB.prototype._validateConfig = function () {
83
75
  if (!this.config.host || typeof this.config.host !== 'string') {
84
- throw new Error('MongoDB配置无效:host必须是有效的字符串');
76
+ throw new TypeError('host必须是有效的字符串');
85
77
  }
86
78
 
87
79
  if (!Number.isInteger(this.config.port) || this.config.port < 1 || this.config.port > 65535) {
88
- throw new Error('MongoDB配置无效:port必须是1-65535之间的整数');
80
+ throw new TypeError('port必须是1-65535之间的整数');
89
81
  }
90
82
 
91
83
  if (!this.config.database || typeof this.config.database !== 'string') {
92
- throw new Error('MongoDB配置无效:database必须是有效的字符串');
84
+ throw new TypeError('database必须是有效的字符串');
93
85
  }
94
86
  };
95
87
 
@@ -101,8 +93,8 @@ MongoDB.prototype._validateConfig = function () {
101
93
  * @return {Promise} 操作结果
102
94
  */
103
95
  MongoDB.prototype._withRetry = async function (operation, operationName) {
104
- const maxAttempts = this.config.retry?.maxAttempts || 3;
105
- const delayMS = this.config.retry?.delayMS || 1000;
96
+ const maxAttempts = 3; // 固定重试次数,不再从配置读取
97
+ const delayMS = 1000; // 固定延迟时间,不再从配置读取
106
98
  let lastError;
107
99
 
108
100
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
@@ -110,7 +102,7 @@ MongoDB.prototype._withRetry = async function (operation, operationName) {
110
102
  return await operation();
111
103
  } catch (error) {
112
104
  lastError = error;
113
- $.log.error(`[MongoDB] ${operationName} 第${attempt}次尝试失败:`, error.message);
105
+ this.logger('error', `${operationName} 第${attempt}次尝试失败:`, error);
114
106
 
115
107
  // 如果不是最后一次尝试,则等待后重试
116
108
  if (attempt < maxAttempts) {
@@ -119,8 +111,8 @@ MongoDB.prototype._withRetry = async function (operation, operationName) {
119
111
  }
120
112
  }
121
113
 
122
- // 所有重试都失败,抛出最后一个错误
123
- throw lastError;
114
+ // 所有重试都失败,触发错误事件
115
+ this.emit('error', lastError);
124
116
  };
125
117
  /**
126
118
  * @description 确保数据库连接已建立
@@ -146,16 +138,16 @@ MongoDB.prototype._ensureConnected = async function () {
146
138
 
147
139
  // 检查连接是否成功
148
140
  if (this.db && this.db.collection) {
149
- $.log.debug(`[MongoDB] [_ensureConnected] 连接成功,db对象存在,开始初始化collection,table=${this.table}`);
141
+ this.logger('debug', `[_ensureConnected] 连接成功,db对象存在,开始初始化collection,table=${this.table}`);
150
142
  this.connected = true;
151
143
  this.connectAttempts = 0;
152
144
 
153
145
  // 保存collection引用到实例变量
154
146
  try {
155
147
  this.collection = this.db.collection(this.table);
156
- $.log.debug(`[MongoDB] [_ensureConnected] 成功初始化collection: ${this.table}`);
148
+ this.logger('debug', `[_ensureConnected] 成功初始化collection: ${this.table}`);
157
149
  } catch (err) {
158
- $.log.error(`[MongoDB] [_ensureConnected] 初始化collection失败:`, err.message);
150
+ this.logger('error', `[_ensureConnected] 初始化collection失败:`, err);
159
151
  this.collection = null;
160
152
  }
161
153
 
@@ -164,15 +156,14 @@ MongoDB.prototype._ensureConnected = async function () {
164
156
  await this._ensureIndexes();
165
157
  }
166
158
 
167
- $.log.info(`[MongoDB] 成功连接到数据库,表名: ${this.table}`);
159
+ this.logger('info', `成功连接到数据库,表名: ${this.table}`);
168
160
  } else {
169
- $.log.error(`[MongoDB] [_ensureConnected] 连接失败,db对象为空或不具有collection方法`);
161
+ this.logger('error', `[_ensureConnected] 连接失败,db对象为空或不具有collection方法`);
170
162
  throw new Error('数据库连接失败,db对象为空');
171
163
  }
172
164
  }
173
165
  } catch (error) {
174
- $.log.error(`[MongoDB] 连接失败 (尝试 ${this.connectAttempts}/${this.maxConnectAttempts}):`,
175
- error.message);
166
+ this.logger('error', `连接失败 (尝试 ${this.connectAttempts}/${this.maxConnectAttempts}):`, error);
176
167
 
177
168
  // 重置连接Promise,允许下次重试
178
169
  this.connectPromise = null;
@@ -182,8 +173,8 @@ MongoDB.prototype._ensureConnected = async function () {
182
173
  throw error;
183
174
  } else {
184
175
  // 超过重试次数,记录严重错误
185
- $.log.error('[MongoDB] 达到最大连接重试次数,连接失败');
186
- throw new Error('数据库连接失败,已达到最大重试次数');
176
+ this.logger('error', '达到最大连接重试次数,连接失败');
177
+ this.emit('error', new Error('数据库连接失败,已达到最大重试次数'));
187
178
  }
188
179
  }
189
180
  })();
@@ -216,7 +207,7 @@ MongoDB.prototype._ensureIndexes = async function () {
216
207
  } catch (error) {
217
208
  // 忽略索引已存在的错误
218
209
  if (error.code !== 85) {
219
- $.log.error('[MongoDB] 创建索引失败:', error);
210
+ this.logger('error', '创建索引失败:', error);
220
211
  }
221
212
  }
222
213
  };
@@ -224,18 +215,23 @@ MongoDB.prototype._ensureIndexes = async function () {
224
215
  /**
225
216
  * @description Redis兼容API - 获取缓存值
226
217
  * @param {String} key 键名
227
- * @return {Promise<any>} 返回键值,不存在返回undefined
218
+ * @return {Promise<any>} 返回键值,不存在返回null
228
219
  */
229
220
  MongoDB.prototype.get = async function (key) {
221
+ // 参数校验
222
+ if (typeof key !== 'string' || !key) {
223
+ throw new TypeError('key必须是有效的字符串');
224
+ }
225
+
230
226
  try {
231
227
  await this._ensureConnected();
232
228
  const result = await this.findOne({
233
229
  key: key
234
230
  });
235
- return result ? result.value : undefined;
231
+ return result ? result.value : null;
236
232
  } catch (error) {
237
- $.log.error('[MongoDB] 获取缓存失败:', error);
238
- throw error;
233
+ this.logger('error', '获取缓存失败:', error);
234
+ this.emit('error', error);
239
235
  }
240
236
  };
241
237
 
@@ -245,9 +241,14 @@ MongoDB.prototype.get = async function (key) {
245
241
  * @return {Promise<Boolean>} 是否成功
246
242
  */
247
243
  MongoDB.prototype.clear = async function (pattern) {
244
+ // 参数校验
245
+ if (pattern !== undefined && pattern !== null && typeof pattern !== 'string') {
246
+ throw new TypeError('pattern必须是有效的字符串');
247
+ }
248
+
248
249
  try {
249
250
  // 触发前置事件
250
- this.emit('clear_before', {
251
+ this.emit('clear:before', {
251
252
  pattern
252
253
  });
253
254
 
@@ -261,7 +262,7 @@ MongoDB.prototype.clear = async function (pattern) {
261
262
  $regex: regex
262
263
  }
263
264
  });
264
- this.emit('clear_after', {
265
+ this.emit('clear:after', {
265
266
  pattern,
266
267
  result
267
268
  });
@@ -269,17 +270,17 @@ MongoDB.prototype.clear = async function (pattern) {
269
270
  } else {
270
271
  // 清空所有数据,直接使用deleteMany操作
271
272
  const result = await this.db.collection(this.table).deleteMany({});
272
- this.emit('clear_after', {
273
+ this.emit('clear:after', {
273
274
  result
274
275
  });
275
276
  return result.acknowledged;
276
277
  }
277
278
  } catch (error) {
278
- this.emit('clear_error', {
279
+ this.emit('clear:error', {
279
280
  error,
280
281
  pattern
281
282
  });
282
- $.log.error('[MongoDB] 清空缓存失败:', error);
283
+ this.logger('error', '清空缓存失败:', error);
283
284
  return false;
284
285
  }
285
286
  };
@@ -290,6 +291,11 @@ MongoDB.prototype.clear = async function (pattern) {
290
291
  * @return {Promise<Array>} 键名数组
291
292
  */
292
293
  MongoDB.prototype.keys = async function (pattern = '*') {
294
+ // 参数校验
295
+ if (typeof pattern !== 'string') {
296
+ throw new TypeError('pattern必须是有效的字符串');
297
+ }
298
+
293
299
  try {
294
300
  await this._ensureConnected();
295
301
  let query = {};
@@ -307,7 +313,7 @@ MongoDB.prototype.keys = async function (pattern = '*') {
307
313
  });
308
314
  return results.map(item => item.key);
309
315
  } catch (error) {
310
- $.log.error('[MongoDB] 获取键列表失败:', error);
316
+ this.logger('error', '获取键列表失败:', error);
311
317
  return [];
312
318
  }
313
319
  };
@@ -319,11 +325,12 @@ MongoDB.prototype.keys = async function (pattern = '*') {
319
325
  * @return {Promise<Number|Boolean>} 不传seconds时返回剩余过期时间(-1表示无过期设置,-2表示已过期或不存在),传seconds时返回是否设置成功
320
326
  */
321
327
  MongoDB.prototype.ttl = async function (key, seconds) {
328
+ // 参数验证
329
+ if (!key || typeof key !== 'string') {
330
+ throw new TypeError('key必须是非空字符串');
331
+ }
332
+
322
333
  try {
323
- // 参数验证
324
- if (!key || typeof key !== 'string') {
325
- return arguments.length === 1 ? -2 : false;
326
- }
327
334
 
328
335
  // 设置模式才需要触发事件
329
336
  if (seconds !== undefined && seconds !== null) {
@@ -333,7 +340,7 @@ MongoDB.prototype.ttl = async function (key, seconds) {
333
340
  seconds,
334
341
  cancel: false
335
342
  };
336
- this.emit('ttl_before', beforeEventData);
343
+ this.emit('ttl:before', beforeEventData);
337
344
 
338
345
  if (beforeEventData.cancel) {
339
346
  return false;
@@ -350,19 +357,19 @@ MongoDB.prototype.ttl = async function (key, seconds) {
350
357
 
351
358
  // 直接尝试获取collection,使用实例的table属性
352
359
  if (!this.collection && this.db && this.db.collection) {
353
- $.log.debug(`[MongoDB] [ttl] 设置模式:直接获取collection, table=${this.table}`);
354
- try {
355
- this.collection = this.db.collection(this.table);
356
- $.log.debug(`[MongoDB] [ttl] 设置模式:成功获取collection`);
360
+ this.logger('debug', `[ttl] 设置模式:直接获取collection, table=${this.table}`);
361
+ try {
362
+ this.collection = this.db.collection(this.table);
363
+ this.logger('debug', `[ttl] 设置模式:成功获取collection`);
357
364
  } catch (err) {
358
- $.log.error(`[MongoDB] [ttl] 设置模式:获取collection失败:`, err.message);
365
+ this.logger('error', `[ttl] 设置模式:获取collection失败:`, err);
359
366
  this.collection = null;
360
367
  }
361
368
  }
362
369
 
363
370
  // 检查collection是否存在
364
371
  if (!this.collection) {
365
- this.emit('ttl_after', {
372
+ this.emit('ttl:after', {
366
373
  key: finalKey,
367
374
  seconds: finalSeconds,
368
375
  result: false
@@ -373,7 +380,7 @@ MongoDB.prototype.ttl = async function (key, seconds) {
373
380
  // 检查键是否存在
374
381
  const count = await this.collection.countDocuments({ key: finalKey });
375
382
  if (count === 0) {
376
- this.emit('ttl_after', {
383
+ this.emit('ttl:after', {
377
384
  key: finalKey,
378
385
  seconds: finalSeconds,
379
386
  result: false
@@ -400,7 +407,7 @@ MongoDB.prototype.ttl = async function (key, seconds) {
400
407
  { upsert: false }
401
408
  );
402
409
 
403
- this.emit('ttl_after', {
410
+ this.emit('ttl:after', {
404
411
  key: finalKey,
405
412
  seconds: finalSeconds,
406
413
  result: true
@@ -418,12 +425,12 @@ MongoDB.prototype.ttl = async function (key, seconds) {
418
425
 
419
426
  // 直接尝试获取collection,使用实例的table属性
420
427
  if (!this.collection && this.db && this.db.collection) {
421
- $.log.debug(`[MongoDB] [ttl] 直接获取collection, table=${this.table}`);
422
- try {
423
- this.collection = this.db.collection(this.table);
424
- $.log.debug(`[MongoDB] [ttl] 成功获取collection`);
428
+ this.logger('debug', `[ttl] 直接获取collection, table=${this.table}`);
429
+ try {
430
+ this.collection = this.db.collection(this.table);
431
+ this.logger('debug', `[ttl] 成功获取collection`);
425
432
  } catch (err) {
426
- $.log.error(`[MongoDB] [ttl] 获取collection失败:`, err.message);
433
+ this.logger('error', `[ttl] 获取collection失败:`, err);
427
434
  this.collection = null;
428
435
  }
429
436
  }
@@ -434,19 +441,19 @@ MongoDB.prototype.ttl = async function (key, seconds) {
434
441
  }
435
442
 
436
443
  // 查询键是否存在及过期时间
437
- const item = await this.collection.findOne({ key });
438
- $.log.debug(`[MongoDB] [ttl] 查询键结果: item=${JSON.stringify(item)}`);
444
+ const item = await this.collection.findOne({ key });
445
+ this.logger('debug', `[ttl] 查询键结果: item=${JSON.stringify(item)}`);
439
446
 
440
- if (!item) {
441
- // 键不存在返回-2
442
- $.log.debug(`[MongoDB] [ttl] 键 ${key} 不存在,返回-2`);
443
- return -2;
444
- }
447
+ if (!item) {
448
+ // 键不存在返回-2
449
+ this.logger('debug', `[ttl] 键 ${key} 不存在,返回-2`);
450
+ return -2;
451
+ }
445
452
 
446
- if (!item.expire_at) {
447
- // 没有过期时间返回-1
448
- $.log.debug(`[MongoDB] [ttl] 键 ${key} 没有过期时间,返回-1`);
449
- return -1;
453
+ if (!item.expire_at) {
454
+ // 没有过期时间返回-1
455
+ this.logger('debug', `[ttl] 键 ${key} 没有过期时间,返回-1`);
456
+ return -1;
450
457
  }
451
458
 
452
459
  // 计算剩余过期时间
@@ -463,8 +470,8 @@ MongoDB.prototype.ttl = async function (key, seconds) {
463
470
  return remainingSeconds;
464
471
  }
465
472
  } catch (error) {
466
- this.emit('ttl_error', { key, seconds, error });
467
- $.log.error(`[MongoDB] [ttl] 操作失败:`, error.message);
473
+ this.emit('ttl:error', { key, seconds, error });
474
+ this.logger('error', `[ttl] 操作失败:`, error);
468
475
  return arguments.length === 1 ? -2 : false;
469
476
  }
470
477
  };
@@ -475,18 +482,19 @@ MongoDB.prototype.ttl = async function (key, seconds) {
475
482
  * @return {Promise<boolean>} 移除成功返回true,键不存在或没有过期时间返回false
476
483
  */
477
484
  MongoDB.prototype.persist = async function (key) {
485
+ // 参数验证
486
+ if (!key || typeof key !== 'string') {
487
+ throw new TypeError('key必须是非空字符串');
488
+ }
489
+
478
490
  try {
479
- // 参数验证
480
- if (!key || typeof key !== 'string') {
481
- return false;
482
- }
483
491
 
484
492
  // 触发前置事件
485
493
  const beforeEventData = {
486
494
  key,
487
495
  cancel: false
488
496
  };
489
- this.emit('persist_before', beforeEventData);
497
+ this.emit('persist:before', beforeEventData);
490
498
 
491
499
  if (beforeEventData.cancel) {
492
500
  return false;
@@ -501,20 +509,20 @@ MongoDB.prototype.persist = async function (key) {
501
509
 
502
510
  // 直接尝试获取collection,不依赖_ensureConnected的复杂逻辑
503
511
  if (!this.collection && this.db && this.db.collection) {
504
- $.log.debug(`[MongoDB] [persist] 直接获取collection, table=${this.table}`);
512
+ this.logger('debug', `[persist] 直接获取collection, table=${this.table}`);
505
513
  try {
506
514
  this.collection = this.db.collection(this.table);
507
- $.log.debug(`[MongoDB] [persist] 成功获取collection`);
515
+ this.logger('debug', `[persist] 成功获取collection`);
508
516
  } catch (err) {
509
- $.log.error(`[MongoDB] [persist] 获取collection失败:`, err.message);
517
+ this.logger('error', `[persist] 获取collection失败:`, err);
510
518
  this.collection = null;
511
519
  }
512
520
  }
513
521
 
514
522
  // 再次检查collection
515
523
  if (!this.collection) {
516
- $.log.error('[MongoDB] persist: collection is undefined');
517
- this.emit('persist_error', {
524
+ this.logger('error', 'persist: collection is undefined');
525
+ this.emit('persist:error', {
518
526
  key: finalKey,
519
527
  error: new Error('collection is undefined')
520
528
  });
@@ -525,7 +533,7 @@ MongoDB.prototype.persist = async function (key) {
525
533
  const item = await this.collection.findOne({ key: finalKey });
526
534
  if (!item) {
527
535
  // 键不存在返回false
528
- this.emit('persist_after', {
536
+ this.emit('persist:after', {
529
537
  key: finalKey,
530
538
  success: false
531
539
  });
@@ -534,7 +542,7 @@ MongoDB.prototype.persist = async function (key) {
534
542
 
535
543
  // 如果没有过期时间,直接返回true
536
544
  if (!item.expire_at) {
537
- this.emit('persist_after', {
545
+ this.emit('persist:after', {
538
546
  key: finalKey,
539
547
  success: true
540
548
  });
@@ -552,14 +560,14 @@ MongoDB.prototype.persist = async function (key) {
552
560
  const success = result.modifiedCount > 0;
553
561
 
554
562
  // 触发后置事件
555
- this.emit('persist_after', {
563
+ this.emit('persist:after', {
556
564
  key: finalKey,
557
565
  success: success
558
566
  });
559
567
  return success;
560
568
  } catch (error) {
561
- $.log.error('[MongoDB] persist error:', error.message);
562
- this.emit('persist_error', {
569
+ this.logger('error', 'persist error:', error);
570
+ this.emit('persist:error', {
563
571
  key,
564
572
  error
565
573
  });
@@ -597,7 +605,7 @@ MongoDB.prototype._add = async function (key, value, expire) {
597
605
  }
598
606
  return true;
599
607
  } catch (error) {
600
- $.log.error('[MongoDB] 添加缓存失败:', error);
608
+ this.logger('error', '添加缓存失败:', error);
601
609
  return false;
602
610
  }
603
611
  };
@@ -618,11 +626,11 @@ MongoDB.prototype.add = async function (key, value, seconds) {
618
626
  ttl: seconds,
619
627
  cancel: false
620
628
  };
621
- this.emit('add_before', beforeEventData);
629
+ this.emit('add:before', beforeEventData);
622
630
 
623
631
  // 如果事件处理器标记为取消,则返回false
624
632
  if (beforeEventData.cancel) {
625
- $.log.debug(`[MongoDB] add操作被事件处理器取消 [${key}]`);
633
+ this.logger('debug', `add操作被事件处理器取消 [${key}]`);
626
634
  return false;
627
635
  }
628
636
 
@@ -641,7 +649,7 @@ MongoDB.prototype.add = async function (key, value, seconds) {
641
649
  });
642
650
  if (existing) {
643
651
  // 键已存在,返回false
644
- this.emit('add_after', {
652
+ this.emit('add:after', {
645
653
  key: finalKey,
646
654
  value: finalValue,
647
655
  ttl: finalSeconds,
@@ -663,7 +671,7 @@ MongoDB.prototype.add = async function (key, value, seconds) {
663
671
  await this.addObj(data);
664
672
 
665
673
  // 触发后置事件
666
- this.emit('add_after', {
674
+ this.emit('add:after', {
667
675
  key: finalKey,
668
676
  value: finalValue,
669
677
  ttl: finalSeconds,
@@ -671,9 +679,9 @@ MongoDB.prototype.add = async function (key, value, seconds) {
671
679
  });
672
680
  return true;
673
681
  } catch (error) {
674
- $.log.error(`[MongoDB] 添加缓存失败 [${key}]:`, error);
682
+ this.logger('error', `添加缓存失败 [${key}]:`, error);
675
683
  // 触发错误事件
676
- this.emit('add_error', {
684
+ this.emit('add:error', {
677
685
  key,
678
686
  value,
679
687
  ttl: seconds,
@@ -706,8 +714,8 @@ MongoDB.prototype._addNum = async function (key, value = 1) {
706
714
  await this._add(key, newValue);
707
715
  return newValue;
708
716
  } catch (error) {
709
- $.log.error('[MongoDB] 增加整数值失败:', error);
710
- return undefined;
717
+ this.logger('error', '增加整数值失败:', error);
718
+ return false;
711
719
  }
712
720
  };
713
721
 
@@ -724,6 +732,11 @@ MongoDB.prototype._addNum = async function (key, value = 1) {
724
732
  * @return {Promise<Number>} 增加后的值
725
733
  */
726
734
  MongoDB.prototype.addInt = async function (key, value = 1, seconds = 0) {
735
+ // 参数验证
736
+ if (!key || typeof key !== 'string') {
737
+ throw new TypeError('key必须是非空字符串');
738
+ }
739
+
727
740
  try {
728
741
  // 触发前置事件,允许修改或阻止操作
729
742
  const beforeEventData = {
@@ -732,11 +745,11 @@ MongoDB.prototype.addInt = async function (key, value = 1, seconds = 0) {
732
745
  seconds,
733
746
  cancel: false
734
747
  };
735
- this.emit('addInt_before', beforeEventData);
748
+ this.emit('addInt:before', beforeEventData);
736
749
 
737
750
  // 如果事件处理器标记为取消,则返回默认值
738
751
  if (beforeEventData.cancel) {
739
- $.log.debug('[MongoDB] addInt操作被事件处理器取消');
752
+ this.logger('debug', 'addInt操作被事件处理器取消');
740
753
  return 0;
741
754
  }
742
755
 
@@ -747,12 +760,6 @@ MongoDB.prototype.addInt = async function (key, value = 1, seconds = 0) {
747
760
  seconds: finalSeconds
748
761
  } = beforeEventData;
749
762
 
750
- // 参数验证
751
- if (!finalKey || typeof finalKey !== 'string') {
752
- $.log.warn('[MongoDB] addInt: key必须是非空字符串');
753
- return 0;
754
- }
755
-
756
763
  finalValue = Number(finalValue) || 0;
757
764
 
758
765
  await this._ensureConnected();
@@ -771,7 +778,7 @@ MongoDB.prototype.addInt = async function (key, value = 1, seconds = 0) {
771
778
  await this._add(finalKey, newValue, finalSeconds);
772
779
 
773
780
  // 触发后置事件
774
- this.emit('addInt_after', {
781
+ this.emit('addInt:after', {
775
782
  key: finalKey,
776
783
  value: finalValue,
777
784
  seconds: finalSeconds,
@@ -781,13 +788,13 @@ MongoDB.prototype.addInt = async function (key, value = 1, seconds = 0) {
781
788
  return newValue;
782
789
  } catch (error) {
783
790
  // 触发错误事件
784
- this.emit('addInt_error', {
791
+ this.emit('addInt:error', {
785
792
  key,
786
793
  value,
787
794
  seconds,
788
795
  error
789
796
  });
790
- $.log.error('[MongoDB] 增加整数值失败:', error);
797
+ this.logger('error', '增加整数值失败:', error);
791
798
  // 与CacheBase保持一致,错误时返回默认值而不是抛出异常
792
799
  return 0;
793
800
  }
@@ -800,6 +807,11 @@ MongoDB.prototype.addInt = async function (key, value = 1, seconds = 0) {
800
807
  * @return {Promise<Number>} 增加后的值
801
808
  */
802
809
  MongoDB.prototype.addFloat = async function (key, value = 1.0, seconds = 0) {
810
+ // 参数验证
811
+ if (!key || typeof key !== 'string') {
812
+ throw new TypeError('key必须是非空字符串');
813
+ }
814
+
803
815
  try {
804
816
  // 触发前置事件,允许修改或阻止操作
805
817
  const beforeEventData = {
@@ -808,11 +820,11 @@ MongoDB.prototype.addFloat = async function (key, value = 1.0, seconds = 0) {
808
820
  seconds,
809
821
  cancel: false
810
822
  };
811
- this.emit('addFloat_before', beforeEventData);
823
+ this.emit('addFloat:before', beforeEventData);
812
824
 
813
825
  // 如果事件处理器标记为取消,则返回默认值
814
826
  if (beforeEventData.cancel) {
815
- $.log.debug('[MongoDB] addFloat操作被事件处理器取消');
827
+ this.logger('debug', 'addFloat操作被事件处理器取消');
816
828
  return 0.0;
817
829
  }
818
830
 
@@ -823,12 +835,6 @@ MongoDB.prototype.addFloat = async function (key, value = 1.0, seconds = 0) {
823
835
  seconds: finalSeconds
824
836
  } = beforeEventData;
825
837
 
826
- // 参数验证
827
- if (!finalKey || typeof finalKey !== 'string') {
828
- $.log.warn('[MongoDB] addFloat: key必须是非空字符串');
829
- return 0.0;
830
- }
831
-
832
838
  finalValue = Number(finalValue) || 0.0;
833
839
 
834
840
  await this._ensureConnected();
@@ -847,7 +853,7 @@ MongoDB.prototype.addFloat = async function (key, value = 1.0, seconds = 0) {
847
853
  await this._add(finalKey, newValue, finalSeconds);
848
854
 
849
855
  // 触发后置事件
850
- this.emit('addFloat_after', {
856
+ this.emit('addFloat:after', {
851
857
  key: finalKey,
852
858
  value: finalValue,
853
859
  seconds: finalSeconds,
@@ -857,13 +863,13 @@ MongoDB.prototype.addFloat = async function (key, value = 1.0, seconds = 0) {
857
863
  return newValue;
858
864
  } catch (error) {
859
865
  // 触发错误事件
860
- this.emit('addFloat_error', {
866
+ this.emit('addFloat:error', {
861
867
  key,
862
868
  value,
863
869
  seconds,
864
870
  error
865
871
  });
866
- $.log.error('[MongoDB] 增加浮点数值失败:', error);
872
+ this.logger('error', '增加浮点数值失败:', error);
867
873
  // 与CacheBase保持一致,错误时返回默认值而不是抛出异常
868
874
  return 0.0;
869
875
  }
@@ -876,22 +882,22 @@ MongoDB.prototype.addFloat = async function (key, value = 1.0, seconds = 0) {
876
882
  * @return {Promise<Number>} 添加后的字符串长度
877
883
  */
878
884
  MongoDB.prototype.addStr = async function (key, value) {
885
+ // 参数验证
886
+ if (!key || typeof key !== 'string') {
887
+ throw new TypeError('key必须是非空字符串');
888
+ }
889
+
890
+ if (value === undefined || value === null) {
891
+ value = '';
892
+ }
893
+
879
894
  try {
880
895
  // 触发前置事件
881
- this.emit('addStr_before', {
896
+ this.emit('addStr:before', {
882
897
  key,
883
898
  value
884
899
  });
885
900
 
886
- // 参数验证
887
- if (!key || typeof key !== 'string') {
888
- throw new Error('key必须是非空字符串');
889
- }
890
-
891
- if (value === undefined || value === null) {
892
- value = '';
893
- }
894
-
895
901
  await this._ensureConnected();
896
902
  // 获取当前值
897
903
  const item = await this.findOne({
@@ -903,7 +909,7 @@ MongoDB.prototype.addStr = async function (key, value) {
903
909
  await this._add(key, newValue);
904
910
 
905
911
  // 触发后置事件
906
- this.emit('addStr_after', {
912
+ this.emit('addStr:after', {
907
913
  key,
908
914
  value,
909
915
  result: newValue.length
@@ -912,12 +918,12 @@ MongoDB.prototype.addStr = async function (key, value) {
912
918
  return newValue.length;
913
919
  } catch (error) {
914
920
  // 触发错误事件
915
- this.emit('addStr_error', {
921
+ this.emit('addStr:error', {
916
922
  key,
917
923
  value,
918
924
  error
919
925
  });
920
- $.log.error('[MongoDB] 添加字符串失败:', error);
926
+ this.logger('error', '添加字符串失败:', error);
921
927
  return 0;
922
928
  }
923
929
  };
@@ -954,7 +960,7 @@ MongoDB.prototype.sort = async function (key, options = {}) {
954
960
 
955
961
  return sorted;
956
962
  } catch (error) {
957
- $.log.error('[MongoDB] 排序失败:', error);
963
+ this.logger('error', '排序失败:', error);
958
964
  return [];
959
965
  }
960
966
  };
@@ -967,6 +973,14 @@ MongoDB.prototype.sort = async function (key, options = {}) {
967
973
  * @return {Promise<number>} 返回1表示新建字段,0表示更新字段
968
974
  */
969
975
  MongoDB.prototype.hset = async function (key, field, value) {
976
+ // 参数校验
977
+ if (typeof key !== 'string' || !key) {
978
+ throw new TypeError('key必须是有效的字符串');
979
+ }
980
+ if (typeof field !== 'string' || !field) {
981
+ throw new TypeError('field必须是有效的字符串');
982
+ }
983
+
970
984
  try {
971
985
  await this._ensureConnected();
972
986
  const item = await this.findOne({
@@ -978,9 +992,9 @@ MongoDB.prototype.hset = async function (key, field, value) {
978
992
  const isNewField = !hash.hasOwnProperty(field);
979
993
  hash[field] = value;
980
994
  await this._add(key, hash);
981
- return isNewField ? 1 : 0;
995
+ return true; // hset操作成功返回true
982
996
  } catch (error) {
983
- $.log.error('[MongoDB] 哈希表设置失败:', error);
997
+ this.logger('error', '哈希表设置失败:', error);
984
998
  throw error;
985
999
  }
986
1000
  };
@@ -992,6 +1006,14 @@ MongoDB.prototype.hset = async function (key, field, value) {
992
1006
  * @return {Promise<any>} 返回字段值,不存在返回undefined
993
1007
  */
994
1008
  MongoDB.prototype.hget = async function (key, field) {
1009
+ // 参数校验
1010
+ if (typeof key !== 'string' || !key) {
1011
+ throw new TypeError('key必须是有效的字符串');
1012
+ }
1013
+ if (typeof field !== 'string' || !field) {
1014
+ throw new TypeError('field必须是有效的字符串');
1015
+ }
1016
+
995
1017
  try {
996
1018
  await this._ensureConnected();
997
1019
  const item = await this.findOne({
@@ -1002,8 +1024,8 @@ MongoDB.prototype.hget = async function (key, field) {
1002
1024
  }
1003
1025
  return item.value[field] !== undefined ? item.value[field] : undefined;
1004
1026
  } catch (error) {
1005
- $.log.error('[MongoDB] 哈希表获取失败:', error);
1006
- throw error;
1027
+ this.logger('error', '哈希表获取失败:', error);
1028
+ return null; // 与Redis保持一致,错误时返回null
1007
1029
  }
1008
1030
  };
1009
1031
 
@@ -1013,6 +1035,11 @@ MongoDB.prototype.hget = async function (key, field) {
1013
1035
  * @return {Promise<Object>} 哈希表对象
1014
1036
  */
1015
1037
  MongoDB.prototype.hgetall = async function (key) {
1038
+ // 参数校验
1039
+ if (typeof key !== 'string' || !key) {
1040
+ throw new TypeError('key必须是有效的字符串');
1041
+ }
1042
+
1016
1043
  try {
1017
1044
  const item = await this.findOne({
1018
1045
  key: key
@@ -1022,7 +1049,7 @@ MongoDB.prototype.hgetall = async function (key) {
1022
1049
  }
1023
1050
  return item.value;
1024
1051
  } catch (error) {
1025
- $.log.error('[MongoDB] 哈希表获取全部失败:', error);
1052
+ this.logger('error', '哈希表获取全部失败:', error);
1026
1053
  return {};
1027
1054
  }
1028
1055
  };
@@ -1034,12 +1061,15 @@ MongoDB.prototype.hgetall = async function (key) {
1034
1061
  * @return {Promise<boolean>} 返回true表示成功删除,false表示未删除
1035
1062
  */
1036
1063
  MongoDB.prototype.hdel = async function (key, fields) {
1037
- try {
1038
- // 参数验证
1039
- if (!key || typeof key !== 'string') {
1040
- return 0;
1041
- }
1064
+ // 参数校验
1065
+ if (typeof key !== 'string' || !key) {
1066
+ throw new TypeError('key必须是有效的字符串');
1067
+ }
1068
+ if (!fields || (typeof fields !== 'string' && !Array.isArray(fields))) {
1069
+ throw new TypeError('fields必须是字符串或字符串数组');
1070
+ }
1042
1071
 
1072
+ try {
1043
1073
  // 统一将fields转换为数组格式
1044
1074
  const fieldArray = Array.isArray(fields) ? fields : [fields];
1045
1075
  if (fieldArray.length === 0) {
@@ -1079,7 +1109,7 @@ MongoDB.prototype.hdel = async function (key, fields) {
1079
1109
 
1080
1110
  return deletedCount;
1081
1111
  } catch (error) {
1082
- $.log.error('[MongoDB] hdel操作失败:', error);
1112
+ this.logger('error', 'hdel操作失败:', error);
1083
1113
  return 0;
1084
1114
  }
1085
1115
  };
@@ -1090,13 +1120,18 @@ MongoDB.prototype.hdel = async function (key, fields) {
1090
1120
  * @return {Promise<Boolean>} 是否存在
1091
1121
  */
1092
1122
  MongoDB.prototype.has = async function (key) {
1123
+ // 参数校验
1124
+ if (typeof key !== 'string' || !key) {
1125
+ throw new TypeError('key必须是有效的字符串');
1126
+ }
1127
+
1093
1128
  try {
1094
1129
  const result = await this.findOne({
1095
1130
  key: key
1096
1131
  });
1097
1132
  return result !== null;
1098
1133
  } catch (error) {
1099
- $.log.error('[MongoDB] [has] 检查键是否存在失败:', error);
1134
+ this.logger('error', '[has] 检查键是否存在失败:', error);
1100
1135
  throw error;
1101
1136
  }
1102
1137
  };
@@ -1118,11 +1153,11 @@ MongoDB.prototype.expire = async function (key, seconds) {
1118
1153
  seconds,
1119
1154
  cancel: false
1120
1155
  };
1121
- this.emit('expire_before', beforeEventData);
1156
+ this.emit('expire:before', beforeEventData);
1122
1157
 
1123
1158
  // 如果事件处理器标记为取消,则返回默认值
1124
1159
  if (beforeEventData.cancel) {
1125
- $.log.debug('[MongoDB] expire操作被事件处理器取消');
1160
+ this.logger('debug', 'expire操作被事件处理器取消');
1126
1161
  return false;
1127
1162
  }
1128
1163
 
@@ -1136,7 +1171,7 @@ MongoDB.prototype.expire = async function (key, seconds) {
1136
1171
  const result = await this.ttl(finalKey, finalSeconds);
1137
1172
 
1138
1173
  // 触发后置事件
1139
- this.emit('expire_after', {
1174
+ this.emit('expire:after', {
1140
1175
  key: finalKey,
1141
1176
  seconds: finalSeconds,
1142
1177
  result
@@ -1146,10 +1181,10 @@ MongoDB.prototype.expire = async function (key, seconds) {
1146
1181
  return result === true || (typeof result === 'number' && result >= -2);
1147
1182
  } catch (error) {
1148
1183
  // 记录错误日志
1149
- $.log.error('[MongoDB] expire方法执行错误', { error: error.message, key, seconds });
1184
+ this.logger('error', 'expire方法执行错误', { error: error.message, key, seconds });
1150
1185
 
1151
1186
  // 触发错误事件
1152
- this.emit('expire_error', {
1187
+ this.emit('expire:error', {
1153
1188
  key,
1154
1189
  seconds,
1155
1190
  error
@@ -1172,11 +1207,11 @@ MongoDB.prototype.incr = async function (key, seconds = 0) {
1172
1207
  seconds,
1173
1208
  cancel: false
1174
1209
  };
1175
- this.emit('incr_before', beforeEventData);
1210
+ this.emit('incr:before', beforeEventData);
1176
1211
 
1177
1212
  // 如果事件处理器标记为取消,则返回默认值
1178
1213
  if (beforeEventData.cancel) {
1179
- $.log.debug('[MongoDB] incr操作被事件处理器取消');
1214
+ this.logger('debug', 'incr操作被事件处理器取消');
1180
1215
  return 0;
1181
1216
  }
1182
1217
 
@@ -1187,9 +1222,8 @@ MongoDB.prototype.incr = async function (key, seconds = 0) {
1187
1222
  } = beforeEventData;
1188
1223
 
1189
1224
  // 参数验证
1190
- if (!finalKey || typeof finalKey !== 'string') {
1191
- $.log.warn('[MongoDB] incr: key必须是非空字符串');
1192
- return 0;
1225
+ if (typeof finalKey !== 'string' || !finalKey) {
1226
+ throw new TypeError('key必须是有效的字符串');
1193
1227
  }
1194
1228
 
1195
1229
  await this._ensureConnected();
@@ -1197,7 +1231,7 @@ MongoDB.prototype.incr = async function (key, seconds = 0) {
1197
1231
  const returnResult = result !== undefined ? result : 0;
1198
1232
 
1199
1233
  // 触发后置事件
1200
- this.emit('incr_after', {
1234
+ this.emit('incr:after', {
1201
1235
  key: finalKey,
1202
1236
  seconds: finalSeconds,
1203
1237
  result: returnResult,
@@ -1207,12 +1241,12 @@ MongoDB.prototype.incr = async function (key, seconds = 0) {
1207
1241
  return returnResult;
1208
1242
  } catch (error) {
1209
1243
  // 触发错误事件
1210
- this.emit('incr_error', {
1244
+ this.emit('incr:error', {
1211
1245
  key,
1212
1246
  seconds,
1213
1247
  error
1214
1248
  });
1215
- $.log.error('[MongoDB] 递增操作失败:', error);
1249
+ this.logger('error', '递增操作失败:', error);
1216
1250
  return 0;
1217
1251
  }
1218
1252
  };
@@ -1230,11 +1264,11 @@ MongoDB.prototype.decr = async function (key, seconds = 0) {
1230
1264
  seconds,
1231
1265
  cancel: false
1232
1266
  };
1233
- this.emit('decr_before', beforeEventData);
1267
+ this.emit('decr:before', beforeEventData);
1234
1268
 
1235
1269
  // 如果事件处理器标记为取消,则返回默认值
1236
1270
  if (beforeEventData.cancel) {
1237
- $.log.debug('[MongoDB] decr操作被事件处理器取消');
1271
+ this.logger('debug', 'decr操作被事件处理器取消');
1238
1272
  return 0;
1239
1273
  }
1240
1274
 
@@ -1245,9 +1279,8 @@ MongoDB.prototype.decr = async function (key, seconds = 0) {
1245
1279
  } = beforeEventData;
1246
1280
 
1247
1281
  // 参数验证
1248
- if (!finalKey || typeof finalKey !== 'string') {
1249
- $.log.warn('[MongoDB] decr: key必须是非空字符串');
1250
- return 0;
1282
+ if (typeof finalKey !== 'string' || !finalKey) {
1283
+ throw new TypeError('key必须是有效的字符串');
1251
1284
  }
1252
1285
 
1253
1286
  await this._ensureConnected();
@@ -1255,7 +1288,7 @@ MongoDB.prototype.decr = async function (key, seconds = 0) {
1255
1288
  const returnResult = result !== undefined ? result : 0;
1256
1289
 
1257
1290
  // 触发后置事件
1258
- this.emit('decr_after', {
1291
+ this.emit('decr:after', {
1259
1292
  key: finalKey,
1260
1293
  seconds: finalSeconds,
1261
1294
  result: returnResult,
@@ -1265,12 +1298,12 @@ MongoDB.prototype.decr = async function (key, seconds = 0) {
1265
1298
  return returnResult;
1266
1299
  } catch (error) {
1267
1300
  // 触发错误事件
1268
- this.emit('decr_error', {
1301
+ this.emit('decr:error', {
1269
1302
  key,
1270
1303
  seconds,
1271
1304
  error
1272
1305
  });
1273
- $.log.error('[MongoDB] 递减操作失败:', error);
1306
+ this.logger('error', '递减操作失败:', error);
1274
1307
  return 0;
1275
1308
  }
1276
1309
  };
@@ -1290,11 +1323,11 @@ MongoDB.prototype.incrby = async function (key, value = 1, seconds = 0) {
1290
1323
  seconds,
1291
1324
  cancel: false
1292
1325
  };
1293
- this.emit('incrby_before', beforeEventData);
1326
+ this.emit('incrby:before', beforeEventData);
1294
1327
 
1295
1328
  // 如果事件处理器标记为取消,则返回默认值
1296
1329
  if (beforeEventData.cancel) {
1297
- $.log.debug('[MongoDB] incrby操作被事件处理器取消');
1330
+ this.logger('debug', 'incrby操作被事件处理器取消');
1298
1331
  return 0;
1299
1332
  }
1300
1333
 
@@ -1306,9 +1339,8 @@ MongoDB.prototype.incrby = async function (key, value = 1, seconds = 0) {
1306
1339
  } = beforeEventData;
1307
1340
 
1308
1341
  // 参数验证
1309
- if (!finalKey || typeof finalKey !== 'string') {
1310
- $.log.warn('[MongoDB] incrby: key必须是非空字符串');
1311
- return 0;
1342
+ if (typeof finalKey !== 'string' || !finalKey) {
1343
+ throw new TypeError('key必须是有效的字符串');
1312
1344
  }
1313
1345
 
1314
1346
  // 确保value是数字
@@ -1319,7 +1351,7 @@ MongoDB.prototype.incrby = async function (key, value = 1, seconds = 0) {
1319
1351
  const returnResult = result !== undefined ? result : 0;
1320
1352
 
1321
1353
  // 触发后置事件
1322
- this.emit('incrby_after', {
1354
+ this.emit('incrby:after', {
1323
1355
  key: finalKey,
1324
1356
  value: finalValue,
1325
1357
  seconds: finalSeconds,
@@ -1330,13 +1362,13 @@ MongoDB.prototype.incrby = async function (key, value = 1, seconds = 0) {
1330
1362
  return returnResult;
1331
1363
  } catch (error) {
1332
1364
  // 触发错误事件
1333
- this.emit('incrby_error', {
1365
+ this.emit('incrby:error', {
1334
1366
  key,
1335
1367
  value,
1336
1368
  seconds,
1337
1369
  error
1338
1370
  });
1339
- $.log.error('[MongoDB] 递增操作失败:', error);
1371
+ this.logger('error', '递增操作失败:', error);
1340
1372
  return 0;
1341
1373
  }
1342
1374
  };
@@ -1356,11 +1388,11 @@ MongoDB.prototype.decrby = async function (key, value = 1, seconds = 0) {
1356
1388
  seconds,
1357
1389
  cancel: false
1358
1390
  };
1359
- this.emit('decrby_before', beforeEventData);
1391
+ this.emit('decrby:before', beforeEventData);
1360
1392
 
1361
1393
  // 如果事件处理器标记为取消,则返回默认值
1362
1394
  if (beforeEventData.cancel) {
1363
- $.log.debug('[MongoDB] decrby操作被事件处理器取消');
1395
+ this.logger('debug', 'decrby操作被事件处理器取消');
1364
1396
  return 0;
1365
1397
  }
1366
1398
 
@@ -1372,9 +1404,8 @@ MongoDB.prototype.decrby = async function (key, value = 1, seconds = 0) {
1372
1404
  } = beforeEventData;
1373
1405
 
1374
1406
  // 参数验证
1375
- if (!finalKey || typeof finalKey !== 'string') {
1376
- $.log.warn('[MongoDB] decrby: key必须是非空字符串');
1377
- return 0;
1407
+ if (typeof finalKey !== 'string' || !finalKey) {
1408
+ throw new TypeError('key必须是有效的字符串');
1378
1409
  }
1379
1410
 
1380
1411
  // 确保value是数字
@@ -1385,7 +1416,7 @@ MongoDB.prototype.decrby = async function (key, value = 1, seconds = 0) {
1385
1416
  const returnResult = result !== undefined ? result : 0;
1386
1417
 
1387
1418
  // 触发后置事件
1388
- this.emit('decrby_after', {
1419
+ this.emit('decrby:after', {
1389
1420
  key: finalKey,
1390
1421
  value: finalValue,
1391
1422
  seconds: finalSeconds,
@@ -1396,13 +1427,13 @@ MongoDB.prototype.decrby = async function (key, value = 1, seconds = 0) {
1396
1427
  return returnResult;
1397
1428
  } catch (error) {
1398
1429
  // 触发错误事件
1399
- this.emit('decrby_error', {
1430
+ this.emit('decrby:error', {
1400
1431
  key,
1401
1432
  value,
1402
1433
  seconds,
1403
1434
  error
1404
1435
  });
1405
- $.log.error('[MongoDB] 递减操作失败:', error);
1436
+ this.logger('error', '递减操作失败:', error);
1406
1437
  return 0;
1407
1438
  }
1408
1439
  };
@@ -1422,11 +1453,11 @@ MongoDB.prototype.incrbyfloat = async function (key, value = 1.0, seconds = 0) {
1422
1453
  seconds,
1423
1454
  cancel: false
1424
1455
  };
1425
- this.emit('incrbyfloat_before', beforeEventData);
1456
+ this.emit('incrbyfloat:before', beforeEventData);
1426
1457
 
1427
1458
  // 如果事件处理器标记为取消,则返回默认值
1428
1459
  if (beforeEventData.cancel) {
1429
- $.log.debug('[MongoDB] incrbyfloat操作被事件处理器取消');
1460
+ this.logger('debug', 'incrbyfloat操作被事件处理器取消');
1430
1461
  return 0.0;
1431
1462
  }
1432
1463
 
@@ -1438,9 +1469,8 @@ MongoDB.prototype.incrbyfloat = async function (key, value = 1.0, seconds = 0) {
1438
1469
  } = beforeEventData;
1439
1470
 
1440
1471
  // 参数验证
1441
- if (!finalKey || typeof finalKey !== 'string') {
1442
- $.log.warn('[MongoDB] incrbyfloat: key必须是非空字符串');
1443
- return 0.0;
1472
+ if (typeof finalKey !== 'string' || !finalKey) {
1473
+ throw new TypeError('key必须是有效的字符串');
1444
1474
  }
1445
1475
 
1446
1476
  // 确保value是数字
@@ -1451,7 +1481,7 @@ MongoDB.prototype.incrbyfloat = async function (key, value = 1.0, seconds = 0) {
1451
1481
  const returnResult = result !== undefined ? result : 0.0;
1452
1482
 
1453
1483
  // 触发后置事件
1454
- this.emit('incrbyfloat_after', {
1484
+ this.emit('incrbyfloat:after', {
1455
1485
  key: finalKey,
1456
1486
  value: finalValue,
1457
1487
  seconds: finalSeconds,
@@ -1462,13 +1492,13 @@ MongoDB.prototype.incrbyfloat = async function (key, value = 1.0, seconds = 0) {
1462
1492
  return returnResult;
1463
1493
  } catch (error) {
1464
1494
  // 触发错误事件
1465
- this.emit('incrbyfloat_error', {
1495
+ this.emit('incrbyfloat:error', {
1466
1496
  key,
1467
1497
  value,
1468
1498
  seconds,
1469
1499
  error
1470
1500
  });
1471
- $.log.error('[MongoDB] 浮点递增操作失败:', error);
1501
+ this.logger('error', '浮点递增操作失败:', error);
1472
1502
  return 0.0;
1473
1503
  }
1474
1504
  };
@@ -1476,43 +1506,46 @@ MongoDB.prototype.incrbyfloat = async function (key, value = 1.0, seconds = 0) {
1476
1506
  /**
1477
1507
  * @description Redis兼容API - 检查键是否存在
1478
1508
  * @param {String|Array<String>} key 键名或键名数组
1479
- * @return {Promise<number>} 返回存在的键数量
1509
+ * @return {Promise<boolean>} 是否存在
1480
1510
  */
1481
1511
  MongoDB.prototype.exists = async function (key) {
1482
1512
  try {
1483
1513
  await this._ensureConnected();
1484
1514
 
1515
+ // 参数验证
1516
+ if (!key) {
1517
+ throw new TypeError('key必须是非空字符串或非空字符串数组');
1518
+ }
1519
+
1485
1520
  // 验证数组中的每个元素都是非空字符串
1486
1521
  if (Array.isArray(key)) {
1487
1522
  for (const k of key) {
1488
1523
  if (typeof k !== 'string' || !k) {
1489
- throw new Error('all keys must be non-empty strings');
1524
+ throw new TypeError('key数组中的每个元素必须是非空字符串');
1490
1525
  }
1491
1526
  }
1527
+ } else if (typeof key !== 'string') {
1528
+ throw new TypeError('key必须是非空字符串或非空字符串数组');
1492
1529
  }
1493
1530
 
1494
- let existsCount = 0;
1495
-
1496
1531
  // 检查输入类型并处理
1497
1532
  if (Array.isArray(key)) {
1498
- // 处理多键检查
1533
+ // 处理多键检查:只要有一个键存在就返回true
1499
1534
  const results = await this.find({
1500
1535
  key: {
1501
1536
  $in: key
1502
1537
  }
1503
1538
  });
1504
- existsCount = results.length;
1539
+ return results.length > 0;
1505
1540
  } else {
1506
1541
  // 处理单键检查
1507
1542
  const result = await this.findOne({
1508
1543
  key: key
1509
1544
  });
1510
- existsCount = result !== null ? 1 : 0;
1545
+ return result !== null;
1511
1546
  }
1512
-
1513
- return existsCount;
1514
1547
  } catch (error) {
1515
- $.log.error('[MongoDB] 检查键是否存在失败:', error);
1548
+ this.logger('error', '检查键是否存在失败:', error);
1516
1549
  throw error;
1517
1550
  }
1518
1551
  };
@@ -1542,9 +1575,9 @@ MongoDB.prototype._set = async function (key, value, expire) {
1542
1575
  );
1543
1576
  return true;
1544
1577
  } catch (error) {
1545
- $.log.error('[MongoDB] 设置键值失败:', error);
1546
- return false; // 与CacheBase保持一致,返回false而不是抛出异常
1547
- }
1578
+ this.logger('error', '设置缓存失败:', error);
1579
+ return false;
1580
+ } // 与CacheBase保持一致,返回false而不是抛出异常
1548
1581
  };
1549
1582
 
1550
1583
  /**
@@ -1562,13 +1595,13 @@ MongoDB.prototype.set = async function (key, value, seconds = 0) {
1562
1595
  * @description Redis兼容API - 哈希表批量设置
1563
1596
  * @param {String} key 键名
1564
1597
  * @param {Array} fieldValues 字段值对数组,格式: [field1, value1, field2, value2, ...] 或对象格式 {field1: value1, field2: value2}
1565
- * @return {Promise<Number>} 设置的字段数量
1598
+ * @return {Promise<Boolean>} 操作结果
1566
1599
  */
1567
1600
  MongoDB.prototype.hmset = async function (key, ...fieldValues) {
1568
1601
  try {
1569
1602
  // 参数验证
1570
1603
  if (!key || typeof key !== 'string') {
1571
- $.log.warn('[MongoDB] hmset: 键名无效');
1604
+ this.logger('warn', 'hmset: 键名无效');
1572
1605
  return 0;
1573
1606
  }
1574
1607
 
@@ -1587,8 +1620,6 @@ MongoDB.prototype.hmset = async function (key, ...fieldValues) {
1587
1620
  }
1588
1621
  }
1589
1622
 
1590
- const fieldsCount = Object.keys(hashData).length;
1591
-
1592
1623
  // 确保连接
1593
1624
  await this._ensureConnected();
1594
1625
 
@@ -1617,10 +1648,10 @@ MongoDB.prototype.hmset = async function (key, ...fieldValues) {
1617
1648
  await this.addObj(data);
1618
1649
  }
1619
1650
 
1620
- return fieldsCount;
1651
+ return true; // 操作成功返回true
1621
1652
  } catch (error) {
1622
- $.log.error('[MongoDB] [hmset] 哈希表批量设置失败:', error);
1623
- return 0;
1653
+ this.logger('error', '[hmset] 哈希表批量设置失败:', error);
1654
+ return false; // 操作失败返回false
1624
1655
  }
1625
1656
  };
1626
1657
 
@@ -1656,7 +1687,7 @@ MongoDB.prototype.hmget = async function (key, fields) {
1656
1687
 
1657
1688
  return values;
1658
1689
  } catch (error) {
1659
- $.log.error('[MongoDB] hmget操作失败:', error);
1690
+ this.logger('error', 'hmget操作失败:', error);
1660
1691
  // 错误时返回与fields长度相同的null数组
1661
1692
  const fieldArray = Array.isArray(fields) ? fields : [fields];
1662
1693
  return fieldArray.map(() => null);
@@ -1670,6 +1701,14 @@ MongoDB.prototype.hmget = async function (key, fields) {
1670
1701
  * @return {Promise<Boolean>} 是否成功
1671
1702
  */
1672
1703
  MongoDB.prototype.hdelMulti = async function (key, fields) {
1704
+ // 参数校验
1705
+ if (typeof key !== 'string' || !key) {
1706
+ throw new TypeError('key必须是有效的字符串');
1707
+ }
1708
+ if (!Array.isArray(fields) || fields.length === 0) {
1709
+ throw new TypeError('fields必须是非空数组');
1710
+ }
1711
+
1673
1712
  try {
1674
1713
  await this._ensureConnected();
1675
1714
  const item = await this.findOne({
@@ -1696,7 +1735,7 @@ MongoDB.prototype.hdelMulti = async function (key, fields) {
1696
1735
  }
1697
1736
  return deleted;
1698
1737
  } catch (error) {
1699
- $.log.error('[MongoDB] 哈希表批量删除失败:', error);
1738
+ this.logger('error', '增加整数值失败:', error);
1700
1739
  return false;
1701
1740
  }
1702
1741
  };
@@ -1707,6 +1746,11 @@ MongoDB.prototype.hdelMulti = async function (key, fields) {
1707
1746
  * @return {Promise<Array>} 值数组
1708
1747
  */
1709
1748
  MongoDB.prototype.hvals = async function (key) {
1749
+ // 参数校验
1750
+ if (typeof key !== 'string' || !key) {
1751
+ throw new TypeError('key必须是有效的字符串');
1752
+ }
1753
+
1710
1754
  try {
1711
1755
  await this._ensureConnected();
1712
1756
  const item = await this.findOne({
@@ -1717,7 +1761,7 @@ MongoDB.prototype.hvals = async function (key) {
1717
1761
  }
1718
1762
  return Object.values(item.value);
1719
1763
  } catch (error) {
1720
- $.log.error('[MongoDB] 哈希表获取所有值失败:', error);
1764
+ this.logger('error', '哈希表获取所有值失败:', error);
1721
1765
  return [];
1722
1766
  }
1723
1767
  };
@@ -1728,6 +1772,11 @@ MongoDB.prototype.hvals = async function (key) {
1728
1772
  * @return {Promise<Array>} 字段名数组
1729
1773
  */
1730
1774
  MongoDB.prototype.hkeys = async function (key) {
1775
+ // 参数校验
1776
+ if (typeof key !== 'string' || !key) {
1777
+ throw new TypeError('key必须是有效的字符串');
1778
+ }
1779
+
1731
1780
  try {
1732
1781
  await this._ensureConnected();
1733
1782
  const item = await this.findOne({
@@ -1738,7 +1787,7 @@ MongoDB.prototype.hkeys = async function (key) {
1738
1787
  }
1739
1788
  return Object.keys(item.value);
1740
1789
  } catch (error) {
1741
- $.log.error('[MongoDB] 哈希表获取所有字段名失败:', error);
1790
+ this.logger('error', '哈希表获取所有字段名失败:', error);
1742
1791
  return [];
1743
1792
  }
1744
1793
  };
@@ -1749,12 +1798,12 @@ MongoDB.prototype.hkeys = async function (key) {
1749
1798
  * @return {Promise<Number>} 字段数量
1750
1799
  */
1751
1800
  MongoDB.prototype.hlen = async function (key) {
1752
- try {
1753
- // 参数验证
1754
- if (!key || typeof key !== 'string') {
1755
- return 0;
1756
- }
1801
+ // 参数校验
1802
+ if (typeof key !== 'string' || !key) {
1803
+ throw new TypeError('key必须是有效的字符串');
1804
+ }
1757
1805
 
1806
+ try {
1758
1807
  await this._ensureConnected();
1759
1808
  const item = await this.findOne({ key: key });
1760
1809
 
@@ -1766,7 +1815,7 @@ MongoDB.prototype.hlen = async function (key) {
1766
1815
  // 使用Object.keys获取自有属性数量,这比for-in循环更高效
1767
1816
  return Object.keys(item.value).length;
1768
1817
  } catch (error) {
1769
- $.log.error('[MongoDB] hlen操作失败:', error);
1818
+ this.logger('error', 'hlen操作失败:', error);
1770
1819
  return 0;
1771
1820
  }
1772
1821
  };
@@ -1778,6 +1827,14 @@ MongoDB.prototype.hlen = async function (key) {
1778
1827
  * @return {Promise<Boolean>} 是否存在
1779
1828
  */
1780
1829
  MongoDB.prototype.hexists = async function (key, field) {
1830
+ // 参数校验
1831
+ if (typeof key !== 'string' || !key) {
1832
+ throw new TypeError('key必须是有效的字符串');
1833
+ }
1834
+ if (typeof field !== 'string' || !field) {
1835
+ throw new TypeError('field必须是有效的字符串');
1836
+ }
1837
+
1781
1838
  try {
1782
1839
  await this._ensureConnected();
1783
1840
  const item = await this.findOne({
@@ -1788,7 +1845,7 @@ MongoDB.prototype.hexists = async function (key, field) {
1788
1845
  }
1789
1846
  return field in item.value;
1790
1847
  } catch (error) {
1791
- $.log.error('[MongoDB] 哈希表字段是否存在失败:', error);
1848
+ this.logger('error', '哈希表字段是否存在失败:', error);
1792
1849
  return false;
1793
1850
  }
1794
1851
  };
@@ -1800,6 +1857,11 @@ MongoDB.prototype.hexists = async function (key, field) {
1800
1857
  * @return {Promise<Number>} 添加后列表长度
1801
1858
  */
1802
1859
  MongoDB.prototype.rpush = async function (key, value) {
1860
+ // 参数校验
1861
+ if (typeof key !== 'string' || !key) {
1862
+ throw new TypeError('key必须是有效的字符串');
1863
+ }
1864
+
1803
1865
  try {
1804
1866
  await this._ensureConnected();
1805
1867
  const item = await this.findOne({
@@ -1812,7 +1874,7 @@ MongoDB.prototype.rpush = async function (key, value) {
1812
1874
  await this._add(key, list);
1813
1875
  return list.length;
1814
1876
  } catch (error) {
1815
- $.log.error('[MongoDB] 列表尾部添加失败:', error);
1877
+ this.logger('error', '列表尾部添加失败:', error);
1816
1878
  return 0;
1817
1879
  }
1818
1880
  };
@@ -1824,6 +1886,11 @@ MongoDB.prototype.rpush = async function (key, value) {
1824
1886
  * @return {Promise<Number>} 添加后列表长度
1825
1887
  */
1826
1888
  MongoDB.prototype.lpush = async function (key, value) {
1889
+ // 参数校验
1890
+ if (typeof key !== 'string' || !key) {
1891
+ throw new TypeError('key必须是有效的字符串');
1892
+ }
1893
+
1827
1894
  try {
1828
1895
  await this._ensureConnected();
1829
1896
  const item = await this.findOne({
@@ -1836,7 +1903,7 @@ MongoDB.prototype.lpush = async function (key, value) {
1836
1903
  await this._add(key, list);
1837
1904
  return list.length;
1838
1905
  } catch (error) {
1839
- $.log.error('[MongoDB] 列表头部添加失败:', error);
1906
+ this.logger('error', '列表头部添加失败:', error);
1840
1907
  return 0;
1841
1908
  }
1842
1909
  };
@@ -1849,6 +1916,17 @@ MongoDB.prototype.lpush = async function (key, value) {
1849
1916
  * @return {Promise<Array>} 元素数组
1850
1917
  */
1851
1918
  MongoDB.prototype.lrange = async function (key, start, stop) {
1919
+ // 参数校验
1920
+ if (typeof key !== 'string' || !key) {
1921
+ throw new TypeError('key必须是有效的字符串');
1922
+ }
1923
+ if (typeof start !== 'number' || isNaN(start)) {
1924
+ throw new TypeError('start必须是有效的数字');
1925
+ }
1926
+ if (typeof stop !== 'number' || isNaN(stop)) {
1927
+ throw new TypeError('stop必须是有效的数字');
1928
+ }
1929
+
1852
1930
  try {
1853
1931
  await this._ensureConnected();
1854
1932
  const item = await this.findOne({
@@ -1868,7 +1946,7 @@ MongoDB.prototype.lrange = async function (key, start, stop) {
1868
1946
 
1869
1947
  return item.value.slice(startIndex, endIndex + 1);
1870
1948
  } catch (error) {
1871
- $.log.error('[MongoDB] 列表范围查询失败:', error);
1949
+ this.logger('error', '列表范围查询失败:', error);
1872
1950
  return [];
1873
1951
  }
1874
1952
  };
@@ -1898,7 +1976,7 @@ MongoDB.prototype.lindex = async function (key, index) {
1898
1976
 
1899
1977
  return item.value[realIndex];
1900
1978
  } catch (error) {
1901
- $.log.error('[MongoDB] 获取列表索引元素失败:', error);
1979
+ this.logger('error', '获取列表索引元素失败:', error);
1902
1980
  return null;
1903
1981
  }
1904
1982
  };
@@ -1935,7 +2013,7 @@ MongoDB.prototype.lset = async function (key, index, value) {
1935
2013
  });
1936
2014
  return true;
1937
2015
  } catch (error) {
1938
- $.log.error('[MongoDB] 设置列表索引元素失败:', error);
2016
+ this.logger('error', '设置列表索引元素失败:', error);
1939
2017
  return false;
1940
2018
  }
1941
2019
  };
@@ -1994,7 +2072,7 @@ MongoDB.prototype.lrem = async function (key, count, value) {
1994
2072
 
1995
2073
  return removedCount;
1996
2074
  } catch (error) {
1997
- $.log.error('[MongoDB] 删除列表元素失败:', error);
2075
+ this.logger('error', '删除列表元素失败:', error);
1998
2076
  return 0;
1999
2077
  }
2000
2078
  };
@@ -2025,7 +2103,7 @@ MongoDB.prototype.ltrim = async function (key, start, stop) {
2025
2103
  });
2026
2104
  return true;
2027
2105
  } catch (error) {
2028
- $.log.error('[MongoDB] 裁剪列表失败:', error);
2106
+ this.logger('error', '增加整数值失败:', error);
2029
2107
  return false;
2030
2108
  }
2031
2109
  };
@@ -2036,6 +2114,11 @@ MongoDB.prototype.ltrim = async function (key, start, stop) {
2036
2114
  * @return {Promise<Number>} 列表长度
2037
2115
  */
2038
2116
  MongoDB.prototype.llen = async function (key) {
2117
+ // 参数校验
2118
+ if (typeof key !== 'string' || !key) {
2119
+ throw new TypeError('key必须是有效的字符串');
2120
+ }
2121
+
2039
2122
  try {
2040
2123
  await this._ensureConnected();
2041
2124
  const item = await this.findOne({
@@ -2046,7 +2129,7 @@ MongoDB.prototype.llen = async function (key) {
2046
2129
  }
2047
2130
  return item.value.length;
2048
2131
  } catch (error) {
2049
- $.log.error('[MongoDB] 获取列表长度失败:', error);
2132
+ this.logger('error', '获取列表长度失败:', error);
2050
2133
  return 0;
2051
2134
  }
2052
2135
  };
@@ -2058,6 +2141,14 @@ MongoDB.prototype.llen = async function (key) {
2058
2141
  * @return {Promise<Number>} 添加的成员数量
2059
2142
  */
2060
2143
  MongoDB.prototype.saddMulti = async function (key, members) {
2144
+ // 参数校验
2145
+ if (typeof key !== 'string' || !key) {
2146
+ throw new TypeError('key必须是有效的字符串');
2147
+ }
2148
+ if (!Array.isArray(members)) {
2149
+ throw new TypeError('members必须是有效的数组');
2150
+ }
2151
+
2061
2152
  try {
2062
2153
  await this._ensureConnected();
2063
2154
  const item = await this.findOne({
@@ -2079,7 +2170,7 @@ MongoDB.prototype.saddMulti = async function (key, members) {
2079
2170
 
2080
2171
  return addedCount;
2081
2172
  } catch (error) {
2082
- $.log.error('[MongoDB] 集合并发添加失败:', error);
2173
+ this.logger('error', '集合并发添加失败:', error);
2083
2174
  return 0;
2084
2175
  }
2085
2176
  };
@@ -2091,6 +2182,14 @@ MongoDB.prototype.saddMulti = async function (key, members) {
2091
2182
  * @return {Promise<Number>} 删除的成员数量
2092
2183
  */
2093
2184
  MongoDB.prototype.sremMulti = async function (key, members) {
2185
+ // 参数校验
2186
+ if (typeof key !== 'string' || !key) {
2187
+ throw new TypeError('key必须是有效的字符串');
2188
+ }
2189
+ if (!Array.isArray(members)) {
2190
+ throw new TypeError('members必须是有效的数组');
2191
+ }
2192
+
2094
2193
  try {
2095
2194
  await this._ensureConnected();
2096
2195
  const item = await this.findOne({
@@ -2114,101 +2213,145 @@ MongoDB.prototype.sremMulti = async function (key, members) {
2114
2213
 
2115
2214
  return removedCount;
2116
2215
  } catch (error) {
2117
- $.log.error('[MongoDB] 集合并发删除失败:', error);
2216
+ this.logger('error', '集合并发删除失败:', error);
2118
2217
  return 0;
2119
2218
  }
2120
2219
  };
2121
2220
 
2122
2221
  /**
2123
2222
  * @description Redis兼容API - 集合差集
2124
- * @param {String} key1 第一个集合键
2125
- * @param {String} key2 第二个集合键
2223
+ * @param {...String} keys 集合键(至少两个)
2126
2224
  * @return {Promise<Array>} 差集数组
2127
2225
  */
2128
- MongoDB.prototype.sdiff = async function (key1, key2) {
2226
+ MongoDB.prototype.sdiff = async function (...keys) {
2227
+ // 参数校验
2228
+ if (!Array.isArray(keys) || keys.length < 2) {
2229
+ throw new TypeError('必须提供至少两个集合键');
2230
+ }
2231
+ for (const key of keys) {
2232
+ if (typeof key !== 'string' || !key) {
2233
+ throw new TypeError('所有集合键必须是有效的字符串');
2234
+ }
2235
+ }
2236
+
2129
2237
  try {
2130
2238
  await this._ensureConnected();
2131
- const item1 = await this.findOne({
2132
- key: key1
2133
- });
2134
- const item2 = await this.findOne({
2135
- key: key2
2136
- });
2137
2239
 
2138
- const set1 = item1 && Array.isArray(item1.value) ? [...new Set(item1.value)] : [];
2139
- const set2 = item2 && Array.isArray(item2.value) ? [...new Set(item2.value)] : [];
2240
+ // 获取所有集合的数据
2241
+ const items = await Promise.all(keys.map(key => this.findOne({ key })));
2242
+
2243
+ // 转换为集合数组
2244
+ const sets = items.map(item =>
2245
+ item && Array.isArray(item.value) ? [...new Set(item.value)] : []
2246
+ );
2247
+
2248
+ // 第一个集合作为基准
2249
+ const baseSet = sets[0];
2140
2250
 
2141
- // 创建第二个集合值的字符串表示用于快速查找
2142
- const set2Str = new Set(set2.map(m => JSON.stringify(m)));
2251
+ // 创建其他所有集合的字符串表示的并集用于快速查找
2252
+ const otherSetsStr = new Set();
2253
+ for (let i = 1; i < sets.length; i++) {
2254
+ sets[i].forEach(member => {
2255
+ otherSetsStr.add(JSON.stringify(member));
2256
+ });
2257
+ }
2143
2258
 
2144
- // 找出在set1中但不在set2中的元素
2145
- return set1.filter(member => !set2Str.has(JSON.stringify(member)));
2259
+ // 找出在baseSet中但不在其他所有集合中的元素
2260
+ return baseSet.filter(member => !otherSetsStr.has(JSON.stringify(member)));
2146
2261
  } catch (error) {
2147
- $.log.error('[MongoDB] 集合差集失败:', error);
2262
+ this.logger('error', '集合差集失败:', error);
2148
2263
  return [];
2149
2264
  }
2150
2265
  };
2151
2266
 
2152
2267
  /**
2153
2268
  * @description Redis兼容API - 集合交集
2154
- * @param {String} key1 第一个集合键
2155
- * @param {String} key2 第二个集合键
2269
+ * @param {...String} keys 集合键(至少两个)
2156
2270
  * @return {Promise<Array>} 交集数组
2157
2271
  */
2158
- MongoDB.prototype.sinter = async function (key1, key2) {
2272
+ MongoDB.prototype.sinter = async function (...keys) {
2273
+ // 参数校验
2274
+ if (!Array.isArray(keys) || keys.length < 2) {
2275
+ throw new TypeError('必须提供至少两个集合键');
2276
+ }
2277
+ for (const key of keys) {
2278
+ if (typeof key !== 'string' || !key) {
2279
+ throw new TypeError('所有集合键必须是有效的字符串');
2280
+ }
2281
+ }
2282
+
2159
2283
  try {
2160
2284
  await this._ensureConnected();
2161
- const item1 = await this.findOne({
2162
- key: key1
2163
- });
2164
- const item2 = await this.findOne({
2165
- key: key2
2166
- });
2167
2285
 
2168
- const set1 = item1 && Array.isArray(item1.value) ? [...new Set(item1.value)] : [];
2169
- const set2 = item2 && Array.isArray(item2.value) ? [...new Set(item2.value)] : [];
2286
+ // 获取所有集合的数据
2287
+ const items = await Promise.all(keys.map(key => this.findOne({ key })));
2170
2288
 
2171
- // 创建较小集合的字符串表示用于快速查找,优化性能
2172
- let smallerSet, largerSet;
2173
- if (set1.length <= set2.length) {
2174
- smallerSet = set1;
2175
- largerSet = set2;
2176
- } else {
2177
- smallerSet = set2;
2178
- largerSet = set1;
2289
+ // 转换为集合数组
2290
+ const sets = items.map(item =>
2291
+ item && Array.isArray(item.value) ? [...new Set(item.value)] : []
2292
+ );
2293
+
2294
+ // 如果有一个集合为空,交集就是空
2295
+ if (sets.some(set => set.length === 0)) {
2296
+ return [];
2297
+ }
2298
+
2299
+ // 找到最小的集合作为基准
2300
+ let smallestSet = sets[0];
2301
+ let smallestIndex = 0;
2302
+ for (let i = 1; i < sets.length; i++) {
2303
+ if (sets[i].length < smallestSet.length) {
2304
+ smallestSet = sets[i];
2305
+ smallestIndex = i;
2306
+ }
2179
2307
  }
2180
2308
 
2181
- const largerSetStr = new Set(largerSet.map(m => JSON.stringify(m)));
2309
+ // 创建其他集合的字符串表示用于快速查找
2310
+ const otherSetsStr = sets.map((set, index) =>
2311
+ index !== smallestIndex ? new Set(set.map(m => JSON.stringify(m))) : null
2312
+ ).filter(Boolean);
2182
2313
 
2183
- // 找出同时存在于两个集合中的元素
2184
- return smallerSet.filter(member => largerSetStr.has(JSON.stringify(member)));
2314
+ // 找出同时存在于所有集合中的元素
2315
+ return smallestSet.filter(member => {
2316
+ const memberStr = JSON.stringify(member);
2317
+ return otherSetsStr.every(set => set.has(memberStr));
2318
+ });
2185
2319
  } catch (error) {
2186
- $.log.error('[MongoDB] 集合并集失败:', error);
2320
+ this.logger('error', '集合交集失败:', error);
2187
2321
  return [];
2188
2322
  }
2189
2323
  };
2190
2324
 
2191
2325
  /**
2192
2326
  * @description Redis兼容API - 集合并集
2193
- * @param {String} key1 第一个集合键
2194
- * @param {String} key2 第二个集合键
2327
+ * @param {...String} keys 集合键(至少两个)
2195
2328
  * @return {Promise<Array>} 并集数组
2196
2329
  */
2197
- MongoDB.prototype.sunion = async function (key1, key2) {
2330
+ MongoDB.prototype.sunion = async function (...keys) {
2331
+ // 参数校验
2332
+ if (!Array.isArray(keys) || keys.length < 2) {
2333
+ throw new TypeError('必须提供至少两个集合键');
2334
+ }
2335
+ for (const key of keys) {
2336
+ if (typeof key !== 'string' || !key) {
2337
+ throw new TypeError('所有集合键必须是有效的字符串');
2338
+ }
2339
+ }
2340
+
2198
2341
  try {
2199
2342
  await this._ensureConnected();
2200
- const item1 = await this.findOne({
2201
- key: key1
2202
- });
2203
- const item2 = await this.findOne({
2204
- key: key2
2205
- });
2206
2343
 
2207
- const set1 = item1 && Array.isArray(item1.value) ? item1.value : [];
2208
- const set2 = item2 && Array.isArray(item2.value) ? item2.value : [];
2344
+ // 获取所有集合的数据
2345
+ const items = await Promise.all(keys.map(key => this.findOne({ key })));
2346
+
2347
+ // 转换为集合数组
2348
+ const sets = items.map(item =>
2349
+ item && Array.isArray(item.value) ? item.value : []
2350
+ );
2351
+
2352
+ // 合并所有集合
2353
+ const combined = sets.reduce((acc, set) => [...acc, ...set], []);
2209
2354
 
2210
- // 合并并去重
2211
- const combined = [...set1, ...set2];
2212
2355
  // 使用Map进行对象去重,基于JSON字符串表示
2213
2356
  const uniqueMap = new Map();
2214
2357
 
@@ -2221,7 +2364,7 @@ MongoDB.prototype.sunion = async function (key1, key2) {
2221
2364
 
2222
2365
  return Array.from(uniqueMap.values());
2223
2366
  } catch (error) {
2224
- $.log.error('[MongoDB] 集合并集失败:', error);
2367
+ this.logger('error', '集合并集失败:', error);
2225
2368
  return [];
2226
2369
  }
2227
2370
  };
@@ -2232,6 +2375,11 @@ MongoDB.prototype.sunion = async function (key1, key2) {
2232
2375
  * @return {Promise<Number>} 成员数量
2233
2376
  */
2234
2377
  MongoDB.prototype.scard = async function (key) {
2378
+ // 参数校验
2379
+ if (typeof key !== 'string' || !key) {
2380
+ throw new TypeError('key必须是有效的字符串');
2381
+ }
2382
+
2235
2383
  try {
2236
2384
  await this._ensureConnected();
2237
2385
  const item = await this.findOne({
@@ -2245,7 +2393,7 @@ MongoDB.prototype.scard = async function (key) {
2245
2393
  const uniqueItems = new Set(item.value.map(m => JSON.stringify(m)));
2246
2394
  return uniqueItems.size;
2247
2395
  } catch (error) {
2248
- $.log.error('[MongoDB] 获取集合成员数量失败:', error);
2396
+ this.logger('error', '获取集合成员数量失败:', error);
2249
2397
  return 0;
2250
2398
  }
2251
2399
  };
@@ -2257,8 +2405,16 @@ MongoDB.prototype.scard = async function (key) {
2257
2405
  * @return {Promise<Boolean>} 是否是成员
2258
2406
  */
2259
2407
  MongoDB.prototype.sismember = async function (key, member) {
2408
+ // 参数校验
2409
+ if (typeof key !== 'string' || !key) {
2410
+ throw new TypeError('key必须是有效的字符串');
2411
+ }
2412
+ if (member === undefined || member === null) {
2413
+ throw new TypeError('member不能为undefined或null');
2414
+ }
2415
+
2260
2416
  try {
2261
- this.emit('sismember_before', {
2417
+ this.emit('sismember:before', {
2262
2418
  key,
2263
2419
  member
2264
2420
  });
@@ -2276,19 +2432,19 @@ MongoDB.prototype.sismember = async function (key, member) {
2276
2432
  result = item.value.includes(memberStr);
2277
2433
  }
2278
2434
 
2279
- this.emit('sismember_after', {
2435
+ this.emit('sismember:after', {
2280
2436
  key,
2281
2437
  member,
2282
2438
  result
2283
2439
  });
2284
2440
  return result;
2285
2441
  } catch (error) {
2286
- this.emit('sismember_error', {
2442
+ this.emit('sismember:error', {
2287
2443
  key,
2288
2444
  member,
2289
2445
  error
2290
2446
  });
2291
- $.log.error('[MongoDB] 检查集合成员失败:', error);
2447
+ this.logger('error', '检查集合成员失败:', error);
2292
2448
  return false;
2293
2449
  }
2294
2450
  };
@@ -2299,7 +2455,7 @@ MongoDB.prototype.sismember = async function (key, member) {
2299
2455
  */
2300
2456
  MongoDB.prototype.clearExpire = async function () {
2301
2457
  try {
2302
- this.emit('clearExpire_before', {});
2458
+ this.emit('clearExpire:before', {});
2303
2459
  await this._ensureConnected();
2304
2460
  // 删除所有已过期的数据
2305
2461
  const result = await this.delete({
@@ -2308,15 +2464,15 @@ MongoDB.prototype.clearExpire = async function () {
2308
2464
  $lt: new Date()
2309
2465
  }
2310
2466
  });
2311
- this.emit('clearExpire_after', {
2467
+ this.emit('clearExpire:after', {
2312
2468
  result: true
2313
2469
  });
2314
2470
  return true;
2315
2471
  } catch (error) {
2316
- this.emit('clearExpire_error', {
2472
+ this.emit('clearExpire:error', {
2317
2473
  error
2318
2474
  });
2319
- $.log.error('[MongoDB] 清空过期数据失败:', error);
2475
+ this.logger('error', '清空过期数据失败:', error);
2320
2476
  return false;
2321
2477
  }
2322
2478
  };
@@ -2342,7 +2498,7 @@ MongoDB.prototype.mget = async function (...keys) {
2342
2498
  // 返回与输入键顺序对应的数组,不存在的键对应位置返回undefined
2343
2499
  return keyArray.map(key => resultMap.hasOwnProperty(key) ? resultMap[key] : undefined);
2344
2500
  } catch (error) {
2345
- $.log.error('[MongoDB] 批量获取失败:', error);
2501
+ this.logger('error', '批量获取失败:', error);
2346
2502
  throw error;
2347
2503
  }
2348
2504
  };
@@ -2360,11 +2516,11 @@ MongoDB.prototype.mset = async function (keyValues, seconds = 0) {
2360
2516
  seconds,
2361
2517
  cancel: false
2362
2518
  };
2363
- this.emit('mset_before', beforeEventData);
2519
+ this.emit('mset:before', beforeEventData);
2364
2520
 
2365
2521
  // 如果事件处理器标记为取消,则返回false
2366
2522
  if (beforeEventData.cancel) {
2367
- $.log.debug('[MongoDB] mset操作被事件处理器取消');
2523
+ this.logger('debug', 'mset操作被事件处理器取消');
2368
2524
  return false;
2369
2525
  }
2370
2526
 
@@ -2376,7 +2532,7 @@ MongoDB.prototype.mset = async function (keyValues, seconds = 0) {
2376
2532
 
2377
2533
  // 参数验证,确保keyValues是对象且不为null
2378
2534
  if (typeof finalData !== 'object' || finalData === null || Array.isArray(finalData)) {
2379
- $.log.warn('[MongoDB] mset: 参数必须是非空对象');
2535
+ this.logger('warn', 'mset: 参数必须是非空对象');
2380
2536
  return false;
2381
2537
  }
2382
2538
 
@@ -2386,7 +2542,7 @@ MongoDB.prototype.mset = async function (keyValues, seconds = 0) {
2386
2542
  }
2387
2543
 
2388
2544
  // 触发后置事件
2389
- this.emit('mset_after', {
2545
+ this.emit('mset:after', {
2390
2546
  keyValues: finalData,
2391
2547
  seconds: finalSeconds,
2392
2548
  result: true
@@ -2394,12 +2550,12 @@ MongoDB.prototype.mset = async function (keyValues, seconds = 0) {
2394
2550
  return true;
2395
2551
  } catch (error) {
2396
2552
  // 触发错误事件
2397
- this.emit('mset_error', {
2553
+ this.emit('mset:error', {
2398
2554
  keyValues,
2399
2555
  seconds,
2400
2556
  error
2401
2557
  });
2402
- $.log.error('[MongoDB] 批量设置失败:', error);
2558
+ this.logger('error', '批量设置失败:', error);
2403
2559
  return false;
2404
2560
  }
2405
2561
  };
@@ -2412,6 +2568,14 @@ MongoDB.prototype.mset = async function (keyValues, seconds = 0) {
2412
2568
  * @return {Promise<Boolean>} 是否成功
2413
2569
  */
2414
2570
  MongoDB.prototype.zadd = async function (key, score, member) {
2571
+ // 参数校验
2572
+ if (typeof key !== 'string' || !key) {
2573
+ throw new TypeError('key必须是有效的字符串');
2574
+ }
2575
+ if (typeof score !== 'number' || isNaN(score)) {
2576
+ throw new TypeError('score必须是有效的数字');
2577
+ }
2578
+
2415
2579
  try {
2416
2580
  await this._ensureConnected();
2417
2581
  const item = await this.findOne({
@@ -2437,7 +2601,7 @@ MongoDB.prototype.zadd = async function (key, score, member) {
2437
2601
  await this._add(key, sortedSet);
2438
2602
  return true;
2439
2603
  } catch (error) {
2440
- $.log.error('[MongoDB] 有序集合添加成员失败:', error);
2604
+ this.logger('error', '增加浮点数值失败:', error);
2441
2605
  return false;
2442
2606
  }
2443
2607
  };
@@ -2450,6 +2614,17 @@ MongoDB.prototype.zadd = async function (key, score, member) {
2450
2614
  * @return {Promise<Array>} 成员数组
2451
2615
  */
2452
2616
  MongoDB.prototype.zrangebyscore = async function (key, min, max) {
2617
+ // 参数校验
2618
+ if (typeof key !== 'string' || !key) {
2619
+ throw new TypeError('key必须是有效的字符串');
2620
+ }
2621
+ if (typeof min !== 'number' || isNaN(min)) {
2622
+ throw new TypeError('min必须是有效的数字');
2623
+ }
2624
+ if (typeof max !== 'number' || isNaN(max)) {
2625
+ throw new TypeError('max必须是有效的数字');
2626
+ }
2627
+
2453
2628
  try {
2454
2629
  await this._ensureConnected();
2455
2630
  const item = await this.findOne({
@@ -2464,7 +2639,7 @@ MongoDB.prototype.zrangebyscore = async function (key, min, max) {
2464
2639
  .filter(item => item.score >= min && item.score <= max)
2465
2640
  .map(item => item.member);
2466
2641
  } catch (error) {
2467
- $.log.error('[MongoDB] 有序集合范围查询失败:', error);
2642
+ this.logger('error', '有序集合范围查询失败:', error);
2468
2643
  return [];
2469
2644
  }
2470
2645
  };
@@ -2475,6 +2650,11 @@ MongoDB.prototype.zrangebyscore = async function (key, min, max) {
2475
2650
  * @return {Promise<Number>} 成员数量
2476
2651
  */
2477
2652
  MongoDB.prototype.zcard = async function (key) {
2653
+ // 参数校验
2654
+ if (typeof key !== 'string' || !key) {
2655
+ throw new TypeError('key必须是有效的字符串');
2656
+ }
2657
+
2478
2658
  try {
2479
2659
  await this._ensureConnected();
2480
2660
  const item = await this.findOne({
@@ -2485,7 +2665,7 @@ MongoDB.prototype.zcard = async function (key) {
2485
2665
  }
2486
2666
  return item.value.length;
2487
2667
  } catch (error) {
2488
- $.log.error('[MongoDB] 有序集合成员数量失败:', error);
2668
+ this.logger('error', '有序集合成员数量失败:', error);
2489
2669
  return 0;
2490
2670
  }
2491
2671
  };
@@ -2497,6 +2677,11 @@ MongoDB.prototype.zcard = async function (key) {
2497
2677
  * @return {Promise<Number>} 删除的成员数量
2498
2678
  */
2499
2679
  MongoDB.prototype.zrem = async function (key, member) {
2680
+ // 参数校验
2681
+ if (typeof key !== 'string' || !key) {
2682
+ throw new TypeError('key必须是有效的字符串');
2683
+ }
2684
+
2500
2685
  try {
2501
2686
  await this._ensureConnected();
2502
2687
  const item = await this.findOne({
@@ -2516,7 +2701,7 @@ MongoDB.prototype.zrem = async function (key, member) {
2516
2701
 
2517
2702
  return removedCount;
2518
2703
  } catch (error) {
2519
- $.log.error('[MongoDB] 有序集合删除成员失败:', error);
2704
+ this.logger('error', '有序集合删除成员失败:', error);
2520
2705
  return 0;
2521
2706
  }
2522
2707
  };
@@ -2528,6 +2713,11 @@ MongoDB.prototype.zrem = async function (key, member) {
2528
2713
  * @return {Promise<Number|null>} 分数
2529
2714
  */
2530
2715
  MongoDB.prototype.zscore = async function (key, member) {
2716
+ // 参数校验
2717
+ if (typeof key !== 'string' || !key) {
2718
+ throw new TypeError('key必须是有效的字符串');
2719
+ }
2720
+
2531
2721
  try {
2532
2722
  await this._ensureConnected();
2533
2723
  const item = await this.findOne({
@@ -2541,7 +2731,7 @@ MongoDB.prototype.zscore = async function (key, member) {
2541
2731
  const found = item.value.find(item => JSON.stringify(item.member) === memberStr);
2542
2732
  return found ? found.score : null;
2543
2733
  } catch (error) {
2544
- $.log.error('[MongoDB] 获取成员分数失败:', error);
2734
+ this.logger('error', '获取成员分数失败:', error);
2545
2735
  return null;
2546
2736
  }
2547
2737
  };
@@ -2552,6 +2742,11 @@ MongoDB.prototype.zscore = async function (key, member) {
2552
2742
  * @return {Promise<any|null>} 弹出的元素
2553
2743
  */
2554
2744
  MongoDB.prototype.lpop = async function (key) {
2745
+ // 参数校验
2746
+ if (typeof key !== 'string' || !key) {
2747
+ throw new TypeError('key必须是有效的字符串');
2748
+ }
2749
+
2555
2750
  try {
2556
2751
  await this._ensureConnected();
2557
2752
  const item = await this.findOne({
@@ -2569,7 +2764,7 @@ MongoDB.prototype.lpop = async function (key) {
2569
2764
  });
2570
2765
  return popped;
2571
2766
  } catch (error) {
2572
- $.log.error('[MongoDB] 列表弹出头部元素失败:', error);
2767
+ this.logger('error', '列表弹出头部元素失败:', error);
2573
2768
  return null;
2574
2769
  }
2575
2770
  };
@@ -2580,6 +2775,11 @@ MongoDB.prototype.lpop = async function (key) {
2580
2775
  * @return {Promise<any|null>} 弹出的元素
2581
2776
  */
2582
2777
  MongoDB.prototype.rpop = async function (key) {
2778
+ // 参数校验
2779
+ if (typeof key !== 'string' || !key) {
2780
+ throw new TypeError('key必须是有效的字符串');
2781
+ }
2782
+
2583
2783
  try {
2584
2784
  await this._ensureConnected();
2585
2785
  const item = await this.findOne({
@@ -2597,7 +2797,7 @@ MongoDB.prototype.rpop = async function (key) {
2597
2797
  });
2598
2798
  return popped;
2599
2799
  } catch (error) {
2600
- $.log.error('[MongoDB] 列表弹出尾部元素失败:', error);
2800
+ this.logger('error', '列表弹出尾部元素失败:', error);
2601
2801
  return null;
2602
2802
  }
2603
2803
  };
@@ -2608,6 +2808,11 @@ MongoDB.prototype.rpop = async function (key) {
2608
2808
  * @return {Promise<Array>} 成员数组
2609
2809
  */
2610
2810
  MongoDB.prototype.smembers = async function (key) {
2811
+ // 参数校验
2812
+ if (typeof key !== 'string' || !key) {
2813
+ throw new TypeError('key必须是有效的字符串');
2814
+ }
2815
+
2611
2816
  try {
2612
2817
  await this._ensureConnected();
2613
2818
  const item = await this.findOne({
@@ -2627,7 +2832,7 @@ MongoDB.prototype.smembers = async function (key) {
2627
2832
  });
2628
2833
  return Array.from(uniqueMap.values());
2629
2834
  } catch (error) {
2630
- $.log.error('[MongoDB] 获取集合所有成员失败:', error);
2835
+ this.logger('error', '获取集合所有成员失败:', error);
2631
2836
  return [];
2632
2837
  }
2633
2838
  };
@@ -2648,7 +2853,7 @@ MongoDB.prototype.findOne = async function (query, options = {}) {
2648
2853
  // 不需要额外的sanitize,MongoDB驱动会处理
2649
2854
  return await this.db.collection(this.table).findOne(query, options);
2650
2855
  } catch (error) {
2651
- $.log.error('[MongoDB] 查询单条数据失败:', error);
2856
+ this.logger('error', '查询单条数据失败:', error);
2652
2857
  return null;
2653
2858
  }
2654
2859
  };
@@ -2658,11 +2863,31 @@ MongoDB.prototype.findOne = async function (query, options = {}) {
2658
2863
  */
2659
2864
  MongoDB.prototype.setUrl = function () {
2660
2865
  var url = "mongodb://";
2866
+ if (this.config.user) {
2867
+ url += encodeURIComponent(this.config.user);
2868
+ }
2661
2869
  if (this.config.password) {
2662
- url += encodeURIComponent(this.config.user) + ':' + encodeURIComponent(this.config.password) + '@';
2870
+ url += ':' + encodeURIComponent(this.config.password)
2871
+ }
2872
+ if (this.config.user || this.config.password) {
2873
+ url += '@'
2663
2874
  }
2664
2875
  url += this.config.host + ":" + this.config.port + "/";
2665
- this.url = url;
2876
+ url += this.config.database;
2877
+
2878
+ // 添加连接参数到连接字符串
2879
+ var params = [];
2880
+ if (this.config.min_pool_size) params.push('minPoolSize=' + this.config.min_pool_size);
2881
+ if (this.config.max_pool_size) params.push('maxPoolSize=' + this.config.max_pool_size);
2882
+ if (this.config.connect_timeout_ms) params.push('connectTimeoutMS=' + this.config.connect_timeout_ms);
2883
+ if (this.config.server_selection_timeout_ms) params.push('serverSelectionTimeoutMS=' + this.config.server_selection_timeout_ms);
2884
+ if (this.config.retry_writes !== undefined) params.push('retryWrites=' + (this.config.retry_writes ? 'true' : 'false'));
2885
+
2886
+ if (params.length > 0) {
2887
+ url += '?' + params.join('&');
2888
+ }
2889
+
2890
+ return url;
2666
2891
  };
2667
2892
 
2668
2893
  /**
@@ -2670,34 +2895,32 @@ MongoDB.prototype.setUrl = function () {
2670
2895
  * @return {Promise<Boolean>} 连接成功返回true, 失败抛出错误
2671
2896
  */
2672
2897
  MongoDB.prototype.open = async function () {
2673
- if (!this.url) {
2674
- this.setUrl();
2675
- }
2898
+
2676
2899
  if (!this.conn) {
2677
2900
  return await this._withRetry(async () => {
2678
2901
  try {
2679
- this.conn = await MongoClient.connect(this.url, this.config.options);
2902
+ // 新版本MongoDB驱动只接受连接字符串,不再支持配置对象
2903
+ this.conn = await MongoClient.connect(this.setUrl());
2680
2904
  this.db = this.conn.db(this.config.database);
2681
2905
  this.connected = true;
2682
2906
 
2683
2907
  // 设置连接事件监听
2684
2908
  this.conn.on('error', (err) => {
2685
- $.log.error('[MongoDB] 连接错误:', err);
2909
+ this.logger('error', '连接错误:', err);
2686
2910
  this.connected = false;
2687
2911
  });
2688
2912
 
2689
2913
  this.conn.on('close', () => {
2690
- $.log.warn('[MongoDB] 连接已关闭');
2914
+ this.logger('warn', '连接已关闭');
2691
2915
  this.connected = false;
2692
2916
  });
2693
2917
 
2694
- $.log.info(
2695
- `[MongoDB] 成功连接到 ${this.config.host}:${this.config.port}/${this.config.database}`
2918
+ this.logger('info',
2919
+ `成功连接到 ${this.config.host}:${this.config.port}/${this.config.database}`
2696
2920
  );
2697
2921
  return true;
2698
2922
  } catch (error) {
2699
- $.log.error('[MongoDB] MongoDB连接失败:', error);
2700
- throw error;
2923
+ this.logger('error', 'MongoDB连接失败:', error);
2701
2924
  }
2702
2925
  }, '数据库连接');
2703
2926
  }
@@ -2709,8 +2932,8 @@ MongoDB.prototype.open = async function () {
2709
2932
  */
2710
2933
  MongoDB.prototype.close = async function () {
2711
2934
  if (this.conn) {
2712
- $.log.info(`[MongoDB] 关闭连接`);
2713
- await this.conn.close().catch(err => $.log.error('[MongoDB] 关闭MongoDB连接时出错:', err));
2935
+ this.logger('info', `关闭连接`);
2936
+ await this.conn.close().catch(err => this.logger('error', '关闭MongoDB连接时出错:', err));
2714
2937
  this.conn = null;
2715
2938
  this.db = null;
2716
2939
  this.connected = false;
@@ -2723,6 +2946,11 @@ MongoDB.prototype.close = async function () {
2723
2946
  * @return {Promise|Object} 执行结果
2724
2947
  */
2725
2948
  MongoDB.prototype.addTable = async function (table) {
2949
+ // 参数校验
2950
+ if (typeof table !== 'string' || !table) {
2951
+ throw new TypeError('table必须是有效的字符串');
2952
+ }
2953
+
2726
2954
  await this._ensureConnected();
2727
2955
  if (table) {
2728
2956
  this.table = table;
@@ -2739,19 +2967,24 @@ MongoDB.prototype.addTable = async function (table) {
2739
2967
  * @returns {Promise<Object>} 创建索引的结果
2740
2968
  */
2741
2969
  MongoDB.prototype.createIndex = async function (keys, options = {}) {
2970
+ // 参数校验
2971
+ if (typeof keys !== 'object' || keys === null || Array.isArray(keys)) {
2972
+ throw new TypeError('keys必须是非空对象');
2973
+ }
2974
+
2742
2975
  await this._ensureConnected();
2743
2976
  try {
2744
2977
  if (!this.db || !this.table) {
2745
2978
  throw new Error('数据库未连接或未指定表名');
2746
2979
  }
2747
2980
 
2748
- $.log.info(
2749
- `[MongoDB] 创建索引: ${this.table}, keys: ${JSON.stringify(keys)}, options: ${JSON.stringify(options)}`
2981
+ this.logger('info',
2982
+ `创建索引: ${this.table}, keys: ${JSON.stringify(keys)}, options: ${JSON.stringify(options)}`
2750
2983
  );
2751
2984
 
2752
2985
  return await this.db.collection(this.table).createIndex(keys, options);
2753
2986
  } catch (error) {
2754
- $.log.error(`[MongoDB] 创建索引失败: ${error.message}`);
2987
+ this.logger('error', `创建索引失败: ${error.message}`);
2755
2988
  throw error;
2756
2989
  }
2757
2990
  };
@@ -2763,6 +2996,14 @@ MongoDB.prototype.createIndex = async function (keys, options = {}) {
2763
2996
  * @returns {Promise<Object>} 创建索引的结果
2764
2997
  */
2765
2998
  MongoDB.prototype.createTTLIndex = async function (keys, expireAfterSeconds) {
2999
+ // 参数校验
3000
+ if (typeof keys !== 'object' || keys === null || Array.isArray(keys)) {
3001
+ throw new TypeError('keys必须是非空对象');
3002
+ }
3003
+ if (typeof expireAfterSeconds !== 'number' || expireAfterSeconds < 0) {
3004
+ throw new TypeError('expireAfterSeconds必须是非负数');
3005
+ }
3006
+
2766
3007
  await this._ensureConnected();
2767
3008
  try {
2768
3009
  if (!this.db || !this.table) {
@@ -2774,12 +3015,12 @@ MongoDB.prototype.createTTLIndex = async function (keys, expireAfterSeconds) {
2774
3015
  expireAfterSeconds: expireAfterSeconds
2775
3016
  };
2776
3017
 
2777
- $.log.info(
2778
- `[MongoDB] 创建TTL索引: ${this.table}, keys: ${JSON.stringify(keys)}, 过期时间: ${expireAfterSeconds}秒`);
3018
+ this.logger('info',
3019
+ `创建TTL索引: ${this.table}, keys: ${JSON.stringify(keys)}, 过期时间: ${expireAfterSeconds}秒`);
2779
3020
 
2780
3021
  return await this.db.collection(this.table).createIndex(keys, options);
2781
3022
  } catch (error) {
2782
- $.log.error(`[MongoDB] 创建TTL索引失败: ${error.message}`);
3023
+ this.logger('error', `创建TTL索引失败: ${error.message}`);
2783
3024
  throw error;
2784
3025
  }
2785
3026
  };
@@ -2791,16 +3032,16 @@ MongoDB.prototype.createTTLIndex = async function (keys, expireAfterSeconds) {
2791
3032
  MongoDB.prototype.getIndexes = async function () {
2792
3033
  await this._ensureConnected();
2793
3034
  try {
2794
- if (!this.table) {
2795
- throw new Error('未指定表名');
2796
- }
3035
+ if (!this.table) {
3036
+ throw new Error('未指定表名');
3037
+ }
2797
3038
 
2798
- $.log.info(`[MongoDB] 获取索引: ${this.table}`);
2799
- return await this.db.collection(this.table).indexes();
2800
- } catch (error) {
2801
- $.log.error(`[MongoDB] [getIndexes] 获取索引失败: ${error.message}`);
2802
- return [];
2803
- }
3039
+ this.logger('info', `获取索引: ${this.table}`);
3040
+ return await this.db.collection(this.table).indexes();
3041
+ } catch (error) {
3042
+ this.logger('error', `[getIndexes] 获取索引失败: ${error.message}`);
3043
+ return [];
3044
+ }
2804
3045
  };
2805
3046
 
2806
3047
  /**
@@ -2811,17 +3052,17 @@ MongoDB.prototype.getIndexes = async function () {
2811
3052
  MongoDB.prototype.dropIndex = async function (indexName) {
2812
3053
  await this._ensureConnected();
2813
3054
  if (!this.table) {
2814
- throw new Error('未指定表名');
3055
+ throw new TypeError('未指定表名');
2815
3056
  }
2816
3057
  if (!indexName) {
2817
- throw new Error('索引名称不能为空');
3058
+ throw new TypeError('索引名称不能为空');
2818
3059
  }
2819
3060
  try {
2820
- $.log.info(`[MongoDB] [dropIndex] 删除索引: ${this.table}, 索引名: ${indexName}`);
3061
+ this.logger('info', `[dropIndex] 删除索引: ${this.table}, 索引名: ${indexName}`);
2821
3062
  await this.db.collection(this.table).dropIndex(indexName);
2822
3063
  return true;
2823
3064
  } catch (error) {
2824
- $.log.error(`[MongoDB] [dropIndex] 删除索引失败: ${error.message}`);
3065
+ this.logger('error', `[dropIndex] 删除索引失败: ${error.message}`);
2825
3066
  throw error;
2826
3067
  }
2827
3068
  };
@@ -2836,11 +3077,11 @@ MongoDB.prototype.dropTable = async function () {
2836
3077
  throw new Error('未指定表名');
2837
3078
  }
2838
3079
  try {
2839
- $.log.info(`[MongoDB] [dropTable] 删除集合: ${this.table}`);
3080
+ this.logger('info', `[dropTable] 删除集合: ${this.table}`);
2840
3081
  await this.db.collection(this.table).drop();
2841
3082
  return true;
2842
3083
  } catch (error) {
2843
- $.log.error(`[MongoDB] [dropTable] 删除集合失败: ${error.message}`);
3084
+ this.logger('error', `[dropTable] 删除集合失败: ${error.message}`);
2844
3085
  throw error;
2845
3086
  }
2846
3087
  };
@@ -2854,7 +3095,7 @@ MongoDB.prototype.addObj = async function (obj) {
2854
3095
  await this._ensureConnected();
2855
3096
  try {
2856
3097
  // 触发前置事件
2857
- this.emit('addObj_before', {
3098
+ this.emit('addObj:before', {
2858
3099
  table: this.table,
2859
3100
  data: obj
2860
3101
  });
@@ -2863,7 +3104,7 @@ MongoDB.prototype.addObj = async function (obj) {
2863
3104
  const result = await this.db.collection(this.table).insertOne(obj);
2864
3105
 
2865
3106
  // 触发后置事件
2866
- this.emit('addObj_after', {
3107
+ this.emit('addObj:after', {
2867
3108
  table: this.table,
2868
3109
  data: obj,
2869
3110
  result
@@ -2872,7 +3113,7 @@ MongoDB.prototype.addObj = async function (obj) {
2872
3113
  return result;
2873
3114
  } catch (error) {
2874
3115
  // 触发错误事件
2875
- this.emit('addObj_error', {
3116
+ this.emit('addObj:error', {
2876
3117
  table: this.table,
2877
3118
  data: obj,
2878
3119
  error
@@ -2899,7 +3140,7 @@ MongoDB.prototype.get = async function (key) {
2899
3140
  });
2900
3141
  return result ? result.value : null;
2901
3142
  } catch (error) {
2902
- $.log.error(`[MongoDB] 获取键值失败: ${error.message}`);
3143
+ this.logger('error', `获取键值失败: ${error.message}`);
2903
3144
  return null;
2904
3145
  }
2905
3146
  };
@@ -2920,7 +3161,7 @@ MongoDB.prototype.setForList = async function (key, array, seconds = 0) {
2920
3161
 
2921
3162
  // 确保array是数组类型
2922
3163
  if (!Array.isArray(array)) {
2923
- throw new Error('value必须是数组类型');
3164
+ throw new TypeError('value必须是数组类型');
2924
3165
  }
2925
3166
 
2926
3167
  // 触发前置事件,允许修改或阻止操作
@@ -2930,10 +3171,10 @@ MongoDB.prototype.setForList = async function (key, array, seconds = 0) {
2930
3171
  ttl: seconds,
2931
3172
  cancel: false
2932
3173
  };
2933
- this.emit('setForList_before', beforeEventData);
3174
+ this.emit('setForList:before', beforeEventData);
2934
3175
 
2935
3176
  if (beforeEventData.cancel) {
2936
- $.log.debug(`[MongoDB] [setForList] setForList操作被事件处理器取消 [${key}]`);
3177
+ this.logger('debug', `[setForList] setForList操作被事件处理器取消 [${key}]`);
2937
3178
  return 0;
2938
3179
  }
2939
3180
 
@@ -2951,7 +3192,7 @@ MongoDB.prototype.setForList = async function (key, array, seconds = 0) {
2951
3192
  const length = finalValue.length;
2952
3193
 
2953
3194
  // 触发后置事件
2954
- this.emit('setForList_after', {
3195
+ this.emit('setForList:after', {
2955
3196
  key: finalKey,
2956
3197
  value: finalValue,
2957
3198
  ttl: finalSeconds,
@@ -2960,12 +3201,12 @@ MongoDB.prototype.setForList = async function (key, array, seconds = 0) {
2960
3201
  });
2961
3202
  return length;
2962
3203
  } catch (error) {
2963
- this.emit('setForList_error', {
3204
+ this.emit('setForList:error', {
2964
3205
  key,
2965
3206
  value: array,
2966
3207
  error
2967
3208
  });
2968
- $.log.error(`[MongoDB] [setForList] setForList操作失败: ${error.message}`);
3209
+ this.logger('error', `[setForList] setForList操作失败: ${error.message}`);
2969
3210
  return 0;
2970
3211
  }
2971
3212
  };
@@ -2991,10 +3232,10 @@ MongoDB.prototype.addForList = async function (key, value, seconds = 0) {
2991
3232
  ttl: seconds,
2992
3233
  cancel: false
2993
3234
  };
2994
- this.emit('addForList_before', beforeEventData);
3235
+ this.emit('addForList:before', beforeEventData);
2995
3236
 
2996
3237
  if (beforeEventData.cancel) {
2997
- $.log.debug(`[MongoDB] addForList操作被事件处理器取消 [${key}]`);
3238
+ this.logger('debug', `addForList操作被事件处理器取消 [${key}]`);
2998
3239
  return 0;
2999
3240
  }
3000
3241
 
@@ -3021,7 +3262,7 @@ MongoDB.prototype.addForList = async function (key, value, seconds = 0) {
3021
3262
  const length = currentArray.length;
3022
3263
 
3023
3264
  // 触发后置事件
3024
- this.emit('addForList_after', {
3265
+ this.emit('addForList:after', {
3025
3266
  key: finalKey,
3026
3267
  value: finalValue,
3027
3268
  ttl: finalSeconds,
@@ -3030,12 +3271,12 @@ MongoDB.prototype.addForList = async function (key, value, seconds = 0) {
3030
3271
  });
3031
3272
  return length;
3032
3273
  } catch (error) {
3033
- this.emit('addForList_error', {
3274
+ this.emit('addForList:error', {
3034
3275
  key,
3035
3276
  value,
3036
3277
  error
3037
3278
  });
3038
- $.log.error(`[MongoDB] addForList操作失败: ${error.message}`);
3279
+ this.logger('error', `addForList操作失败: ${error.message}`);
3039
3280
  return 0;
3040
3281
  }
3041
3282
  };
@@ -3068,7 +3309,7 @@ MongoDB.prototype.hasForList = async function (key, value) {
3068
3309
  const valueStr = JSON.stringify(value);
3069
3310
  return array.some(item => JSON.stringify(item) === valueStr);
3070
3311
  } catch (error) {
3071
- $.log.error(`[MongoDB] hasForList操作失败: ${error.message}`);
3312
+ this.logger('error', `hasForList操作失败: ${error.message}`);
3072
3313
  return false;
3073
3314
  }
3074
3315
  };
@@ -3106,7 +3347,7 @@ MongoDB.prototype.getForList = async function (key, start = 0, stop = -1) {
3106
3347
 
3107
3348
  return result;
3108
3349
  } catch (error) {
3109
- $.log.error(`[MongoDB] getForList操作失败: ${error.message}`);
3350
+ this.logger('error', `getForList操作失败: ${error.message}`);
3110
3351
  return [];
3111
3352
  }
3112
3353
  };
@@ -3129,7 +3370,7 @@ MongoDB.prototype.clearForList = async function (key) {
3129
3370
  // 使用set方法直接设置为空数组,与其他模块行为一致
3130
3371
  return await this.set(key, []);
3131
3372
  } catch (error) {
3132
- $.log.error(`[MongoDB] clearForList操作失败: ${error.message}`);
3373
+ this.logger('error', `clearForList操作失败: ${error.message}`);
3133
3374
  return false;
3134
3375
  }
3135
3376
  };
@@ -3141,7 +3382,7 @@ MongoDB.prototype.has = async function (key) {
3141
3382
  const exists = await this.exists(key);
3142
3383
  return exists > 0;
3143
3384
  } catch (error) {
3144
- $.log.error(`[MongoDB] 检查键是否存在失败: ${error.message}`);
3385
+ this.logger('error', `检查键是否存在失败: ${error.message}`);
3145
3386
  throw error;
3146
3387
  }
3147
3388
  };
@@ -3149,6 +3390,11 @@ MongoDB.prototype.has = async function (key) {
3149
3390
  MongoDB.prototype.exists = async function (key) {
3150
3391
  await this._ensureConnected();
3151
3392
  try {
3393
+ // 参数验证
3394
+ if (!key) {
3395
+ throw new TypeError('key必须是非空字符串或非空字符串数组');
3396
+ }
3397
+
3152
3398
  // 检查单个键的情况
3153
3399
  if (typeof key === 'string') {
3154
3400
  const result = await this.db.collection(this.table).findOne({
@@ -3165,7 +3411,7 @@ MongoDB.prototype.exists = async function (key) {
3165
3411
  // 验证数组中的每个元素是否都是非空字符串
3166
3412
  for (const k of key) {
3167
3413
  if (!k || typeof k !== 'string') {
3168
- throw new Error('key must be a non-empty string or array of non-empty strings');
3414
+ throw new TypeError('key数组中的每个元素必须是非空字符串');
3169
3415
  }
3170
3416
  }
3171
3417
 
@@ -3177,10 +3423,10 @@ MongoDB.prototype.exists = async function (key) {
3177
3423
  const count = await this.db.collection(this.table).countDocuments(filter);
3178
3424
  return count;
3179
3425
  } else {
3180
- throw new Error('key must be a non-empty string or array of non-empty strings');
3426
+ throw new TypeError('key必须是非空字符串或非空字符串数组');
3181
3427
  }
3182
3428
  } catch (error) {
3183
- $.log.error(`[MongoDB] 检查键是否存在失败: ${error.message}`);
3429
+ this.logger('error', `检查键是否存在失败: ${error.message}`);
3184
3430
  throw error;
3185
3431
  }
3186
3432
  };
@@ -3191,44 +3437,41 @@ MongoDB.prototype.exists = async function (key) {
3191
3437
  * @return {Promise<Boolean>} 是否删除成功
3192
3438
  */
3193
3439
  MongoDB.prototype.del = async function (key) {
3194
- await this._ensureConnected();
3195
- try {
3196
- // 键名必须是非空字符串或非空字符串数组
3197
- if (!key) {
3198
- $.log.error('[MongoDB] 参数错误: key必须是非空字符串或非空字符串数组');
3199
- return false;
3200
- }
3440
+ // 参数验证
3441
+ if (!key) {
3442
+ throw new TypeError('key必须是非空字符串或非空字符串数组');
3443
+ }
3201
3444
 
3202
- // 如果是单个键,验证是否为非空字符串
3203
- if (typeof key === 'string') {
3204
- if (!key) {
3205
- $.log.error('[MongoDB] 参数错误: key必须是非空字符串');
3206
- return false;
3207
- }
3445
+ // 如果是单个键,验证是否为非空字符串
3446
+ if (typeof key === 'string') {
3447
+ if (!key) {
3448
+ throw new TypeError('key必须是非空字符串');
3208
3449
  }
3209
- // 如果是数组,验证每个元素是否为非空字符串
3210
- else if (Array.isArray(key)) {
3211
- for (const k of key) {
3212
- if (!k || typeof k !== 'string') {
3213
- $.log.error('[MongoDB] 参数错误: key必须是非空字符串或非空字符串数组');
3214
- return false;
3215
- }
3450
+ }
3451
+ // 如果是数组,验证每个元素是否为非空字符串
3452
+ else if (Array.isArray(key)) {
3453
+ for (const k of key) {
3454
+ if (!k || typeof k !== 'string') {
3455
+ throw new TypeError('key必须是非空字符串或非空字符串数组');
3216
3456
  }
3217
- } else {
3218
- $.log.error('[MongoDB] 参数错误: key必须是非空字符串或非空字符串数组');
3219
- return false;
3220
3457
  }
3458
+ } else {
3459
+ throw new TypeError('key必须是非空字符串或非空字符串数组');
3460
+ }
3461
+
3462
+ await this._ensureConnected();
3463
+ try {
3221
3464
 
3222
3465
  // 触发前置事件,允许修改或阻止操作
3223
3466
  const beforeEventData = {
3224
3467
  key,
3225
3468
  cancel: false
3226
3469
  };
3227
- this.emit('del_before', beforeEventData);
3470
+ this.emit('del:before', beforeEventData);
3228
3471
 
3229
3472
  // 如果事件处理器标记为取消,则返回false
3230
3473
  if (beforeEventData.cancel) {
3231
- $.log.debug(`[MongoDB] del操作被事件处理器取消 [${key}]`);
3474
+ this.logger('debug', `del操作被事件处理器取消 [${key}]`);
3232
3475
  return false;
3233
3476
  }
3234
3477
 
@@ -3265,7 +3508,7 @@ MongoDB.prototype.del = async function (key) {
3265
3508
  }
3266
3509
 
3267
3510
  // 触发后置事件
3268
- this.emit('del_after', {
3511
+ this.emit('del:after', {
3269
3512
  key: finalKey,
3270
3513
  success,
3271
3514
  deleted
@@ -3274,11 +3517,11 @@ MongoDB.prototype.del = async function (key) {
3274
3517
  return success;
3275
3518
  } catch (error) {
3276
3519
  // 触发错误事件
3277
- this.emit('del_error', {
3520
+ this.emit('del:error', {
3278
3521
  key,
3279
3522
  error: error
3280
3523
  });
3281
- $.log.error('[MongoDB] 删除缓存失败:', error);
3524
+ this.logger('error', '删除缓存失败:', error);
3282
3525
  return false;
3283
3526
  }
3284
3527
  };
@@ -3300,11 +3543,11 @@ MongoDB.prototype.add = async function (key, value, seconds) {
3300
3543
  ttl: seconds,
3301
3544
  cancel: false
3302
3545
  };
3303
- this.emit('add_before', beforeEventData);
3546
+ this.emit('add:before', beforeEventData);
3304
3547
 
3305
3548
  // 如果事件处理器标记为取消,则返回false
3306
3549
  if (beforeEventData.cancel) {
3307
- $.log.debug(`[MongoDB] add操作被事件处理器取消 [${key}]`);
3550
+ this.logger('debug', `add操作被事件处理器取消 [${key}]`);
3308
3551
  return false;
3309
3552
  }
3310
3553
 
@@ -3321,7 +3564,7 @@ MongoDB.prototype.add = async function (key, value, seconds) {
3321
3564
  });
3322
3565
  if (exists) {
3323
3566
  // 键已存在时触发后置事件,但返回false
3324
- this.emit('add_after', {
3567
+ this.emit('add:after', {
3325
3568
  key: finalKey,
3326
3569
  value: finalValue,
3327
3570
  ttl: finalSeconds,
@@ -3346,7 +3589,7 @@ MongoDB.prototype.add = async function (key, value, seconds) {
3346
3589
  const success = result.acknowledged;
3347
3590
 
3348
3591
  // 触发后置事件
3349
- this.emit('add_after', {
3592
+ this.emit('add:after', {
3350
3593
  key: finalKey,
3351
3594
  value: finalValue,
3352
3595
  ttl: finalSeconds,
@@ -3356,13 +3599,13 @@ MongoDB.prototype.add = async function (key, value, seconds) {
3356
3599
  return success;
3357
3600
  } catch (error) {
3358
3601
  // 触发错误事件
3359
- this.emit('add_error', {
3602
+ this.emit('add:error', {
3360
3603
  key,
3361
3604
  value,
3362
3605
  ttl: seconds,
3363
3606
  error
3364
3607
  });
3365
- $.log.error(`[MongoDB] 添加键值失败: ${error.message}`);
3608
+ this.logger('error', `添加键值失败: ${error.message}`);
3366
3609
  return false;
3367
3610
  }
3368
3611
  };
@@ -3378,7 +3621,7 @@ MongoDB.prototype.set = async function (key, value, seconds) {
3378
3621
  try {
3379
3622
  // 键名必须是非空字符串
3380
3623
  if (!key || typeof key !== 'string') {
3381
- $.log.error('[MongoDB] 参数错误: key必须是非空字符串');
3624
+ this.logger('error', '参数错误: key必须是非空字符串');
3382
3625
  return false;
3383
3626
  }
3384
3627
 
@@ -3389,11 +3632,11 @@ MongoDB.prototype.set = async function (key, value, seconds) {
3389
3632
  ttl: seconds,
3390
3633
  cancel: false
3391
3634
  };
3392
- this.emit('set_before', beforeEventData);
3635
+ this.emit('set:before', beforeEventData);
3393
3636
 
3394
3637
  // 如果事件处理器标记为取消,则返回false
3395
3638
  if (beforeEventData.cancel) {
3396
- $.log.debug(`[MongoDB] set操作被事件处理器取消 [${key}]`);
3639
+ this.logger('debug', `set操作被事件处理器取消 [${key}]`);
3397
3640
  return false;
3398
3641
  }
3399
3642
 
@@ -3432,7 +3675,7 @@ MongoDB.prototype.set = async function (key, value, seconds) {
3432
3675
  );
3433
3676
 
3434
3677
  // 触发后置事件
3435
- this.emit('set_after', {
3678
+ this.emit('set:after', {
3436
3679
  key: finalKey,
3437
3680
  value: finalValue,
3438
3681
  ttl: finalSeconds,
@@ -3442,13 +3685,13 @@ MongoDB.prototype.set = async function (key, value, seconds) {
3442
3685
  return result.acknowledged;
3443
3686
  } catch (error) {
3444
3687
  // 触发错误事件
3445
- this.emit('set_error', {
3688
+ this.emit('set:error', {
3446
3689
  key,
3447
3690
  value,
3448
3691
  ttl: seconds,
3449
3692
  error
3450
3693
  });
3451
- $.log.error(`[MongoDB] 设置键值失败: ${error.message}`);
3694
+ this.logger('error', `设置键值失败: ${error.message}`);
3452
3695
  return false;
3453
3696
  }
3454
3697
  };
@@ -3462,7 +3705,7 @@ MongoDB.prototype.addList = async function (list) {
3462
3705
  await this._ensureConnected();
3463
3706
  try {
3464
3707
  // 触发前置事件
3465
- this.emit('addList_before', {
3708
+ this.emit('addList:before', {
3466
3709
  table: this.table,
3467
3710
  data: list
3468
3711
  });
@@ -3471,7 +3714,7 @@ MongoDB.prototype.addList = async function (list) {
3471
3714
  const result = await this.db.collection(this.table).insertMany(list);
3472
3715
 
3473
3716
  // 触发后置事件
3474
- this.emit('addList_after', {
3717
+ this.emit('addList:after', {
3475
3718
  table: this.table,
3476
3719
  data: list,
3477
3720
  result
@@ -3480,7 +3723,7 @@ MongoDB.prototype.addList = async function (list) {
3480
3723
  return result;
3481
3724
  } catch (error) {
3482
3725
  // 触发错误事件
3483
- this.emit('addList_error', {
3726
+ this.emit('addList:error', {
3484
3727
  table: this.table,
3485
3728
  data: list,
3486
3729
  error
@@ -3503,7 +3746,7 @@ MongoDB.prototype.delete = async function (query) {
3503
3746
  } : query;
3504
3747
 
3505
3748
  // 触发前置事件
3506
- this.emit('delete_before', {
3749
+ this.emit('delete:before', {
3507
3750
  table: this.table,
3508
3751
  query: safeQuery
3509
3752
  });
@@ -3512,7 +3755,7 @@ MongoDB.prototype.delete = async function (query) {
3512
3755
  const result = await this.db.collection(this.table).deleteMany(safeQuery);
3513
3756
 
3514
3757
  // 触发后置事件
3515
- this.emit('delete_after', {
3758
+ this.emit('delete:after', {
3516
3759
  table: this.table,
3517
3760
  query: safeQuery,
3518
3761
  result
@@ -3521,7 +3764,7 @@ MongoDB.prototype.delete = async function (query) {
3521
3764
  return result;
3522
3765
  } catch (error) {
3523
3766
  // 触发错误事件
3524
- this.emit('delete_error', {
3767
+ this.emit('delete:error', {
3525
3768
  table: this.table,
3526
3769
  query,
3527
3770
  error
@@ -3568,7 +3811,7 @@ MongoDB.prototype.setting = async function (query, body, options = {}) {
3568
3811
  }, options);
3569
3812
 
3570
3813
  // 触发前置事件
3571
- this.emit('setting_before', {
3814
+ this.emit('setting:before', {
3572
3815
  table: this.table,
3573
3816
  query: safeQuery,
3574
3817
  update: updateBody,
@@ -3579,7 +3822,7 @@ MongoDB.prototype.setting = async function (query, body, options = {}) {
3579
3822
  const result = await this.db.collection(this.table).updateMany(safeQuery, updateBody, updateOptions);
3580
3823
 
3581
3824
  // 触发后置事件
3582
- this.emit('setting_after', {
3825
+ this.emit('setting:after', {
3583
3826
  table: this.table,
3584
3827
  query: safeQuery,
3585
3828
  update: updateBody,
@@ -3591,7 +3834,7 @@ MongoDB.prototype.setting = async function (query, body, options = {}) {
3591
3834
  return typeof query === 'string' ? result.modifiedCount > 0 : result;
3592
3835
  } catch (error) {
3593
3836
  // 触发错误事件
3594
- this.emit('setting_error', {
3837
+ this.emit('setting:error', {
3595
3838
  table: this.table,
3596
3839
  query,
3597
3840
  update: body,
@@ -3618,7 +3861,7 @@ MongoDB.prototype.find = async function (query, options = {}) {
3618
3861
  const cursor = this.db.collection(this.table).find(safeQuery, options);
3619
3862
  return await cursor.toArray();
3620
3863
  } catch (error) {
3621
- $.log.error('[MongoDB] 查询失败:', error);
3864
+ this.logger('error', '查询失败:', error);
3622
3865
  return [];
3623
3866
  }
3624
3867
  };
@@ -3635,7 +3878,7 @@ MongoDB.prototype.count = async function (query = {}) {
3635
3878
  const safeQuery = this._sanitizeQuery(query);
3636
3879
  return await this.db.collection(this.table).countDocuments(safeQuery);
3637
3880
  } catch (error) {
3638
- $.log.error('[MongoDB] 计算文档数量失败:', error);
3881
+ this.logger('error', '计算文档数量失败:', error);
3639
3882
  return 0;
3640
3883
  }
3641
3884
  };
@@ -3654,7 +3897,7 @@ MongoDB.prototype._sanitizeQuery = function (query) {
3654
3897
  // 防止NoSQL注入,如 {$ne: null} 等操作符注入
3655
3898
  if (key.startsWith('$') && typeof key === 'string' && !Array.isArray(value) && typeof value === 'object' &&
3656
3899
  value !== null) {
3657
- $.log.warn('[MongoDB] 检测到可能的操作符注入尝试:', key);
3900
+ this.logger('warn', '检测到可能的操作符注入尝试:', key);
3658
3901
  continue;
3659
3902
  }
3660
3903
  sanitized[key] = value;
@@ -3674,7 +3917,7 @@ MongoDB.prototype.startTransaction = async function () {
3674
3917
  session.startTransaction();
3675
3918
  return session;
3676
3919
  } catch (error) {
3677
- $.log.error('[MongoDB] [startTransaction] 启动事务失败:', error);
3920
+ this.logger('error', '[startTransaction] 启动事务失败:', error);
3678
3921
  throw error;
3679
3922
  }
3680
3923
  };
@@ -3689,7 +3932,7 @@ MongoDB.prototype.commitTransaction = async function (session) {
3689
3932
  await session.commitTransaction();
3690
3933
  await session.endSession();
3691
3934
  } catch (error) {
3692
- $.log.error('[MongoDB] [commitTransaction] 提交事务失败:', error);
3935
+ this.logger('error', '[commitTransaction] 提交事务失败:', error);
3693
3936
  throw error;
3694
3937
  }
3695
3938
  };
@@ -3704,7 +3947,7 @@ MongoDB.prototype.rollbackTransaction = async function (session) {
3704
3947
  await session.abortTransaction();
3705
3948
  await session.endSession();
3706
3949
  } catch (error) {
3707
- $.log.error('[MongoDB] [rollbackTransaction] 回滚事务失败:', error);
3950
+ this.logger('error', '[rollbackTransaction] 回滚事务失败:', error);
3708
3951
  throw error;
3709
3952
  }
3710
3953
  };
@@ -3730,7 +3973,7 @@ if (!$.pool.mongoDB) {
3730
3973
  * @param {Object} config 配置参数
3731
3974
  * @return {Object} 返回一个MongoDB类实例
3732
3975
  */
3733
- function mongodb_admin(scope, config) {
3976
+ function mongodbAdmin(scope, config) {
3734
3977
  if (!scope) {
3735
3978
  scope = 'sys';
3736
3979
  }
@@ -3752,4 +3995,4 @@ function mongodb_admin(scope, config) {
3752
3995
  /**
3753
3996
  * @module 导出MongoDB管理器
3754
3997
  */
3755
- exports.mongodb_admin = mongodb_admin;
3998
+ exports.mongodbAdmin = mongodbAdmin;