koishi-plugin-group-verification 1.0.19 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -17,8 +17,8 @@ export interface GroupVerificationConfig {
17
17
  reminderMessage: string;
18
18
  createdBy: string;
19
19
  updatedBy: string;
20
- createdAt: Date;
21
- updatedAt: Date;
20
+ createdAt: string | Date;
21
+ updatedAt: string | Date;
22
22
  }
23
23
  export interface GroupVerificationStats {
24
24
  id: number;
@@ -26,7 +26,7 @@ export interface GroupVerificationStats {
26
26
  autoApproved: number;
27
27
  manuallyApproved: number;
28
28
  rejected: number;
29
- lastUpdated: Date;
29
+ lastUpdated: string | Date;
30
30
  }
31
31
  export interface PendingVerification {
32
32
  id: number;
@@ -34,7 +34,7 @@ export interface PendingVerification {
34
34
  userId: string;
35
35
  userName: string;
36
36
  requestMessage: string;
37
- applyTime: Date;
37
+ applyTime: string | Date;
38
38
  }
39
39
  export interface Config {
40
40
  defaultReminderMessage?: string;
package/lib/index.js CHANGED
@@ -299,8 +299,8 @@ function apply(ctx, config) {
299
299
  reminderMessage: "string",
300
300
  createdBy: "string",
301
301
  updatedBy: "string",
302
- createdAt: "date",
303
- updatedAt: "date"
302
+ createdAt: "string",
303
+ updatedAt: "string"
304
304
  }, {
305
305
  primary: "id",
306
306
  autoInc: true
@@ -316,7 +316,9 @@ function apply(ctx, config) {
316
316
  autoApproved: "integer",
317
317
  manuallyApproved: "integer",
318
318
  rejected: "integer",
319
- lastUpdated: "date"
319
+ // store as string (ISO timestamp) to preserve full date+time;
320
+ // Koishi `date` type truncates to day which leads to 00:00:00.
321
+ lastUpdated: "string"
320
322
  }, {
321
323
  primary: "id",
322
324
  autoInc: true
@@ -327,7 +329,8 @@ function apply(ctx, config) {
327
329
  userId: "string",
328
330
  userName: "string",
329
331
  requestMessage: "string",
330
- applyTime: "date"
332
+ // record full timestamp as string to keep time component
333
+ applyTime: "string"
331
334
  }, {
332
335
  primary: "id",
333
336
  autoInc: true
@@ -390,29 +393,30 @@ function apply(ctx, config) {
390
393
  logger.info(`用户 ${userId} 被手动邀请加入群 ${groupId},手动批准统计已更新`);
391
394
  }
392
395
  });
393
- async function handleFailedVerification(ctx2, session, config2) {
394
- const guildId = session.guildId;
396
+ async function handleFailedVerification(ctx2, session, config2, matchedCount, requiredThreshold) {
397
+ const guildId = (session.guildId || session.channelId || "").toString().trim();
395
398
  const userId = session.userId;
396
399
  const username = session.username || "未知用户";
397
400
  const message = session.content || "";
401
+ logger.info(`处理失败验证 guild=${guildId} user=${userId} msg="${message}" matched=${matchedCount} threshold=${requiredThreshold}`);
402
+ if (matchedCount === void 0 || requiredThreshold === void 0) {
403
+ const result = await verifyApplication(config2, message, session);
404
+ matchedCount = result.matchedCount;
405
+ requiredThreshold = result.requiredThreshold;
406
+ }
398
407
  let groupName = "未知群组";
399
408
  try {
400
409
  const guild = await session.bot.getGuild(guildId);
401
410
  groupName = guild.name || groupName;
402
411
  } catch (error) {
403
412
  }
404
- const { matchedCount, requiredThreshold } = await verifyApplication(config2, message, session);
405
413
  await ctx2.database.create("group_verification_pending", {
406
414
  groupId: guildId,
407
415
  userId,
408
416
  userName: username,
409
417
  requestMessage: message,
410
- applyTime: /* @__PURE__ */ new Date()
418
+ applyTime: (/* @__PURE__ */ new Date()).toISOString()
411
419
  });
412
- if (!guildId) {
413
- logger.warn("handleFailedVerification 收到无效 guildId,已放弃发送");
414
- return;
415
- }
416
420
  if (!config2.reminderEnabled || !config2.reminderMessage || config2.reminderMessage === "") {
417
421
  logger.info(`群 ${guildId} 的提醒消息已被禁用,跳过发送`);
418
422
  return;
@@ -428,7 +432,7 @@ function apply(ctx, config) {
428
432
  const stats = existingStats[0];
429
433
  await ctx.database.set("group_verification_stats", { id: stats.id }, {
430
434
  [action]: stats[action] + 1,
431
- lastUpdated: /* @__PURE__ */ new Date()
435
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
432
436
  });
433
437
  } else {
434
438
  await ctx.database.create("group_verification_stats", {
@@ -436,7 +440,7 @@ function apply(ctx, config) {
436
440
  autoApproved: action === "autoApproved" ? 1 : 0,
437
441
  manuallyApproved: action === "manuallyApproved" ? 1 : 0,
438
442
  rejected: action === "rejected" ? 1 : 0,
439
- lastUpdated: /* @__PURE__ */ new Date()
443
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
440
444
  });
441
445
  }
442
446
  await syncTotalStats(ctx);
@@ -533,8 +537,8 @@ ${debugInfo}`];
533
537
  remove: flags.remove || options.remove
534
538
  };
535
539
  logger.info(`合并后options: ${JSON.stringify(cleanedOptions, null, 2)}`);
536
- if ((cleanedOptions.query || cleanedOptions.remove) && (parsedKeywords.length > 0 || cleanedOptions.method !== void 0 || cleanedOptions.threshold !== void 0 || cleanedOptions.message !== void 0 || cleanedOptions.enableMessage || cleanedOptions.disableMessage || cleanedOptions.groupId !== void 0)) {
537
- return "参数冲突:-? 或 -r 不能与其他参数或关键词一起使用";
540
+ if ((cleanedOptions.query || cleanedOptions.remove) && (parsedKeywords.length > 0 || cleanedOptions.method !== void 0 || cleanedOptions.threshold !== void 0 || cleanedOptions.message !== void 0 || cleanedOptions.enableMessage || cleanedOptions.disableMessage)) {
541
+ return "参数冲突:-? 或 -r 不能与其他参数或关键词一起使用(仅可搭配 -i)";
538
542
  }
539
543
  const hasRealMessageParam = cleanedOptions.message !== void 0;
540
544
  const hasRealEnableMessageParam = cleanedOptions.enableMessage === true;
@@ -712,7 +716,7 @@ gvc -r # 删除配置`;
712
716
  await ctx.database.set("group_verification_config", { id: existingConfig.id }, {
713
717
  reviewParameters,
714
718
  updatedBy: session.username || session.userId,
715
- updatedAt: /* @__PURE__ */ new Date()
719
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
716
720
  });
717
721
  logger.info(`已更新数据库阈值为: ${reviewParameters}`);
718
722
  } else {
@@ -731,17 +735,20 @@ gvc -r # 删除配置`;
731
735
  reminderEnabled,
732
736
  reminderMessage,
733
737
  updatedBy: session.username || session.userId,
734
- updatedAt: /* @__PURE__ */ new Date()
738
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
735
739
  };
736
740
  if (existingConfig) {
737
- await ctx.database.set("group_verification_config", { id: existingConfig.id }, dbData);
741
+ await ctx.database.set("group_verification_config", { id: existingConfig.id }, {
742
+ ...dbData,
743
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
744
+ });
738
745
  logger.info(`更新配置成功 - 审核方式: ${reviewMethod}, 阈值: ${reviewParameters}`);
739
746
  } else {
740
747
  await ctx.database.create("group_verification_config", {
741
748
  groupId: targetGroupId,
742
749
  ...dbData,
743
750
  createdBy: session.username || session.userId,
744
- createdAt: /* @__PURE__ */ new Date()
751
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
745
752
  });
746
753
  logger.info(`创建配置成功 - 审核方式: ${reviewMethod}, 阈值: ${reviewParameters}`);
747
754
  }
@@ -1047,6 +1054,36 @@ gvc -r # 删除配置`;
1047
1054
  - 私聊时必须指定群号(-i参数)`;
1048
1055
  });
1049
1056
  ctx.on("ready", async () => {
1057
+ try {
1058
+ const configs = await ctx.database.get("group_verification_config", {});
1059
+ for (const cfg of configs) {
1060
+ const updates = {};
1061
+ if (cfg.createdAt instanceof Date) updates.createdAt = cfg.createdAt.toISOString();
1062
+ if (cfg.updatedAt instanceof Date) updates.updatedAt = cfg.updatedAt.toISOString();
1063
+ if (Object.keys(updates).length) {
1064
+ await ctx.database.set("group_verification_config", { id: cfg.id }, updates);
1065
+ }
1066
+ }
1067
+ const stats = await ctx.database.get("group_verification_stats", {});
1068
+ for (const st of stats) {
1069
+ const updates = {};
1070
+ if (st.lastUpdated instanceof Date) updates.lastUpdated = st.lastUpdated.toISOString();
1071
+ if (Object.keys(updates).length) {
1072
+ await ctx.database.set("group_verification_stats", { id: st.id }, updates);
1073
+ }
1074
+ }
1075
+ const pendings = await ctx.database.get("group_verification_pending", {});
1076
+ for (const p of pendings) {
1077
+ const updates = {};
1078
+ if (p.applyTime instanceof Date) updates.applyTime = p.applyTime.toISOString();
1079
+ if (Object.keys(updates).length) {
1080
+ await ctx.database.set("group_verification_pending", { id: p.id }, updates);
1081
+ }
1082
+ }
1083
+ logger.info("旧版日期字段迁移完成");
1084
+ } catch (e) {
1085
+ logger.warn("迁移旧日期字段时出错", e);
1086
+ }
1050
1087
  const totalStats = await ctx.database.get("group_verification_stats", { groupId: "TOTAL" });
1051
1088
  if (totalStats.length === 0) {
1052
1089
  await ctx.database.create("group_verification_stats", {
@@ -1054,7 +1091,7 @@ gvc -r # 删除配置`;
1054
1091
  autoApproved: 0,
1055
1092
  manuallyApproved: 0,
1056
1093
  rejected: 0,
1057
- lastUpdated: /* @__PURE__ */ new Date()
1094
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
1058
1095
  });
1059
1096
  logger.info("已创建总计统计行");
1060
1097
  } else {
@@ -1103,7 +1140,7 @@ gvc -r # 删除配置`;
1103
1140
  autoApproved: totalAutoApproved,
1104
1141
  manuallyApproved: totalManuallyApproved,
1105
1142
  rejected: totalRejected,
1106
- lastUpdated: /* @__PURE__ */ new Date()
1143
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
1107
1144
  });
1108
1145
  logger.info(`总计统计已同步: 自动批准${totalAutoApproved}, 手动批准${totalManuallyApproved}, 拒绝${totalRejected}`);
1109
1146
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-group-verification",
3
3
  "description": "[WIP] Koishi 群组加群验证插件,支持多关键词匹配审核、多种审核方式和详细统计功能(开发中)",
4
- "version": "1.0.19",
4
+ "version": "1.0.21",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
package/readme.md CHANGED
@@ -48,6 +48,9 @@ group-verify.config -r
48
48
 
49
49
  # 指定群号配置
50
50
  group-verify.config -i 123456789 关键词1,关键词2 -m 1 -t 1
51
+
52
+ > **提示**: `-?`(查询)和 `-r`(删除)仍然与所有其它参数 / 关键字互斥,
53
+ > 但可以和 `-i` 组合使用,例如 `gvc -i 123 -?` 或 `gvc -i 123 -r`。这样便于在私聊环境下查询或删除指定群的设置。
51
54
  ```
52
55
 
53
56
  ### 审核命令
@@ -106,6 +109,12 @@ group-verify.stats total
106
109
  - `-nomsg` - 禁用提醒消息功能
107
110
  - 不带参数的 `-msg` 会显示帮助信息
108
111
 
112
+ ### 提醒消息变量
113
+
114
+ ### 其他注意事项
115
+
116
+ - 统计数据的 **最后更新时间** 使用完整的日期+时间存储,升级到最新版后若看到 `00:00:00`,请手动重建或清除旧的统计记录以便记录最新时间。
117
+
109
118
  ### 提醒消息变量
110
119
  ```
111
120
  {user} - 用户名
package/src/index.ts CHANGED
@@ -25,8 +25,8 @@ export interface GroupVerificationConfig {
25
25
  reminderMessage: string
26
26
  createdBy: string
27
27
  updatedBy: string
28
- createdAt: Date
29
- updatedAt: Date
28
+ createdAt: string | Date
29
+ updatedAt: string | Date
30
30
  }
31
31
 
32
32
  // 群组统计信息表
@@ -36,7 +36,7 @@ export interface GroupVerificationStats {
36
36
  autoApproved: number
37
37
  manuallyApproved: number
38
38
  rejected: number
39
- lastUpdated: Date
39
+ lastUpdated: string | Date
40
40
  }
41
41
 
42
42
  // 待审核申请表
@@ -46,7 +46,7 @@ export interface PendingVerification {
46
46
  userId: string
47
47
  userName: string
48
48
  requestMessage: string
49
- applyTime: Date
49
+ applyTime: string | Date
50
50
  }
51
51
 
52
52
  export interface Config {
@@ -417,8 +417,8 @@ export function apply(ctx: Context, config: Config) {
417
417
  reminderMessage: 'string',
418
418
  createdBy: 'string',
419
419
  updatedBy: 'string',
420
- createdAt: 'date',
421
- updatedAt: 'date'
420
+ createdAt: 'string',
421
+ updatedAt: 'string'
422
422
  }, {
423
423
  primary: 'id',
424
424
  autoInc: true
@@ -442,7 +442,9 @@ export function apply(ctx: Context, config: Config) {
442
442
  autoApproved: 'integer',
443
443
  manuallyApproved: 'integer',
444
444
  rejected: 'integer',
445
- lastUpdated: 'date'
445
+ // store as string (ISO timestamp) to preserve full date+time;
446
+ // Koishi `date` type truncates to day which leads to 00:00:00.
447
+ lastUpdated: 'string'
446
448
  }, {
447
449
  primary: 'id',
448
450
  autoInc: true
@@ -454,7 +456,8 @@ export function apply(ctx: Context, config: Config) {
454
456
  userId: 'string',
455
457
  userName: 'string',
456
458
  requestMessage: 'string',
457
- applyTime: 'date'
459
+ // record full timestamp as string to keep time component
460
+ applyTime: 'string'
458
461
  }, {
459
462
  primary: 'id',
460
463
  autoInc: true
@@ -546,12 +549,27 @@ export function apply(ctx: Context, config: Config) {
546
549
  })
547
550
 
548
551
  // 处理验证失败的情况
549
- async function handleFailedVerification(ctx: Context, session: any, config: GroupVerificationConfig) {
550
- const guildId = session.guildId
552
+ // 处理验证失败的情况并发送提醒消息
553
+ // matchedCount/requiredThreshold 可选,为空时内部重新计算(兼容旧调用)
554
+ async function handleFailedVerification(
555
+ ctx: Context,
556
+ session: any,
557
+ config: GroupVerificationConfig,
558
+ matchedCount?: number,
559
+ requiredThreshold?: string
560
+ ) {
561
+ const guildId = (session.guildId || session.channelId || '').toString().trim();
551
562
  const userId = session.userId
552
563
  const username = session.username || '未知用户'
553
564
  const message = session.content || ''
554
-
565
+ logger.info(`处理失败验证 guild=${guildId} user=${userId} msg="${message}" matched=${matchedCount} threshold=${requiredThreshold}`)
566
+ // 如果未传入匹配信息,则重新计算一次(老调用)
567
+ if (matchedCount === undefined || requiredThreshold === undefined) {
568
+ const result = await verifyApplication(config, message, session)
569
+ matchedCount = result.matchedCount
570
+ requiredThreshold = result.requiredThreshold
571
+ }
572
+
555
573
  // 获取群信息
556
574
  let groupName = '未知群组'
557
575
  try {
@@ -560,30 +578,21 @@ export function apply(ctx: Context, config: Config) {
560
578
  } catch (error) {
561
579
  // 无法获取群名称时使用默认值
562
580
  }
563
-
564
- // 执行验证获取详细信息
565
- const { matchedCount, requiredThreshold } = await verifyApplication(config, message, session)
566
-
581
+
567
582
  // 将申请加入待审核列表
568
583
  await ctx.database.create('group_verification_pending', {
569
584
  groupId: guildId,
570
585
  userId: userId,
571
586
  userName: username,
572
587
  requestMessage: message,
573
- applyTime: new Date()
588
+ applyTime: new Date().toISOString()
574
589
  })
575
-
576
- // 如果 guildId 不合法,跳过
577
- if (!guildId) {
578
- logger.warn('handleFailedVerification 收到无效 guildId,已放弃发送')
579
- return
580
- }
581
590
  // 如果提醒消息被禁用,直接返回
582
591
  if (!config.reminderEnabled || !config.reminderMessage || config.reminderMessage === '') {
583
592
  logger.info(`群 ${guildId} 的提醒消息已被禁用,跳过发送`)
584
593
  return
585
594
  }
586
-
595
+
587
596
  // 替换提醒消息中的变量
588
597
  let reminderMsg = config.reminderMessage
589
598
  reminderMsg = reminderMsg
@@ -592,9 +601,9 @@ export function apply(ctx: Context, config: Config) {
592
601
  .replace(/{group}/g, guildId)
593
602
  .replace(/{gname}/g, groupName)
594
603
  .replace(/{question}/g, message)
595
- .replace(/{answer}/g, matchedCount.toString())
596
- .replace(/{threshold}/g, requiredThreshold)
597
-
604
+ .replace(/{answer}/g, matchedCount!.toString())
605
+ .replace(/{threshold}/g, requiredThreshold!)
606
+
598
607
  // 发送提醒消息到群内
599
608
  await ctx.broadcast([guildId], reminderMsg)
600
609
  }
@@ -609,7 +618,7 @@ export function apply(ctx: Context, config: Config) {
609
618
  const stats = existingStats[0]
610
619
  await ctx.database.set('group_verification_stats', { id: stats.id }, {
611
620
  [action]: stats[action] + 1,
612
- lastUpdated: new Date()
621
+ lastUpdated: new Date().toISOString()
613
622
  })
614
623
  } else {
615
624
  await ctx.database.create('group_verification_stats', {
@@ -617,7 +626,7 @@ export function apply(ctx: Context, config: Config) {
617
626
  autoApproved: action === 'autoApproved' ? 1 : 0,
618
627
  manuallyApproved: action === 'manuallyApproved' ? 1 : 0,
619
628
  rejected: action === 'rejected' ? 1 : 0,
620
- lastUpdated: new Date()
629
+ lastUpdated: new Date().toISOString()
621
630
  })
622
631
  }
623
632
 
@@ -755,11 +764,11 @@ export function apply(ctx: Context, config: Config) {
755
764
  }
756
765
  logger.info(`合并后options: ${JSON.stringify(cleanedOptions, null, 2)}`)
757
766
 
758
- // 检查 -? 和 -r 的独占性
767
+ // 检查 -? 和 -r 的独占性;允许与 -i 并存
759
768
  if ((cleanedOptions.query || cleanedOptions.remove) &&
760
769
  (parsedKeywords.length > 0 || cleanedOptions.method !== undefined || cleanedOptions.threshold !== undefined ||
761
- cleanedOptions.message !== undefined || cleanedOptions.enableMessage || cleanedOptions.disableMessage || cleanedOptions.groupId !== undefined)) {
762
- return '参数冲突:-? 或 -r 不能与其他参数或关键词一起使用'
770
+ cleanedOptions.message !== undefined || cleanedOptions.enableMessage || cleanedOptions.disableMessage)) {
771
+ return '参数冲突:-? 或 -r 不能与其他参数或关键词一起使用(仅可搭配 -i)'
763
772
  }
764
773
 
765
774
  // 检查消息参数冲突
@@ -999,7 +1008,7 @@ gvc -r # 删除配置`
999
1008
  await ctx.database.set('group_verification_config', { id: existingConfig.id }, {
1000
1009
  reviewParameters: reviewParameters,
1001
1010
  updatedBy: session.username || session.userId,
1002
- updatedAt: new Date()
1011
+ updatedAt: new Date().toISOString()
1003
1012
  })
1004
1013
  logger.info(`已更新数据库阈值为: ${reviewParameters}`)
1005
1014
  } else {
@@ -1025,18 +1034,22 @@ gvc -r # 删除配置`
1025
1034
  reminderEnabled: reminderEnabled,
1026
1035
  reminderMessage: reminderMessage,
1027
1036
  updatedBy: session.username || session.userId,
1028
- updatedAt: new Date()
1037
+ updatedAt: new Date().toISOString()
1029
1038
  }
1030
1039
 
1031
1040
  if (existingConfig) {
1032
- await ctx.database.set('group_verification_config', { id: existingConfig.id }, dbData)
1041
+ // ensure timestamp strings for compatibility
1042
+ await ctx.database.set('group_verification_config', { id: existingConfig.id }, {
1043
+ ...dbData,
1044
+ updatedAt: new Date().toISOString(),
1045
+ })
1033
1046
  logger.info(`更新配置成功 - 审核方式: ${reviewMethod}, 阈值: ${reviewParameters}`)
1034
1047
  } else {
1035
1048
  await ctx.database.create('group_verification_config', {
1036
1049
  groupId: targetGroupId,
1037
1050
  ...dbData,
1038
1051
  createdBy: session.username || session.userId,
1039
- createdAt: new Date()
1052
+ createdAt: new Date().toISOString()
1040
1053
  })
1041
1054
  logger.info(`创建配置成功 - 审核方式: ${reviewMethod}, 阈值: ${reviewParameters}`)
1042
1055
  }
@@ -1419,6 +1432,38 @@ gvc -r # 删除配置`
1419
1432
 
1420
1433
  // 插件初始化时确保总计统计行存在
1421
1434
  ctx.on('ready', async () => {
1435
+ // 迁移:将旧版保留的 Date 对象字段转换为 ISO 字符串,以避免绑定错误
1436
+ try {
1437
+ const configs = await ctx.database.get('group_verification_config', {})
1438
+ for (const cfg of configs) {
1439
+ const updates: any = {}
1440
+ if (cfg.createdAt instanceof Date) updates.createdAt = cfg.createdAt.toISOString()
1441
+ if (cfg.updatedAt instanceof Date) updates.updatedAt = cfg.updatedAt.toISOString()
1442
+ if (Object.keys(updates).length) {
1443
+ await ctx.database.set('group_verification_config', { id: cfg.id }, updates)
1444
+ }
1445
+ }
1446
+ const stats = await ctx.database.get('group_verification_stats', {})
1447
+ for (const st of stats) {
1448
+ const updates: any = {}
1449
+ if (st.lastUpdated instanceof Date) updates.lastUpdated = st.lastUpdated.toISOString()
1450
+ if (Object.keys(updates).length) {
1451
+ await ctx.database.set('group_verification_stats', { id: st.id }, updates)
1452
+ }
1453
+ }
1454
+ const pendings = await ctx.database.get('group_verification_pending', {})
1455
+ for (const p of pendings) {
1456
+ const updates: any = {}
1457
+ if (p.applyTime instanceof Date) updates.applyTime = p.applyTime.toISOString()
1458
+ if (Object.keys(updates).length) {
1459
+ await ctx.database.set('group_verification_pending', { id: p.id }, updates)
1460
+ }
1461
+ }
1462
+ logger.info('旧版日期字段迁移完成')
1463
+ } catch (e) {
1464
+ logger.warn('迁移旧日期字段时出错', e)
1465
+ }
1466
+
1422
1467
  // 检查是否已存在总计行(groupId为'TOTAL')
1423
1468
  const totalStats = await ctx.database.get('group_verification_stats', { groupId: 'TOTAL' })
1424
1469
 
@@ -1429,7 +1474,7 @@ gvc -r # 删除配置`
1429
1474
  autoApproved: 0,
1430
1475
  manuallyApproved: 0,
1431
1476
  rejected: 0,
1432
- lastUpdated: new Date()
1477
+ lastUpdated: new Date().toISOString()
1433
1478
  })
1434
1479
  logger.info('已创建总计统计行')
1435
1480
  } else {
@@ -1495,7 +1540,7 @@ gvc -r # 删除配置`
1495
1540
  autoApproved: totalAutoApproved,
1496
1541
  manuallyApproved: totalManuallyApproved,
1497
1542
  rejected: totalRejected,
1498
- lastUpdated: new Date()
1543
+ lastUpdated: new Date().toISOString()
1499
1544
  })
1500
1545
 
1501
1546
  logger.info(`总计统计已同步: 自动批准${totalAutoApproved}, 手动批准${totalManuallyApproved}, 拒绝${totalRejected}`)