Explorar o código

fix(family): 修复成员条移除后不刷新 + 可见成员列表字段缺失

E2E Test Bot hai 1 mes
pai
achega
1951c26197

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

@@ -72,4 +72,7 @@ public class FamilyMemberVO {
 
     /** 当前登录用户是否为家庭管理员(creatorId === userId),用于前端控制编辑权限 */
     private Boolean isAdmin;
+
+    /** 是否为当前登录用户本人(用于前端控制移除/切换等操作权限) */
+    private Boolean isSelf;
 }

+ 16 - 16
cfc-backend/src/main/java/com/etotem/cfc/service/UserService.java

@@ -65,6 +65,9 @@ private FamilyInvitationService familyInvitationService;
     @Resource
     private UserProfileHistoryMapper userProfileHistoryMapper;
 
+    @Resource
+    private FamilyMemberService familyMemberService;
+
     public LoginResultDTO wechatLogin(WechatLoginDTO dto) {
         // 1. 通过code获取openid
         Map<String, String> sessionData = wechatService.code2Session(dto.getCode());
@@ -667,7 +670,7 @@ private FamilyInvitationService familyInvitationService;
         Long creatorId = (family != null) ? family.getCreatorId() : null;
         boolean isAdmin = creatorId != null && creatorId.equals(userId);
 
-        // 家长:show_to_family=1 的同家庭家长
+        // 家长:show_to_family=1 的同家庭家长(自己始终可见)
         List<User> parents = userMapper.selectList(new LambdaQueryWrapper<User>()
                 .eq(User::getFamilyId, familyId)
                 .eq(User::getRole, "parent"));
@@ -675,33 +678,30 @@ private FamilyInvitationService familyInvitationService;
             if (p.getId().equals(userId) || (p.getShowToFamily() != null && p.getShowToFamily() == 1)) {
                 FamilyMemberVO vo = new FamilyMemberVO();
                 vo.setId(p.getId());
+                vo.setSource("parent");
+                vo.setUserId(p.getId());
                 vo.setNickname(p.getNickname());
                 vo.setAvatar(p.getAvatar());
+                vo.setPhone(p.getPhone());
+                vo.setGender(p.getGender());
                 vo.setEffectiveRole("parent");
                 vo.setMemberType("parent");
                 vo.setRoleLabel(p.getFamilyRole() != null ? p.getFamilyRole() : "家长");
                 vo.setTotalPoints(p.getTotalPoints());
                 vo.setShowToFamily(p.getShowToFamily() != null ? p.getShowToFamily() : 1);
                 vo.setIsAdmin(isAdmin);
+                vo.setIsSelf(p.getId().equals(userId));
                 result.add(vo);
             }
         }
 
