活动页:每个节点卡片底部渲染参与人(头像 + 名字)

之前节点卡片上只有「👥 N」计数,要看是谁参加得点进节点详情。
现在卡片底部直接列出参与人:头像(缺头像用首字母兜底)+ 名字,
有心情顺带一个小 emoji;点任一人跳到该节点的参与区。
数据侧 Members::forNodes() 一条 IN 查询带回全部节点的参与人
(与 attachCounts 同样的防 N+1 思路),计划列与执行列共用。
无参与人的节点不渲染这一行。

已验证:本地全链 11 步全绿(渲染检查 292 项、表单交互 73 项);
远端 e2e 299 项 0 失败(新增活动页卡片参与人行专项断言);
部署后双 PHP 渲染逐字节一致、60 文件哈希一致。
This commit is contained in:
2026-09-23 15:18:25 +08:00
parent 48237c8947
commit c50bc7de2b
4 changed files with 91 additions and 1 deletions
+23
View File
@@ -84,6 +84,29 @@ class Members
return $out;
}
/**
* 一次查完多个节点的参与人明细(头像 / 姓名 / 情绪),供活动页的节点卡片使用。
* 一条 IN 查询带回全部节点,避免每张卡片单独查(N+1)。
* @return array<int, array<int, array>> node_id => 参与人列表(按 node_members.id ASC)
*/
public static function forNodes(array $nodeIds): array
{
if (empty($nodeIds)) return [];
$ph = implode(',', array_fill(0, count($nodeIds), '?'));
$stmt = Database::get()->prepare('
SELECT nm.trip_node_id, nm.user_id, nm.emotion, u.name, u.avatar
FROM node_members nm
LEFT JOIN users u ON u.id = nm.user_id
WHERE nm.trip_node_id IN (' . $ph . ')
ORDER BY nm.id ASC');
$stmt->execute(array_values($nodeIds));
$out = [];
foreach ($stmt->fetchAll() as $row) {
$out[(int)$row['trip_node_id']][] = $row;
}
return $out;
}
/**
* 新增或更新一个参与人(同一节点同一人只留一条)
* @return array{ok: bool, error?: string}