koishi-plugin-group-verification 1.0.10 → 1.0.12

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 (3) hide show
  1. package/lib/index.js +192 -63
  2. package/package.json +1 -1
  3. package/src/index.ts +226 -90
package/lib/index.js CHANGED
@@ -251,7 +251,15 @@ ${debugInfo}`];
251
251
  }
252
252
  __name(checkPermission, "checkPermission");
253
253
  const groupVerify = ctx.command("group-verify", "群组验证管理命令").alias("gv", "gverify");
254
- groupVerify.subcommand(".config [keywords:text]", "配置群组验证规则").alias("cfg", "配置", "conf", "设置").option("groupId", "-i <groupId> 指定群号").option("method", "-m <method> 审核方式 (0-3)").option("threshold", "-t <threshold> 阈值参数").option("message", "-msg <message> 自定义提醒消息").option("query", "-? 查询当前配置").option("remove", "-r 删除配置").action(async ({ session, options }, keywords) => {
254
+ groupVerify.subcommand(".config [keywords:text]", "配置群组验证规则").alias(
255
+ "gv.cfg",
256
+ "gverify.cfg",
257
+ "group-verify.cfg",
258
+ "gv.配置",
259
+ "gverify.配置",
260
+ "group-verify.配置",
261
+ "gvc"
262
+ ).option("groupId", "-i <groupId> 指定群号").option("method", "-m <method> 审核方式 (0-3)").option("threshold", "-t <threshold> 阈值参数").option("message", "-msg <message> 自定义提醒消息").option("query", "-? 查询当前配置").option("remove", "-r 删除配置").action(async ({ session, options }, keywords) => {
255
263
  const targetGroupId = options.groupId || session.guildId;
256
264
  const [hasPermission, errorMsg] = await checkPermission(session, targetGroupId);
257
265
  if (!hasPermission) {
@@ -373,91 +381,180 @@ ${debugInfo}`];
373
381
  return `已为群 ${targetGroupId} 创建验证配置`;
374
382
  }
375
383
  });
