koishi-plugin-class-score-system 1.0.7 → 1.0.9

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.js CHANGED
@@ -1,3 +1,6 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
1
4
  // src/index.ts
2
5
  import { Schema } from "koishi";
3
6
 
@@ -43,9 +46,13 @@ function extendDatabase(ctx) {
43
46
  unique: ["openId", "guildId"]
44
47
  });
45
48
  }
49
+ __name(extendDatabase, "extendDatabase");
46
50
 
47
51
  // src/services/api.ts
48
52
  var CsmsApiService = class {
53
+ static {
54
+ __name(this, "CsmsApiService");
55
+ }
49
56
  baseUrl;
50
57
  token;
51
58
  ctx;
@@ -67,18 +74,18 @@ var CsmsApiService = class {
67
74
  cleanParams[key] = String(value);
68
75
  }
69
76
  }
70
- this.ctx.logger.debug(`API\u8BF7\u6C42: ${url}`, cleanParams);
77
+ this.ctx.logger.debug(`API请求: ${url}`, cleanParams);
71
78
  const response = await this.ctx.http.get(url, {
72
79
  params: cleanParams,
73
80
  headers: {
74
81
  "Authorization": this.token
75
82
  }
76
83
  });
77
- this.ctx.logger.debug(`API\u54CD\u5E94:`, response);
84
+ this.ctx.logger.debug(`API响应:`, response);
78
85
  return response;
79
86
  } catch (error) {
80
- this.ctx.logger.error("CSMS API \u8BF7\u6C42\u5931\u8D25:", error);
81
- return { error: error.message || "API\u8BF7\u6C42\u5931\u8D25" };
87
+ this.ctx.logger.error("CSMS API 请求失败:", error);
88
+ return { error: error.message || "API请求失败" };
82
89
  }
83
90
  }
84
91
  /**
@@ -97,20 +104,20 @@ var CsmsApiService = class {
97
104
  }),
98
105
  token: this.token
99
106
  };
100
- this.ctx.logger.info(`\u9A8C\u8BC1Token\u4E2D...`);
107
+ this.ctx.logger.info(`验证Token中...`);
101
108
  const response = await this.ctx.http.get(url, { params });
102
109
  if (response.error) {
103
110
  const errorLower = response.error.toLowerCase();
104
- if (errorLower.includes("\u672A\u6388\u6743") || errorLower.includes("token") || errorLower.includes("\u65E0\u6548")) {
105
- this.ctx.logger.warn(`Token\u9A8C\u8BC1\u5931\u8D25: ${response.error}`);
111
+ if (errorLower.includes("未授权") || errorLower.includes("token") || errorLower.includes("无效")) {
112
+ this.ctx.logger.warn(`Token验证失败: ${response.error}`);
106
113
  return { valid: false };
107
114
  }
108
- this.ctx.logger.info(`Token\u9A8C\u8BC1\u6210\u529F`);
115
+ this.ctx.logger.info(`Token验证成功`);
109
116
  return { valid: true };
110
117
  }
111
118
  return { valid: true };
112
119
  } catch (error) {
113
- this.ctx.logger.error(`Token\u9A8C\u8BC1\u5F02\u5E38:`, error);
120
+ this.ctx.logger.error(`Token验证异常:`, error);
114
121
  return { valid: false };
115
122
  }
116
123
  }
@@ -227,12 +234,12 @@ var CsmsApiService = class {
227
234
  * GET /api/global_api.php?action=add_score&data={"users":[...],"description":"xxx"}&token=xxx
228
235
  */
