2026-09-28-registration-zero-fill-design.md 12 KB

规格文档:注册零填写 + 信息按需补充

日期: 2026-09-28 状态: 设计稿 前置文档:

  • 2026-08-04-registration-profile-backfill-design.md(注册引导 + 按需补充回写,本设计继承其回写机制)
  • 2026-08-04-registration-profile-backfill.md(对应实施计划)

1. 概述

核心诉求:取消用户注册时的信息填写步骤,注册成功直接进首页;所有个人信息在功能实际需要时补充。

用户原话:「取消用户注册时填写信息一项,所有信息都在需要时补充,各个功能要列出要使用的信息。」

三个目标:

  1. 注册零填写:可登录用户手机号登录即注册,登录成功直接进首页,不跳任何信息填写页
  2. 功能→信息映射:每个功能列出其使用的用户信息字段,缺失时在功能内就地补充并自动回写
  3. 接受邀请必填:接受家庭邀请时,真实姓名 + 家庭身份必填(仅此场景强制)

2. 角色模型(统一口径)

系统角色分三大类(不区分"家长/孩子"语义,新功能禁止引入孩子概念):

角色类别 说明 注册/创建方式
可登录用户 手机号+微信注册,可登录小程序 注册零填写,登录即注册,直接进首页
服务用户 成长规划师等,需资质审核 独立注册流程 pages/guide/register(证书/照片/身份证,本方案不改动)
不可登录用户 无登录账号,由家庭管理员创建 家庭成员管理页添加(pages/family/add-member),填昵称/辈分/性别/生日等

数据归属:可登录用户信息存 users 表;不可登录用户信息存 family_members 表;同一家庭的可登录用户可代管不可登录用户数据。

3. 现状分析

项目 现状 问题
注册流程 登录成功 → needsRoleSelect=true(新用户)→ 跳 user-edit?autoParent=true 全字段表单 强制填写,与"注册零填写"诉求冲突
默认昵称 后端注册时已设默认(用户+手机尾号 / 微信用户),不依赖前端 ✅ 可复用
接受邀请 join.vue → 已登录用户跳 user-edit?autoParent=true(全字段 + 家庭身份下拉) 全字段表单过重,且家庭身份非必填
添加成员 add-member.vue 填手机号时提示「若手机号已注册,将自动关联该账号」 需求改为「提示是否邀请加入」
按需回写 profile-field-usage.js + profile-backfill.js + 后端 backfill 接口已就绪;仅活动报名接入 映射表不完整,各功能未接入

4. 设计决策记录

# 决策 结论
1 注册后是否填写 完全零填写,登录成功直接进首页(头像/昵称均不填,昵称用后端默认)
2 角色注册 可登录用户默认直接进首页;服务用户保留独立注册流程;不可登录用户由家庭管理员添加
3 接受家庭邀请 新增独立页面(内容与 user-edit 相同),真实姓名 + 家庭身份必填,其余选填
4 功能→信息映射 更新 profile-field-usage.js 建立完整映射(本次仅出文档,各功能后续逐个接入)
5 添加成员手机号冲突 手机号已被注册 → 提示「是否邀请该用户加入家庭」
6 needsRoleSelect 后端字段保留,前端不再消费(登录不再跳转)
7 user-edit.vue 保留「个人中心编辑资料」用途,autoParent=true 新用户流程停用

5. 详细设计

5.1 注册零填写(可登录用户)

文件: 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,登录成功直接进首页(后端默认昵称兜底)
  • 未登录用户点家庭邀请链接 → join.vue 引导登录 → 登录成功 → 直接进 join-form(衔接闭环)
  • 后端 needsRoleSelect 字段保留在 LoginResultDTO,前端不再消费

文件: pages/user-edit/user-edit.vue

  • isNewUserFlow(autoParent=true 分支)停用:onLoad 不再处理 autoParent=true / needsRoleSelect=true 参数,统一走普通编辑模式
  • confirmRole / selectRole / 角色选择区:仅保留非新用户进入时的行为(实际个人中心编辑不涉及角色选择,相关区块可清理或保留不显示)
  • 家庭邀请相关(hasPendingFamilyInvite / familyRole 区块 / requestJoinByCode)逻辑迁移至新页面 5.2
  • 保留:头像/昵称/真实姓名/性别/生日/出生时辰/民族/血型/学历/婚姻/地区/兴趣/饮食偏好 全字段编辑(个人中心入口)

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 家庭身份区块移除
  • L754-768 保存时提交加入申请逻辑移除(迁移至 join-form)

5.3 功能→信息字段映射表(文档 + 配置更新)

新增/更新: 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+)。

5.4 添加成员手机号冲突 → 邀请加入

文件: pages/family/add-member.vue

  • L78-80 提示文案:「填写手机号可关联已有账号 / 若手机号已注册,将自动关联该账号」→ 改为「填写手机号可在已注册时邀请加入」
  • 提交时(doSubmit)若填了手机号:调后端查询该手机号是否已被注册(新增或复用接口,如 POST /api/user/check-phone-exists)
    • 已注册 → 弹确认「该手机号已被注册,是否邀请该用户加入家庭?」→ 确认 → 跳转邀请流程(携带手机号/邀请码);取消 → 继续以不可登录用户身份添加(不关联账号)
    • 未注册 → 正常添加
  • 后端新增接口需确认是否已有类似能力(FamilyMemberService / UserService 查询 phone)

6. 实施范围

阶段 内容 说明
P0(本次) 注册零填写(login.vue)+ user-edit 新用户流程停用 + join-form 新页面 + join.vue 衔接 + 映射表更新 + add-member 手机号冲突提示 可单独上线
P2+(后续逐个接入) 天盘/测评/健康报告/饮食推荐等页面的「缺失就地补充 + 回写」接入 按映射表排期

7. 验收标准

  • 新用户手机号登录 → 登录成功 → 直接进首页,不出现任何信息填写页
  • user-edit 不再接受 autoParent=true 新用户流程参数(个人中心编辑资料正常)
  • 接受家庭邀请(join.vue 已登录场景)→ 跳 join-form:真实姓名 + 家庭身份必填,其余选填;提交后调 requestJoinByCode 等待管理员审批
  • profile-field-usage.js 映射表完整(真实姓名/手机号/生日/出生时辰/性别/饮食偏好/地区 + 各自场景)
  • 后端 backfill 白名单增加 realName(若 member 表无 realName 列则确认边界)
  • add-member 填已注册手机号 → 提示「邀请加入」,确认后走邀请流程
  • mvn clean compile 通过;前端语法/结构校验通过
  • 不破坏:服务用户注册流程、个人中心编辑、现有活动报名回写

8. 实现决策(已完成评估)

# 项 决策
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 字段共用 本期直接新建,不抽公共组件;二期优化时考虑复用

9. 文档索引更新

本设计同步更新 docs/superpowers/PROJECT-OVERVIEW.md v2.13(2026-09-28)。

10. 待实施

详见 docs/superpowers/plans/2026-09-28-registration-zero-fill.md(编写中)。