|
@@ -1045,18 +1045,52 @@ vo.setIsSelf(viewerMember != null && viewerMember.getId().equals(fm.getId()));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
// 管理员可更新辈分关系
|
|
// 管理员可更新辈分关系
|
|
|
|
|
+ boolean identityChanged = false;
|
|
|
|
|
+ String rebuildPeerType = null;
|
|
|
if (isAdmin && dto.getGenerationLevel() != null && !dto.getGenerationLevel().trim().isEmpty()) {
|
|
if (isAdmin && dto.getGenerationLevel() != null && !dto.getGenerationLevel().trim().isEmpty()) {
|
|
|
GenerationLevel genLevel = GenerationLevel.fromValue(dto.getGenerationLevel());
|
|
GenerationLevel genLevel = GenerationLevel.fromValue(dto.getGenerationLevel());
|
|
|
if (genLevel != null) {
|
|
if (genLevel != null) {
|
|
|
|
|
+ // 本人自编辑不设「配偶」:关系是相对的,配偶只能由对方(或管理员代设)指定,
|
|
|
|
|
+ // 自己给自己标配偶会产生「我与我配偶」的歧义关系行。
|
|
|
|
|
+ boolean selfEdit = member.getUserId() != null && member.getUserId().equals(userId);
|
|
|
member.setGeneration(genLevel.getOffset());
|
|
member.setGeneration(genLevel.getOffset());
|
|
|
- boolean isSpouse = genLevel == GenerationLevel.PEER && "spouse".equals(dto.getPeerType());
|
|
|
|
|
|
|
+ boolean isSpouse = genLevel == GenerationLevel.PEER
|
|
|
|
|
+ && "spouse".equals(dto.getPeerType()) && !selfEdit;
|
|
|
member.setIsSpouse(isSpouse);
|
|
member.setIsSpouse(isSpouse);
|
|
|
|
|
+ identityChanged = true;
|
|
|
|
|
+ rebuildPeerType = genLevel == GenerationLevel.PEER
|
|
|
|
|
+ ? (isSpouse ? "spouse" : "sibling")
|
|
|
|
|
+ : null;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
// 孩子身份标记(仅家庭管理员可设置;落库到 users 表对应记录)
|
|
// 孩子身份标记(仅家庭管理员可设置;落库到 users 表对应记录)
|
|
|
applyIsChildFlag(userId, user.getFamilyId(), member.getUserId(), dto.getIsChild());
|
|
applyIsChildFlag(userId, user.getFamilyId(), member.getUserId(), dto.getIsChild());
|
|
|
member.setUpdatedAt(new Date());
|
|
member.setUpdatedAt(new Date());
|
|
|
familyMemberMapper.updateById(member);
|
|
familyMemberMapper.updateById(member);
|
|
|
|
|
+
|
|
|
|
|
+ // 辈分/同辈类型变更后重建关系表:成员列表的关系标签优先读 family_relationships,
|
|
|
|
|
+ // 不重建会出现「编辑资料改了身份、列表标签不刷新」(规格 §10 R-4)。
|
|
|
|
|
+ // 锚点=操作者(编辑人)成员记录:管理员给某成员选「配偶」时,指 TA 与操作者是配偶;
|
|
|
|
|
+ // 本人自编辑时锚点为 null(不写 spouse)。
|
|
|
|
|
+ if (identityChanged) {
|
|
|
|
|
+ Long anchorMemberId = null;
|
|
|
|
|
+ boolean selfEdit = member.getUserId() != null && member.getUserId().equals(userId);
|
|
|
|
|
+ if (!selfEdit) {
|
|
|
|
|
+ FamilyMember operator = familyMemberMapper.selectOne(new LambdaQueryWrapper<FamilyMember>()
|
|
|
|
|
+ .eq(FamilyMember::getFamilyId, member.getFamilyId())
|
|
|
|
|
+ .eq(FamilyMember::getUserId, userId)
|
|
|
|
|
+ .last("LIMIT 1"));
|
|
|
|
|
+ anchorMemberId = operator != null ? operator.getId() : null;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ familyRelationshipService.rebuildRelationsForMember(
|
|
|
|
|
+ member.getFamilyId(), member.getId(), member.getGeneration(), rebuildPeerType, anchorMemberId);
|
|
|
|
|
+ } catch (RuntimeException e) {
|
|
|
|
|
+ // 重建失败必须整体回滚:否则辈分已改而关系未重建,正是 R-4 要消除的不一致状态
|
|
|
|
|
+ log.error("重建成员关系失败,回滚本次资料更新: memberId={}, error={}", member.getId(), e.getMessage());
|
|
|
|
|
+ throw e;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
logMemberAction(member.getFamilyId(), member.getId(), "update", oldNickname, member.getNickname(), userId);
|
|
logMemberAction(member.getFamilyId(), member.getId(), "update", oldNickname, member.getNickname(), userId);
|
|
|
return toFamilyMemberVO(member);
|
|
return toFamilyMemberVO(member);
|
|
|
}
|
|
}
|