229
236
  async batchAddScore(data) {
230
- this.ctx.logger.info(`batchAddScore \u8BF7\u6C42\u6570\u636E:`, JSON.stringify(data));
237
+ this.ctx.logger.info(`batchAddScore 请求数据:`, JSON.stringify(data));
231
238
  const response = await this.request({
232
239
  action: "add_score",
233
240
  data: JSON.stringify(data)
234
241
  });
235
- this.ctx.logger.info(`batchAddScore API \u54CD\u5E94:`, JSON.stringify(response));
242
+ this.ctx.logger.info(`batchAddScore API 响应:`, JSON.stringify(response));
236
243
  if (response.error) {
237
244
  return {
238
245
  success: false,
@@ -250,15 +257,15 @@ var CsmsApiService = class {
250
257
  if (Array.isArray(response.data)) {
251
258
  return {
252
259
  success: true,
253
- message: "\u64CD\u4F5C\u5B8C\u6210",
260
+ message: "操作完成",
254
261
  summary: { success_count: response.data.length, failed_count: 0, total_count: response.data.length },
255
262
  details: response.data
256
263
  };
257
264
  }
258
- this.ctx.logger.error(`batchAddScore \u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u5F02\u5E38\uFF0C\u539F\u59CB\u54CD\u5E94:`, response);
265
+ this.ctx.logger.error(`batchAddScore 返回数据格式异常,原始响应:`, response);
259
266
  return {
260
267
  success: false,
261
- message: "API \u8FD4\u56DE\u6570\u636E\u683C\u5F0F\u5F02\u5E38",
268
+ message: "API 返回数据格式异常",
262
269
  summary: { success_count: 0, failed_count: 0, total_count: 0 },
263
270
  details: []
264
271
  };
@@ -276,6 +283,9 @@ var CsmsApiService = class {
276
283
 
277
284
  // src/services/server.ts
278
285
  var ServerConfigService = class {
286
+ static {
287
+ __name(this, "ServerConfigService");
288
+ }
279
289
  ctx;
280
290
  constructor(ctx) {
281
291
  this.ctx = ctx;
@@ -331,14 +341,14 @@ var ServerConfigService = class {
331
341
  return {
332
342
  valid: true,
333
343
  actualUsername: result.username,
334
- error: `\u8B66\u544A\uFF1A\u63D0\u4F9B\u7684\u7528\u6237\u540D "${username}" \u4E0E\u5B9E\u9645\u767B\u5F55\u7684\u7BA1\u7406\u5458 "${result.username}" \u4E0D\u4E00\u81F4`
344
+ error: `警告:提供的用户名 "${username}" 与实际登录的管理员 "${result.username}" 不一致`
335
345
  };
336
346
  }
337
347
  return { valid: true, actualUsername: result.username };
338
348
  }
339
- return { valid: false, error: "Token \u9A8C\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 Token \u662F\u5426\u6B63\u786E" };
349
+ return { valid: false, error: "Token 验证失败,请检查 Token 是否正确" };
340
350
  } catch (error) {
341
- this.ctx.logger.error("\u9A8C\u8BC1\u670D\u52A1\u5668\u914D\u7F6E\u5931\u8D25:", error);
351
+ this.ctx.logger.error("验证服务器配置失败:", error);
342
352
  return { valid: false, error: error.message };
343
353
  }
344
354
  }
@@ -346,6 +356,9 @@ var ServerConfigService = class {
346
356
 
347
357
  // src/services/binding.ts
348
358
  var QqBindingService = class {
359
+ static {
360
+ __name(this, "QqBindingService");
361
+ }
349
362
  ctx;
350
363
  constructor(ctx) {
351
364
  this.ctx = ctx;
@@ -405,6 +418,9 @@ var QqBindingService = class {
405
418
 
406
419
  // src/services/group-admin.ts
407
420
  var GroupAdminService = class {
421
+ static {
422
+ __name(this, "GroupAdminService");
423
+ }
408
424
  ctx;
409
425
  constructor(ctx) {
410
426
  this.ctx = ctx;
@@ -493,36 +509,39 @@ var CONSTANTS = {
493
509
  DESCRIPTION_MAX_LENGTH: 255
494
510
  };
495
511
  var ERROR_MESSAGES = {
496
- NO_SERVER_CONFIG: "\u672A\u914D\u7F6ECSMS\u670D\u52A1\u5668\uFF0C\u8BF7\u5148\u4F7F\u7528 /\u7ED1\u5B9A\u670D\u52A1\u5668 \u547D\u4EE4\u914D\u7F6E",
497
- INVALID_TOKEN: "\u65E0\u6548\u7684Token\u683C\u5F0F\uFF0CToken\u5FC5\u987B\u7531\u6570\u5B57\u548C\u82F1\u6587\u5927\u5199\u5B57\u6BCD\u7EC4\u6210",
498
- INVALID_QQ: "\u65E0\u6548\u7684QQ\u53F7\u7801\u683C\u5F0F",
499
- INVALID_SCORE: "\u5206\u6570\u5FC5\u987B\u5728 -1000 \u5230 1000 \u4E4B\u95F4",
500
- INVALID_USERNAME: "\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A\u4E14\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC750\u4E2A\u5B57\u7B26",
501
- INVALID_DESCRIPTION: "\u63CF\u8FF0\u4FE1\u606F\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7255\u4E2A\u5B57\u7B26",
502
- INVALID_LIMIT: "\u6570\u91CF\u5FC5\u987B\u5728 1 \u5230 50 \u4E4B\u95F4",
503
- SERVER_NOT_FOUND: "\u670D\u52A1\u5668\u672A\u627E\u5230",
504
- USER_NOT_FOUND: "\u7528\u6237\u672A\u627E\u5230",
505
- USER_ALREADY_BOUND: "\u8BE5QQ\u53F7\u5DF2\u7ED1\u5B9A\u5176\u4ED6\u7528\u6237",
506
- USER_NOT_BOUND: "\u8BE5QQ\u53F7\u672A\u7ED1\u5B9A\u4EFB\u4F55\u7528\u6237",
507
- API_REQUEST_FAILED: "API\u8BF7\u6C42\u5931\u8D25",
508
- INSUFFICIENT_PERMISSION: "\u6743\u9650\u4E0D\u8DB3\uFF0C\u4EC5\u7BA1\u7406\u5458\u53EF\u6267\u884C\u6B64\u64CD\u4F5C",
509
- BINDING_FAILED: "\u7ED1\u5B9A\u5931\u8D25",
510
- UNBINDING_FAILED: "\u89E3\u9664\u7ED1\u5B9A\u5931\u8D25",
511
- CONFIGURATION_FAILED: "\u914D\u7F6E\u4FDD\u5B58\u5931\u8D25"
512
+ NO_SERVER_CONFIG: "未配置CSMS服务器,请先使用 /绑定服务器 命令配置",
513
+ INVALID_TOKEN: "无效的Token格式,Token必须由数字和英文大写字母组成",
514
+ INVALID_QQ: "无效的QQ号码格式",
515
+ INVALID_SCORE: "分数必须在 -1000 1000 之间",
516
+ INVALID_USERNAME: "用户名不能为空且长度不能超过50个字符",
517
+ INVALID_DESCRIPTION: "描述信息长度不能超过255个字符",
518
+ INVALID_LIMIT: "数量必须在 1 50 之间",
519
+ SERVER_NOT_FOUND: "服务器未找到",
520
+ USER_NOT_FOUND: "用户未找到",
521
+ USER_ALREADY_BOUND: "该QQ号已绑定其他用户",
522
+ USER_NOT_BOUND: "该QQ号未绑定任何用户",
523
+ API_REQUEST_FAILED: "API请求失败",
524
+ INSUFFICIENT_PERMISSION: "权限不足,仅管理员可执行此操作",
525
+ BINDING_FAILED: "绑定失败",
526
+ UNBINDING_FAILED: "解除绑定失败",
527
+ CONFIGURATION_FAILED: "配置保存失败"
512
528
  };
513
529
  var HELP_MESSAGES = {
514
- BIND_SERVER: "\u7ED1\u5B9ACSMS\u670D\u52A1\u5668\n\u7528\u6CD5\uFF1A/\u7ED1\u5B9A\u670D\u52A1\u5668 <\u670D\u52A1\u5668\u5730\u5740> <\u7BA1\u7406\u5458\u7528\u6237\u540D> <\u7BA1\u7406\u5458Token>\n\u793A\u4F8B\uFF1A/\u7ED1\u5B9A\u670D\u52A1\u5668 https://example.com admin ABC123",
515
- QUERY_SCORE: "\u67E5\u8BE2\u79EF\u5206\n\u7528\u6CD5\uFF1A/\u67E5\u8BE2\u79EF\u5206 [\u7528\u6237\u540D]\n\u793A\u4F8B\uFF1A/\u67E5\u8BE2\u79EF\u5206 \u5F20\u4E09",
516
- ADJUST_SCORE: "\u8C03\u6574\u79EF\u5206\n\u7528\u6CD5\uFF1A/\u8C03\u6574\u79EF\u5206 <\u7528\u6237\u540D> <\u5206\u6570> <\u539F\u56E0>\n\u793A\u4F8B\uFF1A/\u8C03\u6574\u79EF\u5206 \u5F20\u4E09 +5 \u8868\u73B0\u4F18\u79C0",
517
- BIND_QQ: "\u7ED1\u5B9AQQ\n\u7528\u6CD5\uFF1A/\u7ED1\u5B9AQQ <\u7528\u6237\u540D>\n\u793A\u4F8B\uFF1A/\u7ED1\u5B9AQQ \u5F20\u4E09",
518
- VIEW_BINDING: "\u67E5\u770B\u7ED1\u5B9A\n\u7528\u6CD5\uFF1A/\u67E5\u770B\u7ED1\u5B9A [\u7528\u6237\u540D]\n\u793A\u4F8B\uFF1A/\u67E5\u770B\u7ED1\u5B9A \u5F20\u4E09",
519
- UNBIND_QQ: "\u89E3\u9664\u7ED1\u5B9A\n\u7528\u6CD5\uFF1A/\u89E3\u9664\u7ED1\u5B9A <QQ\u53F7>\n\u793A\u4F8B\uFF1A/\u89E3\u9664\u7ED1\u5B9A 123456789",
520
- RANKING: "\u6392\u884C\u699C\n\u7528\u6CD5\uFF1A/\u6392\u884C\u699C [\u6570\u91CF]\n\u793A\u4F8B\uFF1A/\u6392\u884C\u699C 10",
521
- STATISTICS: "\u7EDF\u8BA1\n\u7528\u6CD5\uFF1A/\u7EDF\u8BA1 [\u7528\u6237\u540D]\n\u793A\u4F8B\uFF1A/\u7EDF\u8BA1 \u5F20\u4E09"
530
+ BIND_SERVER: "绑定CSMS服务器\n用法:/绑定服务器 <服务器地址> <管理员用户名> <管理员Token>\n示例:/绑定服务器 https://example.com admin ABC123",
531
+ QUERY_SCORE: "查询积分\n用法:/查询积分 [用户名]\n示例:/查询积分 张三",
532
+ ADJUST_SCORE: "调整积分\n用法:/调整积分 <用户名> <分数> <原因>\n示例:/调整积分 张三 +5 表现优秀",
533
+ BIND_QQ: "绑定QQ\n用法:/绑定QQ <用户名>\n示例:/绑定QQ 张三",
534
+ VIEW_BINDING: "查看绑定\n用法:/查看绑定 [用户名]\n示例:/查看绑定 张三",
535
+ UNBIND_QQ: "解除绑定\n用法:/解除绑定 <QQ号>\n示例:/解除绑定 123456789",
536
+ RANKING: "排行榜\n用法:/排行榜 [数量]\n示例:/排行榜 10",
537
+ STATISTICS: "统计\n用法:/统计 [用户名]\n示例:/统计 张三"
522
538
  };
523
539
 
524
540
  // src/utils/validator.ts
525
541
  var Validator = class {
542
+ static {
543
+ __name(this, "Validator");
544
+ }
526
545
  static validateToken(token) {
527
546
  return CONSTANTS.TOKEN_PATTERN.test(token);
528
547
  }
@@ -573,7 +592,7 @@ var Validator = class {
573
592
  }
574
593
  static validateLimitWithMessage(limit, max = CONSTANTS.RANKING_MAX_LIMIT) {
575
594
  if (!this.validateLimit(limit, max)) {
576
- return `\u6570\u91CF\u5FC5\u987B\u5728 1 \u5230 ${max} \u4E4B\u95F4`;
595
+ return `数量必须在 1 ${max} 之间`;
577
596
  }
578
597
  return null;
579
598
  }
@@ -581,30 +600,33 @@ var Validator = class {
581
600
 
582
601
  // src/utils/formatter.ts
583
602
  var Formatter = class {
603
+ static {
604
+ __name(this, "Formatter");
605
+ }
584
606
  // QQ 消息单条最大长度限制(留有余量)
585
607
  static MAX_MESSAGE_LENGTH = 1800;
586
608
  static formatScoreInfo(user, ranking) {
587
609
  return [
588
- `\u7528\u6237: ${user.username}`,
589
- `\u6392\u540D: ${ranking || "\u672A\u77E5"}`,
590
- `\u603B\u79EF\u5206: ${user.total_score}`,
591
- `\u7D2F\u8BA1\u52A0\u5206: ${user.add_score}`,
592
- `\u7D2F\u8BA1\u6263\u5206: ${user.deduct_score}`,
593
- `\u8BB0\u5F55\u6570: ${user.score_count}`
610
+ `用户: ${user.username}`,
611
+ `排名: ${ranking || "未知"}`,
612
+ `总积分: ${user.total_score}`,
613
+ `累计加分: ${user.add_score}`,
614
+ `累计扣分: ${user.deduct_score}`,
615
+ `记录数: ${user.score_count}`
594
616
  ].join("\n");
595
617
  }
596
618
  static formatRanking(users) {
597
619
  if (users.length === 0) {
598
- return "\u6682\u65E0\u6392\u540D\u6570\u636E";
620
+ return "暂无排名数据";
599
621
  }
600
- const lines = ["\u3010\u79EF\u5206\u6392\u884C\u699C\u3011"];
622
+ const lines = ["【积分排行榜】"];
601
623
  const displayUsers = users.slice(0, 20);
602
624
  displayUsers.forEach((user, index) => {
603
- const medal = index < 3 ? ["\u{1F947}", "\u{1F948}", "\u{1F949}"][index] : `${index + 1}.`;
604
- lines.push(`${medal} ${user.username}: ${user.total_score}\u5206`);
625
+ const medal = index < 3 ? ["🥇", "🥈", "🥉"][index] : `${index + 1}.`;
626
+ lines.push(`${medal} ${user.username}: ${user.total_score}分`);
605
627
  });
606
628
  if (users.length > 20) {
607
- lines.push(`... \u5171 ${users.length} \u4EBA\uFF0C\u663E\u793A\u524D20\u540D`);
629
+ lines.push(`... ${users.length} 人,显示前20名`);
608
630
  }
609
631
  return lines.join("\n");
610
632
  }
@@ -613,70 +635,70 @@ var Formatter = class {
613
635
  */
614
636
  static formatRankingWithRank(users, startRank) {
615
637
  if (users.length === 0) {
616
- return "\u6682\u65E0\u6392\u540D\u6570\u636E";
638
+ return "暂无排名数据";
617
639
  }
618
- const lines = ["\u3010\u79EF\u5206\u6392\u884C\u699C\u3011"];
640
+ const lines = ["【积分排行榜】"];
619
641
  users.forEach((user, index) => {
620
642
  const rank = startRank + index;
621
- const medal = rank <= 3 ? ["\u{1F947}", "\u{1F948}", "\u{1F949}"][rank - 1] : `${rank}.`;
622
- lines.push(`${medal} ${user.username}: ${user.total_score}\u5206`);
643
+ const medal = rank <= 3 ? ["🥇", "🥈", "🥉"][rank - 1] : `${rank}.`;
644
+ lines.push(`${medal} ${user.username}: ${user.total_score}分`);
623
645
  });
624
646
  return lines.join("\n");
625
647
  }
626
648
  static getMedal(index) {
627
- const medals = ["\u{1F947}", "\u{1F948}", "\u{1F949}"];
649
+ const medals = ["🥇", "🥈", "🥉"];
628
650
  return medals[index] || `${index + 1}.`;
629
651
  }
630
652
  static formatScoreLogs(logs) {
631
653
  if (logs.length === 0) {
632
- return "\u6682\u65E0\u79EF\u5206\u8BB0\u5F55";
654
+ return "暂无积分记录";
633
655
  }
634
- const lines = ["\u3010\u79EF\u5206\u8BB0\u5F55\u3011"];
656
+ const lines = ["【积分记录】"];
635
657
  const displayLogs = logs.slice(0, 10);
636
658
  displayLogs.forEach((log) => {
637
659
  const change = log.score_change > 0 ? `+${log.score_change}` : log.score_change;
638
- lines.push(`${change}\u5206 - ${log.description}`);
660
+ lines.push(`${change} - ${log.description}`);
639
661
  });
640
662
  if (logs.length > 10) {
641
- lines.push(`... \u5171 ${logs.length} \u6761\u8BB0\u5F55`);
663
+ lines.push(`... ${logs.length} 条记录`);
642
664
  }
643
665
  return lines.join("\n");
644
666
  }
645
667
  static formatStatistics(user, logs) {
646
668
  const lines = [
647
- `\u3010${user.username} \u7684\u7EDF\u8BA1\u4FE1\u606F\u3011`,
648
- `\u603B\u79EF\u5206: ${user.total_score}`,
649
- `\u7D2F\u8BA1\u52A0\u5206: ${user.add_score}`,
650
- `\u7D2F\u8BA1\u6263\u5206: ${user.deduct_score}`,
651
- `\u8BB0\u5F55\u6570: ${user.score_count}`,
652
- "\u6700\u8FD1\u79EF\u5206\u8BB0\u5F55:"
669
+ `【${user.username} 的统计信息】`,
670
+ `总积分: ${user.total_score}`,
671
+ `累计加分: ${user.add_score}`,
672
+ `累计扣分: ${user.deduct_score}`,
673
+ `记录数: ${user.score_count}`,
674
+ "最近积分记录:"
653
675
  ];
654
676
  const recentLogs = logs.slice(0, 5);
655
677
  if (recentLogs.length > 0) {
656
678
  recentLogs.forEach((log) => {
657
679
  const change = log.score_change > 0 ? `+${log.score_change}` : log.score_change;
658
- lines.push(`${change}\u5206 - ${log.description}`);
680
+ lines.push(`${change} - ${log.description}`);
659
681
  });
660
682
  } else {
661
- lines.push("\u6682\u65E0\u8BB0\u5F55");
683
+ lines.push("暂无记录");
662
684
  }
663
685
  return lines.join("\n");
664
686
  }
665
687
  static formatAddScoreResult(result) {
666
- const status = result.success ? "\u79EF\u5206\u8C03\u6574\u6210\u529F" : "\u79EF\u5206\u8C03\u6574\u5931\u8D25";
667
- const summary = `\u6210\u529F: ${result.summary.success_count} \u6761\uFF0C\u5931\u8D25: ${result.summary.failed_count} \u6761`;
688
+ const status = result.success ? "积分调整成功" : "积分调整失败";
689
+ const summary = `成功: ${result.summary.success_count} 条,失败: ${result.summary.failed_count} 条`;
668
690
  const lines = [status, summary];
669
691
  if (!result.success && result.message) {
670
- lines.push(`\u539F\u56E0: ${result.message}`);
692
+ lines.push(`原因: ${result.message}`);
671
693
  }
672
694
  if (result.details && result.details.length > 0) {
673
- lines.push("\u8BE6\u60C5:");
695
+ lines.push("详情:");
674
696
  result.details.forEach((detail) => {
675
697
  if (detail.success) {
676
698
  const change = detail.score_change > 0 ? "+" : "";
677
- lines.push(`[OK] ${detail.username}: ${change}${detail.score_change}\u5206`);
699
+ lines.push(`[OK] ${detail.username}: ${change}${detail.score_change}分`);
678
700
  } else {
679
- lines.push(`[FAIL] ${detail.username}: ${detail.error || "\u5931\u8D25"}`);
701
+ lines.push(`[FAIL] ${detail.username}: ${detail.error || "失败"}`);
680
702
  }
681
703
  });
682
704
  }
@@ -722,68 +744,69 @@ var Formatter = class {
722
744
 
723
745
  // src/commands/bind-server.ts
724
746
  function registerBindServerCommand(ctx, serverService, adminService) {
725
- ctx.command("\u7ED1\u5B9A\u670D\u52A1\u5668 <\u5730\u5740:string> <\u7528\u6237\u540D:string> <token:string>").alias("bind-server").action(async ({ session }, address, username, token) => {
747
+ ctx.command("绑定服务器 <地址:string> <用户名:string> <token:string>").alias("bind-server").action(async ({ session }, address, username, token) => {
726
748
  if (!address || !username || !token) {
727
749
  return HELP_MESSAGES.BIND_SERVER;
728
750
  }
729
751
  if (!session.guildId) {
730
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
752
+ return "此命令只能在群聊中使用";
731
753
  }
732
754
  const openId = session.userId?.toString();
733
755
  if (!openId) {
734
- return "\u65E0\u6CD5\u83B7\u53D6\u60A8\u7684\u7528\u6237ID";
756
+ return "无法获取您的用户ID";
735
757
  }
736
758
  const existingConfig = await serverService.getConfigByGuild(session.guildId);
737
759
  if (existingConfig) {
738
- return "\u274C \u8BE5\u7FA4\u804A\u5DF2\u7ED1\u5B9A\u670D\u52A1\u5668\uFF0C\u5982\u9700\u66F4\u6362\u8BF7\u5148\u4F7F\u7528 /\u670D\u52A1\u5668\u89E3\u7ED1";
760
+ return " 该群聊已绑定服务器,如需更换请先使用 /服务器解绑";
739
761
  }
740
762
  const tokenError = Validator.validateTokenWithMessage(token);
741
763
  if (tokenError) {
742
- ctx.logger.info(`Token \u683C\u5F0F\u9A8C\u8BC1\u5931\u8D25: ${tokenError}`);
743
- return `Token \u683C\u5F0F\u9A8C\u8BC1\u5931\u8D25`;
764
+ ctx.logger.info(`Token 格式验证失败: ${tokenError}`);
765
+ return `Token 格式验证失败`;
744
766
  }
745
767
  try {
746
- ctx.logger.info(`\u6B63\u5728\u9A8C\u8BC1\u670D\u52A1\u5668\u914D\u7F6E...`);
768
+ ctx.logger.info(`正在验证服务器配置...`);
747
769
  const result = await serverService.validateConfig(address, username, token);
748
770
  if (!result.valid) {
749
- const errorMsg = result.error || "\u670D\u52A1\u5668\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25";
750
- ctx.logger.info(`\u670D\u52A1\u5668\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25: ${errorMsg}`);
751
- return `\u9A8C\u8BC1\u5931\u8D25: ${errorMsg}`;
771
+ const errorMsg = result.error || "服务器配置验证失败";
772
+ ctx.logger.info(`服务器配置验证失败: ${errorMsg}`);
773
+ return `验证失败: ${errorMsg}`;
752
774
  }
753
775
  const actualUsername = result.actualUsername || username;
754
- const config = await serverService.saveConfig(session.guildId, "CSMS\u670D\u52A1\u5668", address, actualUsername, token);
755
- await adminService.addAdmin(session.guildId, openId, "\u7BA1\u7406\u5458");
756
- ctx.logger.info(`\u7FA4\u804A ${session.guildId} \u7684\u9996\u4E2A\u7ED1\u5B9A\u8005 ${openId} \u88AB\u81EA\u52A8\u6DFB\u52A0\u4E3A\u7BA1\u7406\u5458`);
776
+ const config = await serverService.saveConfig(session.guildId, "CSMS服务器", address, actualUsername, token);
777
+ await adminService.addAdmin(session.guildId, openId, "管理员");
778
+ ctx.logger.info(`群聊 ${session.guildId} 的首个绑定者 ${openId} 被自动添加为管理员`);
757
779
  const domain = config.address.replace(/^https?:\/\//, "").split("/")[0];
758
- ctx.logger.info(`\u670D\u52A1\u5668\u914D\u7F6E\u6210\u529F\uFF0Cdomain=${domain}\uFF0Cusername=${actualUsername}`);
759
- return `\u2705 \u670D\u52A1\u5668\u914D\u7F6E\u6210\u529F`;
780
+ ctx.logger.info(`服务器配置成功,domain=${domain},username=${actualUsername}`);
781
+ return `✅ 服务器配置成功`;
760
782
  } catch (error) {
761
- ctx.logger.error("\u4FDD\u5B58\u670D\u52A1\u5668\u914D\u7F6E\u5931\u8D25:", error);
762
- return `\u914D\u7F6E\u4FDD\u5B58\u5931\u8D25: ${error.message}`;
783
+ ctx.logger.error("保存服务器配置失败:", error);
784
+ return `配置保存失败: ${error.message}`;
763
785
  }
764
786
  });
765
- ctx.command("\u670D\u52A1\u5668\u89E3\u7ED1").alias("unbind-server").action(async ({ session }) => {
787
+ ctx.command("服务器解绑").alias("unbind-server").action(async ({ session }) => {
766
788
  if (!session.guildId) {
767
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
789
+ return "此命令只能在群聊中使用";
768
790
  }
769
791
  const hasPermission = await adminService.hasAdminPermission(session);
770
792
  if (!hasPermission) {
771
- return "\u274C \u6B64\u547D\u4EE4\u4EC5\u9650\u7BA1\u7406\u5458\u4F7F\u7528";
793
+ return " 此命令仅限管理员使用";
772
794
  }
773
795
  const config = await serverService.getConfigByGuild(session.guildId);
774
796
  if (!config) {
775
- return "\u274C \u8BE5\u7FA4\u804A\u5C1A\u672A\u7ED1\u5B9A\u4EFB\u4F55\u670D\u52A1\u5668";
797
+ return " 该群聊尚未绑定任何服务器";
776
798
  }
777
- await session.send("\u26A0\uFE0F \u786E\u5B9A\u8981\u89E3\u9664\u670D\u52A1\u5668\u7ED1\u5B9A\u5417\uFF1F\u89E3\u7ED1\u540E\u5176\u4ED6\u4EBA\u53EF\u91CD\u65B0\u7ED1\u5B9A\u3002\u8BF7\u5728 30 \u79D2\u5185\u8F93\u5165\u300C\u786E\u8BA4\u300D\u6765\u5B8C\u6210\u64CD\u4F5C");
799
+ await session.send("⚠️ 确定要解除服务器绑定吗?解绑后其他人可重新绑定。请在 30 秒内输入「确认」来完成操作");
778
800
  const reply = await session.prompt(3e4);
779
- if (reply?.trim() !== "\u786E\u8BA4") {
780
- return "\u2705 \u5DF2\u53D6\u6D88\u89E3\u7ED1\u64CD\u4F5C";
801
+ if (reply?.trim() !== "确认") {
802
+ return " 已取消解绑操作";
781
803
  }
782
804
  await serverService.deleteConfig(session.guildId);
783
- ctx.logger.info(`\u7FA4\u804A ${session.guildId} \u89E3\u9664\u4E86\u670D\u52A1\u5668\u7ED1\u5B9A`);
784
- return `\u2705 \u5DF2\u89E3\u9664\u670D\u52A1\u5668\u7ED1\u5B9A`;
805
+ ctx.logger.info(`群聊 ${session.guildId} 解除了服务器绑定`);
806
+ return `✅ 已解除服务器绑定`;
785
807
  });
786
808
  }
809
+ __name(registerBindServerCommand, "registerBindServerCommand");
787
810
 
788
811
  // src/utils/image.ts
789
812
  import { h } from "koishi";
@@ -818,10 +841,11 @@ async function generateImage(ctx, html, options = {}) {
818
841
  });
819
842
  return screenshot;
820
843
  } catch (error) {
821
- ctx.logger.error("\u751F\u6210\u56FE\u7247\u5931\u8D25:", error);
844
+ ctx.logger.error("生成图片失败:", error);
822
845
  return null;
823
846
  }
824
847
  }
848
+ __name(generateImage, "generateImage");
825
849
  async function sendImageOrText(ctx, session, html, fallbackText, options = {}) {
826
850
  const image = await generateImage(ctx, html, options);
827
851
  if (image) {
@@ -830,6 +854,7 @@ async function sendImageOrText(ctx, session, html, fallbackText, options = {}) {
830
854
  await session.send(fallbackText);
831
855
  }
832
856
  }
857
+ __name(sendImageOrText, "sendImageOrText");
833
858
  function getBaseStyles() {
834
859
  return `
835
860
  * { margin: 0; padding: 0; box-sizing: border-box; }
@@ -877,12 +902,13 @@ function getBaseStyles() {
877
902
  }
878
903
  `;
879
904
  }
905
+ __name(getBaseStyles, "getBaseStyles");
880
906
 
881
907
  // src/commands/query-score.ts
882
908
  function registerQueryScoreCommand(ctx, serverService, bindingService) {
883
- ctx.command("\u67E5\u8BE2\u79EF\u5206 [\u7528\u6237\u540D:string]").alias("query-score").action(async ({ session }, username) => {
909
+ ctx.command("查询积分 [用户名:string]").alias("query-score").action(async ({ session }, username) => {
884
910
  if (!session.guildId) {
885
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
911
+ return "此命令只能在群聊中使用";
886
912
  }
887
913
  const api = await serverService.createApiService(session.guildId);
888
914
  if (!api) {
@@ -893,11 +919,11 @@ function registerQueryScoreCommand(ctx, serverService, bindingService) {
893
919
  if (!username) {
894
920
  const openId = session.userId?.toString();
895
921
  if (!openId) {
896
- return "\u65E0\u6CD5\u83B7\u53D6\u60A8\u7684\u7528\u6237ID";
922
+ return "无法获取您的用户ID";
897
923
  }
898
924
  const binding = await bindingService.getUserByOpenId(session.guildId, openId);
899
925
  if (!binding) {
900
- return `${ERROR_MESSAGES.USER_NOT_BOUND}\u3002\u8BF7\u5148\u4F7F\u7528 /\u7ED1\u5B9AQQ <\u7528\u6237\u540D> \u547D\u4EE4\u7ED1\u5B9A\u60A8\u7684\u8D26\u53F7`;
926
+ return `${ERROR_MESSAGES.USER_NOT_BOUND}。请先使用 /绑定QQ <用户名> 命令绑定您的账号`;
901
927
  }
902
928
  targetUsername = binding.username;
903
929
  }
@@ -965,40 +991,41 @@ function registerQueryScoreCommand(ctx, serverService, bindingService) {
965
991
  </head>
966
992
  <body>
967
993
  <div class="container">
968
- <div class="title">\u{1F4CA} \u79EF\u5206\u67E5\u8BE2\u7ED3\u679C</div>
994
+ <div class="title">📊 积分查询结果</div>
969
995
  <div class="username">${user.username}</div>
970
- <div class="subtitle">\u7528\u6237ID: ${user.id}</div>
996
+ <div class="subtitle">用户ID: ${user.id}</div>
971
997
  <div class="info-grid">
972
998
  <div class="info-item">
973
- <div class="info-label">\u5F53\u524D\u79EF\u5206</div>
999
+ <div class="info-label">当前积分</div>
974
1000
  <div class="info-value score">${user.total_score}</div>
975
1001
  </div>
976
1002
  <div class="info-item">
977
- <div class="info-label">\u6392\u884C\u699C</div>
1003
+ <div class="info-label">排行榜</div>
978
1004
  <div class="info-value rank">#${ranking}</div>
979
1005
  </div>
980
1006
  </div>
981
- <div class="footer">\u73ED\u7EA7\u64CD\u884C\u5206\u7BA1\u7406\u7CFB\u7EDF v1.0</div>
1007
+ <div class="footer">班级操行分管理系统 v1.0</div>
982
1008
  </div>
983
1009
  </body>
984
1010
  </html>`;
985
1011
  await sendImageOrText(ctx, session, html, textResult, { height: 600 });
986
1012
  return "";
987
1013
  } catch (error) {
988
- ctx.logger.error("\u67E5\u8BE2\u79EF\u5206\u5931\u8D25:", error);
1014
+ ctx.logger.error("查询积分失败:", error);
989
1015
  return ERROR_MESSAGES.API_REQUEST_FAILED;
990
1016
  }
991
1017
  });
992
1018
  }
1019
+ __name(registerQueryScoreCommand, "registerQueryScoreCommand");
993
1020
 
994
1021
  // src/commands/bind-qq.ts
995
1022
  function registerBindQqCommand(ctx, serverService, bindingService) {
996
- ctx.command("\u7ED1\u5B9AQQ <\u7528\u6237\u540D:string>").alias("bind-qq").action(async ({ session }, username) => {
1023
+ ctx.command("绑定QQ <用户名:string>").alias("bind-qq").action(async ({ session }, username) => {
997
1024
  if (!username) {
998
1025
  return HELP_MESSAGES.BIND_QQ;
999
1026
  }
1000
1027
  if (!session.guildId) {
1001
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1028
+ return "此命令只能在群聊中使用";
1002
1029
  }
1003
1030
  const usernameError = Validator.validateUsernameWithMessage(username);
1004
1031
  if (usernameError) {
@@ -1006,9 +1033,9 @@ function registerBindQqCommand(ctx, serverService, bindingService) {
1006
1033
  }
1007
1034
  const openId = session.userId?.toString();
1008
1035
  if (!openId) {
1009
- return "\u65E0\u6CD5\u83B7\u53D6\u60A8\u7684\u7528\u6237ID";
1036
+ return "无法获取您的用户ID";
1010
1037
  }
1011
- ctx.logger.info(`\u83B7\u53D6\u5230\u7684\u7528\u6237 OpenID: ${openId}`);
1038
+ ctx.logger.info(`获取到的用户 OpenID: ${openId}`);
1012
1039
  const config = await serverService.getConfigByGuild(session.guildId);
1013
1040
  if (!config) {
1014
1041
  return ERROR_MESSAGES.NO_SERVER_CONFIG;
@@ -1016,11 +1043,11 @@ function registerBindQqCommand(ctx, serverService, bindingService) {
1016
1043
  try {
1017
1044
  const existingBinding = await bindingService.getUserByOpenId(session.guildId, openId);
1018
1045
  if (existingBinding) {
1019
- return `\u274C \u60A8\u5DF2\u7ED1\u5B9A\u300C${existingBinding.username}\u300D\uFF0C\u5982\u9700\u66F4\u6362\u8D26\u53F7\u8BF7\u5148\u4F7F\u7528 /\u89E3\u9664\u7ED1\u5B9A \u89E3\u7ED1\u540E\u91CD\u65B0\u7ED1\u5B9A`;
1046
+ return `❌ 您已绑定「${existingBinding.username}」,如需更换账号请先使用 /解除绑定 解绑后重新绑定`;
1020
1047
  }
1021
1048
  const existingBindings = await bindingService.getBindingsByUsername(session.guildId, username);
1022
1049
  if (existingBindings.length > 0) {
1023
- return `\u274C \u7528\u6237\u540D\u300C${username}\u300D\u5DF2\u88AB\u5176\u4ED6QQ\u8D26\u53F7\u7ED1\u5B9A\uFF0C\u6BCF\u4E2A\u7528\u6237\u540D\u53EA\u80FD\u7ED1\u5B9A\u4E00\u4E2AQQ`;
1050
+ return `❌ 用户名「${username}」已被其他QQ账号绑定,每个用户名只能绑定一个QQ`;
1024
1051
  }
1025
1052
  const api = await serverService.createApiService(session.guildId);
1026
1053
  if (!api) {
@@ -1032,20 +1059,20 @@ function registerBindQqCommand(ctx, serverService, bindingService) {
1032
1059
  }
1033
1060
  const user = response.data[0];
1034
1061
  await bindingService.bindQq(session.guildId, user.id, username, openId, config.id);
1035
- return `\u2705 \u7ED1\u5B9A\u6210\u529F
1036
- \u7528\u6237\u540D: ${username}`;
1062
+ return `✅ 绑定成功
1063
+ 用户名: ${username}`;
1037
1064
  } catch (error) {
1038
- ctx.logger.error("\u7ED1\u5B9AQQ\u5931\u8D25:", error);
1065
+ ctx.logger.error("绑定QQ失败:", error);
1039
1066
  return ERROR_MESSAGES.BINDING_FAILED;
1040
1067
  }
1041
1068
  });
1042
- ctx.command("\u89E3\u9664\u7ED1\u5B9A").alias("unbind").action(async ({ session }, username) => {
1069
+ ctx.command("解除绑定").alias("unbind").action(async ({ session }, username) => {
1043
1070
  if (!session.guildId) {
1044
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1071
+ return "此命令只能在群聊中使用";
1045
1072
  }
1046
1073
  const openId = session.userId?.toString();
1047
1074
  if (!openId) {
1048
- return "\u65E0\u6CD5\u83B7\u53D6\u60A8\u7684\u7528\u6237ID";
1075
+ return "无法获取您的用户ID";
1049
1076
  }
1050
1077
  let binding = null;
1051
1078
  if (username) {
@@ -1055,27 +1082,28 @@ function registerBindQqCommand(ctx, serverService, bindingService) {
1055
1082
  binding = await bindingService.getUserByOpenId(session.guildId, openId);
1056
1083
  }
1057
1084
  if (!binding) {
1058
- return `\u274C \u60A8\u5C1A\u672A\u7ED1\u5B9A\u4EFB\u4F55\u8D26\u53F7${username ? `\uFF08\u7528\u6237\uFF1A${username}\uFF09` : ""}`;
1085
+ return `❌ 您尚未绑定任何账号${username ? `(用户:${username})` : ""}`;
1059
1086
  }
1060
- await session.send(`\u26A0\uFE0F \u786E\u5B9A\u8981\u89E3\u9664\u300C${binding.username}\u300D\u7684\u7ED1\u5B9A\u5417\uFF1F\u8BF7\u5728 30 \u79D2\u5185\u8F93\u5165\u300C\u786E\u8BA4\u300D\u6765\u5B8C\u6210\u64CD\u4F5C`);
1087
+ await session.send(`⚠️ 确定要解除「${binding.username}」的绑定吗?请在 30 秒内输入「确认」来完成操作`);
1061
1088
  const reply = await session.prompt(3e4);
1062
- if (reply?.trim() !== "\u786E\u8BA4") {
1063
- return "\u2705 \u5DF2\u53D6\u6D88\u89E3\u7ED1\u64CD\u4F5C";
1089
+ if (reply?.trim() !== "确认") {
1090
+ return " 已取消解绑操作";
1064
1091
  }
1065
1092
  await bindingService.unbindQq(session.guildId, openId);
1066
- ctx.logger.info(`\u7528\u6237 ${binding.username}\uFF08OpenID: ${openId}\uFF09\u89E3\u9664\u4E86\u7ED1\u5B9A`);
1067
- return `\u2705 \u5DF2\u89E3\u9664\u300C${binding.username}\u300D\u7684\u7ED1\u5B9A`;
1093
+ ctx.logger.info(`用户 ${binding.username}(OpenID: ${openId})解除了绑定`);
1094
+ return `✅ 已解除「${binding.username}」的绑定`;
1068
1095
  });
1069
1096
  }
1097
+ __name(registerBindQqCommand, "registerBindQqCommand");
1070
1098
 
1071
1099
  // src/commands/adjust-score.ts
1072
1100
  function registerAdjustScoreCommand(ctx, serverService, adminService) {
1073
- ctx.command("\u8C03\u6574\u79EF\u5206 <\u7528\u6237\u540D:string> <\u5206\u6570:number> <\u539F\u56E0:text>").alias("adjust-score").action(async ({ session }, username, score, reason) => {
1101
+ ctx.command("调整积分 <用户名:string> <分数:number> <原因:text>").alias("adjust-score").action(async ({ session }, username, score, reason) => {
1074
1102
  if (!username || score === void 0 || !reason) {
1075
1103
  return HELP_MESSAGES.ADJUST_SCORE;
1076
1104
  }
1077
1105
  if (!session.guildId) {
1078
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1106
+ return "此命令只能在群聊中使用";
1079
1107
  }
1080
1108
  const hasPermission = await adminService.hasAdminPermission(session);
1081
1109
  if (!hasPermission) {
@@ -1107,24 +1135,25 @@ function registerAdjustScoreCommand(ctx, serverService, adminService) {
1107
1135
  ],
1108
1136
  description: reason
1109
1137
  };
1110
- ctx.logger.info(`\u8C03\u6574\u79EF\u5206\u8BF7\u6C42: \u7528\u6237=${username}, \u5206\u6570=${score}, \u539F\u56E0=${reason}`);
1138
+ ctx.logger.info(`调整积分请求: 用户=${username}, 分数=${score}, 原因=${reason}`);
1111
1139
  const result = await api.batchAddScore(data);
1112
- ctx.logger.info(`\u8C03\u6574\u79EF\u5206\u7ED3\u679C:`, JSON.stringify(result));
1140
+ ctx.logger.info(`调整积分结果:`, JSON.stringify(result));
1113
1141
  const message = Formatter.formatAddScoreResult(result);
1114
1142
  return Formatter.splitMessage(message);
1115
1143
  } catch (error) {
1116
- ctx.logger.error("\u8C03\u6574\u79EF\u5206\u5931\u8D25:", error);
1144
+ ctx.logger.error("调整积分失败:", error);
1117
1145
  return ERROR_MESSAGES.API_REQUEST_FAILED;
1118
1146
  }
1119
1147
  });
1120
1148
  }
1149
+ __name(registerAdjustScoreCommand, "registerAdjustScoreCommand");
1121
1150
 
1122
1151
  // src/commands/ranking.ts
1123
1152
  var PAGE_SIZE = 10;
1124
1153
  function registerRankingCommand(ctx, serverService) {
1125
- ctx.command("\u6392\u884C\u699C [\u9875\u7801:number]").alias("ranking").action(async ({ session }, page = 1) => {
1154
+ ctx.command("排行榜 [页码:number]").alias("ranking").action(async ({ session }, page = 1) => {
1126
1155
  if (!session.guildId) {
1127
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1156
+ return "此命令只能在群聊中使用";
1128
1157
  }
1129
1158
  const api = await serverService.createApiService(session.guildId);
1130
1159
  if (!api) {
@@ -1145,14 +1174,14 @@ function registerRankingCommand(ctx, serverService) {
1145
1174
  return ERROR_MESSAGES.API_REQUEST_FAILED;
1146
1175
  }
1147
1176
  if (response.data.length === 0) {
1148
- return `\u6682\u65E0\u6392\u884C\u6570\u636E`;
1177
+ return `暂无排行数据`;
1149
1178
  }
1150
1179
  const startRank = offset + 1;
1151
1180
  const message = Formatter.formatRankingWithRank(response.data, startRank);
1152
- const pageInfo = totalPages > 1 ? `\u7B2C ${page}/${totalPages} \u9875\uFF0C\u5171 ${totalUsers} \u4EBA` : `\u5171 ${totalUsers} \u4EBA`;
1181
+ const pageInfo = totalPages > 1 ? `第 ${page}/${totalPages} 页,共 ${totalUsers} 人` : `共 ${totalUsers} 人`;
1153
1182
  const rankItems = response.data.map((user, index) => {
1154
1183
  const rank = startRank + index;
1155
- const medal = rank === 1 ? "\u{1F947}" : rank === 2 ? "\u{1F948}" : rank === 3 ? "\u{1F949}" : `${rank}.`;
1184
+ const medal = rank === 1 ? "🥇" : rank === 2 ? "🥈" : rank === 3 ? "🥉" : `${rank}.`;
1156
1185
  const scoreColor = user.total_score >= 0 ? "#27ae60" : "#e74c3c";
1157
1186
  return `
1158
1187
  <div class="rank-item">
@@ -1216,32 +1245,33 @@ function registerRankingCommand(ctx, serverService) {
1216
1245
  </head>
1217
1246
  <body>
1218
1247
  <div class="container">
1219
- <div class="title"><span class="title-icon">\u{1F3C6}</span>\u79EF\u5206\u6392\u884C\u699C</div>
1248
+ <div class="title"><span class="title-icon">🏆</span>积分排行榜</div>
1220
1249
  <div class="rank-list">
1221
1250
  ${rankItems}
1222
1251
  </div>
1223
1252
  <div class="page-info">${pageInfo}</div>
1224
- <div class="footer">\u73ED\u7EA7\u64CD\u884C\u5206\u7BA1\u7406\u7CFB\u7EDF v1.0</div>
1253
+ <div class="footer">班级操行分管理系统 v1.0</div>
1225
1254
  </div>
1226
1255
  </body>
1227
1256
  </html>`;
1228
1257
  const textResult = message + (totalPages > 1 ? `
1229
1258
 
1230
- \u{1F4C4} ${pageInfo}` : "");
1259
+ 📄 ${pageInfo}` : "");
1231
1260
  await sendImageOrText(ctx, session, html, textResult, { height: 820 });
1232
1261
  return "";
1233
1262
  } catch (error) {
1234
- ctx.logger.error("\u83B7\u53D6\u6392\u884C\u699C\u5931\u8D25:", error);
1263
+ ctx.logger.error("获取排行榜失败:", error);
1235
1264
  return ERROR_MESSAGES.API_REQUEST_FAILED;
1236
1265
  }
1237
1266
  });
1238
1267
  }
1268
+ __name(registerRankingCommand, "registerRankingCommand");
1239
1269
 
1240
1270
  // src/commands/statistics.ts
1241
1271
  function registerStatisticsCommand(ctx, serverService, bindingService) {
1242
- ctx.command("\u7EDF\u8BA1 [\u7528\u6237\u540D:string]").alias("statistics").action(async ({ session }, username) => {
1272
+ ctx.command("统计 [用户名:string]").alias("statistics").action(async ({ session }, username) => {
1243
1273
  if (!session.guildId) {
1244
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1274
+ return "此命令只能在群聊中使用";
1245
1275
  }
1246
1276
  const api = await serverService.createApiService(session.guildId);
1247
1277
  if (!api) {
@@ -1252,13 +1282,13 @@ function registerStatisticsCommand(ctx, serverService, bindingService) {
1252
1282
  if (!username) {
1253
1283
  const openId = session.userId?.toString();
1254
1284
  if (!openId) {
1255
- return "\u65E0\u6CD5\u83B7\u53D6\u60A8\u7684\u7528\u6237ID";
1285
+ return "无法获取您的用户ID";
1256
1286
  }
1257
1287
  const binding = await bindingService.getUserByOpenId(session.guildId, openId);
1258
1288
  if (!binding) {
1259
1289
  return `${ERROR_MESSAGES.USER_NOT_BOUND}
1260
1290
 
1261
- \u8BF7\u5148\u4F7F\u7528 /\u7ED1\u5B9AQQ <\u7528\u6237\u540D> \u547D\u4EE4\u7ED1\u5B9A\u60A8\u7684\u8D26\u53F7`;
1291
+ 请先使用 /绑定QQ <用户名> 命令绑定您的账号`;
1262
1292
  }
1263
1293
  targetUsername = binding.username;
1264
1294
  }
@@ -1330,48 +1360,49 @@ function registerStatisticsCommand(ctx, serverService, bindingService) {
1330
1360
  </head>
1331
1361
  <body>
1332
1362
  <div class="container">
1333
- <div class="title">\u{1F4CA} \u79EF\u5206\u7EDF\u8BA1</div>
1363
+ <div class="title">📊 积分统计</div>
1334
1364
  <div class="user-info">
1335
1365
  <div class="username">${user.username}</div>
1336
- <div class="user-id">\u7528\u6237ID: ${user.id} | \u5F53\u524D\u79EF\u5206: ${user.total_score}</div>
1366
+ <div class="user-id">用户ID: ${user.id} | 当前积分: ${user.total_score}</div>
1337
1367
  </div>
1338
1368
  <div class="stats-grid">
1339
1369
  <div class="stat-card positive">
1340
- <div class="stat-label">\u7D2F\u8BA1\u52A0\u5206</div>
1370
+ <div class="stat-label">累计加分</div>
1341
1371
  <div class="stat-value positive">+${addScore}</div>
1342
1372
  </div>
1343
1373
  <div class="stat-card negative">
1344
- <div class="stat-label">\u7D2F\u8BA1\u6263\u5206</div>
1374
+ <div class="stat-label">累计扣分</div>
1345
1375
  <div class="stat-value negative">-${deductScore}</div>
1346
1376
  </div>
1347
1377
  <div class="stat-card total">
1348
- <div class="stat-label">\u603B\u79EF\u5206</div>
1378
+ <div class="stat-label">总积分</div>
1349
1379
  <div class="stat-value total">${totalScore}</div>
1350
1380
  </div>
1351
1381
  <div class="stat-card">
1352
- <div class="stat-label">\u64CD\u4F5C\u6B21\u6570</div>
1382
+ <div class="stat-label">操作次数</div>
1353
1383
  <div class="stat-value">${scoreCount}</div>
1354
1384
  </div>
1355
1385
  </div>
1356
- <div class="footer">\u73ED\u7EA7\u64CD\u884C\u5206\u7BA1\u7406\u7CFB\u7EDF v1.0</div>
1386
+ <div class="footer">班级操行分管理系统 v1.0</div>
1357
1387
  </div>
1358
1388
  </body>
1359
1389
  </html>`;
1360
1390
  const textResult = [
1361
- `\u3010${user.username} \u7684\u7EDF\u8BA1\u4FE1\u606F\u3011`,
1362
- `\u603B\u79EF\u5206: ${user.total_score}`,
1363
- `\u7D2F\u8BA1\u52A0\u5206: +${addScore}`,
1364
- `\u7D2F\u8BA1\u6263\u5206: -${deductScore}`,
1365
- `\u64CD\u4F5C\u6B21\u6570: ${scoreCount}`
1391
+ `【${user.username} 的统计信息】`,
1392
+ `总积分: ${user.total_score}`,
1393
+ `累计加分: +${addScore}`,
1394
+ `累计扣分: -${deductScore}`,
1395
+ `操作次数: ${scoreCount}`
1366
1396
  ].join("\n");
1367
1397
  await sendImageOrText(ctx, session, html, textResult, { height: 550 });
1368
1398
  return "";
1369
1399
  } catch (error) {
1370
- ctx.logger.error("\u83B7\u53D6\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25:", error);
1400
+ ctx.logger.error("获取统计信息失败:", error);
1371
1401
  return ERROR_MESSAGES.API_REQUEST_FAILED;
1372
1402
  }
1373
1403
  });
1374
1404
  }
1405
+ __name(registerStatisticsCommand, "registerStatisticsCommand");
1375
1406
 
1376
1407
  // src/commands/admin-manager.ts
1377
1408
  import { h as h2 } from "koishi";
@@ -1384,6 +1415,7 @@ function generateCode() {
1384
1415
  }
1385
1416
  return code;
1386
1417
  }
1418
+ __name(generateCode, "generateCode");
1387
1419
  function cleanupExpiredRequests() {
1388
1420
  const now = Date.now();
1389
1421
  for (const [code, req] of pendingRequests) {
@@ -1392,6 +1424,7 @@ function cleanupExpiredRequests() {
1392
1424
  }
1393
1425
  }
1394
1426
  }
1427
+ __name(cleanupExpiredRequests, "cleanupExpiredRequests");
1395
1428
  setInterval(cleanupExpiredRequests, 3e4);
1396
1429
  function registerGroupAdminCommand(ctx, adminService) {
1397
1430
  function getAtId(session) {
@@ -1403,17 +1436,18 @@ function registerGroupAdminCommand(ctx, adminService) {
1403
1436
  }
1404
1437
  return "";
1405
1438
  }
1406
- ctx.command("\u52A0\u7BA1 [\u5907\u6CE8:string]").alias("add-admin").action(async ({ session }, remark) => {
1439
+ __name(getAtId, "getAtId");
1440
+ ctx.command("加管 [备注:string]").alias("add-admin").action(async ({ session }, remark) => {
1407
1441
  if (!session.guildId) {
1408
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1442
+ return "此命令只能在群聊中使用";
1409
1443
  }
1410
1444
  const hasPermission = await adminService.hasAdminPermission(session);
1411
1445
  if (!hasPermission) {
1412
- return "\u274C \u6B64\u547D\u4EE4\u4EC5\u9650\u7BA1\u7406\u5458\u4F7F\u7528";
1446
+ return " 此命令仅限管理员使用";
1413
1447
  }
1414
1448
  const targetId = getAtId(session);
1415
1449
  if (!targetId) {
1416
- return "\u8BF7\u7528 @ \u6307\u5B9A\u8981\u6DFB\u52A0\u4E3A\u7FA4\u7BA1\u7684\u7528\u6237\uFF1A/\u52A0\u7BA1 @\u67D0\u4EBA";
1450
+ return "请用 @ 指定要添加为群管的用户:/加管 @某人";
1417
1451
  }
1418
1452
  cleanupExpiredRequests();
1419
1453
  for (const [, req] of pendingRequests) {
@@ -1421,11 +1455,11 @@ function registerGroupAdminCommand(ctx, adminService) {
1421
1455
  const admins = await adminService.getAllAdmins(session.guildId);
1422
1456
  const existing = admins.find((a) => a.verify === 0);
1423
1457
  if (existing) {
1424
- return `\u274C \u8BE5\u7528\u6237\u5DF2\u6709\u6B63\u5728\u7B49\u5F85\u786E\u8BA4\u7684\u52A0\u7BA1\u8BF7\u6C42`;
1458
+ return `❌ 该用户已有正在等待确认的加管请求`;
1425
1459
  }
1426
1460
  }
1427
1461
  }
1428
- const adminRemark = remark || "\u672A\u547D\u540D";
1462
+ const adminRemark = remark || "未命名";
1429
1463
  const code = generateCode();
1430
1464
  pendingRequests.set(code, {
1431
1465
  guildId: session.guildId,
@@ -1433,96 +1467,96 @@ function registerGroupAdminCommand(ctx, adminService) {
1433
1467
  createdAt: Date.now()
1434
1468
  });
1435
1469
  await session.send(
1436
- `\u2705 \u5DF2\u53D1\u8D77\u52A0\u7BA1\u8BF7\u6C42
1437
- ` + h2.at(targetId) + ` \u8BF7\u53D1\u9001 /\u786E\u8BA4 ${code} \u540C\u610F\u52A0\u7BA1
1438
- \u5907\u6CE8\uFF1A${adminRemark}
1439
- \uFF08120\u79D2\u5185\u6709\u6548\uFF09`
1470
+ `✅ 已发起加管请求
1471
+ ` + h2.at(targetId) + ` 请发送 /确认 ${code} 同意加管
1472
+ 备注:${adminRemark}
1473
+ (120秒内有效)`
1440
1474
  );
1441
1475
  return "";
1442
1476
  });
1443
- ctx.command("\u786E\u8BA4 [\u786E\u8BA4\u7801:string]").alias("confirm").action(async ({ session }, code) => {
1477
+ ctx.command("确认 [确认码:string]").alias("confirm").action(async ({ session }, code) => {
1444
1478
  if (!session.guildId) {
1445
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1479
+ return "此命令只能在群聊中使用";
1446
1480
  }
1447
1481
  const openId = session.userId?.toString();
1448
1482
  if (!openId) {
1449
- return "\u65E0\u6CD5\u83B7\u53D6\u60A8\u7684\u7528\u6237ID";
1483
+ return "无法获取您的用户ID";
1450
1484
  }
1451
1485
  if (!code) {
1452
- return "\u8BF7\u63D0\u4F9B\u786E\u8BA4\u7801\uFF1A/\u786E\u8BA4 [\u786E\u8BA4\u7801]";
1486
+ return "请提供确认码:/确认 [确认码]";
1453
1487
  }
1454
1488
  cleanupExpiredRequests();
1455
1489
  const req = pendingRequests.get(code);
1456
1490
  if (!req) {
1457
- return "\u274C \u65E0\u6548\u7684\u786E\u8BA4\u7801\u6216\u5DF2\u8FC7\u671F";
1491
+ return " 无效的确认码或已过期";
1458
1492
  }
1459
1493
  if (req.guildId !== session.guildId) {
1460
- return "\u274C \u8BF7\u5728\u53D1\u8D77\u52A0\u7BA1\u8BF7\u6C42\u7684\u7FA4\u804A\u4E2D\u786E\u8BA4";
1494
+ return " 请在发起加管请求的群聊中确认";
1461
1495
  }
1462
1496
  const remark = req.remark;
1463
1497
  pendingRequests.delete(code);
1464
1498
  await adminService.createPendingAdmin(session.guildId, openId, remark);
1465
- ctx.logger.info(`\u7FA4\u804A ${session.guildId} \u7528\u6237\u540C\u610F\u52A0\u7BA1: OpenID=${openId}, \u5907\u6CE8=${remark}, Verify=0`);
1499
+ ctx.logger.info(`群聊 ${session.guildId} 用户同意加管: OpenID=${openId}, 备注=${remark}, Verify=0`);
1466
1500
  await session.send(
1467
- `\u2705 \u60A8\u5DF2\u540C\u610F\u52A0\u7BA1
1468
- \u60A8\u7684 OpenID\uFF1A${openId}
1469
- \u5907\u6CE8\uFF1A${remark}
1470
- \u7B49\u5F85\u7BA1\u7406\u5458\u6267\u884C /\u52A0\u7BA1\u786E\u8BA4 \u5B8C\u6210\u52A0\u7BA1
1471
- \uFF08120\u79D2\u5185\u6709\u6548\uFF09`
1501
+ `✅ 您已同意加管
1502
+ 您的 OpenID:${openId}
1503
+ 备注:${remark}
1504
+ 等待管理员执行 /加管确认 完成加管
1505
+ (120秒内有效)`
1472
1506
  );
1473
1507
  return "";
1474
1508
  });
1475
- ctx.command("\u52A0\u7BA1\u786E\u8BA4 [\u786E\u8BA4\u7801:string]").alias("confirm-add-admin").action(async ({ session }, code) => {
1509
+ ctx.command("加管确认 [确认码:string]").alias("confirm-add-admin").action(async ({ session }, code) => {
1476
1510
  if (!session.guildId) {
1477
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1511
+ return "此命令只能在群聊中使用";
1478
1512
  }
1479
1513
  const hasPermission = await adminService.hasAdminPermission(session);
1480
1514
  if (!hasPermission) {
1481
- return "\u274C \u6B64\u547D\u4EE4\u4EC5\u9650\u7BA1\u7406\u5458\u4F7F\u7528";
1515
+ return " 此命令仅限管理员使用";
1482
1516
  }
1483
1517
  if (!code) {
1484
- return "\u8BF7\u63D0\u4F9B\u786E\u8BA4\u7801\uFF1A/\u52A0\u7BA1\u786E\u8BA4 [\u786E\u8BA4\u7801]";
1518
+ return "请提供确认码:/加管确认 [确认码]";
1485
1519
  }
1486
1520
  const admins = await adminService.getAllAdmins(session.guildId);
1487
1521
  const pendingAdmin = admins.find((a) => a.verify === 0);
1488
1522
  if (!pendingAdmin) {
1489
- return "\u274C \u6CA1\u6709\u5F85\u786E\u8BA4\u7684\u52A0\u7BA1\u8BF7\u6C42";
1523
+ return " 没有待确认的加管请求";
1490
1524
  }
1491
1525
  await adminService.confirmAdmin(session.guildId, pendingAdmin.openId);
1492
- ctx.logger.info(`\u7FA4\u804A ${session.guildId} \u6DFB\u52A0\u7FA4\u7BA1\u5B8C\u6210: OpenID=${pendingAdmin.openId}, \u5907\u6CE8=${pendingAdmin.remark}, Verify=1`);
1493
- return `\u2705 \u52A0\u7BA1\u6210\u529F
1494
- \u5907\u6CE8\uFF1A${pendingAdmin.remark}
1495
- OpenID\uFF1A${pendingAdmin.openId}`;
1526
+ ctx.logger.info(`群聊 ${session.guildId} 添加群管完成: OpenID=${pendingAdmin.openId}, 备注=${pendingAdmin.remark}, Verify=1`);
1527
+ return `✅ 加管成功
1528
+ 备注:${pendingAdmin.remark}
1529
+ OpenID:${pendingAdmin.openId}`;
1496
1530
  });
1497
- ctx.command("\u51CF\u7BA1 [\u5907\u6CE8:string]").alias("remove-admin").action(async ({ session }, remark) => {
1531
+ ctx.command("减管 [备注:string]").alias("remove-admin").action(async ({ session }, remark) => {
1498
1532
  if (!session.guildId) {
1499
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1533
+ return "此命令只能在群聊中使用";
1500
1534
  }
1501
1535
  const hasPermission = await adminService.hasAdminPermission(session);
1502
1536
  if (!hasPermission) {
1503
- return "\u274C \u6B64\u547D\u4EE4\u4EC5\u9650\u7BA1\u7406\u5458\u4F7F\u7528";
1537
+ return " 此命令仅限管理员使用";
1504
1538
  }
1505
1539
  if (!remark) {
1506
- return "\u8BF7\u63D0\u4F9B\u8981\u79FB\u9664\u7684\u7FA4\u7BA1\u5907\u6CE8\uFF1A/\u51CF\u7BA1 [\u5907\u6CE8]";
1540
+ return "请提供要移除的群管备注:/减管 [备注]";
1507
1541
  }
1508
1542
  await adminService.removeAdminByRemark(session.guildId, remark);
1509
- ctx.logger.info(`\u7FA4\u804A ${session.guildId} \u79FB\u9664\u7FA4\u7BA1: \u5907\u6CE8=${remark}`);
1510
- return `\u2705 \u5DF2\u79FB\u9664\u7FA4\u7BA1
1511
- \u5907\u6CE8\uFF1A${remark}`;
1543
+ ctx.logger.info(`群聊 ${session.guildId} 移除群管: 备注=${remark}`);
1544
+ return `✅ 已移除群管
1545
+ 备注:${remark}`;
1512
1546
  });
1513
- ctx.command("\u7FA4\u7BA1\u5217\u8868").alias("admin-list").action(async ({ session }) => {
1547
+ ctx.command("群管列表").alias("admin-list").action(async ({ session }) => {
1514
1548
  if (!session.guildId) {
1515
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1549
+ return "此命令只能在群聊中使用";
1516
1550
  }
1517
1551
  const admins = await adminService.getAllAdmins(session.guildId);
1518
1552
  if (admins.length === 0) {
1519
- return "\u5F53\u524D\u7FA4\u804A\u6CA1\u6709\u7BA1\u7406\u5458";
1553
+ return "当前群聊没有管理员";
1520
1554
  }
1521
1555
  const list = admins.map(
1522
- (admin, index) => `${index + 1}. [${admin.remark}] ${admin.openId} ${admin.verify === 1 ? "\u2705" : "\u23F3"}`
1556
+ (admin, index) => `${index + 1}. [${admin.remark}] ${admin.openId} ${admin.verify === 1 ? "" : ""}`
1523
1557
  ).join("\n");
1524
1558
  const adminItems = admins.map((admin, index) => {
1525
- const status = admin.verify === 1 ? "\u2705 \u5DF2\u9A8C\u8BC1" : "\u23F3 \u5F85\u786E\u8BA4";
1559
+ const status = admin.verify === 1 ? " 已验证" : " 待确认";
1526
1560
  const statusColor = admin.verify === 1 ? "#27ae60" : "#f39c12";
1527
1561
  return `
1528
1562
  <div class="admin-item">
@@ -1603,31 +1637,32 @@ OpenID\uFF1A${pendingAdmin.openId}`;
1603
1637
  </head>
1604
1638
  <body>
1605
1639
  <div class="container">
1606
- <div class="title">\u{1F465} \u7FA4\u7BA1\u5217\u8868</div>
1607
- <div class="count-badge">\u5171 ${admins.length} \u4F4D\u7BA1\u7406\u5458</div>
1640
+ <div class="title">👥 群管列表</div>
1641
+ <div class="count-badge">共 ${admins.length} 位管理员</div>
1608
1642
  <div class="admin-list">
1609
1643
  ${adminItems}
1610
1644
  </div>
1611
- <div class="footer">\u73ED\u7EA7\u64CD\u884C\u5206\u7BA1\u7406\u7CFB\u7EDF v1.0</div>
1645
+ <div class="footer">班级操行分管理系统 v1.0</div>
1612
1646
  </div>
1613
1647
  </body>
1614
1648
  </html>`;
1615
- await sendImageOrText(ctx, session, html, `\u5F53\u524D\u7FA4\u804A\u7684\u7BA1\u7406\u5458\uFF1A
1649
+ await sendImageOrText(ctx, session, html, `当前群聊的管理员:
1616
1650
  ${list}`, { height: 600 });
1617
1651
  return "";
1618
1652
  });
1619
- ctx.command("\u6211\u7684ID").alias("my-id").action(async ({ session }) => {
1653
+ ctx.command("我的ID").alias("my-id").action(async ({ session }) => {
1620
1654
  if (!session.guildId) {
1621
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1655
+ return "此命令只能在群聊中使用";
1622
1656
  }
1623
1657
  const openId = session.userId?.toString();
1624
1658
  if (!openId) {
1625
- return "\u65E0\u6CD5\u83B7\u53D6\u60A8\u7684\u7528\u6237ID";
1659
+ return "无法获取您的用户ID";
1626
1660
  }
1627
- return `\u60A8\u7684 OpenID\uFF1A
1661
+ return `您的 OpenID
1628
1662
  ${openId}`;
1629
1663
  });
1630
1664
  }
1665
+ __name(registerGroupAdminCommand, "registerGroupAdminCommand");
1631
1666
 
1632
1667
  // src/commands/menu.ts
1633
1668
  import { h as h3 } from "koishi";
@@ -1701,7 +1736,7 @@ var MENU_HTML = `
1701
1736
  border-bottom: none;
1702
1737
  }
1703
1738
  .command-item::before {
1704
- content: '\u2022';
1739
+ content: '';
1705
1740
  color: #9b59b6;
1706
1741
  font-weight: bold;
1707
1742
  margin-right: 6px;
@@ -1734,80 +1769,80 @@ var MENU_HTML = `
1734
1769
  </head>
1735
1770
  <body>
1736
1771
  <div class="container">
1737
- <div class="title">\u{1F4CB} \u73ED\u7EA7\u64CD\u884C\u5206\u7BA1\u7406\u7CFB\u7EDF\u83DC\u5355</div>
1772
+ <div class="title">📋 班级操行分管理系统菜单</div>
1738
1773
 
1739
1774
  <div class="section">
1740
- <div class="section-title">\u{1F6E0}\uFE0F \u57FA\u7840\u6307\u4EE4</div>
1775
+ <div class="section-title">🛠️ 基础指令</div>
1741
1776
  <ul class="command-list">
1742
1777
  <li class="command-item">
1743
- <span class="command-name">/\u67E5\u8BE2\u79EF\u5206</span>
1744
- <span class="command-desc">[\u7528\u6237\u540D]</span>
1778
+ <span class="command-name">/查询积分</span>
1779
+ <span class="command-desc">[用户名]</span>
1745
1780
  </li>
1746
1781
  <li class="command-item">
1747
- <span class="command-name">/\u7ED1\u5B9AQQ</span>
1748
- <span class="command-desc">&lt;\u7528\u6237\u540D&gt;</span>
1782
+ <span class="command-name">/绑定QQ</span>
1783
+ <span class="command-desc">&lt;用户名&gt;</span>
1749
1784
  </li>
1750
1785
  <li class="command-item">
1751
- <span class="command-name">/\u6392\u884C\u699C</span>
1752
- <span class="command-desc">[\u6570\u91CF]</span>
1786
+ <span class="command-name">/排行榜</span>
1787
+ <span class="command-desc">[数量]</span>
1753
1788
  </li>
1754
1789
  <li class="command-item">
1755
- <span class="command-name">/\u7EDF\u8BA1</span>
1756
- <span class="command-desc">[\u7528\u6237\u540D]</span>
1790
+ <span class="command-name">/统计</span>
1791
+ <span class="command-desc">[用户名]</span>
1757
1792
  </li>
1758
1793
  </ul>
1759
1794
  </div>
1760
1795
 
1761
1796
  <div class="section">
1762
- <div class="section-title">\u2699\uFE0F \u7BA1\u7406\u5458\u6307\u4EE4</div>
1797
+ <div class="section-title">⚙️ 管理员指令</div>
1763
1798
  <ul class="command-list">
1764
1799
  <li class="command-item">
1765
- <span class="command-name">/\u7ED1\u5B9A\u670D\u52A1\u5668</span>
1766
- <span class="command-desc">&lt;\u5730\u5740&gt; &lt;\u7528\u6237&gt; &lt;token&gt;</span>
1800
+ <span class="command-name">/绑定服务器</span>
1801
+ <span class="command-desc">&lt;地址&gt; &lt;用户&gt; &lt;token&gt;</span>
1767
1802
  </li>
1768
1803
  <li class="command-item">
1769
- <span class="command-name">/\u670D\u52A1\u5668\u89E3\u7ED1</span>
1804
+ <span class="command-name">/服务器解绑</span>
1770
1805
  </li>
1771
1806
  <li class="command-item">
1772
- <span class="command-name">/\u8C03\u6574\u79EF\u5206</span>
1773
- <span class="command-desc">&lt;\u7528\u6237&gt; &lt;\u5206\u6570&gt; &lt;\u539F\u56E0&gt;</span>
1807
+ <span class="command-name">/调整积分</span>
1808
+ <span class="command-desc">&lt;用户&gt; &lt;分数&gt; &lt;原因&gt;</span>
1774
1809
  </li>
1775
1810
  </ul>
1776
1811
  </div>
1777
1812
 
1778
1813
  <div class="section">
1779
- <div class="section-title">\u{1F464} \u7FA4\u7BA1\u6307\u4EE4</div>
1814
+ <div class="section-title">👤 群管指令</div>
1780
1815
  <ul class="command-list">
1781
1816
  <li class="command-item">
1782
- <span class="command-name">/\u52A0\u7BA1</span>
1783
- <span class="command-desc">@\u67D0\u4EBA &lt;\u5907\u6CE8&gt;</span>
1817
+ <span class="command-name">/加管</span>
1818
+ <span class="command-desc">@某人 &lt;备注&gt;</span>
1784
1819
  </li>
1785
1820
  <li class="command-item">
1786
- <span class="command-name">/\u786E\u8BA4</span>
1787
- <span class="command-desc">&lt;\u9A8C\u8BC1\u7801&gt;</span>
1821
+ <span class="command-name">/确认</span>
1822
+ <span class="command-desc">&lt;验证码&gt;</span>
1788
1823
  </li>
1789
1824
  <li class="command-item">
1790
- <span class="command-name">/\u52A0\u7BA1\u786E\u8BA4</span>
1825
+ <span class="command-name">/加管确认</span>
1791
1826
  </li>
1792
1827
  <li class="command-item">
1793
- <span class="command-name">/\u51CF\u7BA1</span>
1794
- <span class="command-desc">&lt;\u5907\u6CE8&gt;</span>
1828
+ <span class="command-name">/减管</span>
1829
+ <span class="command-desc">&lt;备注&gt;</span>
1795
1830
  </li>
1796
1831
  <li class="command-item">
1797
- <span class="command-name">/\u7FA4\u7BA1\u5217\u8868</span>
1832
+ <span class="command-name">/群管列表</span>
1798
1833
  </li>
1799
1834
  </ul>
1800
1835
  </div>
1801
1836
 
1802
- <div class="footer">\u73ED\u7EA7\u64CD\u884C\u5206\u7BA1\u7406\u7CFB\u7EDF v1.0</div>
1837
+ <div class="footer">班级操行分管理系统 v1.0</div>
1803
1838
  </div>
1804
1839
  </body>
1805
1840
  </html>
1806
1841
  `;
1807
1842
  function registerMenuCommand(ctx) {
1808
- ctx.command("\u83DC\u5355").alias("menu").action(async ({ session }) => {
1843
+ ctx.command("菜单").alias("menu").action(async ({ session }) => {
1809
1844
  if (!session.guildId) {
1810
- return "\u6B64\u547D\u4EE4\u53EA\u80FD\u5728\u7FA4\u804A\u4E2D\u4F7F\u7528";
1845
+ return "此命令只能在群聊中使用";
1811
1846
  }
1812
1847
  try {
1813
1848
  const page = await ctx.puppeteer.page();
@@ -1825,44 +1860,45 @@ function registerMenuCommand(ctx) {
1825
1860
  await session.send(h3.image(screenshot, "image/png"));
1826
1861
  return "";
1827
1862
  } catch (error) {
1828
- ctx.logger.error("\u751F\u6210\u83DC\u5355\u56FE\u7247\u5931\u8D25:", error);
1829
- return `\u{1F4CB} **\u73ED\u7EA7\u64CD\u884C\u5206\u7BA1\u7406\u7CFB\u7EDF\u83DC\u5355**
1863
+ ctx.logger.error("生成菜单图片失败:", error);
1864
+ return `📋 **班级操行分管理系统菜单**
1830
1865
 
1831
- \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
1832
- \u{1F6E0}\uFE0F **\u57FA\u7840\u6307\u4EE4**
1833
- \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
1834
- \u2022 /\u67E5\u8BE2\u79EF\u5206 [\u7528\u6237\u540D] - \u67E5\u8BE2\u79EF\u5206\u548C\u6392\u540D
1835
- \u2022 /\u7ED1\u5B9AQQ <\u7528\u6237\u540D> - \u7ED1\u5B9AQQ\u53F7\u4E0E\u7CFB\u7EDF\u8D26\u53F7
1836
- \u2022 /\u6392\u884C\u699C [\u6570\u91CF] - \u663E\u793A\u79EF\u5206\u6392\u884C\u699C
1837
- \u2022 /\u7EDF\u8BA1 [\u7528\u6237\u540D] - \u663E\u793A\u79EF\u5206\u7EDF\u8BA1\u4FE1\u606F
1866
+ ━━━━━━━━━━━━━━━━━━━━━━
1867
+ 🛠️ **基础指令**
1868
+ ━━━━━━━━━━━━━━━━━━━━━━
1869
+ /查询积分 [用户名] - 查询积分和排名
1870
+ /绑定QQ <用户名> - 绑定QQ号与系统账号
1871
+ /排行榜 [数量] - 显示积分排行榜
1872
+ /统计 [用户名] - 显示积分统计信息
1838
1873
 
1839
- \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
1840
- \u2699\uFE0F **\u7BA1\u7406\u5458\u6307\u4EE4**
1841
- \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
1842
- \u2022 /\u7ED1\u5B9A\u670D\u52A1\u5668 <\u5730\u5740> <\u7528\u6237\u540D> <token> - \u7ED1\u5B9ACSMS\u670D\u52A1\u5668
1843
- \u2022 /\u670D\u52A1\u5668\u89E3\u7ED1 - \u89E3\u9664\u670D\u52A1\u5668\u7ED1\u5B9A
1844
- \u2022 /\u8C03\u6574\u79EF\u5206 <\u7528\u6237\u540D> <\u5206\u6570> <\u539F\u56E0> - \u8C03\u6574\u79EF\u5206
1874
+ ━━━━━━━━━━━━━━━━━━━━━━
1875
+ ⚙️ **管理员指令**
1876
+ ━━━━━━━━━━━━━━━━━━━━━━
1877
+ /绑定服务器 <地址> <用户名> <token> - 绑定CSMS服务器
1878
+ /服务器解绑 - 解除服务器绑定
1879
+ /调整积分 <用户名> <分数> <原因> - 调整积分
1845
1880
 
1846
- \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
1847
- \u{1F464} **\u7FA4\u7BA1\u6307\u4EE4**
1848
- \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
1849
- \u2022 /\u52A0\u7BA1 @\u67D0\u4EBA <\u5907\u6CE8> - \u6DFB\u52A0\u7BA1\u7406\u5458
1850
- \u2022 /\u786E\u8BA4 <\u9A8C\u8BC1\u7801> - \u786E\u8BA4\u52A0\u7BA1
1851
- \u2022 /\u52A0\u7BA1\u786E\u8BA4 - \u5B8C\u6210\u52A0\u7BA1\u6D41\u7A0B
1852
- \u2022 /\u51CF\u7BA1 <\u5907\u6CE8> - \u79FB\u9664\u7BA1\u7406\u5458
1853
- \u2022 /\u7FA4\u7BA1\u5217\u8868 - \u663E\u793A\u7BA1\u7406\u5458\u5217\u8868
1881
+ ━━━━━━━━━━━━━━━━━━━━━━
1882
+ 👤 **群管指令**
1883
+ ━━━━━━━━━━━━━━━━━━━━━━
1884
+ /加管 @某人 <备注> - 添加管理员
1885
+ /确认 <验证码> - 确认加管
1886
+ /加管确认 - 完成加管流程
1887
+ /减管 <备注> - 移除管理员
1888
+ /群管列表 - 显示管理员列表
1854
1889
 
1855
- \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501`;
1890
+ ━━━━━━━━━━━━━━━━━━━━━━`;
1856
1891
  }
1857
1892
  });
1858
1893
  }
1894
+ __name(registerMenuCommand, "registerMenuCommand");
1859
1895
 
1860
1896
  // src/index.ts
1861
1897
  var name = "class-score-system";
1862
1898
  var inject = ["database", "puppeteer"];
1863
1899
  var Config = Schema.object({});
1864
1900
  function apply(ctx) {
1865
- ctx.logger.info("\u73ED\u7EA7\u64CD\u884C\u5206\u7BA1\u7406\u7CFB\u7EDF\u63D2\u4EF6\u6B63\u5728\u52A0\u8F7D...");
1901
+ ctx.logger.info("班级操行分管理系统插件正在加载...");
1866
1902
  extendDatabase(ctx);
1867
1903
  const serverService = new ServerConfigService(ctx);
1868
1904
  const bindingService = new QqBindingService(ctx);
@@ -1875,12 +1911,12 @@ function apply(ctx) {
1875
1911
  registerRankingCommand(ctx, serverService);
1876
1912
  registerStatisticsCommand(ctx, serverService, bindingService);
1877
1913
  registerMenuCommand(ctx);
1878
- ctx.logger.info("\u73ED\u7EA7\u64CD\u884C\u5206\u7BA1\u7406\u7CFB\u7EDF\u63D2\u4EF6\u52A0\u8F7D\u5B8C\u6210");
1914
+ ctx.logger.info("班级操行分管理系统插件加载完成");
1879
1915
  }
1916
+ __name(apply, "apply");
1880
1917
  export {
1881
1918
  Config,
1882
1919
  apply,
1883
1920
  inject,
1884
1921
  name
1885
1922
  };
1886
- //# sourceMappingURL=index.js.map