Files
MBTI_wang/开发文档/小程序解锁引导与邀请码方案.md
Ghost d7137f9349 微信小程序:自定义底栏接入 AI 入口(含图标与样式)、AI 聊天相关页面与历史/报告等能力;审核模式与配置联动;资料/企业/首页/授权等页面与 app 入口配合调整。
后端 API:AI 对话/报告/余额告警 等服务与路由;小程序 tabBar 配置与分润相关能力;出站推送 Webhook 与管理端调试;飞书留资、小程序数据分析 等支撑;多份 数据库迁移(AI 聊天、灵魂文章、tabBar、分润等)。
管理端 / 超管:看板、用户/订单/分销/财务、设置与 小程序 tabBar 管理、分润规则、灵魂文章、AI 配置与监控 等大量页面与能力扩展;主题与布局更新。
抖音小程序:与微信侧在 结果页/购买/个人中心 等方向做了同步或优化。
另含 部署/脚本、开发文档 等配套更新。
邀请码与解锁:后端 分销/邀请码 接口与 add_invite_codes 等 SQL;小程序侧 邀请码弹窗组件、个人中心/推广/多类结果页 的填写入口与 解锁门控(inviteCodeGate、unlockGate);并补充 《小程序解锁引导与邀请码方案》 文档。
超管后台:路由与 企业中心(EnterpriseHub) 等交互与结构优化。
小程序体验:在 首页结果、推广、各测评结果页 上继续打磨;与 邀请码门控、审核门控 小步联动。
2026-04-23 11:28:16 +08:00

8.8 KiB
Raw Blame History

小程序:解锁全文引导 + 邀请码弹框 — 开发方案

状态:§一~二已落地;§三邀请码弹框 已开发(支付前弹窗 + POST /api/distribution/bind 扩展 inviteCode
范围:微信小程序(miniprogram/);抖音小程序(douyin-miniprogram/)需同步时按同方案复制实现。
关联页面:面相/分析结果 pages/index/result;个人资料 pages/user-profile/index;支付与登录 utils/payment.jsapp.js


一、需求概述

1.1 解锁完整报告(或「解锁全文本」)点击后的分流

用户完成测试(当前以人脸面相结果页付费解锁为主场景,见 pages/index/resultonTapUnlockPay / unlockFullReport)后,点击解锁类按钮时,在未满足留资条件的情况下不再直接进入支付或仅 Toast而是

条件 行为
① 未绑定手机号 将页面滚动到最底部(或滚动到页面内「授权手机号」引导区域),让用户一眼看到授权入口并完成绑定。
② 已绑定手机号,但个人资料未完善 跳转到个人资料页 pages/user-profile/index,引导补全头像、昵称等(与现有「去完善资料」一致)。

说明:当前 utils/phoneAuth.jsisProfileComplete() 在「已有手机号」时直接返回 true,与「报告门禁」用的 isReportProfileComplete()(昵称+头像+手机均必填)不一致。本需求若强调「有手机仍要补资料」,实现时应统一以 isReportProfileComplete()(或与后端 Test::isWechatProfileComplete 对齐的封装) 作为「资料是否完善」的判断来源,避免与结果页绿色引导条逻辑冲突。

1.2 测试流程中增加「填写邀请码」弹框

在合适的时机弹出邀请码输入框Modal / 自定义弹层),用户可填写邀请码并提交;用于推广归因、企业活动或后续与分销绑定逻辑对接。


二、功能一:解锁点击后的引导(详细设计)

2.1 交互流程(建议)

  1. 用户点击「解锁完整报告」等按钮(入口:onTapUnlockPay 或统一封装的 beforeUnlock())。
  2. 校验登录(沿用现有 app.ensureLogin())。
  3. 分支判断(顺序建议:先手机,再资料,最后进入支付):
    • !hasPhone()
      • 调用 wx.pageScrollTo scroll-view 上使用 scroll-into-view / scroll-top 滚动到页面底部锚点(见 2.2)。
      • 可选:wx.showToast({ title: '请先在页面底部授权手机号', icon: 'none' })
      • 不发起 payment.purchaseFaceTest(或按产品决定:仍允许先支付再在支付后引导绑手机——需与产品确认;本文按「先满足留资再支付」描述)。
    • hasPhone() && !isReportProfileComplete()(或产品确认的资料规则):
      • wx.navigateTo({ url: '/pages/user-profile/index' })
      • 可选:带 query ?from=unlock&redirect=/pages/index/result 便于资料保存后返回(需结果页 onShow 刷新状态)。
    • 若均满足:进入现有 unlockFullReport()payment.purchaseFaceTest(...)

