后端 API:AI 对话/报告/余额告警 等服务与路由;小程序 tabBar 配置与分润相关能力;出站推送 Webhook 与管理端调试;飞书留资、小程序数据分析 等支撑;多份 数据库迁移(AI 聊天、灵魂文章、tabBar、分润等)。 管理端 / 超管:看板、用户/订单/分销/财务、设置与 小程序 tabBar 管理、分润规则、灵魂文章、AI 配置与监控 等大量页面与能力扩展;主题与布局更新。 抖音小程序:与微信侧在 结果页/购买/个人中心 等方向做了同步或优化。 另含 部署/脚本、开发文档 等配套更新。 邀请码与解锁:后端 分销/邀请码 接口与 add_invite_codes 等 SQL;小程序侧 邀请码弹窗组件、个人中心/推广/多类结果页 的填写入口与 解锁门控(inviteCodeGate、unlockGate);并补充 《小程序解锁引导与邀请码方案》 文档。 超管后台:路由与 企业中心(EnterpriseHub) 等交互与结构优化。 小程序体验:在 首页结果、推广、各测评结果页 上继续打磨;与 邀请码门控、审核门控 小步联动。
8.8 KiB
小程序:解锁全文引导 + 邀请码弹框 — 开发方案
状态:§一~二已落地;§三邀请码弹框 已开发(支付前弹窗 +
POST /api/distribution/bind扩展inviteCode)
范围:微信小程序(miniprogram/);抖音小程序(douyin-miniprogram/)需同步时按同方案复制实现。
关联页面:面相/分析结果pages/index/result;个人资料pages/user-profile/index;支付与登录utils/payment.js、app.js。
一、需求概述
1.1 解锁完整报告(或「解锁全文本」)点击后的分流
用户完成测试(当前以人脸面相结果页付费解锁为主场景,见 pages/index/result 内 onTapUnlockPay / unlockFullReport)后,点击解锁类按钮时,在未满足留资条件的情况下不再直接进入支付或仅 Toast,而是:
| 条件 | 行为 |
|---|---|
| ① 未绑定手机号 | 将页面滚动到最底部(或滚动到页面内「授权手机号」引导区域),让用户一眼看到授权入口并完成绑定。 |
| ② 已绑定手机号,但个人资料未完善 | 跳转到个人资料页 pages/user-profile/index,引导补全头像、昵称等(与现有「去完善资料」一致)。 |
说明:当前
utils/phoneAuth.js中isProfileComplete()在「已有手机号」时直接返回true,与「报告门禁」用的isReportProfileComplete()(昵称+头像+手机均必填)不一致。本需求若强调「有手机仍要补资料」,实现时应统一以isReportProfileComplete()(或与后端Test::isWechatProfileComplete对齐的封装) 作为「资料是否完善」的判断来源,避免与结果页绿色引导条逻辑冲突。
1.2 测试流程中增加「填写邀请码」弹框
在合适的时机弹出邀请码输入框(Modal / 自定义弹层),用户可填写邀请码并提交;用于推广归因、企业活动或后续与分销绑定逻辑对接。
二、功能一:解锁点击后的引导(详细设计)
2.1 交互流程(建议)
- 用户点击「解锁完整报告」等按钮(入口:
onTapUnlockPay或统一封装的beforeUnlock())。 - 校验登录(沿用现有
app.ensureLogin())。 - 分支判断(顺序建议:先手机,再资料,最后进入支付):
- 若
!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-y、scroll-top数据绑定,将scrollTop设为较大值或计算出的内容高度;或使用scroll-into-view="{{scrollInto}}"绑定底部子元素id。 - 锚点建议放在**与
post-pay-guide同区域或紧贴付费墙下方**,与现有「授权手机号」按钮(open-type="getPhoneNumber"`)同一视觉区域,避免用户滚动后仍找不到按钮。
2.3 与现有 UI 的关系
- 结果页已有支付后引导条:
post-pay-guide(result.wxml约 47–60 行),含「授权手机号」「去完善资料」。 - 需求①本质是无手机号时把用户视线带到该区域;需求②与现有
goToCompleteProfile()一致,可复用。 - 需在点击解锁路径上增加上述判断,避免与「已付费仅差手机」场景重复冲突(
payInfo.isPaid为 true 时仍以现有post-pay-guide为主)。
2.4 其他结果页扩展(可选)
MBTI / DISC / PDP / SBTI / 简历等结果页若也有「解锁完整报告」按钮(如 pages/result/*.wxml 中 paywall-btn),建议抽成公共方法(如 utils/unlockGate.js 的 handleUnlockClick({ 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.js—ensureInviteCodeGate(page)在unlockGate通过之后、payment.purchase*之前 弹出(对应产品选项 D:支付前);「暂不填写」写入inviteCodeSkipped,成功后写入inviteCodeBound,二者任一存在则不再弹窗。 - 接入页面:面相结果
pages/index/result,问卷结果pages/result/mbti|disc|pdp|sbti,简历pages/result/resume(doPay)。 - 登录顺序:仅在已有登录态绑码(解锁路径已先
ensureLogin)。
3.3 后端接口(已实现:方案 B)
扩展 POST /api/distribution/bind:
- 新增可选参数
inviteCode(字符串);与原有inviterId/eid并存:填码时由服务端解析出inviterId再走既有分销绑定逻辑。 - 邀请码表:
api/database/add_invite_codes.sql(mbti_invite_codes,执行前核对库表前缀与api/config/database.php中prefix)。 - 校验失败:
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 |
onTapUnlockPay、unlockFullReport、goToCompleteProfile |
miniprogram/pages/index/result.wxml |
post-pay-guide、付费墙 onTapUnlockPay |
miniprogram/utils/phoneAuth.js |
hasPhone、isProfileComplete、isReportProfileComplete、bindPhoneByCode |
miniprogram/app.js |
登录、saveTestResult、可挂邀请码 pending |
api/app/controller/api/Distribution.php |
bind 等分销绑定 |
api/route/api.php |
路由注册(新接口需追加) |
六、修订记录
| 日期 | 版本 | 说明 |
|---|---|---|
| 2026-04-15 | v0.1 | 初稿:解锁分流 + 邀请码弹框需求与实现要点 |