koishi-plugin-bind-bot 2.0.0 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,17 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.McidCommandHandler = void 0;
4
4
  const koishi_1 = require("koishi");
5
- class McidCommandHandler {
6
- ctx;
7
- deps;
8
- constructor(ctx, deps) {
9
- this.ctx = ctx;
10
- this.deps = deps;
11
- }
5
+ const base_handler_1 = require("./base.handler");
6
+ class McidCommandHandler extends base_handler_1.BaseHandler {
12
7
  /**
13
8
  * 注册所有MCID命令
14
9
  */
15
- registerCommands(cmd) {
10
+ register() {
11
+ const cmd = this.ctx.command('mcid', 'MC账号绑定管理');
16
12
  // mcid.query - 查询MC账号
17
13
  cmd.subcommand('.query [target:string]', '查询用户绑定的MC账号')
18
14
  .action(async ({ session }, target) => this.handleQuery(session, target));
@@ -60,16 +56,16 @@ class McidCommandHandler {
60
56
  if (target) {
61
57
  const normalizedTargetId = this.deps.normalizeQQId(target);
62
58
  if (!normalizedTargetId) {
63
- this.deps.logger.warn('查询', `QQ(${normalizedUserId})提供的目标用户ID"${target}"无效`);
59
+ this.logger.warn('查询', `QQ(${normalizedUserId})提供的目标用户ID"${target}"无效`);
64
60
  if (target.startsWith('@')) {
65
61
  return this.deps.sendMessage(session, [koishi_1.h.text('❌ 请使用真正的@功能,而不是手动输入@符号\n正确做法:点击或长按用户头像选择@功能')]);
66
62
  }
67
63
  return this.deps.sendMessage(session, [koishi_1.h.text('❌ 目标用户ID无效\n请提供有效的QQ号或使用@功能选择用户')]);
68
64
  }
69
- this.deps.logger.info('查询', `QQ(${normalizedUserId})查询QQ(${normalizedTargetId})的MC账号信息`);
65
+ this.logger.info('查询', `QQ(${normalizedUserId})查询QQ(${normalizedTargetId})的MC账号信息`);
70
66
  const targetBind = await this.deps.getMcBindByQQId(normalizedTargetId);
71
67
  if (!targetBind || !targetBind.mcUsername || targetBind.mcUsername.startsWith('_temp_')) {
72
- this.deps.logger.info('查询', `QQ(${normalizedTargetId})未绑定MC账号`);
68
+ this.logger.info('查询', `QQ(${normalizedTargetId})未绑定MC账号`);
73
69
  // 检查是否绑定了B站
74
70
  if (targetBind && targetBind.buidUid) {
75
71
  const buidUser = await this.deps.validateBUID(targetBind.buidUid);
@@ -91,7 +87,7 @@ class McidCommandHandler {
91
87
  buidInfo += `\n粉丝牌: ${refreshedBind.medalName} Lv.${refreshedBind.medalLevel}`;
92
88
  }
93
89
  const messageElements = [koishi_1.h.text(buidInfo)];
94
- if (this.deps.config.showAvatar) {
90
+ if (this.config.showAvatar) {
95
91
  messageElements.push(koishi_1.h.image(`https://workers.vrp.moe/bilibili/avatar/${refreshedBind.buidUid}?size=160`));
96
92
  }
97
93
  return this.deps.sendMessage(session, messageElements);
@@ -100,15 +96,15 @@ class McidCommandHandler {
100
96
  }
101
97
  return this.deps.sendMessage(session, [koishi_1.h.text('该用户尚未绑定MC账号')]);
102
98
  }
103
- // 显示MC绑定信息
104
- const updatedBind = await this.deps.checkAndUpdateUsername(targetBind);
99
+ // 显示MC绑定信息(使用智能缓存检测,避免频繁API调用)
100
+ const updatedBind = await this.deps.checkAndUpdateUsernameWithCache(targetBind);
105
101
  return this.buildQueryResponse(session, updatedBind, normalizedTargetId);
106
102
  }
107
103
  // 查询自己
108
- this.deps.logger.info('查询', `QQ(${normalizedUserId})查询自己的MC账号信息`);
104
+ this.logger.info('查询', `QQ(${normalizedUserId})查询自己的MC账号信息`);
109
105
  const selfBind = await this.deps.getMcBindByQQId(normalizedUserId);
110
106
  if (!selfBind || !selfBind.mcUsername || selfBind.mcUsername.startsWith('_temp_')) {
111
- this.deps.logger.info('查询', `QQ(${normalizedUserId})未绑定MC账号`);
107
+ this.logger.info('查询', `QQ(${normalizedUserId})未绑定MC账号`);
112
108
  // 检查是否绑定了B站
113
109
  if (selfBind && selfBind.buidUid) {
114
110
  const buidUser = await this.deps.validateBUID(selfBind.buidUid);
@@ -131,7 +127,7 @@ class McidCommandHandler {
131
127
  }
132
128
  buidInfo += `\n\n💡 您可以使用 ${this.deps.formatCommand('mcid bind <用户名>')} 绑定MC账号`;
133
129
  const messageElements = [koishi_1.h.text(buidInfo)];
134
- if (this.deps.config.showAvatar) {
130
+ if (this.config.showAvatar) {
135
131
  messageElements.push(koishi_1.h.image(`https://workers.vrp.moe/bilibili/avatar/${refreshedBind.buidUid}?size=160`));
136
132
  }
137
133
  return this.deps.sendMessage(session, messageElements);
@@ -140,12 +136,13 @@ class McidCommandHandler {
140
136
  }
141
137
  return this.deps.sendMessage(session, [koishi_1.h.text('您尚未绑定MC账号,请使用 ' + this.deps.formatCommand('mcid bind <用户名>') + ' 进行绑定')]);
142
138
  }
143
- const updatedBind = await this.deps.checkAndUpdateUsername(selfBind);
139
+ // 使用智能缓存检测,避免频繁API调用
140
+ const updatedBind = await this.deps.checkAndUpdateUsernameWithCache(selfBind);
144
141
  return this.buildQueryResponse(session, updatedBind, null);
145
142
  }
146
143
  catch (error) {
147
144
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
148
- this.deps.logger.error('查询', `QQ(${normalizedUserId})查询MC账号失败: ${error.message}`);
145
+ this.logger.error('查询', `QQ(${normalizedUserId})查询MC账号失败: ${error.message}`);
149
146
  return this.deps.sendMessage(session, [koishi_1.h.text(`查询失败: ${error.message}`)]);
150
147
  }
151
148
  }
@@ -156,8 +153,8 @@ class McidCommandHandler {
156
153
  const formattedUuid = this.deps.formatUuid(bind.mcUuid);
157
154
  // MC头像
158
155
  let mcAvatarUrl = null;
159
- if (this.deps.config.showAvatar) {
160
- if (this.deps.config.showMcSkin) {
156
+ if (this.config.showAvatar) {
157
+ if (this.config.showMcSkin) {
161
158
  mcAvatarUrl = this.deps.getStarlightSkinUrl(bind.mcUsername);
162
159
  }
163
160
  else {
@@ -171,7 +168,7 @@ class McidCommandHandler {
171
168
  const serverList = bind.whitelist.map((serverId, index) => {
172
169
  const server = this.deps.getServerConfigById(serverId);
173
170
  if (!server) {
174
- const disabledServer = this.deps.config.servers?.find(s => s.id === serverId);
171
+ const disabledServer = this.config.servers?.find(s => s.id === serverId);
175
172
  if (disabledServer && disabledServer.enabled === false) {
176
173
  return `${index < circledNumbers.length ? circledNumbers[index] : (index + 1)} ${disabledServer.name} [已停用]`;
177
174
  }
@@ -206,21 +203,21 @@ class McidCommandHandler {
206
203
  if (bind.medalName) {
207
204
  buidInfo += `\n粉丝牌: ${bind.medalName} Lv.${bind.medalLevel}`;
208
205
  }
209
- if (this.deps.config.showAvatar) {
206
+ if (this.config.showAvatar) {
210
207
  buidAvatar = koishi_1.h.image(`https://workers.vrp.moe/bilibili/avatar/${bind.buidUid}?size=160`);
211
208
  }
212
209
  }
213
210
  else {
214
211
  buidInfo = targetId ? '该用户尚未绑定B站账号' : `您尚未绑定B站账号,使用 ${this.deps.formatCommand('buid bind <B站UID>')} 进行绑定`;
215
212
  }
216
- this.deps.logger.info('查询', `QQ(${bind.qqId})的MC账号信息:用户名=${bind.mcUsername}, UUID=${bind.mcUuid}`);
213
+ this.logger.info('查询', `QQ(${bind.qqId})的MC账号信息:用户名=${bind.mcUsername}, UUID=${bind.mcUuid}`);
217
214
  // 自动设置群昵称
218
215
  if (bind.buidUid && bind.buidUsername) {
219
216
  const mcName = bind.mcUsername && !bind.mcUsername.startsWith('_temp_') ? bind.mcUsername : null;
220
217
  await this.deps.autoSetGroupNickname(session, mcName, bind.buidUsername, targetId || undefined);
221
218
  }
222
219
  else {
223
- this.deps.logger.info('查询', `QQ(${bind.qqId})未绑定B站账号,跳过群昵称设置`);
220
+ this.logger.info('查询', `QQ(${bind.qqId})未绑定B站账号,跳过群昵称设置`);
224
221
  }
225
222
  const displayUsername = bind.mcUsername && !bind.mcUsername.startsWith('_temp_') ? bind.mcUsername : '未绑定';
226
223
  const prefix = targetId ? `用户 ${targetId} 的` : '您的';
@@ -240,23 +237,23 @@ class McidCommandHandler {
240
237
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
241
238
  // 检查权限
242
239
  if (!await this.deps.isAdmin(session.userId)) {
243
- this.deps.logger.warn('反向查询', `权限不足: QQ(${normalizedUserId})不是管理员`);
240
+ this.logger.warn('反向查询', `权限不足: QQ(${normalizedUserId})不是管理员`);
244
241
  return this.deps.sendMessage(session, [koishi_1.h.text('只有管理员才能使用此命令')]);
245
242
  }
246
243
  if (!username) {
247
- this.deps.logger.warn('反向查询', `QQ(${normalizedUserId})未提供MC用户名`);
244
+ this.logger.warn('反向查询', `QQ(${normalizedUserId})未提供MC用户名`);
248
245
  return this.deps.sendMessage(session, [koishi_1.h.text('请提供要查询的MC用户名')]);
249
246
  }
250
- this.deps.logger.info('反向查询', `QQ(${normalizedUserId})尝试通过MC用户名"${username}"查询绑定的QQ账号`);
247
+ this.logger.info('反向查询', `QQ(${normalizedUserId})尝试通过MC用户名"${username}"查询绑定的QQ账号`);
251
248
  const bind = await this.deps.getMcBindByUsername(username);
252
249
  if (!bind || !bind.qqId) {
253
- this.deps.logger.info('反向查询', `MC用户名"${username}"未被任何QQ账号绑定`);
250
+ this.logger.info('反向查询', `MC用户名"${username}"未被任何QQ账号绑定`);
254
251
  return this.deps.sendMessage(session, [koishi_1.h.text(`未找到绑定MC用户名"${username}"的QQ账号`)]);
255
252
  }
256
253
  // MC头像
257
254
  let mcAvatarUrl = null;
258
- if (this.deps.config.showAvatar) {
259
- if (this.deps.config.showMcSkin) {
255
+ if (this.config.showAvatar) {
256
+ if (this.config.showMcSkin) {
260
257
  mcAvatarUrl = this.deps.getStarlightSkinUrl(bind.mcUsername);
261
258
  }
262
259
  else {
@@ -280,7 +277,7 @@ class McidCommandHandler {
280
277
  adminInfo += `\n绑定时间: ${bind.lastModified ? new Date(bind.lastModified).toLocaleString() : '未知'}`;
281
278
  adminInfo += `\n管理员权限: ${bind.isAdmin ? '是' : '否'}`;
282
279
  }
283
- this.deps.logger.info('反向查询', `成功: MC用户名"${username}"被QQ(${bind.qqId})绑定`);
280
+ this.logger.info('反向查询', `成功: MC用户名"${username}"被QQ(${bind.qqId})绑定`);
284
281
  const displayUsername = bind.mcUsername && !bind.mcUsername.startsWith('_temp_') ? bind.mcUsername : '未绑定';
285
282
  return this.deps.sendMessage(session, [
286
283
  koishi_1.h.text(`MC用户名"${displayUsername}"绑定信息:\nQQ号: ${bind.qqId}\nUUID: ${formattedUuid}${adminInfo}`),
@@ -289,7 +286,7 @@ class McidCommandHandler {
289
286
  }
290
287
  catch (error) {
291
288
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
292
- this.deps.logger.error('反向查询', `QQ(${normalizedUserId})通过MC用户名"${username}"查询失败: ${error.message}`);
289
+ this.logger.error('反向查询', `QQ(${normalizedUserId})通过MC用户名"${username}"查询失败: ${error.message}`);
293
290
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
294
291
  }
295
292
  }
@@ -301,13 +298,13 @@ class McidCommandHandler {
301
298
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
302
299
  // 检查用户名格式
303
300
  if (!username || !/^[a-zA-Z0-9_]{3,16}$/.test(username)) {
304
- this.deps.logger.warn('绑定', `QQ(${normalizedUserId})提供的用户名"${username}"格式无效`);
301
+ this.logger.warn('绑定', `QQ(${normalizedUserId})提供的用户名"${username}"格式无效`);
305
302
  return this.deps.sendMessage(session, [koishi_1.h.text('请提供有效的Minecraft用户名(3-16位字母、数字、下划线)')]);
306
303
  }
307
304
  // 验证用户名是否存在
308
305
  const profile = await this.deps.validateUsername(username);
309
306
  if (!profile) {
310
- this.deps.logger.warn('绑定', `QQ(${normalizedUserId})提供的用户名"${username}"不存在`);
307
+ this.logger.warn('绑定', `QQ(${normalizedUserId})提供的用户名"${username}"不存在`);
311
308
  return this.deps.sendMessage(session, [koishi_1.h.text(`无法验证用户名: ${username},该用户可能不存在`)]);
312
309
  }
313
310
  username = profile.name;
@@ -321,61 +318,61 @@ class McidCommandHandler {
321
318
  }
322
319
  catch (error) {
323
320
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
324
- this.deps.logger.error('绑定', `QQ(${normalizedUserId})绑定MC账号"${username}"失败: ${error.message}`);
321
+ this.logger.error('绑定', `QQ(${normalizedUserId})绑定MC账号"${username}"失败: ${error.message}`);
325
322
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
326
323
  }
327
324
  }
328
325
  async handleBindForOther(session, username, uuid, target, operatorId) {
329
326
  const normalizedTargetId = this.deps.normalizeQQId(target);
330
327
  if (!normalizedTargetId) {
331
- this.deps.logger.warn('绑定', `QQ(${operatorId})提供的目标用户ID"${target}"无效`);
328
+ this.logger.warn('绑定', `QQ(${operatorId})提供的目标用户ID"${target}"无效`);
332
329
  if (target.startsWith('@')) {
333
330
  return this.deps.sendMessage(session, [koishi_1.h.text('❌ 请使用真正的@功能,而不是手动输入@符号\n正确做法:点击或长按用户头像选择@功能')]);
334
331
  }
335
332
  return this.deps.sendMessage(session, [koishi_1.h.text('❌ 目标用户ID无效\n请提供有效的QQ号或使用@功能选择用户')]);
336
333
  }
337
- this.deps.logger.debug('绑定', `QQ(${operatorId})尝试为QQ(${normalizedTargetId})绑定MC账号: ${username}(${uuid})`);
334
+ this.logger.debug('绑定', `QQ(${operatorId})尝试为QQ(${normalizedTargetId})绑定MC账号: ${username}(${uuid})`);
338
335
  // 检查权限
339
336
  if (!await this.deps.isAdmin(session.userId)) {
340
- this.deps.logger.warn('绑定', `权限不足: QQ(${operatorId})不是管理员`);
337
+ this.logger.warn('绑定', `权限不足: QQ(${operatorId})不是管理员`);
341
338
  return this.deps.sendMessage(session, [koishi_1.h.text('只有管理员才能为其他用户绑定MC账号')]);
342
339
  }
343
- // 检查用户名是否已被占用
344
- if (await this.deps.checkUsernameExists(username, target)) {
345
- this.deps.logger.warn('绑定', `MC用户名"${username}"已被其他QQ号绑定`);
340
+ // 检查用户名是否已被占用(支持改名检测)
341
+ if (await this.deps.checkUsernameExists(username, target, uuid)) {
342
+ this.logger.warn('绑定', `MC用户名"${username}"已被其他QQ号绑定`);
346
343
  return this.deps.sendMessage(session, [koishi_1.h.text(`用户名 ${username} 已被其他用户绑定`)]);
347
344
  }
348
345
  // 绑定
349
346
  const bindResult = await this.deps.createOrUpdateMcBind(target, username, uuid);
350
347
  if (!bindResult) {
351
- this.deps.logger.error('绑定', `管理员QQ(${operatorId})为QQ(${normalizedTargetId})绑定MC账号"${username}"失败`);
348
+ this.logger.error('绑定', `管理员QQ(${operatorId})为QQ(${normalizedTargetId})绑定MC账号"${username}"失败`);
352
349
  return this.deps.sendMessage(session, [koishi_1.h.text(`为用户 ${normalizedTargetId} 绑定MC账号失败: 数据库操作出错,请联系管理员`)]);
353
350
  }
354
- this.deps.logger.info('绑定', `成功: 管理员QQ(${operatorId})为QQ(${normalizedTargetId})绑定MC账号: ${username}(${uuid})`);
351
+ this.logger.info('绑定', `成功: 管理员QQ(${operatorId})为QQ(${normalizedTargetId})绑定MC账号: ${username}(${uuid})`);
355
352
  // 清理绑定会话
356
353
  this.deps.removeBindingSession(target, session.channelId);
357
- this.deps.logger.info('绑定', `管理员为QQ(${normalizedTargetId})绑定MC账号后,已清理该用户的交互式绑定会话`);
354
+ this.logger.info('绑定', `管理员为QQ(${normalizedTargetId})绑定MC账号后,已清理该用户的交互式绑定会话`);
358
355
  // 尝试设置群昵称
359
356
  let targetBuidStatus = '';
360
357
  try {
361
358
  const latestTargetBind = await this.deps.getMcBindByQQId(normalizedTargetId);
362
359
  if (latestTargetBind && latestTargetBind.buidUid && latestTargetBind.buidUsername) {
363
360
  await this.deps.autoSetGroupNickname(session, username, latestTargetBind.buidUsername, normalizedTargetId);
364
- this.deps.logger.info('绑定', `管理员QQ(${operatorId})为QQ(${normalizedTargetId})MC绑定完成,已尝试设置群昵称`);
361
+ this.logger.info('绑定', `管理员QQ(${operatorId})为QQ(${normalizedTargetId})MC绑定完成,已尝试设置群昵称`);
365
362
  targetBuidStatus = '\n✅ 该用户已绑定B站账号,群昵称已更新';
366
363
  }
367
364
  else {
368
- this.deps.logger.info('绑定', `管理员QQ(${operatorId})为QQ(${normalizedTargetId})MC绑定完成,但目标用户未绑定B站账号`);
365
+ this.logger.info('绑定', `管理员QQ(${operatorId})为QQ(${normalizedTargetId})MC绑定完成,但目标用户未绑定B站账号`);
369
366
  targetBuidStatus = '\n⚠️ 该用户尚未绑定B站账号,建议提醒其使用 buid bind 命令完成B站绑定';
370
367
  }
371
368
  }
372
369
  catch (renameError) {
373
- this.deps.logger.warn('绑定', `管理员QQ(${operatorId})为QQ(${normalizedTargetId})MC绑定后群昵称设置失败: ${renameError.message}`);
370
+ this.logger.warn('绑定', `管理员QQ(${operatorId})为QQ(${normalizedTargetId})MC绑定后群昵称设置失败: ${renameError.message}`);
374
371
  }
375
372
  // MC头像
376
373
  let mcAvatarUrl = null;
377
- if (this.deps.config.showAvatar) {
378
- if (this.deps.config.showMcSkin) {
374
+ if (this.config.showAvatar) {
375
+ if (this.config.showMcSkin) {
379
376
  mcAvatarUrl = this.deps.getStarlightSkinUrl(username);
380
377
  }
381
378
  else {
@@ -389,7 +386,7 @@ class McidCommandHandler {
389
386
  ]);
390
387
  }
391
388
  async handleBindForSelf(session, username, uuid, operatorId) {
392
- this.deps.logger.debug('绑定', `QQ(${operatorId})尝试绑定MC账号: ${username}(${uuid})`);
389
+ this.logger.debug('绑定', `QQ(${operatorId})尝试绑定MC账号: ${username}(${uuid})`);
393
390
  // 检查是否已绑定
394
391
  const selfBind = await this.deps.getMcBindByQQId(operatorId);
395
392
  if (selfBind && selfBind.mcUsername) {
@@ -397,55 +394,55 @@ class McidCommandHandler {
397
394
  if (!isTempUsername) {
398
395
  // 检查冷却时间
399
396
  if (!await this.deps.isAdmin(session.userId) && !this.deps.checkCooldown(selfBind.lastModified)) {
400
- const days = this.deps.config.cooldownDays;
397
+ const days = this.config.cooldownDays;
401
398
  const now = new Date();
402
399
  const diffTime = now.getTime() - selfBind.lastModified.getTime();
403
400
  const passedDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
404
401
  const remainingDays = days - passedDays;
405
- this.deps.logger.warn('绑定', `QQ(${operatorId})已绑定MC账号"${selfBind.mcUsername}",且在冷却期内`);
402
+ this.logger.warn('绑定', `QQ(${operatorId})已绑定MC账号"${selfBind.mcUsername}",且在冷却期内`);
406
403
  const displayUsername = selfBind.mcUsername && !selfBind.mcUsername.startsWith('_temp_') ? selfBind.mcUsername : '未绑定';
407
404
  return this.deps.sendMessage(session, [koishi_1.h.text(`您已绑定MC账号: ${displayUsername},如需修改,请在冷却期结束后(还需${remainingDays}天)使用 ` + this.deps.formatCommand('mcid change') + ` 命令或联系管理员。`)]);
408
405
  }
409
- this.deps.logger.debug('绑定', `QQ(${operatorId})已绑定MC账号"${selfBind.mcUsername}",建议使用change命令`);
406
+ this.logger.debug('绑定', `QQ(${operatorId})已绑定MC账号"${selfBind.mcUsername}",建议使用change命令`);
410
407
  const displayUsername = selfBind.mcUsername && !selfBind.mcUsername.startsWith('_temp_') ? selfBind.mcUsername : '未绑定';
411
408
  return this.deps.sendMessage(session, [koishi_1.h.text(`您已绑定MC账号: ${displayUsername},如需修改请使用 ` + this.deps.formatCommand('mcid change') + ` 命令。`)]);
412
409
  }
413
410
  else {
414
- this.deps.logger.debug('绑定', `QQ(${operatorId})之前绑定的是临时用户名"${selfBind.mcUsername}",允许直接使用bind命令`);
411
+ this.logger.debug('绑定', `QQ(${operatorId})之前绑定的是临时用户名"${selfBind.mcUsername}",允许直接使用bind命令`);
415
412
  }
416
413
  }
417
- // 检查用户名是否已被占用
418
- if (await this.deps.checkUsernameExists(username)) {
419
- this.deps.logger.warn('绑定', `MC用户名"${username}"已被其他QQ号绑定`);
414
+ // 检查用户名是否已被占用(支持改名检测)
415
+ if (await this.deps.checkUsernameExists(username, session.userId, uuid)) {
416
+ this.logger.warn('绑定', `MC用户名"${username}"已被其他QQ号绑定`);
420
417
  return this.deps.sendMessage(session, [koishi_1.h.text(`用户名 ${username} 已被其他用户绑定`)]);
421
418
  }
422
419
  // 绑定
423
420
  const bindResult = await this.deps.createOrUpdateMcBind(session.userId, username, uuid);
424
421
  if (!bindResult) {
425
- this.deps.logger.error('绑定', `QQ(${operatorId})绑定MC账号"${username}"失败`);
422
+ this.logger.error('绑定', `QQ(${operatorId})绑定MC账号"${username}"失败`);
426
423
  return this.deps.sendMessage(session, [koishi_1.h.text('绑定失败,数据库操作出错,请联系管理员')]);
427
424
  }
428
- this.deps.logger.info('绑定', `成功: QQ(${operatorId})绑定MC账号: ${username}(${uuid})`);
425
+ this.logger.info('绑定', `成功: QQ(${operatorId})绑定MC账号: ${username}(${uuid})`);
429
426
  // 尝试设置群昵称
430
427
  let buidReminder = '';
431
428
  try {
432
429
  const latestBind = await this.deps.getMcBindByQQId(operatorId);
433
430
  if (latestBind && latestBind.buidUid && latestBind.buidUsername) {
434
431
  await this.deps.autoSetGroupNickname(session, username, latestBind.buidUsername);
435
- this.deps.logger.info('绑定', `QQ(${operatorId})MC绑定完成,已尝试设置群昵称`);
432
+ this.logger.info('绑定', `QQ(${operatorId})MC绑定完成,已尝试设置群昵称`);
436
433
  }
437
434
  else {
438
435
  buidReminder = `\n\n💡 提醒:您还未绑定B站账号,建议使用 ${this.deps.formatCommand('buid bind <B站UID>')} 完成B站绑定以享受完整功能`;
439
- this.deps.logger.info('绑定', `QQ(${operatorId})MC绑定完成,但未绑定B站账号`);
436
+ this.logger.info('绑定', `QQ(${operatorId})MC绑定完成,但未绑定B站账号`);
440
437
  }
441
438
  }
442
439
  catch (renameError) {
443
- this.deps.logger.warn('绑定', `QQ(${operatorId})MC绑定后群昵称设置失败: ${renameError.message}`);
440
+ this.logger.warn('绑定', `QQ(${operatorId})MC绑定后群昵称设置失败: ${renameError.message}`);
444
441
  }
445
442
  // MC头像
446
443
  let mcAvatarUrl = null;
447
- if (this.deps.config.showAvatar) {
448
- if (this.deps.config.showMcSkin) {
444
+ if (this.config.showAvatar) {
445
+ if (this.config.showMcSkin) {
449
446
  mcAvatarUrl = this.deps.getStarlightSkinUrl(username);
450
447
  }
451
448
  else {
@@ -466,13 +463,13 @@ class McidCommandHandler {
466
463
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
467
464
  // 检查用户名格式
468
465
  if (!username || !/^[a-zA-Z0-9_]{3,16}$/.test(username)) {
469
- this.deps.logger.warn('修改', `QQ(${normalizedUserId})提供的用户名"${username}"格式无效`);
466
+ this.logger.warn('修改', `QQ(${normalizedUserId})提供的用户名"${username}"格式无效`);
470
467
  return this.deps.sendMessage(session, [koishi_1.h.text('请提供有效的Minecraft用户名(3-16位字母、数字、下划线)')]);
471
468
  }
472
469
  // 验证用户名是否存在
473
470
  const profile = await this.deps.validateUsername(username);
474
471
  if (!profile) {
475
- this.deps.logger.warn('修改', `QQ(${normalizedUserId})提供的用户名"${username}"不存在`);
472
+ this.logger.warn('修改', `QQ(${normalizedUserId})提供的用户名"${username}"不存在`);
476
473
  return this.deps.sendMessage(session, [koishi_1.h.text(`无法验证用户名: ${username},该用户可能不存在`)]);
477
474
  }
478
475
  username = profile.name;
@@ -486,53 +483,53 @@ class McidCommandHandler {
486
483
  }
487
484
  catch (error) {
488
485
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
489
- this.deps.logger.error('修改', `QQ(${normalizedUserId})修改MC账号为"${username}"失败: ${error.message}`);
486
+ this.logger.error('修改', `QQ(${normalizedUserId})修改MC账号为"${username}"失败: ${error.message}`);
490
487
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
491
488
  }
492
489
  }
493
490
  async handleChangeForOther(session, username, uuid, target, operatorId) {
494
491
  const normalizedTargetId = this.deps.normalizeQQId(target);
495
492
  if (!normalizedTargetId) {
496
- this.deps.logger.warn('修改', `QQ(${operatorId})提供的目标用户ID"${target}"无效`);
493
+ this.logger.warn('修改', `QQ(${operatorId})提供的目标用户ID"${target}"无效`);
497
494
  if (target.startsWith('@')) {
498
495
  return this.deps.sendMessage(session, [koishi_1.h.text('❌ 请使用真正的@功能,而不是手动输入@符号\n正确做法:点击或长按用户头像选择@功能')]);
499
496
  }
500
497
  return this.deps.sendMessage(session, [koishi_1.h.text('❌ 目标用户ID无效\n请提供有效的QQ号或使用@功能选择用户')]);
501
498
  }
502
- this.deps.logger.info('修改', `QQ(${operatorId})尝试修改QQ(${normalizedTargetId})的MC账号为: ${username}(${uuid})`);
499
+ this.logger.info('修改', `QQ(${operatorId})尝试修改QQ(${normalizedTargetId})的MC账号为: ${username}(${uuid})`);
503
500
  // 检查权限
504
501
  if (!await this.deps.isAdmin(session.userId)) {
505
- this.deps.logger.warn('修改', `权限不足: QQ(${operatorId})不是管理员`);
502
+ this.logger.warn('修改', `权限不足: QQ(${operatorId})不是管理员`);
506
503
  return this.deps.sendMessage(session, [koishi_1.h.text('只有管理员才能修改其他用户的MC账号')]);
507
504
  }
508
505
  // 获取目标用户信息
509
506
  const targetBind = await this.deps.getMcBindByQQId(normalizedTargetId);
510
507
  if (!targetBind || !targetBind.mcUsername) {
511
- this.deps.logger.warn('修改', `QQ(${normalizedTargetId})尚未绑定MC账号`);
508
+ this.logger.warn('修改', `QQ(${normalizedTargetId})尚未绑定MC账号`);
512
509
  return this.deps.sendMessage(session, [koishi_1.h.text(`用户 ${normalizedTargetId} 尚未绑定MC账号,请先使用 ` + this.deps.formatCommand('mcid bind') + ` 命令进行绑定`)]);
513
510
  }
514
511
  // 检查是否与当前用户名相同
515
512
  if (targetBind.mcUsername === username) {
516
- this.deps.logger.warn('修改', `QQ(${normalizedTargetId})已绑定相同的MC账号"${username}"`);
513
+ this.logger.warn('修改', `QQ(${normalizedTargetId})已绑定相同的MC账号"${username}"`);
517
514
  return this.deps.sendMessage(session, [koishi_1.h.text(`用户 ${normalizedTargetId} 当前已绑定此用户名: ${username}`)]);
518
515
  }
519
- // 检查用户名是否已被占用
520
- if (await this.deps.checkUsernameExists(username, target)) {
521
- this.deps.logger.warn('修改', `MC用户名"${username}"已被其他QQ号绑定`);
516
+ // 检查用户名是否已被占用(支持改名检测)
517
+ if (await this.deps.checkUsernameExists(username, target, uuid)) {
518
+ this.logger.warn('修改', `MC用户名"${username}"已被其他QQ号绑定`);
522
519
  return this.deps.sendMessage(session, [koishi_1.h.text(`用户名 ${username} 已被其他用户绑定`)]);
523
520
  }
524
521
  const oldUsername = targetBind.mcUsername;
525
522
  // 更新绑定信息
526
523
  const bindResult = await this.deps.createOrUpdateMcBind(target, username, uuid);
527
524
  if (!bindResult) {
528
- this.deps.logger.error('修改', `管理员QQ(${operatorId})修改QQ(${normalizedTargetId})的MC账号失败`);
525
+ this.logger.error('修改', `管理员QQ(${operatorId})修改QQ(${normalizedTargetId})的MC账号失败`);
529
526
  return this.deps.sendMessage(session, [koishi_1.h.text(`修改用户 ${normalizedTargetId} 的MC账号失败: 数据库操作出错,请联系管理员`)]);
530
527
  }
531
- this.deps.logger.info('修改', `成功: 管理员QQ(${operatorId})修改QQ(${normalizedTargetId})的MC账号: ${oldUsername} -> ${username}(${uuid})`);
528
+ this.logger.info('修改', `成功: 管理员QQ(${operatorId})修改QQ(${normalizedTargetId})的MC账号: ${oldUsername} -> ${username}(${uuid})`);
532
529
  // MC头像
533
530
  let mcAvatarUrl = null;
534
- if (this.deps.config.showAvatar) {
535
- if (this.deps.config.showMcSkin) {
531
+ if (this.config.showAvatar) {
532
+ if (this.config.showMcSkin) {
536
533
  mcAvatarUrl = this.deps.getStarlightSkinUrl(username);
537
534
  }
538
535
  else {
@@ -549,41 +546,41 @@ class McidCommandHandler {
549
546
  const selfBind = await this.deps.getMcBindByQQId(operatorId);
550
547
  // 检查是否已绑定
551
548
  if (!selfBind || !selfBind.mcUsername) {
552
- this.deps.logger.warn('修改', `QQ(${operatorId})尚未绑定MC账号`);
549
+ this.logger.warn('修改', `QQ(${operatorId})尚未绑定MC账号`);
553
550
  return this.deps.sendMessage(session, [koishi_1.h.text('您尚未绑定MC账号,请使用 ' + this.deps.formatCommand('mcid bind') + ' 命令进行绑定')]);
554
551
  }
555
552
  // 检查是否与当前用户名相同
556
553
  if (selfBind.mcUsername === username) {
557
- this.deps.logger.warn('修改', `QQ(${operatorId})已绑定相同的MC账号"${username}"`);
554
+ this.logger.warn('修改', `QQ(${operatorId})已绑定相同的MC账号"${username}"`);
558
555
  return this.deps.sendMessage(session, [koishi_1.h.text(`您当前已绑定此用户名: ${username}`)]);
559
556
  }
560
557
  // 检查冷却时间
561
558
  if (!await this.deps.isAdmin(session.userId) && !this.deps.checkCooldown(selfBind.lastModified)) {
562
- const days = this.deps.config.cooldownDays;
559
+ const days = this.config.cooldownDays;
563
560
  const now = new Date();
564
561
  const diffTime = now.getTime() - selfBind.lastModified.getTime();
565
562
  const passedDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
566
563
  const remainingDays = days - passedDays;
567
- this.deps.logger.warn('修改', `QQ(${operatorId})在冷却期内,无法修改MC账号`);
564
+ this.logger.warn('修改', `QQ(${operatorId})在冷却期内,无法修改MC账号`);
568
565
  return this.deps.sendMessage(session, [koishi_1.h.text(`您的MC账号绑定在冷却期内,还需${remainingDays}天才能修改。如需立即修改,请联系管理员。`)]);
569
566
  }
570
- // 检查用户名是否已被占用
571
- if (await this.deps.checkUsernameExists(username, session.userId)) {
572
- this.deps.logger.warn('修改', `MC用户名"${username}"已被其他QQ号绑定`);
567
+ // 检查用户名是否已被占用(支持改名检测)
568
+ if (await this.deps.checkUsernameExists(username, session.userId, uuid)) {
569
+ this.logger.warn('修改', `MC用户名"${username}"已被其他QQ号绑定`);
573
570
  return this.deps.sendMessage(session, [koishi_1.h.text(`用户名 ${username} 已被其他用户绑定`)]);
574
571
  }
575
572
  const oldUsername = selfBind.mcUsername;
576
573
  // 更新绑定信息
577
574
  const bindResult = await this.deps.createOrUpdateMcBind(session.userId, username, uuid);
578
575
  if (!bindResult) {
579
- this.deps.logger.error('修改', `QQ(${operatorId})修改MC账号失败`);
576
+ this.logger.error('修改', `QQ(${operatorId})修改MC账号失败`);
580
577
  return this.deps.sendMessage(session, [koishi_1.h.text('修改失败,数据库操作出错,请联系管理员')]);
581
578
  }
582
- this.deps.logger.info('修改', `成功: QQ(${operatorId})修改MC账号: ${oldUsername} -> ${username}(${uuid})`);
579
+ this.logger.info('修改', `成功: QQ(${operatorId})修改MC账号: ${oldUsername} -> ${username}(${uuid})`);
583
580
  // MC头像
584
581
  let mcAvatarUrl = null;
585
- if (this.deps.config.showAvatar) {
586
- if (this.deps.config.showMcSkin) {
582
+ if (this.config.showAvatar) {
583
+ if (this.config.showMcSkin) {
587
584
  mcAvatarUrl = this.deps.getStarlightSkinUrl(username);
588
585
  }
589
586
  else {
@@ -612,50 +609,50 @@ class McidCommandHandler {
612
609
  catch (error) {
613
610
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
614
611
  const targetInfo = target ? `为QQ(${this.deps.normalizeQQId(target)})` : '';
615
- this.deps.logger.error('解绑', `QQ(${normalizedUserId})${targetInfo}解绑MC账号失败: ${error.message}`);
612
+ this.logger.error('解绑', `QQ(${normalizedUserId})${targetInfo}解绑MC账号失败: ${error.message}`);
616
613
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
617
614
  }
618
615
  }
619
616
  async handleUnbindForOther(session, target, operatorId) {
620
617
  const normalizedTargetId = this.deps.normalizeQQId(target);
621
618
  if (!normalizedTargetId) {
622
- this.deps.logger.warn('解绑', `QQ(${operatorId})提供的目标用户ID"${target}"无效`);
619
+ this.logger.warn('解绑', `QQ(${operatorId})提供的目标用户ID"${target}"无效`);
623
620
  if (target.startsWith('@')) {
624
621
  return this.deps.sendMessage(session, [koishi_1.h.text('❌ 请使用真正的@功能,而不是手动输入@符号\n正确做法:点击或长按用户头像选择@功能')]);
625
622
  }
626
623
  return this.deps.sendMessage(session, [koishi_1.h.text('❌ 目标用户ID无效\n请提供有效的QQ号或使用@功能选择用户')]);
627
624
  }
628
- this.deps.logger.info('解绑', `QQ(${operatorId})尝试为QQ(${normalizedTargetId})解绑MC账号`);
625
+ this.logger.info('解绑', `QQ(${operatorId})尝试为QQ(${normalizedTargetId})解绑MC账号`);
629
626
  // 检查权限
630
627
  if (!await this.deps.isAdmin(session.userId)) {
631
- this.deps.logger.warn('解绑', `权限不足: QQ(${operatorId})不是管理员`);
628
+ this.logger.warn('解绑', `权限不足: QQ(${operatorId})不是管理员`);
632
629
  return this.deps.sendMessage(session, [koishi_1.h.text('只有管理员才能为其他用户解绑MC账号')]);
633
630
  }
634
631
  // 获取目标用户信息
635
632
  const targetBind = await this.deps.getMcBindByQQId(normalizedTargetId);
636
633
  if (!targetBind || !targetBind.mcUsername) {
637
- this.deps.logger.warn('解绑', `QQ(${normalizedTargetId})尚未绑定MC账号`);
634
+ this.logger.warn('解绑', `QQ(${normalizedTargetId})尚未绑定MC账号`);
638
635
  return this.deps.sendMessage(session, [koishi_1.h.text(`用户 ${normalizedTargetId} 尚未绑定MC账号`)]);
639
636
  }
640
637
  const oldUsername = targetBind.mcUsername && !targetBind.mcUsername.startsWith('_temp_') ? targetBind.mcUsername : '未绑定';
641
638
  const oldBuidInfo = targetBind.buidUid ? ` 和 B站账号: ${targetBind.buidUsername}(${targetBind.buidUid})` : '';
642
639
  // 删除绑定记录
643
640
  await this.deps.deleteMcBind(target);
644
- this.deps.logger.info('解绑', `成功: 管理员QQ(${operatorId})为QQ(${normalizedTargetId})解绑MC账号: ${oldUsername}${oldBuidInfo}`);
641
+ this.logger.info('解绑', `成功: 管理员QQ(${operatorId})为QQ(${normalizedTargetId})解绑MC账号: ${oldUsername}${oldBuidInfo}`);
645
642
  return this.deps.sendMessage(session, [koishi_1.h.text(`已成功为用户 ${normalizedTargetId} 解绑MC账号: ${oldUsername}${oldBuidInfo}`)]);
646
643
  }
647
644
  async handleUnbindForSelf(session, operatorId) {
648
- this.deps.logger.info('解绑', `QQ(${operatorId})尝试解绑自己的MC账号`);
645
+ this.logger.info('解绑', `QQ(${operatorId})尝试解绑自己的MC账号`);
649
646
  const selfBind = await this.deps.getMcBindByQQId(operatorId);
650
647
  if (!selfBind || !selfBind.mcUsername) {
651
- this.deps.logger.warn('解绑', `QQ(${operatorId})尚未绑定MC账号`);
648
+ this.logger.warn('解绑', `QQ(${operatorId})尚未绑定MC账号`);
652
649
  return this.deps.sendMessage(session, [koishi_1.h.text('您尚未绑定MC账号')]);
653
650
  }
654
651
  const oldUsername = selfBind.mcUsername && !selfBind.mcUsername.startsWith('_temp_') ? selfBind.mcUsername : '未绑定';
655
652
  const oldBuidInfo = selfBind.buidUid ? ` 和 B站账号: ${selfBind.buidUsername}(${selfBind.buidUid})` : '';
656
653
  // 删除绑定记录
657
654
  await this.deps.deleteMcBind(operatorId);
658
- this.deps.logger.info('解绑', `成功: QQ(${operatorId})解绑MC账号: ${oldUsername}${oldBuidInfo}`);
655
+ this.logger.info('解绑', `成功: QQ(${operatorId})解绑MC账号: ${oldUsername}${oldBuidInfo}`);
659
656
  return this.deps.sendMessage(session, [koishi_1.h.text(`已成功解绑MC账号: ${oldUsername}${oldBuidInfo}`)]);
660
657
  }
661
658
  /**
@@ -665,43 +662,43 @@ class McidCommandHandler {
665
662
  try {
666
663
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
667
664
  const normalizedTargetId = this.deps.normalizeQQId(target);
668
- this.deps.logger.info('管理员', `QQ(${normalizedUserId})尝试将QQ(${normalizedTargetId})设为管理员`);
665
+ this.logger.info('管理员', `QQ(${normalizedUserId})尝试将QQ(${normalizedTargetId})设为管理员`);
669
666
  // 检查是否为主人
670
667
  if (!this.deps.isMaster(session.userId)) {
671
- this.deps.logger.warn('管理员', `权限不足: QQ(${normalizedUserId})不是主人`);
668
+ this.logger.warn('管理员', `权限不足: QQ(${normalizedUserId})不是主人`);
672
669
  return this.deps.sendMessage(session, [koishi_1.h.text('只有主人才能设置管理员')]);
673
670
  }
674
671
  // 检查目标用户是否已经是管理员
675
672
  const targetBind = await this.deps.getMcBindByQQId(normalizedTargetId);
676
673
  const isAlreadyAdmin = targetBind && targetBind.isAdmin === true;
677
674
  if (isAlreadyAdmin) {
678
- this.deps.logger.warn('管理员', `QQ(${normalizedTargetId})已经是管理员`);
675
+ this.logger.warn('管理员', `QQ(${normalizedTargetId})已经是管理员`);
679
676
  return this.deps.sendMessage(session, [koishi_1.h.text(`用户 ${normalizedTargetId} 已经是管理员`)]);
680
677
  }
681
678
  // 如果用户存在绑定记录,更新为管理员
682
679
  if (targetBind) {
683
- await this.deps.mcidbindRepo.update(normalizedTargetId, {
680
+ await this.repos.mcidbind.update(normalizedTargetId, {
684
681
  isAdmin: true,
685
682
  });
686
- this.deps.logger.info('管理员', `成功: 主人QQ(${normalizedUserId})将QQ(${normalizedTargetId})设为管理员`);
683
+ this.logger.info('管理员', `成功: 主人QQ(${normalizedUserId})将QQ(${normalizedTargetId})设为管理员`);
687
684
  return this.deps.sendMessage(session, [koishi_1.h.text(`已成功将用户 ${normalizedTargetId} 设为管理员`)]);
688
685
  }
689
686
  else {
690
687
  // 用户不存在绑定记录,创建一个新记录并设为管理员
691
688
  const tempUsername = `_temp_${normalizedTargetId}`;
692
689
  try {
693
- await this.deps.mcidbindRepo.create({
690
+ await this.repos.mcidbind.create({
694
691
  qqId: normalizedTargetId,
695
692
  mcUsername: tempUsername,
696
693
  mcUuid: '',
697
694
  lastModified: new Date(),
698
695
  isAdmin: true
699
696
  });
700
- this.deps.logger.info('管理员', `成功: 主人QQ(${normalizedUserId})将QQ(${normalizedTargetId})设为管理员 (创建新记录)`);
697
+ this.logger.info('管理员', `成功: 主人QQ(${normalizedUserId})将QQ(${normalizedTargetId})设为管理员 (创建新记录)`);
701
698
  return this.deps.sendMessage(session, [koishi_1.h.text(`已成功将用户 ${normalizedTargetId} 设为管理员 (未绑定MC账号)`)]);
702
699
  }
703
700
  catch (createError) {
704
- this.deps.logger.error('管理员', `创建管理员记录失败: ${createError.message}`);
701
+ this.logger.error('管理员', `创建管理员记录失败: ${createError.message}`);
705
702
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(createError))]);
706
703
  }
707
704
  }
@@ -709,7 +706,7 @@ class McidCommandHandler {
709
706
  catch (error) {
710
707
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
711
708
  const normalizedTargetId = this.deps.normalizeQQId(target);
712
- this.deps.logger.error('管理员', `QQ(${normalizedUserId})将QQ(${normalizedTargetId})设为管理员失败: ${error.message}`);
709
+ this.logger.error('管理员', `QQ(${normalizedUserId})将QQ(${normalizedTargetId})设为管理员失败: ${error.message}`);
713
710
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
714
711
  }
715
712
  }
@@ -720,30 +717,30 @@ class McidCommandHandler {
720
717
  try {
721
718
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
722
719
  const normalizedTargetId = this.deps.normalizeQQId(target);
723
- this.deps.logger.info('管理员', `QQ(${normalizedUserId})尝试撤销QQ(${normalizedTargetId})的管理员权限`);
720
+ this.logger.info('管理员', `QQ(${normalizedUserId})尝试撤销QQ(${normalizedTargetId})的管理员权限`);
724
721
  // 检查是否为主人
725
722
  if (!this.deps.isMaster(session.userId)) {
726
- this.deps.logger.warn('管理员', `权限不足: QQ(${normalizedUserId})不是主人`);
723
+ this.logger.warn('管理员', `权限不足: QQ(${normalizedUserId})不是主人`);
727
724
  return this.deps.sendMessage(session, [koishi_1.h.text('只有主人才能撤销管理员权限')]);
728
725
  }
729
726
  // 检查目标用户是否是管理员
730
727
  const targetBind = await this.deps.getMcBindByQQId(normalizedTargetId);
731
728
  const isAdmin = targetBind && targetBind.isAdmin === true;
732
729
  if (!isAdmin) {
733
- this.deps.logger.warn('管理员', `QQ(${normalizedTargetId})不是管理员`);
730
+ this.logger.warn('管理员', `QQ(${normalizedTargetId})不是管理员`);
734
731
  return this.deps.sendMessage(session, [koishi_1.h.text(`用户 ${normalizedTargetId} 不是管理员`)]);
735
732
  }
736
733
  // 撤销管理员权限
737
- await this.deps.mcidbindRepo.update(normalizedTargetId, {
734
+ await this.repos.mcidbind.update(normalizedTargetId, {
738
735
  isAdmin: false,
739
736
  });
740
- this.deps.logger.info('管理员', `成功: 主人QQ(${normalizedUserId})撤销了QQ(${normalizedTargetId})的管理员权限`);
737
+ this.logger.info('管理员', `成功: 主人QQ(${normalizedUserId})撤销了QQ(${normalizedTargetId})的管理员权限`);
741
738
  return this.deps.sendMessage(session, [koishi_1.h.text(`已成功撤销用户 ${normalizedTargetId} 的管理员权限`)]);
742
739
  }
743
740
  catch (error) {
744
741
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
745
742
  const normalizedTargetId = this.deps.normalizeQQId(target);
746
- this.deps.logger.error('管理员', `QQ(${normalizedUserId})撤销QQ(${normalizedTargetId})的管理员权限失败: ${error.message}`);
743
+ this.logger.error('管理员', `QQ(${normalizedUserId})撤销QQ(${normalizedTargetId})的管理员权限失败: ${error.message}`);
747
744
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
748
745
  }
749
746
  }
@@ -753,16 +750,16 @@ class McidCommandHandler {
753
750
  async handleAdminlist(session) {
754
751
  try {
755
752
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
756
- this.deps.logger.info('管理员', `QQ(${normalizedUserId})尝试查看管理员列表`);
753
+ this.logger.info('管理员', `QQ(${normalizedUserId})尝试查看管理员列表`);
757
754
  // 检查是否为主人
758
755
  if (!this.deps.isMaster(session.userId)) {
759
- this.deps.logger.warn('管理员', `权限不足: QQ(${normalizedUserId})不是主人`);
756
+ this.logger.warn('管理员', `权限不足: QQ(${normalizedUserId})不是主人`);
760
757
  return this.deps.sendMessage(session, [koishi_1.h.text('只有主人才能查看管理员列表')]);
761
758
  }
762
759
  // 查询所有管理员
763
- const admins = await this.deps.mcidbindRepo.findAllAdmins();
760
+ const admins = await this.repos.mcidbind.findAllAdmins();
764
761
  if (admins.length === 0) {
765
- this.deps.logger.info('管理员', `管理员列表为空`);
762
+ this.logger.info('管理员', `管理员列表为空`);
766
763
  return this.deps.sendMessage(session, [koishi_1.h.text('当前没有管理员')]);
767
764
  }
768
765
  // 格式化管理员列表
@@ -770,12 +767,12 @@ class McidCommandHandler {
770
767
  const displayUsername = admin.mcUsername && !admin.mcUsername.startsWith('_temp_') ? admin.mcUsername : null;
771
768
  return `- ${admin.qqId}${displayUsername ? ` (MC: ${displayUsername})` : ''}`;
772
769
  }).join('\n');
773
- this.deps.logger.info('管理员', `成功: 主人QQ(${normalizedUserId})查看了管理员列表`);
770
+ this.logger.info('管理员', `成功: 主人QQ(${normalizedUserId})查看了管理员列表`);
774
771
  return this.deps.sendMessage(session, [koishi_1.h.text(`管理员列表:\n${adminList}\n\n共 ${admins.length} 名管理员`)]);
775
772
  }
776
773
  catch (error) {
777
774
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
778
- this.deps.logger.error('管理员', `QQ(${normalizedUserId})查看管理员列表失败: ${error.message}`);
775
+ this.logger.error('管理员', `QQ(${normalizedUserId})查看管理员列表失败: ${error.message}`);
779
776
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
780
777
  }
781
778
  }
@@ -785,14 +782,14 @@ class McidCommandHandler {
785
782
  async handleStats(session) {
786
783
  try {
787
784
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
788
- this.deps.logger.info('统计', `QQ(${normalizedUserId})尝试查看数据库统计`);
785
+ this.logger.info('统计', `QQ(${normalizedUserId})尝试查看数据库统计`);
789
786
  // 检查权限
790
787
  if (!await this.deps.isAdmin(session.userId)) {
791
- this.deps.logger.warn('统计', `权限不足: QQ(${normalizedUserId})不是管理员`);
788
+ this.logger.warn('统计', `权限不足: QQ(${normalizedUserId})不是管理员`);
792
789
  return this.deps.sendMessage(session, [koishi_1.h.text('只有管理员才能查看统计信息')]);
793
790
  }
794
791
  // 查询所有绑定记录
795
- const allBinds = await this.deps.mcidbindRepo.findAll();
792
+ const allBinds = await this.repos.mcidbind.findAll();
796
793
  // 统计绑定情况
797
794
  let mcidBoundUsers = 0;
798
795
  let buidBoundUsers = 0;
@@ -809,12 +806,12 @@ class McidCommandHandler {
809
806
  let statsInfo = `📊 绑定统计\n`;
810
807
  statsInfo += `\n已绑定MCID: ${mcidBoundUsers}人\n`;
811
808
  statsInfo += `已绑定BUID: ${buidBoundUsers}人`;
812
- this.deps.logger.info('统计', `成功: 管理员QQ(${normalizedUserId})查看了数据库统计`);
809
+ this.logger.info('统计', `成功: 管理员QQ(${normalizedUserId})查看了数据库统计`);
813
810
  return this.deps.sendMessage(session, [koishi_1.h.text(statsInfo)]);
814
811
  }
815
812
  catch (error) {
816
813
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
817
- this.deps.logger.error('统计', `QQ(${normalizedUserId})查看统计失败: ${error.message}`);
814
+ this.logger.error('统计', `QQ(${normalizedUserId})查看统计失败: ${error.message}`);
818
815
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
819
816
  }
820
817
  }
@@ -826,7 +823,7 @@ class McidCommandHandler {
826
823
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
827
824
  // 检查权限
828
825
  if (!await this.deps.isAdmin(session.userId)) {
829
- this.deps.logger.warn('群昵称修复', `权限不足: QQ(${normalizedUserId})不是管理员`);
826
+ this.logger.warn('群昵称修复', `权限不足: QQ(${normalizedUserId})不是管理员`);
830
827
  return this.deps.sendMessage(session, [koishi_1.h.text('只有管理员才能执行群昵称修复操作')]);
831
828
  }
832
829
  // 确定目标群ID
@@ -842,14 +839,14 @@ class McidCommandHandler {
842
839
  }
843
840
  }
844
841
  catch (error) {
845
- this.deps.logger.warn('群昵称修复', `Bot不在群${targetGroupId}中或无法获取群信息`);
842
+ this.logger.warn('群昵称修复', `Bot不在群${targetGroupId}中或无法获取群信息`);
846
843
  return this.deps.sendMessage(session, [koishi_1.h.text(`❌ Bot不在群 ${targetGroupId} 中或无权限操作该群`)]);
847
844
  }
848
845
  const groupDisplayText = groupId ? `群 ${targetGroupId}` : '当前群';
849
- this.deps.logger.info('群昵称修复', `管理员QQ(${normalizedUserId})开始批量修复${groupDisplayText}的群昵称`);
846
+ this.logger.info('群昵称修复', `管理员QQ(${normalizedUserId})开始批量修复${groupDisplayText}的群昵称`);
850
847
  await this.deps.sendMessage(session, [koishi_1.h.text(`🔧 开始检查并修复${groupDisplayText}的所有用户群昵称格式,请稍候...`)]);
851
848
  // 获取所有已绑定B站的用户
852
- const allBinds = await this.deps.mcidbindRepo.findAll();
849
+ const allBinds = await this.repos.mcidbind.findAll();
853
850
  const usersWithBuid = allBinds.filter(bind => bind.buidUid && bind.buidUsername);
854
851
  let checkedCount = 0;
855
852
  let fixedCount = 0;
@@ -894,7 +891,7 @@ class McidCommandHandler {
894
891
  catch (error) {
895
892
  errorCount++;
896
893
  results.push(`❌ ${bind.qqId}: 处理出错 - ${error.message}`);
897
- this.deps.logger.error('群昵称修复', `处理用户QQ(${bind.qqId})时出错: ${error.message}`);
894
+ this.logger.error('群昵称修复', `处理用户QQ(${bind.qqId})时出错: ${error.message}`);
898
895
  }
899
896
  }
900
897
  // 生成最终报告
@@ -911,12 +908,12 @@ class McidCommandHandler {
911
908
  }
912
909
  }
913
910
  }
914
- this.deps.logger.info('群昵称修复', `修复完成: 管理员QQ(${normalizedUserId})在${groupDisplayText}检查${checkedCount}个用户,修复${fixedCount}个,错误${errorCount}个`);
911
+ this.logger.info('群昵称修复', `修复完成: 管理员QQ(${normalizedUserId})在${groupDisplayText}检查${checkedCount}个用户,修复${fixedCount}个,错误${errorCount}个`);
915
912
  return this.deps.sendMessage(session, [koishi_1.h.text(resultMessage)]);
916
913
  }
917
914
  catch (error) {
918
915
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
919
- this.deps.logger.error('群昵称修复', `QQ(${normalizedUserId})执行群昵称修复失败: ${error.message}`);
916
+ this.logger.error('群昵称修复', `QQ(${normalizedUserId})执行群昵称修复失败: ${error.message}`);
920
917
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
921
918
  }
922
919
  }
@@ -928,7 +925,7 @@ class McidCommandHandler {
928
925
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
929
926
  // 检查权限
930
927
  if (!await this.deps.isAdmin(session.userId)) {
931
- this.deps.logger.warn('清除冷却', `权限不足: QQ(${normalizedUserId})不是管理员`);
928
+ this.logger.warn('清除冷却', `权限不足: QQ(${normalizedUserId})不是管理员`);
932
929
  return this.deps.sendMessage(session, [koishi_1.h.text('只有管理员才能清除提醒冷却和次数')]);
933
930
  }
934
931
  // 注意: reminderCooldown 需要从外部传入或在 deps 中提供
@@ -937,23 +934,23 @@ class McidCommandHandler {
937
934
  const normalizedTargetId = this.deps.normalizeQQId(target);
938
935
  const bind = await this.deps.getMcBindByQQId(normalizedTargetId);
939
936
  if (bind) {
940
- await this.deps.mcidbindRepo.update(normalizedTargetId, { reminderCount: 0 });
937
+ await this.repos.mcidbind.update(normalizedTargetId, { reminderCount: 0 });
941
938
  }
942
- this.deps.logger.info('清除冷却', `管理员QQ(${normalizedUserId})清除了QQ(${normalizedTargetId})的提醒次数`);
939
+ this.logger.info('清除冷却', `管理员QQ(${normalizedUserId})清除了QQ(${normalizedTargetId})的提醒次数`);
943
940
  return this.deps.sendMessage(session, [koishi_1.h.text(`已清除用户 ${normalizedTargetId} 的随机提醒次数`)]);
944
941
  }
945
942
  else {
946
- const allBinds = await this.deps.mcidbindRepo.findAll();
943
+ const allBinds = await this.repos.mcidbind.findAll();
947
944
  for (const bind of allBinds) {
948
- await this.deps.mcidbindRepo.update(bind.qqId, { reminderCount: 0 });
945
+ await this.repos.mcidbind.update(bind.qqId, { reminderCount: 0 });
949
946
  }
950
- this.deps.logger.info('清除冷却', `管理员QQ(${normalizedUserId})清除了所有用户的提醒次数`);
947
+ this.logger.info('清除冷却', `管理员QQ(${normalizedUserId})清除了所有用户的提醒次数`);
951
948
  return this.deps.sendMessage(session, [koishi_1.h.text(`已清除所有用户的随机提醒次数`)]);
952
949
  }
953
950
  }
954
951
  catch (error) {
955
952
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
956
- this.deps.logger.error('清除冷却', `QQ(${normalizedUserId})清除提醒冷却失败: ${error.message}`);
953
+ this.logger.error('清除冷却', `QQ(${normalizedUserId})清除提醒冷却失败: ${error.message}`);
957
954
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
958
955
  }
959
956
  }
@@ -965,12 +962,12 @@ class McidCommandHandler {
965
962
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
966
963
  // 检查权限
967
964
  if (!await this.deps.isAdmin(session.userId)) {
968
- this.deps.logger.warn('数据导出', `权限不足: QQ(${normalizedUserId})不是管理员`);
965
+ this.logger.warn('数据导出', `权限不足: QQ(${normalizedUserId})不是管理员`);
969
966
  return this.deps.sendMessage(session, [koishi_1.h.text('只有管理员才能导出群数据')]);
970
967
  }
971
968
  // 检查是否为私聊
972
969
  if (!session.channelId?.startsWith('private:')) {
973
- this.deps.logger.warn('数据导出', `QQ(${normalizedUserId})尝试在群聊中使用导出命令`);
970
+ this.logger.warn('数据导出', `QQ(${normalizedUserId})尝试在群聊中使用导出命令`);
974
971
  return this.deps.sendMessage(session, [koishi_1.h.text('为了数据安全,导出命令仅支持在私聊中使用')]);
975
972
  }
976
973
  // 验证群ID格式
@@ -984,10 +981,10 @@ class McidCommandHandler {
984
981
  }
985
982
  }
986
983
  catch (error) {
987
- this.deps.logger.warn('数据导出', `Bot不在群${groupId}中或无法获取群信息`);
984
+ this.logger.warn('数据导出', `Bot不在群${groupId}中或无法获取群信息`);
988
985
  return this.deps.sendMessage(session, [koishi_1.h.text(`❌ Bot不在群 ${groupId} 中或无权限操作该群`)]);
989
986
  }
990
- this.deps.logger.info('数据导出', `管理员QQ(${normalizedUserId})开始导出群${groupId}的数据`);
987
+ this.logger.info('数据导出', `管理员QQ(${normalizedUserId})开始导出群${groupId}的数据`);
991
988
  await this.deps.sendMessage(session, [koishi_1.h.text(`📊 开始导出群 ${groupId} 的数据,请稍候...`)]);
992
989
  try {
993
990
  // 导出数据
@@ -1005,14 +1002,14 @@ class McidCommandHandler {
1005
1002
  name: fileName
1006
1003
  });
1007
1004
  await this.deps.sendMessage(session, [koishi_1.h.text(`📁 文件已发送: ${fileName}`)]);
1008
- this.deps.logger.info('数据导出', `成功发送文件到私聊: ${fileName}`);
1005
+ this.logger.info('数据导出', `成功发送文件到私聊: ${fileName}`);
1009
1006
  }
1010
1007
  else {
1011
1008
  throw new Error('Bot不支持内部API调用');
1012
1009
  }
1013
1010
  }
1014
1011
  catch (fileError) {
1015
- this.deps.logger.error('数据导出', `文件发送失败: ${fileError.message}`);
1012
+ this.logger.error('数据导出', `文件发送失败: ${fileError.message}`);
1016
1013
  // 降级方案:保存文件
1017
1014
  try {
1018
1015
  const filePath = await this.deps.groupExporter.saveExcelFile(excelBuffer, fileName);
@@ -1020,7 +1017,7 @@ class McidCommandHandler {
1020
1017
  koishi_1.h.text(`⚠️ 直接发送失败,文件已保存\n文件路径: ${filePath}\n文件名: ${fileName}\n请联系管理员获取文件`)
1021
1018
  ]);
1022
1019
  // 清理过期文件
1023
- this.deps.groupExporter.cleanupOldFiles().catch(err => this.deps.logger.warn('数据导出', `清理临时文件时出错: ${err.message}`));
1020
+ this.deps.groupExporter.cleanupOldFiles().catch(err => this.logger.warn('数据导出', `清理临时文件时出错: ${err.message}`));
1024
1021
  }
1025
1022
  catch (saveError) {
1026
1023
  await this.deps.sendMessage(session, [
@@ -1028,16 +1025,16 @@ class McidCommandHandler {
1028
1025
  ]);
1029
1026
  }
1030
1027
  }
1031
- this.deps.logger.info('数据导出', `管理员QQ(${normalizedUserId})成功导出群${groupId}的数据,文件名: ${fileName}`);
1028
+ this.logger.info('数据导出', `管理员QQ(${normalizedUserId})成功导出群${groupId}的数据,文件名: ${fileName}`);
1032
1029
  }
1033
1030
  catch (exportError) {
1034
- this.deps.logger.error('数据导出', `导出群${groupId}数据失败: ${exportError.message}`);
1031
+ this.logger.error('数据导出', `导出群${groupId}数据失败: ${exportError.message}`);
1035
1032
  return this.deps.sendMessage(session, [koishi_1.h.text(`❌ 导出失败: ${exportError.message}`)]);
1036
1033
  }
1037
1034
  }
1038
1035
  catch (error) {
1039
1036
  const normalizedUserId = this.deps.normalizeQQId(session.userId);
1040
- this.deps.logger.error('数据导出', `QQ(${normalizedUserId})导出群数据失败: ${error.message}`);
1037
+ this.logger.error('数据导出', `QQ(${normalizedUserId})导出群数据失败: ${error.message}`);
1041
1038
  return this.deps.sendMessage(session, [koishi_1.h.text(this.deps.getFriendlyErrorMessage(error))]);
1042
1039
  }
1043
1040
  }