日期: 2026-09-28 状态: 设计稿 前置文档:
2026-08-04-registration-profile-backfill-design.md(注册引导 + 按需补充回写,本设计继承其回写机制)2026-08-04-registration-profile-backfill.md(对应实施计划)核心诉求:取消用户注册时的信息填写步骤,注册成功直接进首页;所有个人信息在功能实际需要时补充。
用户原话:「取消用户注册时填写信息一项,所有信息都在需要时补充,各个功能要列出要使用的信息。」
三个目标:
系统角色分三大类(不区分"家长/孩子"语义,新功能禁止引入孩子概念):
| 角色类别 | 说明 | 注册/创建方式 |
|---|---|---|
| 可登录用户 | 手机号+微信注册,可登录小程序 | 注册零填写,登录即注册,直接进首页 |
| 服务用户 | 成长规划师等,需资质审核 | 独立注册流程 pages/guide/register(证书/照片/身份证,本方案不改动) |
| 不可登录用户 | 无登录账号,由家庭管理员创建 | 家庭成员管理页添加(pages/family/add-member),填昵称/辈分/性别/生日等 |
数据归属:可登录用户信息存 users 表;不可登录用户信息存 family_members 表;同一家庭的可登录用户可代管不可登录用户数据。
| 项目 | 现状 | 问题 |
|---|---|---|
| 注册流程 | 登录成功 → needsRoleSelect=true(新用户)→ 跳 user-edit?autoParent=true 全字段表单 |
强制填写,与"注册零填写"诉求冲突 |
| 默认昵称 | 后端注册时已设默认(用户+手机尾号 / 微信用户),不依赖前端 |
✅ 可复用 |
| 接受邀请 | join.vue → 已登录用户跳 user-edit?autoParent=true(全字段 + 家庭身份下拉) |
全字段表单过重,且家庭身份非必填 |
| 添加成员 | add-member.vue 填手机号时提示「若手机号已注册,将自动关联该账号」 |
需求改为「提示是否邀请加入」 |
| 按需回写 | profile-field-usage.js + profile-backfill.js + 后端 backfill 接口已就绪;仅活动报名接入 |
映射表不完整,各功能未接入 |
| # | 决策 | 结论 |
|---|---|---|
| 1 | 注册后是否填写 | 完全零填写,登录成功直接进首页(头像/昵称均不填,昵称用后端默认) |
| 2 | 角色注册 | 可登录用户默认直接进首页;服务用户保留独立注册流程;不可登录用户由家庭管理员添加 |
| 3 | 接受家庭邀请 | 新增独立页面(内容与 user-edit 相同),真实姓名 + 家庭身份必填,其余选填 |
| 4 | 功能→信息映射 | 更新 profile-field-usage.js 建立完整映射(本次仅出文档,各功能后续逐个接入) |
| 5 | 添加成员手机号冲突 | 手机号已被注册 → 提示「是否邀请该用户加入家庭」 |
| 6 | needsRoleSelect |
后端字段保留,前端不再消费(登录不再跳转) |
| 7 | user-edit.vue |
保留「个人中心编辑资料」用途,autoParent=true 新用户流程停用 |
文件: pages/login/login.vue
completeLogin()(L177-178)改造:
当前:
if (data.needsRoleSelect || hasPendingFamilyInvite) {
uni.redirectTo('/pages/user-edit/user-edit?...&autoParent=true')
} else {
self.handlePostLoginRouting()
}
改为:
// 注册零填写:needsRoleSelect 不再触发跳转
// 家庭邀请衔接:有 pendingFamilyInviteCode → 直接进 join-form 填真实姓名+家庭身份
var pendingInvite = uni.getStorageSync('pendingFamilyInviteCode')
if (pendingInvite) {
uni.redirectTo({ url: '/pages/invite/join-form?familyInviteCode=' + encodeURIComponent(pendingInvite) })
} else {
self.handlePostLoginRouting()
}
needsRoleSelect=true)不再跳 user-edit,登录成功直接进首页(后端默认昵称兜底)needsRoleSelect 字段保留在 LoginResultDTO,前端不再消费文件: pages/user-edit/user-edit.vue
isNewUserFlow(autoParent=true 分支)停用:onLoad 不再处理 autoParent=true / needsRoleSelect=true 参数,统一走普通编辑模式confirmRole / selectRole / 角色选择区:仅保留非新用户进入时的行为(实际个人中心编辑不涉及角色选择,相关区块可清理或保留不显示)hasPendingFamilyInvite / familyRole 区块 / requestJoinByCode)逻辑迁移至新页面 5.2新增文件: pages/invite/join-form.vue(注册到 pages.json 的 pages/invite 分包)
页面内容: 字段与 user-edit.vue 编辑模式相同,但仅强制两项:
| 字段 | 必填 | 说明 |
|---|---|---|
| 真实姓名 | ✅ | 家庭管理员据此识别申请人 |
| 家庭身份 | ✅ | 爸爸/妈妈/爷爷/奶奶/姥爷/姥姥/其他(复用 familyRoleOptions) |
| 昵称 | 选填 | 为空时前端用默认(用户+手机尾号),不强制触发后端重算 |
| 头像/性别/生日/其他 | 选填 | 可顺手填,不填不影响加入申请 |
交互流程:
join.vue(已登录、不在目标家庭)
→ goJoinForm() 跳 /pages/invite/join-form?familyInviteCode=xxx
→ 填写真实姓名 + 家庭身份(其余选填)
→ 保存:updateUserInfo(realName, nickname, avatar, ...)(可选字段透传)
+ requestJoinByCode(inviteCode, familyRole) 提交加入申请
→ 成功 toast「加入家庭申请已提交,等待管理员审批」→ goHome
join.vue(未登录)
→ goLogin → 登录成功后 login.vue completeLogin 检测到 pendingFamilyInviteCode
→ 跳 join-form(衔接闭环)
join.vue 改造(L261-284):
goUserEdit() 改为 goJoinForm():跳 /pages/invite/join-form?familyInviteCode=...&token=...&userId=...goNext() 未登录分支(L274-278)保持不变:调 goLogin();登录后由 login.vue 完成衔接(见上面流程)user-edit.vue 的 requestJoinByCode 调用逻辑到新页面(user-edit.vue 中 L754-768 相关逻辑迁移)user-edit.vue 家庭邀请逻辑清理:
hasPendingFamilyInvite 计算属性移除(已无引用)familyRole form 字段、L48-57 家庭身份区块移除新增/更新: cfc-frontend/utils/profile-field-usage.js
完整映射(基于全前端探查):
| 字段 | 功能场景 | 页面 | 字段去向 | 现状 |
|---|---|---|---|---|
| realName 真实姓名 | 活动报名 | activity-detail | user/member | 手动填,未回写 |
| 接受家庭邀请 | invite/join-form | user | 本次新增必填 | |
| 创建联系人 | ContactImport | 独立实体 | 自填 | |
| phone 手机号 | 活动报名 | activity-detail | user/member | ✅ 已回写 |
| 添加成员关联账号 | add-member | member | 本次改「邀请加入」提示 | |
| birthday 生日 | 家庭天盘 | tianpan/* | user/member | 后端计算生肖/五行/生命数字,前端缺失无引导 |
| 测评年龄计算 | assessment/* | member | 后端计算,前端缺失无引导 | |
| 健康报告匹配 | health/report-* | member | 报告页自填(newMember) | |
| 饮食推荐 | nutrition-profile | member | 后端计算 | |
| birthHour 出生时辰 | 家庭天盘 | tianpan/* | user/member | 后端计算 |
| gender 性别 | 家庭天盘 | tianpan/* | user/member | 后端计算 |
| 测评维度计算 | assessment/* | member | 后端计算 | |
| 健康报告匹配 | health/report-* | member | 报告页自填 | |
| dietPreferences 饮食偏好 | 饮食推荐 | nutrition-profile | user/member | 后端计算 |
| address 地区 | 收货地址(独立地址簿) | shop/* | 独立实体 | 不走个人信息 |
| 活动地点 | activity-detail | user | 低优先级 | |
| avatar/nickname | 全局展示(家庭成员列表/评论/推荐人) | 各页 | user/member | 后端默认昵称兜底 |
约定: 功能页接入时在 scenes 中登记本场景;回写前校验字段属于本场景(profile-backfill.js 已实现该机制);回写白名单沿用后端 6 字段(phone/gender/birthday/birthHour/dietPreferences/address)+ realName(本次新增,后端白名单同步加)。
后端回写白名单扩展: UserService.backfillProfile() 的 USER_BACKFILL_WHITELIST 增加 "realName"(MEMBER_BACKFILL_WHITELIST 同步确认 family_members 是否有 realName 列;无则维持 phone/gender/birthday/birthHour)。
各功能页「缺失即就地补充 + 回写」的接入不在本次范围,按映射表后续逐个排期实施(P2+)。
文件: pages/family/add-member.vue
doSubmit)若填了手机号:调后端查询该手机号是否已被注册(新增或复用接口,如 POST /api/user/check-phone-exists)
FamilyMemberService / UserService 查询 phone)| 阶段 | 内容 | 说明 |
|---|---|---|
| P0(本次) | 注册零填写(login.vue)+ user-edit 新用户流程停用 + join-form 新页面 + join.vue 衔接 + 映射表更新 + add-member 手机号冲突提示 | 可单独上线 |
| P2+(后续逐个接入) | 天盘/测评/健康报告/饮食推荐等页面的「缺失就地补充 + 回写」接入 | 按映射表排期 |
user-edit 不再接受 autoParent=true 新用户流程参数(个人中心编辑资料正常)join-form:真实姓名 + 家庭身份必填,其余选填;提交后调 requestJoinByCode 等待管理员审批profile-field-usage.js 映射表完整(真实姓名/手机号/生日/出生时辰/性别/饮食偏好/地区 + 各自场景)realName(若 member 表无 realName 列则确认边界)mvn clean compile 通过;前端语法/结构校验通过| # | 项 | 决策 |
|---|---|---|
| 1 | 手机号已注册查询接口 | 复用现有 POST /api/auth/check-phone(前端已封装 checkPhone(phone) in api.js L344) |
| 2 | member 表 realName 列 | family_members 无 real_name 列(仅 nickname/phone/gender/birthday/birthHour 等);realName 只加进 USER 回写白名单(member 白名单维持 phone/gender/birthday/birthHour 4 字段) |
| 3 | join-form 与 user-edit 字段共用 | 本期直接新建,不抽公共组件;二期优化时考虑复用 |
本设计同步更新 docs/superpowers/PROJECT-OVERVIEW.md v2.13(2026-09-28)。
详见 docs/superpowers/plans/2026-09-28-registration-zero-fill.md(编写中)。