# 孕育无忧 H5 应用修改记录 > 项目: app_03 (孕育无忧 — H5 小程序嵌入式) > 时间跨度: 2026-05-21 ~ 2026-05-27 > 技术栈: FastAPI + MongoDB + React 18 + Vite 6 --- ## 一、认证流程演进(4 次重构) ### Phase 1: JWT 直传(80904e6 ~ 1eef3ae) **方案:** 小程序 `?token=JWT` → H5 decodeToken → 后端 verify_signature=False 按 openid 查/创建用户 **关键改动:** - 后端 `get_current_user` 取消签名验证 - JWT payload 字段调整为 `{uid, openid, phone}` - 前端 `decodeToken()` 解析 token - 无需小程序手动传递 uid,仅 token 即可 **问题:** 小程序端 web-view URL 中 `openid=` 为空值 → 走 dev-login 分支 → 数据库记录 name='开发测试用户' ### Phase 2: 参数直传(1eef3ae) **方案:** `?uid=&openid=&phone=` → 前端 `createDummyToken()` 构建本地 JWT → 直接登录 **关键改动:** - 新增 `createDummyToken()` 函数,前端构造 base64 编码的 JWT - JWT base64url 解码需 `replace(/-/g,'+').replace(/_/g,'/')` - 新增 `/auth/params-login` 后端接口(可选,暂不需要) - 移除 paramsLogin API 调用,纯前端完成 **问题:** URL 传 3 个参数太繁琐,小程序端需要额外处理手机号敏感信息 ### Phase 3: 统一调试(150dafc ~ bceb4f4) **新增功能:** - `services/debug.ts` — 统一调试模块:`isDebug()`, `debugLog()`, `getDebugLogs()` - 通过 `.env` 中 `VITE_DEBUG=true` 控制,开发默认开启,生产关闭 - LoginPage 自动记录登录流程;ProfilePage 按条件显示调试面板 - 头像支持:后端 `UserProfileUpdate` 新增 `avatar_url` 字段 - ProfilePage 头像卡片显示真实头像(有 avatar_url 时) - ProfilePage 增加用户姓名编辑字段 ### Phase 4: CRMEB 代理(bceb4f4 ~ 96a938e,当前版本) **方案:** `?openid=xxx`(单参数)→ 后端 `openid-login` → 调 CRMEB 内部接口获取信息 → 自动补齐 **关键改动(96a938e):** 后端: - 新增 `POST /auth/openid-login` — 接收 openid,调 CRMEB 获取 nickname/phone/avatar - `config.py` 新增 `crmeb_base_url`、`crmeb_api_key` - 查找/创建用户时自动同步:name、phone、avatar_url 前端: - LoginPage 简化:检测 openid → 调 openid-login → 跳转 - UserContext 修复 avatar_url 未映射导致头像不显示 CRMEB 端(外部): - 新增 `InternalController`,`GET /api/internal/user-info?openid=xxx` - `X-Internal-Key` Header 认证,硬编码密钥(后续改为 config 读取) --- ## 二、完整 Commit 清单 | SHA | 时间 | 类型 | 摘要 | |-----|------|------|------| | `96a938e` | 05/27 22:24 | feat | **openid-login + avatar_url 修复** — CRMEB 代理登录方案最终版 | | `bceb4f4` | 05/27 20:24 | feat | 支持从小程序获取微信头像和昵称同步到 H5 | | `150dafc` | 05/27 20:19 | feat | 统一调试模块 debug.ts,VITE_DEBUG 环境变量控制 | | `27b5856` | 05/27 18:52 | cleanup | 移除所有调试代码,登录页精简 | | `1eef3ae` | 05/27 18:48 | refactor | 小程序参数直传 uid/openid/phone,前端构建本地 token | | `8c50afc` | 05/27 03:44 | feat | 小程序 web-view Token 传递问题分析与修复方案 | | `6dc6258` | 05/27 03:07 | feat | H5 登录调试面板,URL 信息显示 | | `5a0f1f4` | 05/27 02:27 | feat | API 前缀配置调整,Vite 代理更新 | | `fe116b9` | 05/27 02:19 | feat | 调试面板 | | `80904e6` | 05/27 01:49 | feat | 按 openid 查找/创建用户,调整 JWT 负载字段 | | `3506731` | 05/23 02:15 | fix | 修复 DEV_MODE 解析 | | `08df182` | 05/23 01:59 | refactor | 简化 H5 应用用户授权 | | `53128a6` | 05/22 00:51 | feat | 添加 serv.sh 服务管理脚本 | | `ded7ea1` | 05/21 20:56 | feat | 新增可配置路径前缀支持子路径部署 | | `fd1aea1` | 05/21 17:10 | build | 配置部署子路径 /app_03/ | | `409daba` | 05/21 00:46 | feat | 初始化项目基础代码结构 | --- ## 三、新增/修改文件清单 ### 新增文件 | 文件 | 目的 | |------|------| | `frontend/src/app/services/debug.ts` | 统一调试模块:日志记录/读取/清除 | | `backend/serv.sh` | 服务管理脚本(start/stop/restart/logs) | | `docs/crmeb-internal-api-plan.md` | CRMEB 内部接口方案文档 | | `.env.example` | 环境变量模板 | ### 关键修改文件 | 文件 | 变化 | |------|------| | `frontend/src/app/pages/LoginPage.tsx` | 3 次重写:token 解码 → 参数直传 → openid-login | | `frontend/src/app/pages/ProfilePage.tsx` | 添加头像显示、姓名编辑、调试面板 | | `frontend/src/app/services/api.ts` | 添加 fetchApi export、createDummyToken | | `frontend/src/app/context/UserContext.tsx` | 修复 avatar_url 映射 | | `frontend/.env` | 添加 VITE_API_PREFIX、VITE_DEBUG、VITE_UPLOADS_PREFIX | | `backend/app/config.py` | 添加 crmeb_base_url、crmeb_api_key | | `backend/app/routers/auth.py` | 添加 openid-login 接口、dev-login 调整 | | `backend/app/schemas/user.py` | UserProfileUpdate 添加 avatar_url | | `backend/app/middleware/auth.py` | verify_signature=False | | `backend/app/models/user.py` | 添加 avatar_url 字段 | --- ## 四、部署与运维记录 ### 服务器信息 | 项目 | 地址 | |------|------| | app_03 服务 | 8.145.39.61:8030(uvicorn) | | CRMEB 服务 | 8.130.191.152:20199(Swoole) | | H5 入口 | https://mp.yizhezhe.com/app_03/ | | Git 远程 | gitea@git@git@gitea.nexjs.com:jone/app_03_pregnancy.git | ### 部署关键点 1. **Nginx 尾随斜杠问题**:`location = /app_03 { return 301 /app_03/; }` 必须带,否则丢 query 参数 2. **API 代理**:前后端统一使用 `/app_03/api/*` 路径,Nginx rewrite 剥离前缀 3. **后端重启命令**: ```bash fuser -k 8030/tcp && sleep 2 && \ nohup env DEV_MODE=1 .venv/bin/uvicorn app.main:app \ --host 127.0.0.1 --port 8030 --workers 1 > app.log 2>&1 & ``` 4. **前端构建**: ```bash cd frontend && npm run build scp -r dist/* root@8.145.39.61:/opt/app/app_03_pregnancy/frontend/dist/ ``` ### 服务器 Git 管理 - 服务器仓库 reset 到 1eef3ae(合并前状态),remote 指向 gitea - 回滚后 HEAD 在 96a938e,状态 clean - 本地实现新功能后再 push 到 gitea,服务器 pull 部署 --- ## 五、测试账号 | 角色 | openid | 手机号 | 昵称 | |------|--------|--------|------| | 真实用户 | `oauWC1zc7hVn3j60QwkuHyjGn03Y` | 13693687880 | 枫逸 | | 开发测试 | `dev_test_account_001` | 13800000000 | 开发测试用户 | --- ## 六、废弃方案记录 | 方案 | 原因 | commit | |------|------|--------| | JWT 签名验证 | 小程序 token 无法共享签名密钥,改为不验签 | — | | jwt-yun `exchange-code` | 外部服务不可用 | — | | URL 传 3 参数 (`?uid=&openid=&phone=`) | 参数繁琐,敏感信息暴露 | 1eef3ae | | paramsLogin 后端接口 | 纯前端可完成,不需要额外 API | 1eef3ae | | 前端 createDummyToken() | 替代为后端 openid-login 返回 token | bceb4f4 | --- ## 七、待办项 - [ ] CRMEB InternalController 密钥从 config 读取(当前硬编码) - [ ] 小程序端 web-view URL 改为 `?openid=` 单参格式 - [ ] 前后端代码 commit + push 到 gitea - [ ] 服务器 deploy 最新代码