diff --git a/templates/kin/tree.php b/templates/kin/tree.php index 899976a..0912269 100644 --- a/templates/kin/tree.php +++ b/templates/kin/tree.php @@ -45,6 +45,24 @@ $rankKey = static function (int $id) use ($people): string { }; // ---- ④ 打成前端要的数据包(代数 → 户 → 人)---- + +// 「我」的血亲集合:只走 parent/child 边(不含配偶)能从「我」到达的人。 +// 用途:给每张卡标 blood —— 前端据此判定一户的「主父户」 +// (我的户同时被父母户与岳父母户认作子女,树递归只能走本家那条, +// 否则树变图、布局重复铺人;判定标准就是「父户的主位是不是我方血亲」)。 +$blood = [$meId => true]; +$bq = [$meId]; +while ($bq) { + $bid = (int)array_shift($bq); + foreach (array_merge($graph['parents'][$bid] ?? [], $graph['children'][$bid] ?? []) as $nb) { + $nb = (int)$nb; + if (!isset($blood[$nb])) { + $blood[$nb] = true; + $bq[] = $nb; + } + } +} + $payloadUnits = []; foreach ($units as $i => $u) { $sorted = array_map('intval', $u['ids']); @@ -66,6 +84,8 @@ foreach ($units as $i => $u) { 'me' => $id === (int)$meId, 'ph' => (int)($p['is_placeholder'] ?? 0) === 1, 'gender' => $g === 'm' ? 'M' : ($g === 'f' ? 'F' : 'U'), + // ⚠️ 本家血亲标记:前端用它判定一户的「主父户」(见上方 $blood 的说明) + 'blood' => isset($blood[$id]), // ⚠️ 长幼排序键:前端要靠它分「哥哥/弟弟」「姐姐/妹妹」。 // 不用生日硬排(很多人没填生日),用 Kinship 里已有的 rankValueFor —— // 它先看 birth_rank,再退回生日,最后用 id 兜底,保证顺序稳定。 @@ -82,21 +102,8 @@ foreach ($units as $i => $u) { // 我排在她右边"(实测线上就是这个症状:红围脖@639 在我的左边)。 // // 正解:按「**与"我"的血缘距离**」判定 —— 这一户里离「我」更近的那一位才是主位。 - // 我用一次不带配偶边的 BFS 算出血亲集合(Kinship::bloodRelatives 语义), + // 血亲集合 $blood 已在循环外算好(只走 parent/child 边的 BFS), // 两边都在血亲集合里时,退到「与我的步数」比大小。 - $blood = []; - $bq = [$meId]; - $blood[$meId] = true; - while ($bq) { - $bid = array_shift($bq); - foreach (array_merge($graph['parents'][$bid] ?? [], $graph['children'][$bid] ?? []) as $nb) { - $nb = (int)$nb; - if (!isset($blood[$nb])) { - $blood[$nb] = true; - $bq[] = $nb; - } - } - } $head = null; $headScore = null; foreach ($cards as $c) { @@ -180,17 +187,17 @@ $payloadJson = json_encode(