forked from wangziqi/gongxue-base
203 lines
7.7 KiB
Markdown
203 lines
7.7 KiB
Markdown
# Taro 前端对接指南
|
||
|
||
更新时间:2026-06-28
|
||
|
||
目标:用一套 Taro 工程同时服务微信小程序和 H5 Web 题库,统一调用 `apps/api`,并支持多租户、品牌主题、地区题库、会员权益、销售追踪和对象存储资源。
|
||
|
||
建议新建:
|
||
|
||
```text
|
||
F:\project\apps\taro
|
||
```
|
||
|
||
旧前端参考:
|
||
|
||
```text
|
||
F:\project\参考\旧题库项目\src
|
||
```
|
||
|
||
## 启动流程
|
||
|
||
### H5
|
||
|
||
1. 从 `window.location.host` 获取当前域名。
|
||
2. 调用 `GET /api/tenant/resolve?host=<host>`。
|
||
3. 保存 `tenant.id`、`tenant.slug`、`branding`、`features`、`publicConfig`。
|
||
4. 初始化主题、Logo、页面标题、功能开关。
|
||
5. 检查本地 session token,调用 `GET /api/auth/me`。
|
||
6. 如果未登录,进入登录页;如果已登录,加载个人中心和首页数据。
|
||
|
||
### 微信小程序
|
||
|
||
1. 从编译环境或小程序启动参数读取 `tenantCode`。
|
||
2. 推广码、销售码、分享码从 `options` 或 `scene` 中解析。
|
||
3. 调用 `GET /api/tenant/resolve?tenantCode=<tenantCode>`。
|
||
4. 如存在 referral 参数,先调用 `/api/referral/resolve` 和 `/api/referral/track-event`。
|
||
5. 登录后再调用 `/api/referral/bind` 完成首绑保护。
|
||
|
||
## 请求封装
|
||
|
||
前端应封装一个统一 API client,所有页面禁止直接散写 `Taro.request`。
|
||
|
||
迁移期请求头:
|
||
|
||
```text
|
||
Authorization: Bearer <tk_session>
|
||
x-tenant-id: <tenantId>
|
||
x-user-id: <userId>
|
||
```
|
||
|
||
生产目标:
|
||
|
||
```text
|
||
Authorization: Bearer <jwt_or_session>
|
||
```
|
||
|
||
生产后不应再由前端传 `x-user-id`。租户可以由可信 JWT claim、服务端 session、域名解析结果共同确定;前端传入的租户参数只能作为路由/展示上下文,不能作为安全依据。
|
||
|
||
统一错误处理:
|
||
|
||
| HTTP | 前端动作 |
|
||
| --- | --- |
|
||
| 400 | 展示表单错误或参数错误 |
|
||
| 401 | 清 session,跳登录 |
|
||
| 403 | 展示无权限或会员升级 |
|
||
| 404 | 展示空状态 |
|
||
| 409 | 展示业务冲突,例如激活码已用 |
|
||
| 413 | 提示上传/导入文件过大 |
|
||
| 429 | 倒计时重试,例如短信冷却 |
|
||
| 500 | 展示系统异常并上报日志 |
|
||
|
||
## 全局状态建议
|
||
|
||
| Store | 内容 |
|
||
| --- | --- |
|
||
| tenantStore | tenant、branding、theme、features、publicConfig |
|
||
| authStore | session、user、roles、permissions、loginState |
|
||
| regionStore | 当前地区、可选地区、地区权益 |
|
||
| catalogStore | content entries、nodes、collections、blueprints |
|
||
| entitlementStore | SVIP 权益、视频权益、资料下载权益 |
|
||
| referralStore | inviteCode、referrer、scene、bindState |
|
||
| uiStore | 当前主题、tab、loading、toast、modal |
|
||
|
||
注意缓存必须带租户维度,例如:
|
||
|
||
```text
|
||
tenant:<tenantId>:catalog:entries
|
||
tenant:<tenantId>:profile
|
||
tenant:<tenantId>:theme
|
||
```
|
||
|
||
切换租户或切换小程序环境时必须清理旧租户缓存。
|
||
|
||
## 页面/API 映射
|
||
|
||
| 页面 | 主要接口 |
|
||
| --- | --- |
|
||
| 启动页 | `GET /api/tenant/resolve` |
|
||
| 登录页 | `POST /api/auth/sms/send`、`POST /api/auth/sms/verify`、后续微信/QQ provider |
|
||
| 首页 | `/api/catalog/content-entries`、`/api/catalog/banners`、`/api/catalog/announcements`、`/api/profile/me` |
|
||
| 选地区 | `/api/catalog/regions`、`/api/commerce/entitlements/check` |
|
||
| 题库入口 | `/api/catalog/content-entries` |
|
||
| 分类树 | `/api/catalog/content-nodes?entryId=...&parentId=root` |
|
||
| 题目列表 | `/api/catalog/question-collections`、`/api/catalog/question-collections/questions` |
|
||
| 开始练习 | `POST /api/learning/practice-sessions` |
|
||
| 提交答案 | `POST /api/learning/answers` |
|
||
| 错题本 | `GET /api/learning/wrong-questions`、`POST /api/learning/wrong-questions/resolve` |
|
||
| 收藏夹 | `GET/POST /api/learning/favorites/questions` |
|
||
| 题目视频 | `GET /api/questions/{questionId}/videos`、`POST /api/questions/videos/batch` |
|
||
| 背单词 | `/api/catalog/vocabulary-units`、`/api/catalog/vocabulary-words` |
|
||
| 单词进度 | `/api/learning/vocabulary/progress`、`/api/learning/vocabulary/stats` |
|
||
| 单词收藏 | `/api/learning/vocabulary/favorites` |
|
||
| 知识手册 | `/api/catalog/handbook-subjects`、`handbook-chapters`、`handbook-entries` |
|
||
| 分数线 | `/api/scoreline/fields`、`schools`、`majors`、`records`、`trend`、`years` |
|
||
| 资料下载 | `/api/catalog/assets`、`/api/catalog/assets/download` |
|
||
| 商城 | `/api/catalog/svip-plans`、`POST /api/commerce/orders` |
|
||
| 订单/权益 | `/api/commerce/orders`、`/api/commerce/entitlements` |
|
||
| 激活码兑换 | `POST /api/commerce/activation-codes/redeem` |
|
||
| 个人中心 | `GET/PATCH /api/profile/me` |
|
||
| 销售分享 | `/api/referral/resolve`、`track-event`、`bind` |
|
||
|
||
## 题库新模型接入方式
|
||
|
||
旧项目常按“地区 -> 科目 -> 章节/试卷”固定层级处理。新项目不要写死层级,按下面模型渲染:
|
||
|
||
```text
|
||
content_entries
|
||
-> content_nodes 任意深度分类树
|
||
-> question_collections 题目列表/试卷/章节/题型集合
|
||
-> practice_blueprints 顺序/随机/全真模拟规则
|
||
```
|
||
|
||
前端建议:
|
||
|
||
- `entryType=question_practice` 渲染为刷题入口。
|
||
- `entryType=vocabulary` 渲染为背单词入口。
|
||
- `entryType=handbook` 渲染为知识手册入口。
|
||
- `markerType=school` 或 `markerType=exam_track` 可作为学生目标院校/专业意向采集。
|
||
- 不同地区节点层级可以不同,页面组件必须支持递归树和面包屑。
|
||
|
||
## 多租户前端优化
|
||
|
||
- Logo、标题、主题色、客服信息全部来自 `tenant/resolve`。
|
||
- 功能开关控制菜单显示,但接口权限仍以后端为准。
|
||
- 私有图片、PDF、视频不要直接拼 URL,一律通过后端签名。
|
||
- 支付渠道从后端返回或租户配置读取,不在页面硬编码。
|
||
- 小程序分享路径必须带 tenantCode 和 referral code。
|
||
- 用户首绑归属由后端保护,前端不要提供“换绑销售”入口。
|
||
- 管理后台菜单按 `GET /api/tenant-admin/permissions` 和用户权限渲染。
|
||
- H5 自定义域名下要注意缓存隔离,不能把 A 租户主题缓存用到 B 租户。
|
||
|
||
## 第一阶段页面建议
|
||
|
||
1. `pages/bootstrap/index`
|
||
- 租户解析、主题初始化、登录态恢复。
|
||
2. `pages/login/index`
|
||
- 先接短信登录;后续接微信小程序登录。
|
||
3. `pages/home/index`
|
||
- Banner、公告、题库入口、会员入口、资料入口。
|
||
4. `pages/region/index`
|
||
- 地区选择和权益提示。
|
||
5. `pages/catalog/index`
|
||
- entry/node/collection/blueprint 通用导航。
|
||
6. `pages/practice/index`
|
||
- 刷题、答题、解析、错题、收藏。
|
||
7. `pages/vocabulary/index`
|
||
- 单词单元、学习、收藏。
|
||
8. `pages/handbook/index`
|
||
- 手册目录和阅读。
|
||
9. `pages/scoreline/index`
|
||
- 动态字段筛选和趋势。
|
||
10. `pages/profile/index`
|
||
- 会员、订单、激活码、学习数据。
|
||
|
||
## 租户后台前端建议
|
||
|
||
租户后台可以先做 H5 管理台,也可以后续使用 Taro H5 复用部分组件。优先页面:
|
||
|
||
- 概览:`/api/tenant-admin/overview`
|
||
- 品牌/主题/域名/公开设置
|
||
- 支付账户/登录 provider/密钥引用
|
||
- 用户与成员权限
|
||
- 内容入口/分类树/题目集合/练习蓝图
|
||
- 题目/单词/知识手册/分数线/视频维护
|
||
- JSON 导入 preview/import/issues
|
||
- Banner/FAQ/公告/激活码/优惠券
|
||
- 销售/代理/CRM 队列
|
||
|
||
租户后台不应在前端自行决定权限;隐藏菜单只是体验优化,接口仍会校验权限。
|
||
|
||
## 联调顺序
|
||
|
||
1. 启动页和租户解析。
|
||
2. 短信登录和 `auth/me`。
|
||
3. 首页、地区、内容入口、题库树。
|
||
4. 练习 session、答题、错题、收藏。
|
||
5. 背单词、知识手册、分数线。
|
||
6. 会员套餐、订单、激活码。
|
||
7. 资料下载、视频解析。
|
||
8. 销售追踪和分享链路。
|
||
9. 租户后台内容维护和导入。
|
||
10. 正式鉴权、真实支付、对象存储生产联调。
|
||
|