376
- groupVerify.subcommand(".approve <userId>", "同意用户加群申请").alias("accept", "同意", "appr", "通过").action(async ({ session }, userId) => {
377
- if (!await checkPermission(session)) {
378
- return "权限不足";
384
+ groupVerify.subcommand(".approve [userId]", "同意加群申请").alias(
385
+ "gv.accept",
386
+ "gverify.accept",
387
+ "group-verify.accept",
388
+ "gv.同意",
389
+ "gverify.同意",
390
+ "group-verify.同意",
391
+ "gva"
392
+ ).action(async ({ session }, userId) => {
393
+ const [hasPermission, errorMsg] = await checkPermission(session);
394
+ if (!hasPermission) {
395
+ return errorMsg || "权限不足";
379
396
  }
380
- if (!session.guildId) {
397
+ const groupId = session.guildId;
398
+ if (!groupId) {
381
399
  return "请在群聊中使用此命令";
382
400
  }
383
- if (!userId) {
384
- return "请提供用户ID";
401
+ if (!userId || userId.toLowerCase() === "all") {
402
+ if (userId?.toLowerCase() === "all") {
403
+ const pendingRequests2 = await ctx.database.get("group_verification_pending", { groupId });
404
+ if (pendingRequests2.length === 0) {
405
+ return "当前无待审核的加群申请";
406
+ }
407
+ let approvedCount = 0;
408
+ for (const request2 of pendingRequests2) {
409
+ try {
410
+ await ctx.database.remove("group_verification_pending", { id: request2.id });
411
+ await updateStats(groupId, "manuallyApproved");
412
+ approvedCount++;
413
+ } catch (error) {
414
+ logger.warn(`处理申请 ${request2.id} 时出错:`, error);
415
+ }
416
+ }
417
+ return `已处理 ${approvedCount} 个加群申请`;
418
+ } else {
419
+ const recentRequest = await ctx.database.get("group_verification_pending", { groupId }, ["id", "userId", "userName"]);
420
+ if (recentRequest.length === 0) {
421
+ return "当前无待审核的加群申请";
422
+ }
423
+ const request2 = recentRequest[0];
424
+ try {
425
+ await session.bot.handleGuildMemberRequest(request2.userId, true);
426
+ await ctx.database.remove("group_verification_pending", { id: request2.id });
427
+ await updateStats(groupId, "manuallyApproved");
428
+ return `已同意用户 ${request2.userName}(${request2.userId}) 的加群申请`;
429
+ } catch (error) {
430
+ return `处理申请时出错: ${error.message}`;
431
+ }
432
+ }
385
433
  }
386
- const pendingApplications = await ctx.database.get("group_verification_pending", {
387
- groupId: session.guildId,
434
+ const pendingRequests = await ctx.database.get("group_verification_pending", {
435
+ groupId,
388
436
  userId
389
437
  });
390
- if (pendingApplications.length === 0) {
438
+ if (pendingRequests.length === 0) {
391
439
  return `未找到用户 ${userId} 的待审核申请`;
392
440
  }
393
- const application = pendingApplications[0];
394
- await ctx.database.remove("group_verification_pending", { id: application.id });
395
- await updateStats(session.guildId, "manuallyApproved");
396
- return `已同意用户 ${application.userName}(${userId}) 的加群申请`;
441
+ const request = pendingRequests[0];
442
+ try {
443
+ await session.bot.handleGuildMemberRequest(request.userId, true);
444
+ await ctx.database.remove("group_verification_pending", { id: request.id });
445
+ await updateStats(groupId, "manuallyApproved");
446
+ return `已同意用户 ${request.userName}(${userId}) 的加群申请`;
447
+ } catch (error) {
448
+ return `处理申请时出错: ${error.message}`;
449
+ }
397
450
  });
398
- groupVerify.subcommand(".reject <userId>", "拒绝用户加群申请").alias("拒绝", "rej", "拒绝").action(async ({ session }, userId) => {
399
- if (!await checkPermission(session)) {
400
- return "权限不足";
451
+ groupVerify.subcommand(".reject [userId]", "拒绝加群申请").alias(
452
+ "gv.拒绝",
453
+ "gverify.拒绝",
454
+ "group-verify.拒绝",
455
+ "gv.rej",
456
+ "gverify.rej",
457
+ "group-verify.rej",
458
+ "gvr"
459
+ ).action(async ({ session }, userId) => {
460
+ const [hasPermission, errorMsg] = await checkPermission(session);
461
+ if (!hasPermission) {
462
+ return errorMsg || "权限不足";
401
463
  }
402
- if (!session.guildId) {
464
+ const groupId = session.guildId;
465
+ if (!groupId) {
403
466
  return "请在群聊中使用此命令";
404
467
  }
405
- if (!userId) {
406
- return "请提供用户ID";
468
+ if (!userId || userId.toLowerCase() === "all") {
469
+ if (userId?.toLowerCase() === "all") {
470
+ const pendingRequests2 = await ctx.database.get("group_verification_pending", { groupId });
471
+ if (pendingRequests2.length === 0) {
472
+ return "当前无待审核的加群申请";
473
+ }
474
+ let rejectedCount = 0;
475
+ for (const request2 of pendingRequests2) {
476
+ try {
477
+ await ctx.database.remove("group_verification_pending", { id: request2.id });
478
+ await updateStats(groupId, "rejected");
479
+ rejectedCount++;
480
+ } catch (error) {
481
+ logger.warn(`处理申请 ${request2.id} 时出错:`, error);
482
+ }
483
+ }
484
+ return `已拒绝 ${rejectedCount} 个加群申请`;
485
+ } else {
486
+ const recentRequest = await ctx.database.get("group_verification_pending", { groupId }, ["id", "userId", "userName"]);
487
+ if (recentRequest.length === 0) {
488
+ return "当前无待审核的加群申请";
489
+ }
490
+ const request2 = recentRequest[0];
491
+ try {
492
+ await ctx.database.remove("group_verification_pending", { id: request2.id });
493
+ await updateStats(groupId, "rejected");
494
+ return `已拒绝用户 ${request2.userName}(${request2.userId}) 的加群申请`;
495
+ } catch (error) {
496
+ return `处理申请时出错: ${error.message}`;
497
+ }
498
+ }
407
499
  }
408
- const pendingApplications = await ctx.database.get("group_verification_pending", {
409
- groupId: session.guildId,
500
+ const pendingRequests = await ctx.database.get("group_verification_pending", {
501
+ groupId,
410
502
  userId
411
503
  });
412
- if (pendingApplications.length === 0) {
504
+ if (pendingRequests.length === 0) {
413
505
  return `未找到用户 ${userId} 的待审核申请`;
414
506
  }
415
- const application = pendingApplications[0];
416
- await ctx.database.remove("group_verification_pending", { id: application.id });
417
- await updateStats(session.guildId, "rejected");
418
- return `已拒绝用户 ${application.userName}(${userId}) 的加群申请`;
507
+ const request = pendingRequests[0];
508
+ try {
509
+ await ctx.database.remove("group_verification_pending", { id: request.id });
510
+ await updateStats(groupId, "rejected");
511
+ return `已拒绝用户 ${request.userName}(${userId}) 的加群申请`;
512
+ } catch (error) {
513
+ return `处理申请时出错: ${error.message}`;
514
+ }
419
515
  });
420
- groupVerify.subcommand(".stats [groupId]", "查看群组验证统计信息").alias("统计", "stat", "statistics").option("total", "-t 显示总计统计").action(async ({ session, options }, groupId) => {
421
- const targetGroupId = groupId || session.guildId;
422
- if (!targetGroupId && !options.total) {
423
- return "请在群聊中使用此命令或指定群号,或使用 -t 参数查看总计统计";
424
- }
425
- let statsList = [];
426
- if (options.total) {
427
- const totalStats = await ctx.database.get("group_verification_stats", { groupId: "TOTAL" });
428
- if (totalStats.length > 0) {
429
- statsList.push(totalStats[0]);
430
- }
431
- if (targetGroupId && targetGroupId !== "TOTAL") {
432
- const groupStats = await ctx.database.get("group_verification_stats", { groupId: targetGroupId });
433
- statsList = statsList.concat(groupStats);
516
+ groupVerify.subcommand(".stats [target]", "查看群组验证统计信息").alias(
517
+ "gv.统计",
518
+ "gverify.统计",
519
+ "group-verify.统计",
520
+ "gvs"
521
+ ).action(async ({ session }, target) => {
522
+ const validTargets = ["all", "total"];
523
+ const isGroupId = target && /^\d+$/.test(target);
524
+ const isSpecialTarget = target && validTargets.includes(target.toLowerCase());
525
+ if (target && !isGroupId && !isSpecialTarget) {
526
+ return "参数错误:只能指定群号、all、total或留空";
527
+ }
528
+ if (target?.toLowerCase() === "total" || target?.toLowerCase() === "all") {
529
+ const koishiAuthority = session.author?.authority || session.user?.authority;
530
+ if (!(koishiAuthority && koishiAuthority >= 3)) {
531
+ return "查看总计统计需要koishi 3级以上权限";
434
532
  }
435
- } else {
436
- const groupStats = await ctx.database.get("group_verification_stats", { groupId: targetGroupId });
437
- statsList = groupStats;
438
533
  }
439
- if (statsList.length === 0) {
440
- if (options.total) {
441
- return "暂无统计信息";
442
- } else {
443
- return `群 ${targetGroupId} 暂无验证统计信息`;
534
+ const groupId = session.guildId;
535
+ if (!target) {
536
+ if (!groupId) {
537
+ return "请在群聊中使用此命令或指定群号";
444
538
  }
539
+ return await getGroupStats(groupId);
445
540
  }
446
- let result = "";
447
- for (const stats of statsList) {
448
- const groupName = stats.groupId === "TOTAL" ? "总计" : `群 ${stats.groupId}`;
449
- const lastUpdated = new Date(stats.lastUpdated).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
450
- result += `${groupName} 验证统计:
451
- 自动批准: ${stats.autoApproved}
452
- 手动批准: ${stats.manuallyApproved}
453
- 拒绝: ${stats.rejected}
454
- 最后更新: ${lastUpdated}
455
-
456
- `;
541
+ if (target.toLowerCase() === "all" || target.toLowerCase() === "total") {
542
+ return await getTotalStats();
543
+ }
544
+ if (isGroupId) {
545
+ return await getGroupStats(target);
457
546
  }
458
- return result.trim();
547
+ return "参数错误";
459
548
  });
460
- groupVerify.subcommand(".pending", "查看待审核加群申请").alias("list", "待审", "pend", "待处理").action(async ({ session }) => {
549
+ groupVerify.subcommand(".pending", "查看待审核加群申请").alias(
550
+ "gv.list",
551
+ "gverify.list",
552
+ "group-verify.list",
553
+ "gv.待处理",
554
+ "gverify.待处理",
555
+ "group-verify.待处理",
556
+ "gvp"
557
+ ).action(async ({ session }) => {
461
558
  if (!session.guildId) {
462
559
  return "请在群聊中使用此命令";
463
560
  }
@@ -477,7 +574,11 @@ ${debugInfo}`];
477
574
  });
478
575
  return result;
479
576
  });
480
- groupVerify.subcommand(".help", "显示帮助信息").alias("帮助", "hlp", "帮助信息").action(() => {
577
+ groupVerify.subcommand(".help", "显示帮助信息").alias(
578
+ "gv.帮助",
579
+ "gverify.帮助",
580
+ "group-verify.帮助"
581
+ ).action(() => {
481
582
  return `群组验证命令帮助:
482
583
  主指令别名:gv, gverify
483
584
 
@@ -532,6 +633,34 @@ ${debugInfo}`];
532
633
  }
533
634
  await syncTotalStats(ctx);
534
635
  });
636
+ async function getGroupStats(groupId) {
637
+ const stats = await ctx.database.get("group_verification_stats", { groupId });
638
+ if (stats.length === 0) {
639
+ return `群 ${groupId} 暂无验证统计信息`;
640
+ }
641
+ const stat = stats[0];
642
+ const lastUpdated = new Date(stat.lastUpdated).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
643
+ return `群 ${groupId} 验证统计:
644
+ 自动批准: ${stat.autoApproved}
645
+ 手动批准: ${stat.manuallyApproved}
646
+ 拒绝: ${stat.rejected}
647
+ 最后更新: ${lastUpdated}`;
648
+ }
649
+ __name(getGroupStats, "getGroupStats");
650
+ async function getTotalStats() {
651
+ const stats = await ctx.database.get("group_verification_stats", { groupId: "TOTAL" });
652
+ if (stats.length === 0) {
653
+ return "暂无统计信息";
654
+ }
655
+ const stat = stats[0];
656
+ const lastUpdated = new Date(stat.lastUpdated).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
657
+ return `总计验证统计:
658
+ 自动批准: ${stat.autoApproved}
659
+ 手动批准: ${stat.manuallyApproved}
660
+ 拒绝: ${stat.rejected}
661
+ 最后更新: ${lastUpdated}`;
662
+ }
663
+ __name(getTotalStats, "getTotalStats");
535
664
  async function syncTotalStats(ctx2) {
536
665
  try {
537
666
  const allStats = await ctx2.database.get("group_verification_stats", {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-group-verification",
3
3
  "description": "Koishi 群组加群验证插件,支持多关键词匹配审核、多种审核方式和详细统计功能",
4
- "version": "1.0.10",
4
+ "version": "1.0.12",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
package/src/index.ts CHANGED
@@ -371,7 +371,11 @@ export function apply(ctx: Context, config: Config) {
371
371
  // Subcommand: configure group verification
372
372
  groupVerify
373
373
  .subcommand('.config [keywords:text]', '配置群组验证规则')
374
- .alias('cfg', '配置', 'conf', '设置')
374
+ .alias(
375
+ 'gv.cfg', 'gverify.cfg', 'group-verify.cfg',
376
+ 'gv.配置', 'gverify.配置', 'group-verify.配置',
377
+ 'gvc'
378
+ )
375
379
  .option('groupId', '-i <groupId> 指定群号')
376
380
  .option('method', '-m <method> 审核方式 (0-3)')
377
381
  .option('threshold', '-t <threshold> 阈值参数')
@@ -536,138 +540,232 @@ export function apply(ctx: Context, config: Config) {
536
540
 
537
541
  // Subcommand: approve join request
538
542
  groupVerify
539
- .subcommand('.approve <userId>', '同意用户加群申请')
540
- .alias('accept', '同意', 'appr', '通过')
543
+ .subcommand('.approve [userId]', '同意加群申请')
544
+ .alias(
545
+ 'gv.accept', 'gverify.accept', 'group-verify.accept',
546
+ 'gv.同意', 'gverify.同意', 'group-verify.同意',
547
+ 'gva'
548
+ )
541
549
  .action(async ({ session }, userId) => {
542
550
  // 权限检查
543
- if (!(await checkPermission(session))) {
544
- return '权限不足'
551
+ const [hasPermission, errorMsg] = await checkPermission(session)
552
+ if (!hasPermission) {
553
+ return errorMsg || '权限不足'
545
554
  }
546
555
 
547
- if (!session.guildId) {
556
+ const groupId = session.guildId
557
+ if (!groupId) {
548
558
  return '请在群聊中使用此命令'
549
559
  }
550
-
551
- if (!userId) {
552
- return '请提供用户ID'
560
+
561
+ // 处理默认情况和all情况
562
+ if (!userId || userId.toLowerCase() === 'all') {
563
+ if (userId?.toLowerCase() === 'all') {
564
+ // 处理所有待审核申请
565
+ const pendingRequests = await ctx.database.get('group_verification_pending', { groupId })
566
+ if (pendingRequests.length === 0) {
567
+ return '当前无待审核的加群申请'
568
+ }
569
+
570
+ let approvedCount = 0
571
+ for (const request of pendingRequests) {
572
+ try {
573
+ // TODO: 需要获取实际的requestId来进行审批
574
+ // await session.bot.handleGuildMemberRequest(request.requestId, true)
575
+ await ctx.database.remove('group_verification_pending', { id: request.id })
576
+ await updateStats(groupId, 'manuallyApproved')
577
+ approvedCount++
578
+ } catch (error) {
579
+ logger.warn(`处理申请 ${request.id} 时出错:`, error)
580
+ }
581
+ }
582
+
583
+ return `已处理 ${approvedCount} 个加群申请`
584
+ } else {
585
+ // 处理最近的一个申请
586
+ const recentRequest = await ctx.database.get('group_verification_pending', { groupId }, ['id', 'userId', 'userName'])
587
+ if (recentRequest.length === 0) {
588
+ return '当前无待审核的加群申请'
589
+ }
590
+
591
+ const request = recentRequest[0]
592
+ try {
593
+ // 这里需要获取实际的requestId,暂时用userId作为示例
594
+ await session.bot.handleGuildMemberRequest(request.userId, true)
595
+ await ctx.database.remove('group_verification_pending', { id: request.id })
596
+ await updateStats(groupId, 'manuallyApproved')
597
+ return `已同意用户 ${request.userName}(${request.userId}) 的加群申请`
598
+ } catch (error) {
599
+ return `处理申请时出错: ${error.message}`
600
+ }
601
+ }
553
602
  }
554
-
555
- // Find pending applications
556
- const pendingApplications = await ctx.database.get('group_verification_pending', {
557
- groupId: session.guildId,
558
- userId: userId
603
+
604
+ // 处理指定用户ID的情况
605
+ const pendingRequests = await ctx.database.get('group_verification_pending', {
606
+ groupId,
607
+ userId: userId
559
608
  })
560
-
561
- if (pendingApplications.length === 0) {
609
+
610
+ if (pendingRequests.length === 0) {
562
611
  return `未找到用户 ${userId} 的待审核申请`
563
612
  }
564
-
565
- const application = pendingApplications[0]
566
-
567
- // Remove pending record
568
- await ctx.database.remove('group_verification_pending', { id: application.id })
569
- await updateStats(session.guildId, 'manuallyApproved')
570
-
571
- return `已同意用户 ${application.userName}(${userId}) 的加群申请`
613
+
614
+ const request = pendingRequests[0]
615
+ try {
616
+ // 这里需要获取实际的requestId来进行审批
617
+ await session.bot.handleGuildMemberRequest(request.userId, true)
618
+ await ctx.database.remove('group_verification_pending', { id: request.id })
619
+ await updateStats(groupId, 'manuallyApproved')
620
+ return `已同意用户 ${request.userName}(${userId}) 的加群申请`
621
+ } catch (error) {
622
+ return `处理申请时出错: ${error.message}`
623
+ }
572
624
  })
573
625
 
574
626
  // Subcommand: reject join request
575
627
  groupVerify
576
- .subcommand('.reject <userId>', '拒绝用户加群申请')
577
- .alias('拒绝', 'rej', '拒绝')
628
+ .subcommand('.reject [userId]', '拒绝加群申请')
629
+ .alias(
630
+ 'gv.拒绝', 'gverify.拒绝', 'group-verify.拒绝',
631
+ 'gv.rej', 'gverify.rej', 'group-verify.rej',
632
+ 'gvr'
633
+ )
578
634
  .action(async ({ session }, userId) => {
579
635
  // 权限检查
580
- if (!(await checkPermission(session))) {
581
- return '权限不足'
636
+ const [hasPermission, errorMsg] = await checkPermission(session)
637
+ if (!hasPermission) {
638
+ return errorMsg || '权限不足'
582
639
  }
583
640
 
584
- if (!session.guildId) {
641
+ const groupId = session.guildId
642
+ if (!groupId) {
585
643
  return '请在群聊中使用此命令'
586
644
  }
587
-
588
- if (!userId) {
589
- return '请提供用户ID'
645
+
646
+ // 处理默认情况和all情况
647
+ if (!userId || userId.toLowerCase() === 'all') {
648
+ if (userId?.toLowerCase() === 'all') {
649
+ // 拒绝所有待审核申请
650
+ const pendingRequests = await ctx.database.get('group_verification_pending', { groupId })
651
+ if (pendingRequests.length === 0) {
652
+ return '当前无待审核的加群申请'
653
+ }
654
+
655
+ let rejectedCount = 0
656
+ for (const request of pendingRequests) {
657
+ try {
658
+ // TODO: 需要获取实际的requestId来进行拒绝
659
+ // await session.bot.handleGuildMemberRequest(request.requestId, false)
660
+ await ctx.database.remove('group_verification_pending', { id: request.id })
661
+ await updateStats(groupId, 'rejected')
662
+ rejectedCount++
663
+ } catch (error) {
664
+ logger.warn(`处理申请 ${request.id} 时出错:`, error)
665
+ }
666
+ }
667
+
668
+ return `已拒绝 ${rejectedCount} 个加群申请`
669
+ } else {
670
+ // 拒绝最近的一个申请
671
+ const recentRequest = await ctx.database.get('group_verification_pending', { groupId }, ['id', 'userId', 'userName'])
672
+ if (recentRequest.length === 0) {
673
+ return '当前无待审核的加群申请'
674
+ }
675
+
676
+ const request = recentRequest[0]
677
+ try {
678
+ // TODO: 需要获取实际的requestId来进行拒绝
679
+ // await session.bot.handleGuildMemberRequest(request.requestId, false)
680
+ await ctx.database.remove('group_verification_pending', { id: request.id })
681
+ await updateStats(groupId, 'rejected')
682
+ return `已拒绝用户 ${request.userName}(${request.userId}) 的加群申请`
683
+ } catch (error) {
684
+ return `处理申请时出错: ${error.message}`
685
+ }
686
+ }
590
687
  }
591
-
592
- // Find pending applications
593
- const pendingApplications = await ctx.database.get('group_verification_pending', {
594
- groupId: session.guildId,
595
- userId: userId
688
+
689
+ // 处理指定用户ID的情况
690
+ const pendingRequests = await ctx.database.get('group_verification_pending', {
691
+ groupId,
692
+ userId: userId
596
693
  })
597
-
598
- if (pendingApplications.length === 0) {
694
+
695
+ if (pendingRequests.length === 0) {
599
696
  return `未找到用户 ${userId} 的待审核申请`
600
697
  }
601
-
602
- const application = pendingApplications[0]
603
-
604
- // Remove pending record
605
- await ctx.database.remove('group_verification_pending', { id: application.id })
606
- await updateStats(session.guildId, 'rejected')
607
-
608
- return `已拒绝用户 ${application.userName}(${userId}) 的加群申请`
698
+
699
+ const request = pendingRequests[0]
700
+ try {
701
+ // TODO: 需要获取实际的requestId来进行拒绝
702
+ // await session.bot.handleGuildMemberRequest(request.requestId, false)
703
+ await ctx.database.remove('group_verification_pending', { id: request.id })
704
+ await updateStats(groupId, 'rejected')
705
+ return `已拒绝用户 ${request.userName}(${userId}) 的加群申请`
706
+ } catch (error) {
707
+ return `处理申请时出错: ${error.message}`
708
+ }
609
709
  })
610
710
 
611
711
  // Subcommand: view statistics
612
712
  groupVerify
613
- .subcommand('.stats [groupId]', '查看群组验证统计信息')
614
- .alias('统计', 'stat', 'statistics')
615
- .option('total', '-t 显示总计统计')
616
- .action(async ({ session, options }, groupId) => {
617
- // 权限检查(统计命令相对宽松,任意用户可查看)
618
- const targetGroupId = groupId || session.guildId
713
+ .subcommand('.stats [target]', '查看群组验证统计信息')
714
+ .alias(
715
+ 'gv.统计', 'gverify.统计', 'group-verify.统计',
716
+ 'gvs'
717
+ )
718
+ .action(async ({ session }, target) => {
719
+ // 参数验证:只能是群号、all、total或空
720
+ const validTargets = ['all', 'total']
721
+ const isGroupId = target && /^\d+$/.test(target)
722
+ const isSpecialTarget = target && validTargets.includes(target.toLowerCase())
723
+
724
+ if (target && !isGroupId && !isSpecialTarget) {
725
+ return '参数错误:只能指定群号、all、total或留空'
726
+ }
619
727
 
620
- if (!targetGroupId && !options.total) {
621
- return '请在群聊中使用此命令或指定群号,或使用 -t 参数查看总计统计'
728
+ // 权限检查:总计统计需要3级以上权限
729
+ if (target?.toLowerCase() === 'total' || target?.toLowerCase() === 'all') {
730
+ // 检查是否为koishi 3级以上权限
731
+ const koishiAuthority = (session as any).author?.authority || (session as any).user?.authority
732
+ if (!(koishiAuthority && koishiAuthority >= 3)) {
733
+ return '查看总计统计需要koishi 3级以上权限'
734
+ }
622
735
  }
623
736
 
624
- let statsList: GroupVerificationStats[] = []
737
+ const groupId = session.guildId
625
738
 
626
- if (options.total) {
627
- // 显示总计统计
628
- const totalStats = await ctx.database.get('group_verification_stats', { groupId: 'TOTAL' })
629
- if (totalStats.length > 0) {
630
- statsList.push(totalStats[0])
631
- }
632
-
633
- // 如果同时指定了具体群号,也显示该群统计
634
- if (targetGroupId && targetGroupId !== 'TOTAL') {
635
- const groupStats = await ctx.database.get('group_verification_stats', { groupId: targetGroupId })
636
- statsList = statsList.concat(groupStats)
739
+ // 处理不同参数情况
740
+ if (!target) {
741
+ // 无参数:显示当前群统计
742
+ if (!groupId) {
743
+ return '请在群聊中使用此命令或指定群号'
637
744
  }
638
- } else {
639
- // 显示指定群统计
640
- const groupStats = await ctx.database.get('group_verification_stats', { groupId: targetGroupId })
641
- statsList = groupStats
745
+ return await getGroupStats(groupId)
642
746
  }
643
747
 
644
- if (statsList.length === 0) {
645
- if (options.total) {
646
- return '暂无统计信息'
647
- } else {
648
- return `群 ${targetGroupId} 暂无验证统计信息`
649
- }
748
+ if (target.toLowerCase() === 'all' || target.toLowerCase() === 'total') {
749
+ // 显示总计统计
750
+ return await getTotalStats()
650
751
  }
651
752
 
652
- let result = ''
653
- for (const stats of statsList) {
654
- const groupName = stats.groupId === 'TOTAL' ? '总计' : `群 ${stats.groupId}`
655
- const lastUpdated = new Date(stats.lastUpdated).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
656
-
657
- result += `${groupName} 验证统计:
658
- 自动批准: ${stats.autoApproved}
659
- 手动批准: ${stats.manuallyApproved}
660
- 拒绝: ${stats.rejected}
661
- 最后更新: ${lastUpdated}\n\n`
753
+ if (isGroupId) {
754
+ // 显示指定群统计
755
+ return await getGroupStats(target)
662
756
  }
663
757
 
664
- return result.trim()
758
+ return '参数错误'
665
759
  })
666
760
 
667
761
  // Subcommand: view pending requests
668
762
  groupVerify
669
763
  .subcommand('.pending', '查看待审核加群申请')
670
- .alias('list', '待审', 'pend', '待处理')
764
+ .alias(
765
+ 'gv.list', 'gverify.list', 'group-verify.list',
766
+ 'gv.待处理', 'gverify.待处理', 'group-verify.待处理',
767
+ 'gvp'
768
+ )
671
769
  .action(async ({ session }) => {
672
770
  if (!session.guildId) {
673
771
  return '请在群聊中使用此命令'
@@ -696,7 +794,9 @@ export function apply(ctx: Context, config: Config) {
696
794
  // Subcommand: help information
697
795
  groupVerify
698
796
  .subcommand('.help', '显示帮助信息')
699
- .alias('帮助', 'hlp', '帮助信息')
797
+ .alias(
798
+ 'gv.帮助', 'gverify.帮助', 'group-verify.帮助'
799
+ )
700
800
  .action(() => {
701
801
  return `群组验证命令帮助:
702
802
  主指令别名:gv, gverify
@@ -760,6 +860,42 @@ export function apply(ctx: Context, config: Config) {
760
860
  await syncTotalStats(ctx)
761
861
  })
762
862
 
863
+ // 辅助函数:获取群组统计
864
+ async function getGroupStats(groupId: string): Promise<string> {
865
+ const stats = await ctx.database.get('group_verification_stats', { groupId })
866
+
867
+ if (stats.length === 0) {
868
+ return `群 ${groupId} 暂无验证统计信息`
869
+ }
870
+
871
+ const stat = stats[0]
872
+ const lastUpdated = new Date(stat.lastUpdated).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
873
+
874
+ return `群 ${groupId} 验证统计:
875
+ 自动批准: ${stat.autoApproved}
876
+ 手动批准: ${stat.manuallyApproved}
877
+ 拒绝: ${stat.rejected}
878
+ 最后更新: ${lastUpdated}`
879
+ }
880
+
881
+ // 辅助函数:获取总计统计
882
+ async function getTotalStats(): Promise<string> {
883
+ const stats = await ctx.database.get('group_verification_stats', { groupId: 'TOTAL' })
884
+
885
+ if (stats.length === 0) {
886
+ return '暂无统计信息'
887
+ }
888
+
889
+ const stat = stats[0]
890
+ const lastUpdated = new Date(stat.lastUpdated).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
891
+
892
+ return `总计验证统计:
893
+ 自动批准: ${stat.autoApproved}
894
+ 手动批准: ${stat.manuallyApproved}
895
+ 拒绝: ${stat.rejected}
896
+ 最后更新: ${lastUpdated}`
897
+ }
898
+
763
899
  // 同步统计数据到总计行的函数
764
900
  async function syncTotalStats(ctx: Context) {
765
901
  try {