docs: 更新登录码和支付宝接入文档

This commit is contained in:
2026-04-24 14:52:55 +08:00
parent 693075a30c
commit b3dc966576

View File

@@ -1647,5 +1647,135 @@ fi
---
**最后更新**2026-04-17
## 十五、网页端登录码流程(2026-04-24
### 功能概述
实现**无需微信登录**的网页端登录确认流程。用户在小程序生成登录码,在后端网页完成微信授权登录,再由小程序确认完成整个登录流程。
### 业务流程
```
小程序 → 后端 GET /payment/generate-code生成登录码
用户在外部浏览器打开支付页
后端 GET /payment/login-status?code=xxx网页轮询
网页端微信扫码授权openid 写入 DB
网页端 POST /api/web-login/confirm确认登录token 写入 DB
小程序轮询 GET /payment/login-status?code=xxx
confirmed=true, token=xxx → 小程序保存 token 登录完成
```
### 新增接口
| 接口 | 方法 | 认证 | 说明 |
|------|------|------|------|
| `GET /payment/generate-code` | GET | 无 | 网页端生成登录码 |
| `GET /payment/login-status` | GET | 无 | 查询登录码状态(网页轮询)|
| `POST /api/web-login/confirm` | POST | JWT | 小程序确认登录 |
### 数据库
`web_login_codes` 表(迁移 `005_add_web_login_codes.sql`
```sql
CREATE TABLE web_login_codes (
id SERIAL PRIMARY KEY,
code VARCHAR(32) UNIQUE NOT NULL, -- 登录码(如 ASD-XXXXXX
openid VARCHAR(128), -- 微信 openid授权后填充
token TEXT, -- JWT确认后填充
expires_at TIMESTAMPTZ NOT NULL, -- 过期时间10分钟
user_id INTEGER, -- 关联用户 ID
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_web_login_codes_code ON web_login_codes(code);
CREATE INDEX idx_web_login_codes_expires ON web_login_codes(expires_at);
```
状态演变:
1. **初始**`code` 有值,`openid`=NULL, `token`=NULL
2. **微信授权后**`openid` 被填充
3. **确认后**`token` 被填充,`code` 被删除
### 关键 commits
| Commit | 说明 |
|--------|------|
| `034aa66` | 实现网页端登录码流程(无需微信登录) |
| `c66d130` | 统一登录码参数名为 code与前端保持一致|
| `92fb4e3` | web_login_confirm 查询改为精确匹配 code |
| `3bcfd9a` | web_login_confirm 加日志排查 + 精确匹配 code |
### 已知问题
- [ ] `web_login_confirm` (POST /api/web-login/confirm) JSON 反序列化偶发失败日志已添加诊断commit `3bcfd9a`
---
## 十六、支付宝网页支付接入2026-04-23
### 功能概述
接入支付宝沙箱环境,用户在外部浏览器完成支付,支付成功回调更新用户会员状态。
### 支付流程
```
小程序 → 后端 /payment/page → 支付宝网页支付 → 回调 /payment/notify → 更新用户状态
```
### 关键 commits
| Commit | 说明 |
|--------|------|
| `8c9552f` | 新增支付页面接口,为接入支付宝做准备 |
| `e828631` | 接入支付宝沙箱环境 (alipay.trade.page.pay) |
| `375f0af` | 更新支付系统和支付宝集成文档 |
| `502ae8b` | payment_page 支持 URL 参数传递 JWT |
| `af4ae27` | 跳转外部支付页不再携带 JWT由网页端微信扫码登录 |
### 沙箱测试
- 沙箱网关:`https://openapi-sandbox.dl.alipaydev.com/gateway.do`
- 测试账号https://open.alipay.com/develop/sandbox/app
---
## 十七、常见 Bug 与修复2026-04
### 1. gitignore 阻止 source 文件追踪
**问题**`.gitignore` 配置 `*` 阻止了所有文件,包括源码文件。
**现象**`git add` 后 `git commit` 无响应,`git status` 显示文件但 `git diff --cached` 为空。
**修复**:使用 `git add -f <file>` 强制添加被忽略的文件。
### 2. `unwrap_or(None)` 误用导致 SQL 错误被吞掉
**问题**`fetch_optional` 返回 `Result<Option<T>, E>``unwrap_or(None)` 只处理 `Err`,不处理 `Ok(None)`。
```rust
// 错误sqlx::Error 被 ok() 吞掉,但 record 仍是 Option<T>
// 导致 record = None永远走不到查询逻辑
let record = sqlx::query_as(...).fetch_optional(pool).await.ok();
// 正确:用 .ok().flatten() 处理 Result<Option<T>>
let record = sqlx::query_as(...).fetch_optional(pool).await.ok().flatten();
```
### 3. `serde(skip_deserializing)` 导致 SELECT 结果无法填充字段
**问题**`#[serde(skip_deserializing)]` 在 POST 请求体解析时跳过字段,但也阻止了数据库 SELECT 结果填充字段。
**修复**:对需要同时支持上传和查询的字段,使用 `#[serde(default)]`。
---
**最后更新**2026-04-24
**维护者**milky