feat: 完善微信认证功能,新增用户资料更新与token刷新接口

- 新增 userService.js,包含用户认证、资料更新、token 刷新等功能
- 新增 wechatService.js,处理微信API交互,获取openid和手机号
- 新增 appError.js,封装应用错误处理
- 新增 logger.js,提供日志记录功能
- 新增 response.js,统一成功响应格式
- 新增 sanitize.js,提供输入数据清洗功能
- 更新 OpenAPI 文档,描述新增接口及请求响应格式
- 更新 PocketBase 数据库结构,调整用户表字段及索引策略
- 增强错误处理机制,确保错误信息可观测性
- 更新变更记录文档,详细记录本次变更内容
This commit is contained in:
2026-03-24 10:36:19 +08:00
parent d5dc47fc07
commit 02d5686c7b
76 changed files with 1722 additions and 2641 deletions

139
pocket-base/README.md Normal file
View File

@@ -0,0 +1,139 @@
# PocketBase Hooks API Project
这是从 `back-end/` 迁移出来的 PocketBase `bai_api_pb_hooks` 原生 API 项目。
## 目标
- 使用 PocketBase 自定义路由承载对外 API
- 最终部署时只复制 `bai_api_pb_hooks/` 整个目录到服务器的 PocketBase 实例目录
- 按接口类型拆分不同子目录,便于维护
## 目录结构
```text
pocket-base/
├─ bai-api-main.pb.js
├─ bai_api_pb_hooks/
│ ├─ bai_api_routes/
│ │ ├─ system/
│ │ └─ wechat/
│ └─ bai_api_shared/
│ ├─ config/
│ ├─ middlewares/
│ ├─ services/
│ └─ utils/
├─ spec/
├─ tests/
└─ scripts/
```
## 当前接口
- `POST /api/system/test-helloworld`
- `POST /api/system/health`
- `POST /api/wechat/login`
- `POST /api/wechat/profile`
- `POST /api/wechat/refresh-token`
> 当前自定义路由统一使用 `/api/...` 前缀。
## 鉴权说明
- 当前接口统一使用 PocketBase 原生 `Authorization: Bearer <token>`
- `Open-Authorization` 不是本项目接口定义的 Header如调试工具里出现通常是工具全局预设应删除。
- `users_wx_openid` Header 已移除,不再需要客户端额外传递。
- 当前用户身份以 PocketBase auth record 中的 `openid` 字段为准。
## 部署方式
由于服务器只有一个公共 `pb_hooks/` 目录,部署时请将以下内容复制到服务器 `pb_hooks/` 根目录下:
- `bai-api-main.pb.js`
- `bai_api_pb_hooks/`
建议部署后的结构类似:
```text
pb_hooks/
├─ bai-api-main.pb.js
└─ bai_api_pb_hooks/
├─ bai_api_routes/
└─ bai_api_shared/
```
## 环境配置
PocketBase JSVM 不会自动读取 `back-end/.env`。当前 Hook 运行配置来自 **PocketBase 进程环境变量**
已补充模板文件:
- `pocket-base/bai_api_pb_hooks/bai_api_shared/config/env.example`
- `pocket-base/bai_api_pb_hooks/bai_api_shared/config/runtime.example.js`
至少需要在服务器的 PocketBase 运行环境中提供,或写入 `runtime.js`
- `WECHAT_APPID`
- `WECHAT_SECRET`
可选保留:
- `APP_BASE_URL`
- `POCKETBASE_API_URL`
- `POCKETBASE_AUTH_TOKEN`
说明:
- `WECHAT_APPID` / `WECHAT_SECRET` 是必须的,因为微信登录逻辑会直接调用微信官方接口。
-`back-end/.env` 中的这些值可以作为来源参考,但 **不会被 pb_hooks 自动读取**
- 如果不方便改 PocketBase 进程环境,可在服务器创建:`pb_hooks/bai_api_pb_hooks/bai_api_shared/config/runtime.js`
- `runtime.js` 的内容可直接参考 `runtime.example.js`
- 当前 Hook 代码已不依赖自定义 JWT因此 `JWT_SECRET``JWT_EXPIRES_IN` 不是运行必需项。
## 额外要求
部署前请确认 PocketBase 所在环境提供以下环境变量:
- `WECHAT_APPID`
- `WECHAT_SECRET`
如果你还需要构建时间展示,可额外提供:
- `BUILD_TIME`
## 注意
PocketBase JSVM 不是 Node.js 运行时:
- 不能直接复用 axios/jsonwebtoken/express 中间件
- 只能使用 PocketBase 暴露的全局对象,如 `$app``$apis``$http``$security`
- 共享逻辑必须通过 `require(`${__hooks}/...`)` 方式加载本地 CommonJS 模块
## 建议验证
迁移完成后,在 PocketBase 服务器上检查:
1. 自定义路由是否生效
2. `tbl_auth_users``tbl_company` 集合名是否与当前数据库一致
3. PocketBase 所在服务器是否能访问微信开放接口
4. 反向代理是否放行 `/api/` 路由
## OpenSpec 变更记录
本项目 active hooks 相关的最新规范记录见:
- `pocket-base/spec/openapi.yaml`
- `pocket-base/spec/changes.2026-03-23-pocketbase-hooks-auth-hardening.md`
本次变更重点包括:
- 微信登录链路错误显式返回
- `recordAuthResponse` 使用空 `authMethod`
- active hooks 中移除 `-created` 排序
- `users_phone` 索引由唯一改为普通索引
- `tbl_auth_users``openid` 为业务身份锚点
- auth 集合兼容占位 `email`、随机密码与 `passwordConfirm`
## 与原项目关系
-`back-end/` 保留不动
- 当前 `pocket-base/` 为新的正式 Hook 项目
- 后续只部署 `bai_api_pb_hooks/` 的内部内容到服务器 `pb_hooks/` 即可