主题
客户端小程序 — 登录与账号初始化
上级文档:客户端小程序
概述
对应主文档 §8.1、§13.1
登录是用户使用小程序的强制前置流程。采用微信一键登录 + 手机号授权方案。登录前用户仅可浏览门店列表(无价格),完成登录后进入核心功能链路。
登录策略
| 策略 | 说明 |
|---|---|
| 强制登录 | 不提供跳过登录选项。核心功能(购买、录脸、淋浴、个人中心)均需登录态 |
| 浏览降级 | 未登录时可浏览门店列表和门店详情(价格隐藏),引导登录查看优惠 |
| 微信唯一 | 仅支持微信登录,不支持手机号+验证码、第三方账号等 |
| 手机号必绑 | 登录时必须授权微信绑定的手机号,用于身份验证和权益发放 |
登录流程
用户打开小程序
│
├─ 已有有效 token → 直接进入首页
│
└─ 无 token / token 失效
│
├─ 进入登录页(/pages/auth/login)
├─ 点击「微信一键登录」
│
├─ 静默调用 wx.login 获取 code
├─ POST /api/v1/auth/consumer/wx-login → 获取 token
│
├─ 弹出手机号授权弹窗(Button open-type="getPhoneNumber")
│ │
│ ├─ 用户同意 → POST /api/v1/auth/bind-phone → 绑定手机号
│ │
│ └─ 用户拒绝 → 提示「手机号用于验证身份和领取优惠,授权后才能继续使用」
│ └─ 可再次点击触发授权(不强制弹窗,但功能不可用)
│
├─ 手机号绑定成功 → 登录完成
│
├─ 【新用户】检查新人欢迎弹窗配置
│ │
│ ├─ 后台开启新人欢迎 → 弹出欢迎卡片
│ │
│ └─ 后台关闭新人欢迎 → 弹出企微引导浮层
│
└─ 【老用户】直接进入首页页面路由
| 路由 | 页面 | 说明 |
|---|---|---|
/pages/auth/login | 登录授权 | 微信一键登录 + 手机号授权 + 协议确认 |
登录页要素
品牌视觉区
| 要素 | 说明 |
|---|---|
| 背景 | 品牌主色调渐变背景或品牌形象图 |
| LOGO | 品牌 Logo 居中展示 |
| Slogan | 品牌宣传语,如「24H 无人智能健身」 |
登录按钮区
| 要素 | 说明 |
|---|---|
| 微信一键登录按钮 | 绿色圆角大按钮,微信标准样式(白色微信图标 + 文字) |
| 手机号授权 | 点击登录按钮后,弹出微信手机号授权组件(Button open-type="getPhoneNumber") |
| 协议勾选 | 「我已阅读并同意」复选框 + 三份协议链接(勾选后才可点击登录) |
协议区域
三份协议并列展示,链接可点击查看全文:
| 协议 | 说明 |
|---|---|
| 《用户服务协议》 | 用户使用服务的权利义务 |
| 《隐私政策》 | 数据收集与使用说明 |
| 《平台协议》 | 平台运营规则与免责条款 |
合规要求:
- 登录按钮仅在用户勾选协议后才可点击
- 协议全文页面需支持返回登录页
- 协议内容可在管理后台更新,前端动态拉取
- 勾选状态本地缓存,下次打开自动勾选
登录异常处理
| 异常 | 处理 |
|---|---|
wx.login 失败 | 展示「登录失败,请重试」+ 重试按钮 |
| 手机号授权失败(用户拒绝) | 提示「手机号用于验证身份和领取优惠,授权后才能继续使用」+ 再次授权按钮 |
| 手机号授权接口报错 | 展示「授权失败,请重试」+ 重试按钮 |
| token 失效(401) | 清空本地 token,重新走登录流程 |
| 网络异常 | 展示网络错误提示 + 重试按钮 |
登录后初始化
登录成功后,前端需并行拉取:
| 数据 | 接口 | 用途 |
|---|---|---|
| 消费者资料 | GET /api/v1/consumer/profile | 昵称、头像、手机号 |
| 人脸状态 | profile.faceEnrolled | 决定是否引导录脸 |
| 会员权益摘要 | GET /api/v1/consumer/membership | 首页会员卡片、状态提醒 |
| 待支付订单 | GET /api/v1/orders?status=PENDING | 首页待支付提醒 |
| 新人福利配置 | GET /api/v1/config/welcome-gift | 判断是否弹出新人福利 |
| 消费者标签 | profile.tags | 判断是否新用户(用于 Banner 分层) |
新人欢迎弹窗
登录成功后,仅新用户(首次登录)弹出欢迎引导。后台可关闭此功能。
弹窗触发条件
| 条件 | 说明 |
|---|---|
| 用户类型 | isNewUser === true(服务端登录接口返回) |
| 后台开关 | welcomeGift.enabled === true(管理后台配置) |
| 弹出时机 | 登录后初始化数据加载完成后 |
弹窗要素
| 要素 | 说明 |
|---|---|
| 标题 | 如「🎉 欢迎加入 FITRON」 |
| 欢迎内容 | 简短的品牌介绍 + 新人引导说明 |
| 引导按钮 | 「开始体验」→ 关闭弹窗进入首页 |
| 关闭按钮 | 「以后再说」→ 关闭弹窗 |
| 关闭后 | 弹出企微引导浮层(如未添加企微) |
新人欢迎 — 管理后台配置
| 配置项 | 说明 |
|---|---|
| 功能开关 | 开启/关闭新人欢迎弹窗 |
| 弹窗标题 | 自定义弹窗文案 |
| 弹窗图片 | 弹窗背景/装饰图 |
新人欢迎 — 异常处理
| 异常 | 处理 |
|---|---|
| 接口返回关闭 | 不弹窗,直接进入首页 |
| 用户非新用户 | 不弹窗 |
企微引导浮层
新人福利弹窗关闭后(或后台关闭新人福利时),弹出半透明引导浮层。仅在用户尚未添加该门店企微时展示。
浮层触发条件
| 条件 | 说明 |
|---|---|
| 时机 | 新人福利弹窗关闭后 / 后台关闭新人福利时的登录后 |
| 前提 | 用户未添加当前门店的企微(wechatContact.added === false) |
| 频率 | 每个门店仅弹一次(本地存储 addedWechat_{storeId}) |
浮层要素
| 要素 | 说明 |
|---|---|
| 遮罩层 | 半透明黑色遮罩(透明度 60-70%),点击遮罩不关闭 |
| 浮层卡片 | 居中弹出,白色圆角卡片 |
| 店长头像 | 企微头像(管理后台配置) |
| 店长昵称 | 企微名称 |
| 引导文案 | 如「添加店长企微,享受专属优惠和训练指导」 |
| 添加按钮 | 「立即添加」→ 跳转企微添加页 |
| 关闭按钮 | 「X」按钮 + 「以后再说」文字链接 |
| 点击「以后再说」 | 关闭浮层,进入首页 |
浮层交互规则
| 规则 | 说明 |
|---|---|
| 遮罩点击 | 不关闭(防止误触跳过) |
| 关闭方式 | 仅通过「X」或「以后再说」关闭 |
| 不再弹出 | 关闭后本地标记,同一门店不再弹出 |
| 再次触发 | 用户切换到其他门店且未添加该门店企微时,可再次弹出 |
线下扫码入口
用户通过线下二维码扫码进入小程序时,可能携带场景值(scene),需在 onLaunch 中解析:
扫码场景总览
| 场景值 | 来源 | 跳转行为 | 说明 |
|---|---|---|---|
store | 门店张贴 | 门店详情页 | 展示门店信息与导航 |
shower | 淋浴间张贴 | 淋浴控制页 | 直接启动淋浴 |
activity | 活动海报 | 活动详情页 | 查看活动参与 |
wifi | 门店内 WiFi 二维码 | WiFi 连接页 | 自动连接门店 WiFi |
equipment_report | 器械上的二维码 | 器械报修页 | 提交设备故障报修 |
general | 无特殊参数 | 首页 | 通用入口 |
WiFi 连接
门店内张贴 WiFi 二维码,用户扫码后小程序自动连接门店 WiFi,免手动搜索和输入密码。
WiFi 连接流程
用户扫描 WiFi 二维码
→ 解析 scene=wifi&ssid=Fitron-Guest&password=xxxxx
→ 进入 WiFi 连接页(/pages/wifi/connect)
→ 显示门店名称 + WiFi 名称 + 「一键连接」
→ 调用 wx.connectWifi(需用户确认)
│
├─ 连接成功 → 提示「已连接 Fitron-Guest」→ 2 秒后自动关闭或手动关闭
│
└─ 连接失败 → 提示原因 + 重试按钮
├─ 用户拒绝授权 → 「请在系统设置中允许 WiFi 连接权限」
├─ 密码错误 → 「WiFi 密码已变更,请联系门店工作人员」
└─ 其他错误 → 「连接失败,请重试或手动连接」WiFi 连接页要素
| 要素 | 说明 |
|---|---|
| 门店名称 | 当前门店 |
| WiFi 名称 | ssid 参数解析 |
| 信号强度 | wx.getConnectedWifi 获取 |
| 「一键连接」按钮 | 调用 wx.connectWifi |
| 连接状态 | 等待中 / 连接中 / 已连接 / 连接失败 |
| 使用须知 | 「连接后将获取网络访问权限」 |
WiFi 异常处理
| 异常 | 处理 |
|---|---|
| 二维码参数缺失 | 提示「无效的 WiFi 二维码」 |
系统不支持 connectWifi | 提示「当前微信版本不支持自动连接,请手动搜索 WiFi 并输入密码」+ 展示 WiFi 名称和密码 |
| 用户拒绝授权 | 引导至系统设置开启权限 |
| WiFi 连接超时 | 10 秒超时,提示失败 + 重试 |
器械报修
器械上张贴专属二维码,用户扫码后可快速提交设备故障报修,无需联系客服转述。
器械报修流程
用户扫描器械上的二维码
→ 解析 scene=equipment_report&storeId=xxx&equipmentId=yyy
→ 进入器械报修页(/pages/equipment/report)
→ 显示设备信息(名称、位置、编号)
→ 用户填写报修内容
→ 提交报修
│
├─ 提交成功 → 提示「报修已提交,工作人员将尽快处理」+ 返回
│
└─ 提交失败 → 提示失败原因 + 重试器械报修页要素
| 要素 | 说明 |
|---|---|
| 门店名称 | 自动识别 |
| 设备名称 | 如「跑步机 #03」 |
| 设备位置 | 如「有氧区 B 排」,管理后台配置 |
| 设备编号 | 器械唯一编号 |
| 故障类型 | 多选:无法启动 / 运行异常 / 异响 / 外观损坏 / 其他 |
| 故障描述 | 文本输入框(必填),用户描述具体问题 |
| 现场照片 | 支持拍照或相册上传(最多 3 张) |
| 联系方式 | 可选,方便工作人员联系确认 |
| 「提交报修」按钮 | 校验后提交 |
报修校验规则
| 规则 | 说明 |
|---|---|
| 故障描述 | 必填,10-500 字 |
| 故障类型 | 至少选一项 |
| 照片 | 可选,最多 3 张,单张 ≤ 5MB |
| 联系方式 | 可选,如填写需校验手机号格式 |
| 同一设备重复报修 | 允许,但提示「该设备已有待处理报修,是否继续提交?」 |
报修后续
| 状态 | 说明 |
|---|---|
| 已提交 | 报修成功,通知门店管理员(管理后台工单系统) |
| 处理中 | 店长在管理后台标记处理中 |
| 已修复 | 店长标记已修复后,可选择发送模板消息通知报修用户 |
| 超时未处理 | 超过 24 小时未处理,自动升级通知总部 |
扫码通用规则
- 所有扫码入口的登录流程与常规登录一致,区别在于登录成功后的跳转目标
- 扫码后如未登录,先走登录流程,登录成功后自动跳转到扫码目标页
- scene 参数在
App.onLaunch中解析,存储到全局变量,登录后读取并跳转
接口
text
# 消费者微信登录
POST /api/v1/auth/consumer/wx-login
Body: { code: string }
Response: {
accessToken: string,
refreshToken: string,
isNewUser: boolean,
consumer: { id, nickname, avatarUrl, faceEnrolled: boolean, tags: string[] }
}
# 绑定手机号
POST /api/v1/auth/consumer/bind-phone
Auth: JWT(iss: consumer)
Body: { code: string } // getPhoneNumber 返回的 code
Response: {
success: boolean,
phone: string // 脱敏展示
}
# 新人欢迎配置
GET /api/v1/config/welcome-gift
Auth: JWT
Response: {
enabled: boolean,
title: string,
imageUrl: string
}
# 器械报修
POST /api/v1/equipment/report
Auth: JWT
Body: {
storeId: string,
equipmentId: string,
faultTypes: string[], // 故障类型枚举
description: string, // 故障描述(10-500 字)
photos: string[], // 图片 URL(最多 3 张)
contactPhone?: string // 联系方式(可选)
}
Response: {
success: boolean,
ticketId: string // 报修工单 ID
}