mm_mongodb 1.5.0 → 1.5.2

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