Kaynağa Gözat

fix(family): 修复辈分关系和出生日期保存回显问题

- 新增 UpdateFamilyMemberDTO.generationLevel/peerType,让后端可保存辈分关系
- 修复 UserService.updateFamilyMember:在管理员权限下保存 generationLevel/peerType
- 新增 FamilyMemberVO.birthday 字段,并回显至前端
- 修复 FamilyMemberService.toFamilyMemberVO:回写 birthday 为 yyyy-MM-dd 字符串
- 前端 family-members.vue onEditRelation:传递 birthday/generationLevel 在 URL
- 前端 add-member.vue onLoad:从 options 回显 birthday/generationLevel
- 前端 family-members.vue:修复 userId 取值(.id→.userId),移除修改关系入口
liaoxg 1 gün önce
ebeveyn
işleme
9d55436443

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

@@ -64,6 +64,9 @@ public class FamilyMemberVO {
     /** 是否配偶 */
     private Boolean isSpouse;
 
+    /** 出生日期(yyyy-MM-dd 字符串,供前端编辑回显) */
+    private String birthday;
+
     /** 信任度分数 */
     private java.math.BigDecimal trustScore;
 

+ 4 - 0
cfc-backend/src/main/java/com/etotem/cfc/dto/UpdateFamilyMemberDTO.java

@@ -14,4 +14,8 @@ public class UpdateFamilyMemberDTO {
     private String relationshipType;
     private String roleOverride;
     private Integer showToFamily;
+    /** 辈分等级字符串(仅管理员可更新):parent/child/grandparent/peer/great_grandparent 等 */
+    private String generationLevel;
+    /** 同辈类型(generationLevel=peer 时填写):sibling=兄弟姐妹,spouse=配偶 */
+    private String peerType;
 }

+ 14 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/FamilyMemberService.java

@@ -261,8 +261,9 @@ public class FamilyMemberService {
             vo.setShowToFamily(fm.getShowToFamily());
             if (fm.getBirthday() != null) {
                 vo.setAge(calculateAge(fm.getBirthday()));
+                vo.setBirthday(formatDate(fm.getBirthday()));
             }
-            // 计算视角相关的关系标签(优先使用关系表)
+            // 计算视角相关的关系标签
             if (viewerMember != null) {
                 Integer genValue = null;
                 if (familyRelationshipService != null && viewerMember.getId() != null) {
@@ -985,6 +986,7 @@ vo.setIsSelf(viewerMember != null && viewerMember.getId().equals(fm.getId()));
         vo.setShowToFamily(member.getShowToFamily());
         if (member.getBirthday() != null) {
             vo.setAge(calculateAge(member.getBirthday()));
+            vo.setBirthday(formatDate(member.getBirthday()));
         }
         // 设置 isSwitchable:仅无 openid 的不可登录成员可被切换(可登录成员不允许切换视角)
         if (member.getUserId() != null) {
@@ -1011,6 +1013,17 @@ vo.setIsSelf(viewerMember != null && viewerMember.getId().equals(fm.getId()));
         return Math.max(0, age);
     }
 
+    /** 格式化为 yyyy-MM-dd(前端编辑回显用),返回 null 时不修改 */
+    private String formatDate(java.util.Date d) {
+        if (d == null) return null;
+        try {
+            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
+            return sdf.format(d);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
     /**
      * 计算成员的实际角色(effective role)
      * 优先使用年龄判定(birthday → age < childThreshold → child),

+ 0 - 0
cfc-frontend/pages/family/components/GenerationPicker.vue → cfc-frontend/components/GenerationPicker.vue


+ 1 - 1
cfc-frontend/pages/family/add-member.vue

@@ -108,7 +108,7 @@
 
 <script>
 import { addFamilyMember, updateFamilyMember, recordConsent, checkPhone } from '../../utils/api.js'
-import GenerationPicker from '@/pages/family/components/GenerationPicker.vue'
+import GenerationPicker from '@/components/GenerationPicker.vue'
 import { parseDate } from '../../utils/format.js'
 
 export default {

+ 1 - 1
cfc-frontend/pages/profile-extra/family-members.vue

@@ -138,7 +138,7 @@ import {
   rejectJoinRequest, reportAppEnter
 } from '../../utils/api.js'
 import store from '../../store/index.js'
-import GenerationPicker from '@/pages/family/components/GenerationPicker.vue'
+import GenerationPicker from '@/components/GenerationPicker.vue'
 
 export default {
   components: { GenerationPicker },