|
|
@@ -11,7 +11,9 @@ import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.stream.Collectors;
|
|
|
@@ -202,4 +204,63 @@ public class FamilyRelationshipService {
|
|
|
}
|
|
|
return computeRelationshipLabel(generationValue, gender);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重建某个成员的全部关系(用于「编辑资料」修改辈分/同辈类型,《规格 §10 R-4》:
|
|
|
+ * 原先只改 family_members.generation 不重建 family_relationships,导致成员列表标签
|
|
|
+ * 仍读旧关系而不刷新)。
|
|
|
+ *
|
|
|
+ * <p>实现要点:先按 (from→to) 快照双向行的关系质量评分(信任/亲密/沟通,来自
|
|
|
+ * relationship-questionnaire 的答卷人视角),再删旧建新,最后按同一方向回填评分,
|
|
|
+ * 避免重建把历史评分清零。</p>
|
|
|
+ */
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void rebuildRelationsForMember(Long familyId, Long memberId, Integer newMemberGeneration,
|
|
|
+ String peerType, Long anchorMemberId) {
|
|
|
+ if (familyId == null || memberId == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<FamilyRelationship> oldRows = selectRelationsTouching(memberId);
|
|
|
+ Map<String, FamilyRelationship> scoreSnapshot = new HashMap<>();
|
|
|
+ for (FamilyRelationship r : oldRows) {
|
|
|
+ boolean hasScore = r.getTrustScore() != null
|
|
|
+ || r.getIntimacyScore() != null
|
|
|
+ || r.getCommunicationScore() != null;
|
|
|
+ if (hasScore) {
|
|
|
+ scoreSnapshot.put(r.getFromMemberId() + "->" + r.getToMemberId(), r);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ deleteRelationsForMember(memberId);
|
|
|
+ createRelationsForNewMember(familyId, memberId, newMemberGeneration, peerType, anchorMemberId);
|
|
|
+
|
|
|
+ if (scoreSnapshot.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<FamilyRelationship> freshRows = selectRelationsTouching(memberId);
|
|
|
+ for (FamilyRelationship r : freshRows) {
|
|
|
+ FamilyRelationship old = scoreSnapshot.get(r.getFromMemberId() + "->" + r.getToMemberId());
|
|
|
+ if (old == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ r.setTrustScore(old.getTrustScore());
|
|
|
+ r.setIntimacyScore(old.getIntimacyScore());
|
|
|
+ r.setCommunicationScore(old.getCommunicationScore());
|
|
|
+ try {
|
|
|
+ familyRelationshipMapper.updateById(r);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("关系评分回填失败(不阻断): relId={}, error={}", r.getId(), e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 查询所有「以该成员为起点或终点」的关系行(双向) */
|
|
|
+ private List<FamilyRelationship> selectRelationsTouching(Long memberId) {
|
|
|
+ List<FamilyRelationship> rows = familyRelationshipMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<FamilyRelationship>()
|
|
|
+ .and(w -> w.eq(FamilyRelationship::getFromMemberId, memberId)
|
|
|
+ .or()
|
|
|
+ .eq(FamilyRelationship::getToMemberId, memberId)));
|
|
|
+ return rows != null ? new ArrayList<>(rows) : new ArrayList<>();
|
|
|
+ }
|
|
|
}
|