v7:家谱树与名册三处口径统一(树上的人自动互相可见)
用户反馈:我把一个人设成配偶、又设了我们的孩子,配偶登录后首页能看到
孩子、家谱也能看到,名册里却看不到——没分享的人却在家谱上看得到,
口径打架。
口径由用户拍板:**以每个人为中心上下三代那棵家谱树(= 首页「我的家人」
同一棵)里的人,自动进他名册(source=kin,默认归公共「家人」组);
树外的人三处都不可见。**
- PersonRoster::syncKinForFamily():整树同步(补缺、撤多余;已存在的
self/shared/seeded 行绝不碰,用户改过的分组/顺序保留)。幂等。
- 同步挂在事件上:建边 / 解边 / 开通账号 / 结构升级回填。
- Relations::addParent/addSpouse 建边后同步;remove/detach 解边后同步。
- 名册不许单独移走 kin 来源的人(服务端拦截 + 人话提示 + 卡片隐藏
移走按钮改提示语):他在首页/家谱照样看得见,单藏名册只会回到口径
打架;想不再看到他,解除关系即自动移出。
- 名册卡片给 kin 来源标「家谱」徽标(来历可辨)。
- Schema v7:widenRosterSourceEnum(⚠️ CREATE TABLE IF NOT EXISTS 不会
更新已存在表的枚举,v6 老库不扩宽则 strict 模式下插 kin 整条被拒、
且被容错吞掉——e2e 的 v6 旧库当场抓出)+ 按已有关系回填 kin 条目。
验证:e2e 309/0、升级专测 82/0、部署静态空跑 78/0、桌面几何 0 失败、
交互 97/0、移动几何 180/0;线上探针 ver=7、enum 含 kin、无升级告警。
This commit is contained in:
+21
-4
@@ -37,6 +37,8 @@ final class Relations
|
||||
'INSERT INTO relations (family_id, from_id, to_id, kind, from_role) VALUES (?,?,?,"parent",?)'
|
||||
);
|
||||
$st->execute([$familyId, $parentId, $childId, $role]);
|
||||
// 家谱变了 ⇒ 全家每个账号的 kin 名册条目按新树对齐(v7,三处口径一致)
|
||||
PersonRoster::syncKinForFamily($familyId);
|
||||
return ['ok' => true, 'error' => ''];
|
||||
}
|
||||
|
||||
@@ -54,27 +56,42 @@ final class Relations
|
||||
);
|
||||
$st->execute([$familyId, $a, $b, $b, $a]);
|
||||
if ($st->fetchColumn()) {
|
||||
// 已存在 ≠ 什么都不做:名册那边可能还没跟上(老数据/升级前建的边),补一次
|
||||
PersonRoster::syncKinForFamily($familyId);
|
||||
return ['ok' => true, 'error' => ''];
|
||||
}
|
||||
$st = $db->prepare(
|
||||
'INSERT INTO relations (family_id, from_id, to_id, kind) VALUES (?,?,?,"spouse")'
|
||||
);
|
||||
$st->execute([$familyId, $a, $b]);
|
||||
PersonRoster::syncKinForFamily($familyId);
|
||||
return ['ok' => true, 'error' => ''];
|
||||
}
|
||||
|
||||
/** 解除某条关系(按 id) */
|
||||
public static function remove(int $familyId, int $id): void
|
||||
/**
|
||||
* 解除某条关系(按 id)。
|
||||
*
|
||||
* ⚠️ v7 起「家谱树 ⇒ 名册自动同步」:边没了,树上够不着的人的 kin 名册条目
|
||||
* 也跟着撤(可能不止这一对——比如解开「父子」,孩子就从配偶的名册里一起消失,
|
||||
* 因为树是从配偶那边绕过我来展开的)。self/shared/seeded 的条目绝不碰。
|
||||
*
|
||||
* @return int 撤掉的 kin 名册条目数(路由层用它把话说全)
|
||||
*/
|
||||
public static function remove(int $familyId, int $id): int
|
||||
{
|
||||
Database::get()->prepare('DELETE FROM relations WHERE id = ? AND family_id = ?')
|
||||
$db = Database::get();
|
||||
$db->prepare('DELETE FROM relations WHERE id = ? AND family_id = ?')
|
||||
->execute([$id, $familyId]);
|
||||
$st = PersonRoster::syncKinForFamily($familyId);
|
||||
return (int)$st['dropped'];
|
||||
}
|
||||
|
||||
/** 解除两人之间的某种关系 */
|
||||
/** 解除两人之间的某种关系(与 remove() 同样的名册同步语义;当前无其他调用方) */
|
||||
public static function detach(int $familyId, int $personId, string $kind, string $role = ''): void
|
||||
{
|
||||
$sql = 'DELETE FROM relations WHERE family_id = ? AND to_id = ? AND kind = ? AND from_role = ?';
|
||||
Database::get()->prepare($sql)->execute([$familyId, $personId, $kind, $role]);
|
||||
PersonRoster::syncKinForFamily($familyId);
|
||||
}
|
||||
|
||||
/** 某人身上挂着的全部关系(详情页编辑用) */
|
||||
|
||||
Reference in New Issue
Block a user