| 1511 | : { failureDetails: [], unresolved: true, unresolvedReason: 'UNKNOWN_ERROR' }; |
| 1512 | |
| 1513 | // 内部日志辅助:不含 HTML 转义的纯文本原因汇总 |
| 1514 | const summarizeReasonsPlain = (details: BatchGroupFailure[]): string => { |
| 1515 | const counts = new Map<string, number>(); |
| 1516 | for (const item of details) { |
| 1517 | counts.set(item.reason, (counts.get(item.reason) || 0) + 1); |
| 1518 | } |
| 1519 | return Array.from(counts.entries()) |
| 1520 | .sort((a, b) => b[1] - a[1]) |
| 1521 | .slice(0, 5) |
| 1522 | .map(([reason, count]) => `${reason}×${count}`) |
| 1523 | .join(', '); |
| 1524 | }; |
| 1525 | |
| 1526 | if (failureDetails.length > 0) { |
| 1527 | console.warn(`[sb] 封禁失败汇总: failed=${failureDetails.length}, unresolved=${unresolved ? 'yes' : 'no'}, reasons=[${summarizeReasonsPlain(failureDetails)}]`); |
| 1528 | } |
| 1529 | |
| 1530 | const summarizeReasons = (details: BatchGroupFailure[]): string => { |
| 1531 | const counts = new Map<string, number>(); |
| 1532 | for (const item of details) { |
| 1533 | counts.set(item.reason, (counts.get(item.reason) || 0) + 1); |
| 1534 | } |
| 1535 | return Array.from(counts.entries()) |
| 1536 | .sort((a, b) => b[1] - a[1]) |
| 1537 | .slice(0, 3) |
| 1538 | .map(([reason, count]) => `${htmlEscape(reason)}×${count}`) |
| 1539 | .join('、'); |
| 1540 | }; |
| 1541 | |
| 1542 | const failureSummary = unresolved |
| 1543 | ? `\n⚠️ 目标实体无法解析:${htmlEscape(unresolvedReason || 'UNKNOWN_ERROR')}` |
| 1544 | : failed > 0 |
| 1545 | ? `\n⚠️ 失败 ${failed} 个频道/群组(${summarizeReasons(failureDetails)})` |
| 1546 | : ''; |
| 1547 | const capabilityNote = hasBasicGroups |
| 1548 | ? `\nℹ️ 基础群仅支持移出现有成员,不支持对未入群目标提前封禁` |
| 1549 | : ''; |
| 1550 | |
| 1551 | // 更新最终结果 |
| 1552 | const finalActionText = (message as any).isGroup && !(message as any).isChannel ? '移出' : '封禁'; |
| 1553 | const result = `✅ 在${success}个频道/群组中${finalActionText}该用户 ${htmlEscape(display)}${failureSummary}${capabilityNote}\n🗑️当前群组消息: ${deleteSuccess ? '✓已清理' : '✗'} | ⏱️${elapsed.toFixed(1)}s`; |
| 1554 | |
| 1555 | // 更新为最终结果 |
| 1556 | const lc1 = getCurrentGenerationContext(); |
| 1557 | if (lc1) { |
| 1558 | lc1.setTimeout(() => { |
| 1559 | MessageManager.smartEdit(status, result, 30).catch(() => {}); |
| 1560 | }, 100, { label: 'aban:sb-result-update' }); |
| 1561 | } |
| 1562 | }; |
| 1563 | |
| 1564 | // 后台执行,不等待 |
| 1565 | backgroundProcess().catch(() => {}); |
| 1566 | |
| 1567 | } catch (error: any) { |
| 1568 | await MessageManager.smartEdit(message, `❌ ${error.message}`); |
| 1569 | } |
| 1570 | } |
nothing calls this directly
no test coverage detected