-        // 孩子:show_to_family=1 的同家庭孩子
-        List<FamilyMember> children = familyMemberMapper.selectList(new LambdaQueryWrapper<FamilyMember>()
-                .eq(FamilyMember::getFamilyId, familyId));
-        for (FamilyMember c : children) {
-            if (c.getShowToFamily() == null || c.getShowToFamily() == 1) {
-                FamilyMemberVO vo = new FamilyMemberVO();
-                vo.setId(c.getId());
-                vo.setNickname(c.getNickname());
-                vo.setAvatar("");
-                vo.setEffectiveRole("child");
-                vo.setMemberType("child");
-                vo.setRoleLabel("孩子");
-                vo.setTotalPoints(c.getTotalPoints());
-                vo.setShowToFamily(c.getShowToFamily() != null ? c.getShowToFamily() : 1);
-                vo.setIsAdmin(isAdmin);
+        // 孩子/其他成员:复用 FamilyMemberService.listMembers 的完整字段计算(关系标签/辈分/配偶/信任分等),
+        // 再按 show_to_family 过滤(自己始终可见)
+        List<FamilyMemberVO> members = familyMemberService.listMembers(userId);
+        for (FamilyMemberVO vo : members) {
+            boolean isSelf = vo.getUserId() != null && vo.getUserId().equals(userId);
+            if (isSelf || vo.getShowToFamily() == null || vo.getShowToFamily() == 1) {
+                vo.setIsSelf(isSelf);
                 result.add(vo);
             }
         }

+ 17 - 18
cfc-frontend/components/FamilyMemberStrip.vue

@@ -72,7 +72,7 @@
 
 <script>
 import FamilyMemberCard from '@/components/FamilyMemberCard'
-import config from '@/config.js'
+import { kickFamilyMemberById } from '@/utils/api'
 
 export default {
   components: { FamilyMemberCard },
@@ -90,13 +90,16 @@ export default {
   },
   computed: {
     canSwitch: function() {
-      return this.actionMember && this.actionMember.userId
+      // 仅家庭成员记录(source=family_member)且已关联账号时才能切换视角;
+      // 家长卡片(source=parent)是 users 表记录,switch 接口只查 family_members 表,切换会失败
+      return this.actionMember && this.actionMember.userId && this.actionMember.source === 'family_member'
     },
     canEdit: function() {
       return this.isParent && this.actionMember && !this.actionMember.userId && this.actionMember.source === 'family_member'
     },
     canRemove: function() {
-      return this.isParent && this.actionMember && !this.actionMember.isSelf
+      // 仅家庭成员记录可移除(kick 接口只查 family_members 表),且不能移除自己
+      return this.isParent && this.actionMember && !this.actionMember.isSelf && this.actionMember.source === 'family_member'
     }
   },
   methods: {
@@ -147,6 +150,7 @@ export default {
       }
     },
     removeMember: function() {
+      var self = this
       var member = this.actionMember
       this.closeMenu()
       if (member) {
@@ -156,22 +160,17 @@ export default {
           success: function(res) {
             if (res.confirm) {
               uni.showLoading({ title: '移除中...' })
-              uni.request({
-                url: config.API_BASE_URL + '/api/family/member/kick',
-                method: 'POST',
-                data: { memberId: member.id },
-                header: { 'Authorization': 'Bearer ' + uni.getStorageSync('token') },
-                success: function(resp) {
+              kickFamilyMemberById(member.id)
+                .then(function() {
                   uni.hideLoading()
-                  if (resp.data && resp.data.code === 200) {
-                    uni.showToast({ title: '已移除', icon: 'success' })
-                    // 通知父组件刷新
-                    getApp().globalData.refreshFamilyMembers = true
-                  } else {
-                    uni.showToast({ title: resp.data.message || '移除失败', icon: 'none' })
-                  }
-                }
-              })
+                  uni.showToast({ title: '已移除', icon: 'success' })
+                  // 通知父组件刷新成员列表(替代无效的 globalData 标志)
+                  self.$emit('removed', member)
+                })
+                .catch(function(err) {
+                  uni.hideLoading()
+                  uni.showToast({ title: (err && err.message) || '移除失败', icon: 'none' })
+                })
             }
           }
         })

+ 2 - 1
cfc-frontend/pages/action/index.vue

@@ -13,7 +13,8 @@
       v-if="isLoggedIn"
       :members="familyMembersVisible"
       :selectedMemberId="selectedMemberId"
-      @select="onFamilyMemberSelect" />
+      @select="onFamilyMemberSelect"
+      @removed="loadFamilyMembersVisible" />
 
     <!-- 游客登录引导卡 -->
     <template v-if="!isLoggedIn">

+ 2 - 1
cfc-frontend/pages/body/index.vue

@@ -32,7 +32,8 @@
       v-if="isLoggedIn"
       :members="familyMembersVisible"
       :selectedMemberId="selectedMemberId"
-      @select="onFamilyMemberSelect" />
+      @select="onFamilyMemberSelect"
+      @removed="loadFamilyMembersVisible" />
 
     <!-- 游客专属区块 -->
     <template v-if="!isLoggedIn">

+ 2 - 1
cfc-frontend/pages/home-pages/child-index.vue

@@ -58,7 +58,8 @@
   v-if="hasChildren && familyMembersVisible.length > 0"
   :members="familyMembersVisible"
   :selectedMemberId="selectedMemberId"
-  @select="onFamilyMemberSelect" />
+  @select="onFamilyMemberSelect"
+  @removed="loadFamilyMembersVisible" />
 
 <!-- 连续打卡徽章 -->
 <view

+ 2 - 1
cfc-frontend/pages/home-pages/parent-index.vue

@@ -16,7 +16,8 @@
   :selectedMemberId="selectedMemberId"
   :isParent="isFamilyAdmin"
   @select="onFamilyMemberSelect"
-  @switch="onFamilyMemberSwitch" />
+  @switch="onFamilyMemberSwitch"
+  @removed="loadFamilyMembersVisible" />
 
 <!-- ===== 微行动卡片(P0:有效启动) ===== -->
 <MicroActionCard

+ 2 - 1
cfc-frontend/pages/index-home/index.vue

@@ -70,7 +70,8 @@
       :selectedMemberId="selectedMemberId"
       :isParent="isFamilyAdmin"
       @select="onFamilyMemberSelect"
-      @switch="onFamilyMemberSwitch" />
+      @switch="onFamilyMemberSwitch"
+      @removed="loadFamilyMembers" />
 
     <!-- 五维能量条 -->
     <FamilyEnergyBar

+ 2 - 1
cfc-frontend/pages/mind/index.vue

@@ -23,7 +23,8 @@
       v-if="isLoggedIn"
       :members="familyMembersVisible"
       :selectedMemberId="selectedMemberId"
-      @select="onFamilyMemberSelect" />
+      @select="onFamilyMemberSelect"
+      @removed="loadFamilyMembersVisible" />
 
     <!-- 游客登录引导卡 -->
     <template v-if="!isLoggedIn">

+ 2 - 1
cfc-frontend/pages/wealth/index.vue

@@ -34,7 +34,8 @@
         v-if="isLoggedIn"
         :members="familyMembersVisible"
         :selectedMemberId="selectedMemberId"
-        @select="onFamilyMemberSelect" />
+        @select="onFamilyMemberSelect"
+        @removed="loadFamilyMembersVisible" />
 
       <!-- 模式切换 / 退出切换入口(家长未切时显示"切换到孩子视角";已切时显示"退出切换") -->
  <!-- 已切孩子态:点击"退出切换"回到家长模式 -->

+ 2 - 1
cfc-frontend/pages/wisdom/index.vue

@@ -30,7 +30,8 @@
       v-if="isLoggedIn"
       :members="familyMembersVisible"
       :selectedMemberId="selectedMemberId"
-      @select="onFamilyMemberSelect" />
+      @select="onFamilyMemberSelect"
+      @removed="loadFamilyMembersVisible" />
 
     <!-- 3. 游客专属区块 -->
     <template v-if="!isLoggedIn">