2026-06-15-family-member-cards-design.md 6.3 KB

家庭成员卡片跨页面展示 + 可见性控制 — 设计文档

日期: 2026-06-15 状态: 草案(待审批)

1. 概述

在首页、身体、心智、行动四个 Tab 页面顶部增加家庭成员卡片条,点击卡片切换当前查看的成员,页面数据随之过滤为该成员在对应维度的内容。成员(家长/孩子)可控制自己是否对其他家庭成员可见。

2. 数据模型

2.1 现有模型

  • children 表 (Child.java): nickname, age, gender, totalPoints, familyId
  • users 表 (User.java): nickname, avatar, role, familyId
  • getFamilyMembers() API (/api/family/user/family-members): 返回 { parents: [...], children: [...] }

2.2 新增字段

children 表和 users 表各新增:

show_to_family TINYINT DEFAULT 1 COMMENT '是否对家庭成员可见: 1=是, 0=否'

通过 DatabaseInitializer 自动迁移:

// 检查并添加 show_to_family 列
String checkChildCol = "SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'children' AND COLUMN_NAME = 'show_to_family'";
if (jdbcTemplate.queryForObject(checkChildCol, Integer.class) == 0) {
    jdbcTemplate.execute("ALTER TABLE children ADD COLUMN show_to_family TINYINT DEFAULT 1 COMMENT '是否对家庭成员可见'");
}
// 同样处理 users 表

2.3 新增 DTO: FamilyMemberVO

@Data
public class FamilyMemberVO {
    private Long id;           // 成员ID (child.id 或 user.id)
    private String nickname;   // 昵称
    private String avatar;     // 头像URL (用户表)
    private String memberType; // 'child' 或 'parent'
    private String roleLabel;  // '孩子' 或 '家长'
    private Integer totalPoints;
    private Boolean showToFamily;
}

3. API 设计

3.1 POST /api/family/members/visible

获取当前家庭中所有 show_to_family = 1 的成员。

请求体: 无(通过 JWT 获取 userId)

响应:

{
  "code": 200,
  "data": [
    {
      "id": 1,
      "nickname": "小明",
      "avatar": "",
      "memberType": "child",
      "roleLabel": "孩子",
      "totalPoints": 120,
      "showToFamily": true
    },
    {
      "id": 2,
      "nickname": "妈妈",
      "avatar": "https://...",
      "memberType": "parent",
      "roleLabel": "家长",
      "totalPoints": 500,
      "showToFamily": true
    }
  ]
}

3.2 POST /api/family/members/update-visibility

切换当前用户的可见性。

请求体:

{
  "memberId": 1,
  "memberType": "child",
  "showToFamily": false
}

约束: 只有家长可以修改孩子的可见性;用户只能修改自己的可见性。

4. 前端组件

4.1 FamilyMemberCard.vue

单个成员卡片组件。

Props:

  • member: Object — 成员数据 (FamilyMemberVO)
  • isSelected: Boolean — 是否当前选中

Events:

  • @select(member) — 点击选中

样式:

  • 尺寸: 120rpx × 160rpx 竖卡
  • 头像(圆形)+ 昵称 + 角色标签
  • 选中态: 橙色边框 + 底部对勾标记
  • 不可见成员不展示(由父组件过滤)

4.2 FamilyMemberStrip.vue

水平滚动成员卡片条。

Props:

  • members: Array — 成员列表
  • selectedMemberId: Number — 当前选中ID

Events:

  • @select(member) — 卡片点击
  • @visibilityChange(memberId, show) — 可见性变更

行为:

  • 少于 4 个成员:居中均匀排列
  • 4 个及以上:scroll-view 水平滚动
  • 点击卡片 → 触发 select 事件

5. 页面集成

5.1 组件层级(四页统一)

PageBanner
  ↓
FamilyMemberStrip ← 新增(水平滚动,高亮选中成员)
  ↓
FamilyEnergyBar(已有,数据响应 selectedMemberId)
  ↓
UserQuickEntry(已有,保持不变)
  ↓
各维度专属内容(随 selectedMemberId 切换)

5.2 各页面差异

页面 选中成员后的数据切换逻辑
parent-index.vue 能量沙盘、成长数据统计切换为该成员的数据;孩子卡片区域保持不变
body/index.vue 健康报告、功能入口切换为该成员
mind/index.vue EMI/DAN 测评数据切换为该成员
action/index.vue 任务、活动、商品切换为该成员

5.3 数据流

FamilyMemberStrip
  @select(member)
    → 父页面设置 selectedMemberId
    → 重新请求该成员在对应维度的数据
    → 下发给 FamilyEnergyBar / 内容组件

已有模式参考:UserQuickEntry 的 @childChanged → onChildChanged → 重新加载数据。

6. 可见性控制 UI

6.1 家长端

  • 孩子编辑页(pages/family/child-edit.vue 或新增设置页):新增开关"对其他家庭成员可见"
  • 个人设置页(pages/profile/profile.vue):新增开关"对家庭成员可见"

6.2 孩子端

  • 孩子本人不可修改可见性(由家长控制)

7. 向后兼容

  • show_to_family 默认 1,现有成员不受影响
  • 新增 API /api/family/members/visible 不影响现有 getFamilyMembers
  • 各页面插 FamilyMemberStrip 用 v-if="isLoggedIn" 控制,不登录不影响

8. 实施计划

Phase 1: 后端

  1. DatabaseInitializer 添加 show_to_family 字段迁移
  2. FamilyMemberVO DTO
  3. FamilyService.getVisibleMembers(userId) 查询逻辑
  4. FamilyService.updateVisibility(memberId, memberType, showToFamily) 更新逻辑
  5. FamilyController 新增两个端点
  6. mvn clean compile 验证

Phase 2: 前端组件

  1. FamilyMemberCard.vue 组件
  2. FamilyMemberStrip.vue 组件
  3. api.js 添加 getVisibleFamilyMembers 和 updateMemberVisibility

Phase 3: 页面集成

  1. parent-index.vue — 插 FamilyMemberStrip
  2. body/index.vue — 插 FamilyMemberStrip
  3. mind/index.vue — 插 FamilyMemberStrip
  4. action/index.vue — 插 FamilyMemberStrip

Phase 4: 可见性控制UI

  1. 孩子编辑页添加 showToFamily 开关
  2. 个人设置页添加 showToFamily 开关

9. 未纳入范围

  • 本设计不涉及家长端/孩子端之间数据权限的细粒度控制(如"只对爸爸可见不对妈妈可见"),当前仅用 show_to_family 二值控制
  • 不涉及首页 child-index/teacher-index 的成员卡片(仅 parent-index + body/mind/action 三个维度页)
  • 不修改现有 FamilyEnergyBar 和 wuxing-sandbox 的行为