2.2 「滚动到最下面」实现要点

  • 若整页为普通 view 堆叠:使用 wx.createSelectorQuery() 取底部锚点 id="unlock-anchor"boundingClientRect,结合 wx.pageScrollTo({ scrollTop })(注意累加 scrollTop + node.top 的换算)。
  • 若外层为 scroll-view:需设置 scroll-yscroll-top 数据绑定,将 scrollTop 设为较大值或计算出的内容高度;或使用 scroll-into-view="{{scrollInto}}" 绑定底部子元素 id
  • 锚点建议放在**与 post-pay-guide 同区域或紧贴付费墙下方**,与现有「授权手机号」按钮(open-type="getPhoneNumber"`)同一视觉区域,避免用户滚动后仍找不到按钮。

2.3 与现有 UI 的关系

  • 结果页已有支付后引导条:post-pay-guideresult.wxml 约 4760 行),含「授权手机号」「去完善资料」。
  • 需求①本质是无手机号时把用户视线带到该区域;需求②与现有 goToCompleteProfile() 一致,可复用。
  • 需在点击解锁路径上增加上述判断,避免与「已付费仅差手机」场景重复冲突(payInfo.isPaid 为 true 时仍以现有 post-pay-guide 为主)。

2.4 其他结果页扩展(可选)

MBTI / DISC / PDP / SBTI / 简历等结果页若也有「解锁完整报告」按钮(如 pages/result/*.wxmlpaywall-btn),建议抽成公共方法(如 utils/unlockGate.jshandleUnlockClick({ page, hasPhone, isProfileComplete, onPay })),避免复制粘贴。

2.5 验收标准

  • 未登录:仍提示先登录。
  • 无手机号:点击解锁后页面自动滚动,底部「授权手机号」可见;不误触支付(除非产品改为先付后绑)。
  • 有手机号、资料不全:进入个人资料页;保存后返回结果页能继续解锁流程。
  • 手机+资料均齐:行为与线上一致,可正常支付解锁。

三、功能二:填写邀请码弹框(详细设计)

3.1 产品需确认项(落地前评审)

选项
弹出时机 A进入首页/相机前一次B每次开始测试前C登录成功后首次D支付前
是否强制 可跳过 / 必须填写(企业活动可能强制)
邀请码形态 纯数字 / 字母数字 / 与现有分销 inviterId 或企业 scene 解析并存
与后端关系 新接口「校验+绑定」 vs 扩展现有 POST /api/distribution/bind(当前为 inviterId + eid

3.2 前端实现(已实现)

  • 组件miniprogram/components/invite-code-dialog/(属性 visible,事件 skip / success)。
  • 闸门miniprogram/utils/inviteCodeGate.jsensureInviteCodeGate(page)unlockGate 通过之后、payment.purchase* 之前 弹出(对应产品选项 D支付前);「暂不填写」写入 inviteCodeSkipped,成功后写入 inviteCodeBound,二者任一存在则不再弹窗。
  • 接入页面:面相结果 pages/index/result,问卷结果 pages/result/mbti|disc|pdp|sbti,简历 pages/result/resumedoPay)。
  • 登录顺序:仅在已有登录态绑码(解锁路径已先 ensureLogin)。

3.3 后端接口(已实现:方案 B

扩展 POST /api/distribution/bind

  • 新增可选参数 inviteCode(字符串);与原有 inviterId / eid 并存:填码时由服务端解析出 inviterId 再走既有分销绑定逻辑。
  • 邀请码表:api/database/add_invite_codes.sqlmbti_invite_codes,执行前核对库表前缀与 api/config/database.phpprefix)。
  • 校验失败:400 + 文案「邀请码无效或已失效」。鉴权JWT 必填。

(若后续需独立「活动报名」语义,仍可再拆 POST /api/invite/claim。)

3.4 安全与幂等

  • 邀请码错误:明确错误文案,不计入绑定。
  • 同一用户重复提交同一码:返回成功幂等或提示「已绑定」。
  • 限流防刷接口IP + userId 频率限制)。

3.5 验收标准

  • 弹框可输入、取消、确认(若允许跳过则跳过不阻塞主流程)。
  • 确认后调用接口成功有反馈;失败有 Toast。
  • 与分销/企业后台数据一致(以最终表结构为准)。

四、任务拆分(供排期)

序号 任务 备注
T1 统一「资料是否完善」判定 phoneAuth 导出与报告一致的方法,结果页与解锁逻辑共用
T2 结果页 onTapUnlockPay / unlockFullReport 前置分支 滚动锚点 + navigateTo 个人资料
T3 (可选)抽象 unlockGate 工具 多结果页复用
T4 邀请码弹框 UI 组件 + 全局/页面触发点 支付前;见 §3.2
T5 后端邀请码校验与绑定接口 distribution/bind + invite_codes
T6 抖音小程序对齐 复制逻辑与 API

五、相关文件索引(当前仓库)

路径 说明
miniprogram/pages/index/result.js onTapUnlockPayunlockFullReportgoToCompleteProfile
miniprogram/pages/index/result.wxml post-pay-guide、付费墙 onTapUnlockPay
miniprogram/utils/phoneAuth.js hasPhoneisProfileCompleteisReportProfileCompletebindPhoneByCode
miniprogram/app.js 登录、saveTestResult、可挂邀请码 pending
api/app/controller/api/Distribution.php bind 等分销绑定
api/route/api.php 路由注册(新接口需追加)

六、修订记录

日期 版本 说明
2026-04-15 v0.1 初稿:解锁分流 + 邀请码弹框需求与实现要点