feat(赛马插件): 在结算时显示用户昵称而非ID

- 新增 `_get_user_name` 和 `_build_name_map` 函数,用于根据群名片或昵称获取用户显示名
- 修改 `_format_point_change_lines` 函数,接受并应用昵称映射
- 在 `run_race_with_settlement` 中构建昵称映射,并在冠军马主和中奖下注者处使用显示名
This commit is contained in:
2026-04-06 23:24:32 +08:00
parent 498d39b676
commit 386e67ec60

View File

@@ -23,6 +23,27 @@ message_service = MessageService(config)
_race_image_renderer: ImageRenderer | None = None
async def _get_user_name(bot: Bot, scope: str, user_id: str) -> str:
"""Get user display name (group card > nickname > user_id)."""
try:
if scope.startswith("group_"):
group_id = int(scope.split("_", 1)[1])
info = await bot.get_group_member_info(group_id=group_id, user_id=int(user_id))
return info.get("card") or info.get("nickname") or user_id
except Exception:
pass
return user_id
async def _build_name_map(bot: Bot, scope: str, user_ids: list[str]) -> dict[str, str]:
"""Build a mapping from user_id to display name."""
name_map: dict[str, str] = {}
for uid in user_ids:
if uid not in name_map:
name_map[uid] = await _get_user_name(bot, scope, uid)
return name_map
def _get_race_image_renderer() -> ImageRenderer:
global _race_image_renderer
if _race_image_renderer is None:
@@ -169,7 +190,7 @@ def _build_point_changes(room: Room, odds: dict[str, float]) -> tuple[dict[str,
return point_changes, point_summaries
def _format_point_change_lines(room: Room, point_changes: dict[str, int], point_summaries: dict[str, str]) -> list[str]:
def _format_point_change_lines(room: Room, point_changes: dict[str, int], point_summaries: dict[str, str], name_map: dict[str, str]) -> list[str]:
ordered_user_ids: list[str] = []
for horse in _get_horses_in_order(room):
if horse.owner_id not in ordered_user_ids:
@@ -182,7 +203,8 @@ def _format_point_change_lines(room: Room, point_changes: dict[str, int], point_
for user_id in ordered_user_ids:
delta = point_changes.get(user_id, 0)
summary = point_summaries.get(user_id, _describe_points_delta(delta))
lines.append(f" {user_id} {delta:+d} 积分 · {summary}")
display_name = name_map.get(user_id, user_id)
lines.append(f" {display_name} {delta:+d} 积分 · {summary}")
return lines
@@ -283,20 +305,26 @@ async def run_race_with_settlement(bot: Bot, room: Room, scope: str):
# Settle
result = await settle_race(room)
# Build user_id -> display name mapping
all_user_ids = [h.owner_id for h in room.horses.values()] + [b.user_id for b in room.bets]
name_map = await _build_name_map(bot, scope, all_user_ids)
odds = calculate_odds(room)
champion = room.horses.get(room.champion_name)
champion_name_display = name_map.get(champion.owner_id, champion.owner_id) if champion else '?'
result_lines = [
f"比赛结束!冠军:{_format_horse_label(champion) if champion else room.champion_name}",
f"马主 {champion.owner_id if champion else '?'} 获得 {config.CHAMPION_REWARD} 积分",
f"马主 {champion_name_display} 获得 {config.CHAMPION_REWARD} 积分",
]
winning_bets = [b for b in room.bets if b.horse_name == room.champion_name]
if winning_bets:
result_lines.append("下注中奖:")
for b in winning_bets:
payout = int(b.amount * odds.get(b.horse_name, config.MIN_ODDS))
result_lines.append(f" {b.user_id} 下注 {b.amount} -> 获得 {payout}")
bettor_name = name_map.get(b.user_id, b.user_id)
result_lines.append(f" {bettor_name} 下注 {b.amount} -> 获得 {payout}")
if result:
result_lines.extend(_format_point_change_lines(room, result.point_changes, result.point_change_summaries))
result_lines.extend(_format_point_change_lines(room, result.point_changes, result.point_change_summaries, name_map))
await _send_to_scope(bot, scope, "\n".join(result_lines))