# P0 任务工作票 — 家庭成员辈分重构 **任务 ID:** TASK-P0-001 **优先级:** P0(阻塞性) **预计工时:** 3-5 天(后端 3d + 前端 2d) **状态:** 已实施 **负责人:** 待分配 **关联文档:** `plans/2026-07-07-家庭成员辈分重构实施计划.md` --- ## 业务背景 当前家庭成员关系使用 `relationship_types` 表定义关系类型(spouse/parent/child/sibling),存在以下问题: 1. **关系类型与辈分耦合**——spouse/parent/child/sibling 混合了辈分和关系性质 2. **无法表达多代关系**——缺少祖辈/孙辈等辈分定义 3. **视角转换复杂**——需要遍历关系树计算相对标签 辈分重构用 `generation`(辈分值)模型替代关系类型,简化视角转换逻辑。 --- ## 范围 ### 包含 - 数据库迁移:添加 `generation`、`is_spouse` 列,迁移旧数据,删除废弃列和表 - 后端实体/DTO/Service 重写 - 管理端(cfc-web)关系类型管理页面删除,成员添加页面改为辈分选择器 - 小程序前端 `GenerationPicker` 组件,替换 `RelationshipPicker` ### 不包含 - 家庭关系图谱 UI 重设计(已独立完成) - 成员卡片样式变更(仅数据模型变更) - 其他维度功能 --- ## 技术方案 ### 数据库变更 ```sql -- 迁移 1: 添加新列 ALTER TABLE family_members ADD COLUMN generation INT COMMENT '辈分值(0=家庭创建者,+n=向上,-n=向下)', ADD COLUMN is_spouse TINYINT(1) DEFAULT 0 COMMENT '是否配偶(同辈)'; -- 迁移 2: 旧数据映射 UPDATE family_members SET generation = 0, is_spouse = 1 WHERE relationship_type = 'spouse'; UPDATE family_members SET generation = 1 WHERE relationship_type = 'parent'; UPDATE family_members SET generation = -1 WHERE relationship_type = 'child'; UPDATE family_members SET generation = 0 WHERE relationship_type = 'sibling'; UPDATE family_members SET generation = 0 WHERE generation IS NULL; -- 迁移 3: 删除废弃列(确认无引用后) ALTER TABLE family_members DROP COLUMN relationship_type; ALTER TABLE family_members DROP COLUMN role_override; -- 迁移 4: 删除关系类型表 DROP TABLE IF EXISTS relationship_types; ``` ### 后端改动 | 文件 | 改动类型 | 说明 | |------|----------|------| | `enums/GenerationLevel.java` | 新建 | 7级辈分枚举 | | `entity/FamilyMember.java` | 修改 | 删除 relationshipType/roleOverride,新增 generation/isSpouse | | `dto/FamilyMemberVO.java` | 修改 | 删除 relationshipType/relationshipTypeName,新增 generation | | `dto/AddFamilyMemberDTO.java` | 新建 | relativeMemberId + generationLevel + peerType | | `service/FamilyMemberService.java` | 重写 | computeEffectiveRole, computeRelativeLabel, addMember, listMembers, toFamilyMemberVO | | `controller/family/FamilyMembersController.java` | 修改 | 更新请求/响应 DTO | | `config/DatabaseInitializer.java` | 修改 | 新增 4 个迁移 | | `mapper/FamilyMemberMapper.java` | 无改动 | - | | `schema.sql` | 同步 | 更新表结构 | ### 前端改动 | 文件 | 改动类型 | 说明 | |------|----------|------| | `utils/generationLevel.js` | 新建 | 辈分选项常量(7级 + 同辈类型) | | `components/GenerationPicker.vue` | 新建 | 辈分选择器组件 | | `components/RelationshipPicker.vue` | 删除 | 旧关系类型选择器 | | `pages/family/member-add.vue` | 修改 | 替换关系类型选择为辈分选择 | | `pages/family/member-edit.vue` | 修改 | 同上 | | `cfc-web/src/views/family/member-add.vue` | 修改 | 管理端成员添加页面 | | `cfc-web/src/router/family.js` | 无改动 | - | --- ## API 变更 ### 废弃端点 | 端点 | 操作 | 替代方案 | |------|------|----------| | `GET /api/family/member/types` | 获取关系类型列表 | 删除(前端使用 generationLevel.js 常量) | | `POST /api/admin/relationship-type/save` | 保存关系类型 | 删除(关系类型不再可配置) | | `POST /api/admin/relationship-type/list` | 查询关系类型 | 删除 | ### 修改端点 | 端点 | 请求体变更 | 响应体变更 | |------|-----------|-----------| | `POST /api/family/member/add` | `{relativeMemberId, generationLevel, peerType?, ...}` | `{..., generation}` | | `POST /api/family/member/list` | 无 | 移除 `relationshipType`、`relationshipTypeName`,新增 `generation` | | `POST /api/family/member/update` | 同上 | 同上 | --- ## 验收标准 ### 功能验收 - [ ] 添加成员时可选择辈分(7级)和同辈类型(亲兄弟姐妹/配偶) - [ ] 添加配偶后,`is_spouse=1`,`generation=0` - [ ] 添加子侄辈后,`generation=-1` - [ ] 成员列表显示正确的相对标签("我"、"爸爸"、"妈妈"、"儿子"、"女儿"等) - [ ] 家长切换视角后,相对标签自动更新 - [ ] 管理端成员添加页面无关系类型字段 ### 数据迁移验收 - [ ] 旧数据 `relationship_type='spouse'` → `generation=0, is_spouse=1` - [ ] 旧数据 `relationship_type='parent'` → `generation=1` - [ ] 旧数据 `relationship_type='child'` → `generation=-1` - [ ] 旧数据 `relationship_type='sibling'` → `generation=0, is_spouse=0` - [ ] 迁移后 `SELECT relationship_type FROM family_members` 返回空 ### 代码质量验收 - [ ] `mvn clean compile` 零错误 - [ ] 单元测试覆盖率 ≥ 80%(核心方法) - [ ] LSP 诊断零错误 - [ ] `grep -r "relationshipType" cfc-backend/src/main/java` 返回空 - [ ] `grep -r "RelationshipType" cfc-backend/src/main/java` 返回空 - [ ] 前端小程序编译零警告 ### 性能验收 - [ ] 成员列表 API 响应时间 ≤ 200ms(100 个成员以内) - [ ] 相对标签计算性能:1000 次调用 ≤ 50ms --- ## 测试策略 ### 单元测试(后端) ```java @Test void computeRelativeLabel_shouldReturnCorrectLabel() { // 测试所有辈分组合 // case: 我 vs 爸爸 (genDiff=1) → "爸爸" // case: 我 vs 儿子 (genDiff=-1) → "儿子" // case: 我 vs 配偶 (genDiff=0, isSpouse=true) → "配偶" // case: 我 vs 兄弟 (genDiff=0, isSpouse=false) → "哥哥"/"弟弟"(按年龄) } ``` ### 集成测试(后端) ```java @Test void addMember_withGenerationLevel_shouldPersistGeneration() { // 添加配偶 // 验证 generation=0, is_spouse=1 // 添加子侄辈 // 验证 generation=-1 } ``` ### E2E 测试(前端) - 添加成员流程:选择参照成员 → 选择辈分 → 填写信息 → 提交成功 - 成员列表:显示正确的相对标签 - 视角切换:切换角色后标签自动更新 --- ## 部署检查清单 - [ ] 数据库迁移脚本在预生产环境演练通过 - [ ] 生产环境数据库备份完成 - [ ] 回滚方案准备(恢复 relationship_type 列和表) - [ ] 管理端关系类型管理页面已下线 - [ ] 小程序前端新版本已提交审核 - [ ] 监控指标:`family_member_add_duration`、`relative_label_compute_duration` --- ## 回滚计划 ### 触发条件 - 数据迁移失败且无法恢复 - 核心功能(添加成员、成员列表)严重故障 - 性能下降 ≥ 50% ### 回滚步骤 1. 数据库回滚:恢复 `relationship_type`、`role_override` 列,恢复 `relationship_types` 表 2. 代码回滚:切换至上一版本分支 3. 前端回滚:小程序回滚至旧版本 4. 验证:核心功能恢复,数据无丢失 --- ## 联系信息 - **技术负责人:** 见 Git 仓库 MAINTAINERS.md - **产品负责人:** 见 PROJECT-OVERVIEW.md 维护字段 - **DevOps 支持:** 见 cfc-backend/start.sh --- **文档结束**