145 lines
6.5 KiB
Markdown
145 lines
6.5 KiB
Markdown
# login 页面数据来源排查
|
||
|
||
> 排查日期:2026-03-18
|
||
> 页面路径:pages/login/login
|
||
> 涉及文件:login.ts, login.wxml, login.wxss, login.json, utils/request.ts, utils/config.ts
|
||
|
||
## 概览
|
||
|
||
| 分类 | 数量 | 说明 |
|
||
|------|------|------|
|
||
| A. Mock 数据 | 0 | 未引用 mock-data.ts,无内联 mock |
|
||
| B. 硬编码数据 | 5 | 含开发模式 openid、默认高度、错误提示文案等 |
|
||
| C. 已对接 API | 2 | dev-login + login(含 token 刷新机制) |
|
||
| D. 前端计算/派生数据 | 3 | isDevMode 判断、按钮禁用态、错误消息映射 |
|
||
| E. 路由参数 | 0 | onLoad 未接收任何 options 参数 |
|
||
| F. WXML 硬编码文案 | 7 | 应用名称、功能标签、按钮文案、协议文案、底部提示 |
|
||
|
||
---
|
||
|
||
## 一、Mock 数据
|
||
|
||
**结论:无 Mock 数据。**
|
||
|
||
- `login.ts` 未 import `mock-data.ts`
|
||
- 页面内无内联 mock 对象或假数据
|
||
- 开发模式走 `/api/xcx/dev-login` 真实接口(非前端 mock)
|
||
|
||
---
|
||
|
||
## 二、硬编码数据
|
||
|
||
| # | 位置 | 代码 | 值 | 风险 | 说明 |
|
||
|---|------|------|----|------|------|
|
||
| B1 | login.ts L4 | `API_BASE.startsWith("http://127.0.0.1")` | `"http://127.0.0.1"` | 🟢 低 | 开发环境判断,config.ts develop 分支返回 `http://127.0.0.1:8000`,逻辑一致 |
|
||
| B2 | login.ts L8 | `data: { agreed: false, loading: false }` | `false` | 🟢 低 | UI 初始状态,合理默认值 |
|
||
| B3 | login.ts L10 | `statusBarHeight: 20` | `20` | 🟡 中 | 默认状态栏高度 fallback,onLoad 中会被 `wx.getWindowInfo()` 覆盖;但若 API 返回 0 或 undefined 则回退到 20px,部分机型可能不准 |
|
||
| B4 | login.ts L39 | `data: { openid: "dev_test_openid" }` | `"dev_test_openid"` | 🟡 中 | 开发模式固定 openid,仅 develop 环境生效;但若 `isDevMode` 判断逻辑被绕过则有安全隐患 |
|
||
| B5 | login.ts L93-98 | 错误提示 `msg` 三元表达式 | `"账号已被禁用"` / `"登录凭证无效,请重试"` / `"登录失败,请稍后重试"` | 🟢 低 | 用户友好提示,无需后端下发 |
|
||
|
||
---
|
||
|
||
## 三、已对接 API
|
||
|
||
### 3.1 开发模式登录 — `POST /api/xcx/dev-login`
|
||
|
||
| 项目 | 值 |
|
||
|------|----|
|
||
| 触发条件 | `isDevMode === true`(API_BASE 以 `http://127.0.0.1` 开头) |
|
||
| 请求方式 | `POST` |
|
||
| 请求参数 | `{ openid: "dev_test_openid" }` |
|
||
| needAuth | `false` |
|
||
| 响应字段(使用到的) | `access_token`, `refresh_token`, `user_id`, `user_status` |
|
||
| 后续处理 | 写入 globalData + Storage → 按 `user_status` 路由跳转 |
|
||
|
||
### 3.2 正式登录 — `POST /api/xcx/login`
|
||
|
||
| 项目 | 值 |
|
||
|------|----|
|
||
| 触发条件 | `isDevMode === false`(trial / release 环境) |
|
||
| 前置步骤 | `wx.login()` 获取临时 `code` |
|
||
| 请求方式 | `POST` |
|
||
| 请求参数 | `{ code: loginRes.code }` |
|
||
| needAuth | `false` |
|
||
| 响应字段(使用到的) | `access_token`, `refresh_token`, `user_id`, `user_status` |
|
||
| 后续处理 | 同 3.1 |
|
||
|
||
### 3.3 Token 刷新(request.ts 内置) — `POST /api/xcx/refresh`
|
||
|
||
| 项目 | 值 |
|
||
|------|----|
|
||
| 触发条件 | 任意需认证请求返回 401 时自动触发 |
|
||
| 请求参数 | `{ refresh_token: <当前 refresh_token> }` |
|
||
| 响应字段 | `access_token`, `refresh_token` |
|
||
| 失败处理 | 清除 token → `wx.reLaunch` 跳转 login 页 |
|
||
|
||
### 登录成功后数据持久化
|
||
|
||
```
|
||
globalData.token ← data.access_token
|
||
globalData.refreshToken ← data.refresh_token
|
||
globalData.authUser ← { userId: data.user_id, status: data.user_status }
|
||
Storage: token, refreshToken, userId, userStatus
|
||
```
|
||
|
||
### 登录后路由映射
|
||
|
||
| user_status | 跳转页面 |
|
||
|-------------|----------|
|
||
| `"approved"` | `/pages/task-list/task-list` |
|
||
| `"pending"` | `/pages/reviewing/reviewing` |
|
||
| `"new"` | `/pages/apply/apply` |
|
||
| `"rejected"` | `/pages/no-permission/no-permission` |
|
||
| `"disabled"` | `/pages/no-permission/no-permission` |
|
||
| 其他/default | `/pages/apply/apply` |
|
||
|
||
---
|
||
|
||
## 四、前端计算/派生数据
|
||
|
||
| # | 变量/逻辑 | 来源 | 说明 |
|
||
|---|-----------|------|------|
|
||
| D1 | `isDevMode` | `API_BASE.startsWith("http://127.0.0.1")` | 模块顶层常量,决定走 dev-login 还是 wx.login 流程 |
|
||
| D2 | 按钮禁用态 | WXML: `(!agreed \|\| loading) ? 'login-btn--disabled' : 'login-btn--active'` | 由 `agreed` 和 `loading` 两个 data 字段派生 |
|
||
| D3 | 错误消息 `msg` | `err.statusCode` 三元映射 | 403→"账号已被禁用",401→"登录凭证无效",其他→"登录失败" |
|
||
|
||
---
|
||
|
||
## 五、路由参数
|
||
|
||
**结论:无路由参数。**
|
||
|
||
- `onLoad()` 未声明 `options` 参数
|
||
- 页面作为小程序首页(入口页),不接收外部传参
|
||
|
||
---
|
||
|
||
## 六、WXML 硬编码文案
|
||
|
||
| # | 元素 | 文案 | 建议 |
|
||
|---|------|------|------|
|
||
| F1 | `<text class="app-name">` | `球房运营助手` | 应用名称,可考虑从配置读取 |
|
||
| F2 | `<text class="app-desc">` | `为台球厅提升运营效率的内部管理工具` | 应用描述 |
|
||
| F3 | `<text class="feature-text">` ×3 | `任务管理` / `数据看板` / `智能助手` | 功能亮点标签 |
|
||
| F4 | `<text class="login-btn-text">` | `使用微信登录` | 按钮文案 |
|
||
| F5 | `<text class="agreement-text">` | `我已阅读并同意` | 协议前缀 |
|
||
| F6 | `<text class="link">` ×2 | `《用户协议》` / `《隐私政策》` | 协议链接文案(当前无跳转) |
|
||
| F7 | `<text class="footer-tip">` | `仅限球房内部员工使用` | 底部提示 |
|
||
|
||
> 注:login.json 中 `"navigationBarTitleText": "登录"` 也是硬编码,但因使用 `"navigationStyle": "custom"` 自定义导航栏,系统标题栏不显示,实际无影响。
|
||
|
||
---
|
||
|
||
## 七、联调 TODO
|
||
|
||
| 优先级 | 项目 | 当前状态 | 待办 |
|
||
|--------|------|----------|------|
|
||
| ✅ 已完成 | 登录接口对接 | dev-login + login 均已对接 | — |
|
||
| ✅ 已完成 | Token 持久化 | globalData + Storage 双写 | — |
|
||
| ✅ 已完成 | 401 自动刷新 | request.ts 内置 refresh 机制 | — |
|
||
| ✅ 已完成 | 状态路由 | 5 种 user_status 均有对应页面 | — |
|
||
| 🟡 待确认 | 协议链接跳转 | `《用户协议》`和`《隐私政策》`仅为文案,无 `bindtap` 跳转 | 需补充协议页面或 webview 跳转 |
|
||
| 🟡 待确认 | dev_test_openid 安全性 | 硬编码在前端代码中 | 确认后端 dev-login 仅在开发环境可用,生产环境应禁用该端点 |
|
||
| 🟢 可优化 | statusBarHeight fallback | 默认 20px | 可改为 `wx.getSystemInfoSync().statusBarHeight` 更精确的 fallback |
|
||
| 🟢 可优化 | 错误提示国际化 | 硬编码中文 | 当前仅面向内部员工,优先级低 |
|