FamilyMemberStrip(横向滚动容器)
└── FamilyMemberCard(单个成员卡片)
├── 头像(avatar)
├── 角色标签(roleBadge: parent/child/teacher/elderly)
├── 昵称(nickname)
├── 能量分数(energyScore,可选)
└── 选中标记(isSelected)
/api/family/member/list 返回的 FamilyMember 对象,包含:
id, familyId, userId, nickname, phone, avatar, gender, birthday,
generation, isSpouse, totalPoints, trustScore, intimacyScore, ...
| 页面 | 用途 |
|---|---|
| parent-index | 家长首页成员选择器 |
| child-index | 孩子首页成员选择器 |
| mind/body/wisdom/wealth/action/index | 五维首页成员选择器 |
| index-home | 首页成员选择 |
| # | 功能 | 需求 | 当前实现 | 差距 |
|---|---|---|---|---|
| 1 | 关系标签 | 显示成员与当前用户的关系(爸爸/妈妈/儿子/女儿/配偶) | 只显示 roleLabel(parent/child/teacher),没有家庭关系语义 |
❌ 缺少关系标签 |
| 2 | 辈分/世代 | 显示辈分信息(如"二代") | FamilyMember 有 generation 字段,但未展示 |
❌ 未使用 |
| 3 | 配偶标记 | 标记配偶关系 | isSpouse 字段存在,但未展示 |
❌ 未使用 |
| 4 | 联系方式 | 快速拨打电话/发消息 | 无电话显示,无快捷操作 | ❌ 缺少 |
| 5 | 成员编辑 | 编辑成员信息(昵称/头像/角色) | 无编辑入口 | ❌ 缺少 |
| 6 | 移除成员 | 从家庭中移除成员 | 无移除操作 | ❌ 缺少 |
| 7 | 角色切换 | 一键切换到该成员视角 | 只有 member/switch API 但卡片未集成 |
❌ 缺少 |
| 8 | 成员详情 | 点击进入成员详情页 | 只有 select 事件,无导航到详情页 |
❌ 缺少 |
| 9 | 长按菜单 | 长按弹出操作菜单(编辑/切换/移除) | 无长按交互 | ❌ 缺少 |
| 10 | 关系色 | 根据关系类型显示不同配色 | 只有4种角色色(parent橙/child蓝/teacher紫/elderly灰) | ⚠️ 部分实现 |
| 11 | 能量分数 | 显示成员五维能量综合分数 | 已实现,但只显示一个总分 | ⚠️ 部分实现 |
| 12 | 选中状态 | 高亮当前选中的成员 | 已实现 | ✅ |
| 13 | 横向滚动 | 成员多时可横向滚动 | 已实现(scroll-view) | ✅ |
| 14 | 头像显示 | 显示成员头像 | 已实现,有默认头像 fallback | ✅ |
当前 roleBadge 显示的是系统角色(parent/child/teacher),但用户需要看到的是家庭关系:
FamilyMember 实体中没有直接的关系字段。关系信息存在于 family_relationships 表中(双向关系),需要通过 /api/family/relationship/list 获取。
实现方案:
// 需要的 API 返回数据
{
"id": 1003,
"nickname": "小明",
"relationship": "儿子", // 当前用户的儿子
"generation": 2, // 第二代
"isSpouse": false,
"avatar": "...",
"phone": "138xxxx"
}
当前卡片只能点击选中,缺少以下操作:
| 操作 | 触发方式 | 功能 |
|---|---|---|
| 切换视角 | 点击 | 切换到该成员视角(家长可用) |
| 编辑资料 | 长按菜单/编辑按钮 | 修改昵称、头像 |
| 移除成员 | 长按菜单 | 从家庭中移除(仅限家长操作) |
| 拨打电话 | 点击电话图标 | 调用系统拨号 |
当前卡片信息过于简单,缺少:
trustScore, intimacyScore 字段已存在但未使用)<template>
<view class="family-member-card" :class="{ selected: isSelected }"
@click="onClick" @longpress="onLongPress">
<!-- 头像 -->
<view class="card-avatar-wrap">
<image class="card-avatar" :src="member.avatar || defaultAvatar" />
<view class="card-role-badge" :style="{ background: relationColor }">
<text>{{ member.relationship || member.roleLabel || '成员' }}</text>
</view>
</view>
<!-- 昵称 + 辈分 -->
<text class="card-nickname">{{ member.nickname }}</text>
<text class="card-generation" v-if="member.generation">
第{{ member.generation }}代
</text>
<!-- 联系方式 -->
<view class="card-contact" v-if="member.phone" @click.stop="callMember">
<text class="contact-icon">📞</text>
</view>
<!-- 能量分数 -->
<view class="card-energy" v-if="energyScore !== null">
<text class="energy-value">{{ energyScore }}</text>
</view>
<!-- 选中标记 -->
<view class="card-selected-mark" v-if="isSelected">✓</view>
</view>
</template>
| 端点 | 说明 | 当前状态 |
|---|---|---|
GET /api/family/member/list |
返回含 relationship 字段 | ❌ 需增加 relationship 字段 |
GET /api/family/relationship/list |
获取家庭成员关系 | ✅ 已存在 |
POST /api/family/member/switch |
切换到成员视角 | ✅ 已存在 |
POST /api/family/member/update |
更新成员信息 | ✅ 已存在 |
POST /api/family/member/kick |
移除成员 | ✅ 已存在 |
// FamilyMemberDTO 增加
private String relationship; // 与当前用户的关系: 爸爸/妈妈/儿子/女儿
private Integer generation; // 辈分
private Boolean isSpouse; // 是否配偶
private BigDecimal trustScore; // 信任度
private BigDecimal intimacyScore; // 亲密度
// 查询家庭成员列表时,同时计算每个成员与当前用户的关系
List<FamilyMember> members = familyMemberMapper.selectList(...);
// 查询关系类型配置
List<RelationshipType> relationTypes = relationshipTypeMapper.selectList(...);
// 为每个成员计算关系标签
for (FamilyMember member : members) {
String relation = relationshipService.calculateRelation(currentUserId, member.getUserId());
member.setRelationship(relation);
}