Files
jackyu66gitandCursor 7155b8b53a feat(api): 接入微信登录并原生实现咨询域(ECR-049/050)
小程序可在 Go 上完成微信手机号登录、测评、预约和下单,不再反代 Java。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 00:26:29 +08:00

165 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Feature Spec: 账号登录
> Status: `Active` · Map: `5.x 账号 [P1+]` · Phase: `P1`
> 规范:[../feature-design.md](../feature-design.md)
> 关联:[profile-bootstrap.md](profile-bootstrap.md)
---
## 1. 功能定义
| 字段 | 内容 |
|---|---|
| Name | 账号登录(小程序微信;H5 过渡账密) |
| Purpose | 跨设备持久用户身份;未登录不可生成/查看生日衍生结果 |
| Business Goal | 数据归属清晰;咨询与魔方同一人;为会员与深度版付费打底 |
| In | Out |
|---|---|
| 小程序微信登录 / 登出 / me | 短信 OTP |
| 设备身份绑定到已注册账号 | 游客可看完整报告 |
| Bearer Session | 运营 Admin 登录(独立) |
---
## 2. 用户价值
1. 换手机后仍能看到自己的档案与报告。
2. 登录后输入生日一次生成、各页直读。
3. N/A(登录本身免费)。
---
## 3. 用户角色
| Actor | 能力 |
|---|---|
| Visitor | 仅设备身份;可打开登录页;**不可**建档出结果 |
| User(已注册) | CRUD 本人档案与 TA;读已生成报告 |
| VIP / DeepAccess | 同前,权益不变 |
---
## 4. 用户流程
```text
进入结果页或建档
未登录? → 小程序 login-pop(微信)或 H5 /login(过渡账密)
Device 绑定到账号 User
进入档案 / 结果页(读缓存报告)
```
---
## 5. 页面设计
| 路由 | 页面 |
|---|---|
| `/login` | H5 LoginPage(过渡账密;小程序已删除此页) |
| 小程序 `login-pop` | 微信手机号授权(唯一 C 端登录) |
| `/mine` | 展示账号手机号尾号 + 退出 |
---
## 6. 页面状态规范
| 状态 | UI |
|---|---|
| Loading | 登录中 |
| Error | 密码错误 / 手机号已注册 |
| Normal | 跳转 redirect 或 /mine |
---
## 7. Business Rules
| ID | Rule |
|---|---|
| R1 | **小程序:** 微信 `code` + 手机号授权登录;按 `wx_openid` 命中,否则按手机号合并历史账密账号;未命中则建号 |
| R2 | **H5 过渡:** OpenLogin(任意非空手机号+密码)仍可用,避免 H5 断服;小程序不再提供账密页。正式关掉账密须另改本 Spec |
| R3 | 登录成功后:签发 sessiondevice_identities.user_id 改绑到账号 |
| R4 | 生成/查看档案与报告 API 必须已注册(users.phone 非空)且有效 session 或已绑设备账号 |
| R5 | 登出作废 session;设备可再登录其他账号 |
| R6 | 正式环境恢复校验前须改回本 Spec |
| R7 | 新账号未填昵称时,服务端用「意象词+场景词」词库(100×100)随机生成,如心语岛、微光谷 |
| R8 | 账号昵称可在个人档案页修改(PATCH `/auth/me`);首页与各页「自己」展示位统一用昵称(合盘/问答/星座/档案卡) |
| R9 | 账号头像可在「我的」页更换:相册或拍照上传;服务端持久化;GET `/auth/me` 返回 `avatar_url`;未设置时 UI 用愈心小人正面默认头像(`public/default-avatar.png`,源图 `public/logo/愈心小人1.png` |
---
## 8. 数据模型影响
- `users.phone` UNIQUE · `users.wx_openid` UNIQUE · `users.wx_unionid` · `users.java_platform_user_id` · `users.password_hash` · `users.nickname` · `users.avatar_url`
- `user_sessions(token, user_id, expires_at)`
- 本地文件:`data/avatars/{user_id}.{jpg|png|webp}`(进程相对路径)
---
## 9. API 需求
| Method | Path | 说明 |
|---|---|---|
| POST | `/api/v1/auth/wechat` | 小程序微信登录 `{ code, encryptedData, iv }` |
| POST | `/api/v1/auth/register` | H5 过渡注册(可带 nickname |
| POST | `/api/v1/auth/login` | H5 过渡登录 |
| POST | `/api/v1/auth/logout` | 登出 |
| GET | `/api/v1/auth/me` | 当前账号(含 avatar_url |
| PATCH | `/api/v1/auth/me` | 更新昵称 `{ nickname }` |
| POST | `/api/v1/auth/me/avatar` | multipart `file`jpeg/png/webp;≤2MB → 更新 avatar_url |
| GET | `/api/v1/media/avatars/:file` | 公开读头像文件 |
---
## 10. 权限设计
| 能力 | Visitor | User |
|---|---|---|
| register/login | ✓ | ✓ |
| profiles / reports 写读 | ✗ | ✓ |
| 上传头像 | ✗ | ✓ |
| 读头像媒体 | ✓ | ✓ |
---
## 11. 埋点
经统一 `track()`(见 [analytics.md](analytics.md) · [ops-analytics.md](ops-analytics.md))。
**非** P1 核心漏斗 5 事件;接入后走自有 `POST /analytics/events`(及可选 GA)。
禁止参数含手机号、明文密码、头像绝对 URL / `user_id`
| Event | 触发 | 可选 params |
|---|---|---|
| `auth_register` | 账号新建成功(含 OpenLogin 自动建号,`is_new=true` | `source`: login_page |
| `auth_login` | 已有账号登录成功(`is_new=false` | `source`: login_page |
| `auth_logout` | 用户在「我的」点退出且本地 session 已清 | `surface`: mine |
| `avatar_sheet_opened` | 「我的」打开更换头像 sheet | `surface`: mine |
| `avatar_upload_succeeded` | 头像上传 API 成功且 UI 刷新为新图 | `source`: album \| camera |
| `avatar_upload_failed` | 头像上传失败(校验/网络/服务端) | `source`: album \| camera · `reason`: too_large \| bad_type \| network \| server \| unknown |
| `nickname_updated` | PATCH 昵称成功 | `surface`: profile |
`page_view``/login` · `/mine` 由路由自动采集,本 Spec 不重复定义。
**实现状态:** 事件名以本表为准;H5 已挂 Login / Mine / Profile`track` → 自有 ingest + 可选 GA)。
---
## 12. 测试验收标准
| Given | When | Then |
|---|---|---|
| 新设备 | 未登录 POST portrait | 401 |
| 注册成功 | 建档 | 200 且生成报告包 |
| 登录另一设备 | list profiles | 见同一账号数据 |
| 已登录设备 | POST logout 后无 Bearer 再 GET /auth/me | 401(设备已解绑,刷新不再显示登录态) |
---
## 13. AI 开发前检查
- [x] lexicon:登录/注册/账号
- [x] 不碰 Admin Auth
- [x] 咨询域见 Spec `consult-miniprogram`ECR-050