Răsfoiți Sursa

fix(family): FamilyMemberVO/Service + family-members.vue 完善

User 2 luni în urmă
părinte
comite
b468daaddb

+ 3 - 0
cfc-backend/src/main/java/com/etotem/cfc/dto/FamilyMemberVO.java

@@ -43,6 +43,9 @@ public class FamilyMemberVO {
     /** 角色标签显示文本(家长/孩子/配偶/父母等) */
     private String roleLabel;
 
+    /** 视角相关的关系标签(如 "我"/"儿子"/"女儿"/"父亲"/"母亲"/"哥哥"/"姐姐") */
+    private String relativeLabel;
+
     /** 年龄 */
     private Integer age;
 

+ 115 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/FamilyMemberService.java

@@ -13,6 +13,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -138,6 +139,16 @@ public class FamilyMemberService {
         // 2. 查询 family_members 表
         List<FamilyMember> familyMembers = familyMemberMapper.selectList(
                 new LambdaQueryWrapper<FamilyMember>().eq(FamilyMember::getFamilyId, familyId));
+
+        // 2b. 查找当前查看者在 family_members 中的记录(用于计算视角标签)
+        FamilyMember viewerMember = null;
+        for (FamilyMember fm : familyMembers) {
+            if (userId.equals(fm.getUserId())) {
+                viewerMember = fm;
+                break;
+            }
+        }
+
         for (FamilyMember fm : familyMembers) {
             FamilyMemberVO vo = new FamilyMemberVO();
             vo.setId(fm.getId());
@@ -157,6 +168,10 @@ public class FamilyMemberService {
             if (fm.getBirthday() != null) {
                 vo.setAge(calculateAge(fm.getBirthday()));
             }
+            // 计算视角相关的关系标签
+            if (viewerMember != null) {
+                vo.setRelativeLabel(computeRelativeLabel(viewerMember, fm, familyMembers));
+            }
             result.add(vo);
         }
 
@@ -400,4 +415,104 @@ public class FamilyMemberService {
         }
         return "parent";
     }
+
+    /**
+     * 计算视角相关的关系标签
+     * 规则:
+     * - 查看者自己 → "我"
+     * - parent→child:独生→"儿子"/"女儿",多子女→"长"/"次"/"三"...+"子"/"女"
+     * - child→parent → "父亲"/"母亲"
+     * - child→child → 按年龄比较→"哥哥"/"姐姐"/"弟弟"/"妹妹"
+     * - parent→parent → "丈夫"/"妻子"
+     * - 性别缺失且为孩子角色 → "孩子"
+     */
+    private String computeRelativeLabel(FamilyMember viewer, FamilyMember target, List<FamilyMember> allMembers) {
+        // 自己 → "我"
+        if (viewer.getId().equals(target.getId())) {
+            return "我";
+        }
+
+        String viewerRole = computeEffectiveRole(viewer);
+        String targetRole = computeEffectiveRole(target);
+        String targetGender = target.getGender();
+
+        // parent → child
+        if ("parent".equals(viewerRole) && "child".equals(targetRole)) {
+            // 收集所有孩子,按生日从小到大排序(年长的排前面)
+            List<FamilyMember> children = allMembers.stream()
+                    .filter(m -> "child".equals(computeEffectiveRole(m)))
+                    .sorted(Comparator.comparing(FamilyMember::getBirthday, Comparator.nullsLast(Comparator.naturalOrder())))
+                    .collect(Collectors.toList());
+
+            // 找到目标在孩子中的序号
+            int index = -1;
+            for (int i = 0; i < children.size(); i++) {
+                if (children.get(i).getId().equals(target.getId())) {
+                    index = i;
+                    break;
+                }
+            }
+
+            if (children.size() == 1) {
+                // 独生子女,无序号前缀
+                if ("male".equals(targetGender)) return "儿子";
+                if ("female".equals(targetGender)) return "女儿";
+                return "孩子";
+            }
+
+            // 多子女,按年龄排序加序号前缀
+            String[] ordinals = {"长", "次", "三", "四", "五", "六", "七", "八", "九", "十"};
+            String prefix = (index >= 0 && index < ordinals.length) ? ordinals[index] : ("第" + (index + 1));
+            if ("male".equals(targetGender)) return prefix + "子";
+            if ("female".equals(targetGender)) return prefix + "女";
+            return prefix + "孩子";
+        }
+
+        // child → parent
+        if ("child".equals(viewerRole) && "parent".equals(targetRole)) {
+            if ("male".equals(targetGender)) return "父亲";
+            if ("female".equals(targetGender)) return "母亲";
+            return "父亲";
+        }
+
+        // child → child (sibling)
+        if ("child".equals(viewerRole) && "child".equals(targetRole)) {
+            Date viewerBday = viewer.getBirthday();
+            Date targetBday = target.getBirthday();
+
+            if (viewerBday != null && targetBday != null) {
+                int cmp = viewerBday.compareTo(targetBday);
+                if (cmp > 0) {
+                    // viewer older → target younger
+                    if ("male".equals(targetGender)) return "弟弟";
+                    if ("female".equals(targetGender)) return "妹妹";
+                    return "孩子";
+                } else if (cmp < 0) {
+                    // viewer younger → target older
+                    if ("male".equals(targetGender)) return "哥哥";
+                    if ("female".equals(targetGender)) return "姐姐";
+                    return "孩子";
+                }
+            }
+            // 无法比较生日或同龄 → 默认用哥哥/姐姐
+            if ("male".equals(targetGender)) return "哥哥";
+            if ("female".equals(targetGender)) return "姐姐";
+            return "孩子";
+        }
+
+        // parent → parent (partner)
+        if ("parent".equals(viewerRole) && "parent".equals(targetRole)) {
+            if ("male".equals(targetGender)) return "丈夫";
+            if ("female".equals(targetGender)) return "妻子";
+            return "配偶";
+        }
+
+        // 默认fallback:孩子角色无性别 → "孩子"
+        if ("child".equals(targetRole)) {
+            if ("male".equals(targetGender)) return "儿子";
+            if ("female".equals(targetGender)) return "女儿";
+            return "孩子";
+        }
+        return null;
+    }
 }

+ 2 - 2
cfc-frontend/pages/profile/family-members.vue

@@ -27,7 +27,7 @@
         <view class="member-detail">
           <text class="member-name">{{ m.nickname || '未设置' }}</text>
           <view class="member-tags">
-            <text class="member-role-tag">{{ m.roleLabel || '家长' }}</text>
+            <text class="member-role-tag">{{ m.relativeLabel || m.roleLabel || '家长' }}</text>
             <text class="member-source-tag" v-if="m.source === 'family_member'">手动添加</text>
           </view>
           <!-- 三维评分进度条 -->
@@ -74,7 +74,7 @@
         <view class="member-detail">
           <text class="member-name">{{ m.nickname || '未设置' }}</text>
           <view class="member-tags">
-            <text class="member-role-tag">{{ m.roleLabel || '孩子' }}</text>
+            <text class="member-role-tag">{{ m.relativeLabel || m.roleLabel || '孩子' }}</text>
             <text class="member-source-tag" v-if="m.source === 'family_member'">手动添加</text>
             <text class="member-extra" v-if="m.age"> {{ m.age }}岁</text>
             <text class="member-extra" v-if="m.gender"> · {{ m.gender === 'male' ? '男' : '女' }}</text>