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

View File

@@ -0,0 +1,253 @@
openapi: 3.1.0
info:
title: BAI PocketBase Hooks API
description: 基于 PocketBase `bai_api_pb_hooks` 的对外接口文档,可直接导入 Postman。
version: 1.0.0
servers:
- url: https://bai-api.blv-oa.com/pb
description: 生产环境
- url: http://localhost:8090
description: PocketBase 本地环境
tags:
- name: 系统
description: 基础检查接口
- name: 微信认证
description: 基于微信 openid 与 PocketBase 原生 token 的认证接口
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: PocketBaseAuthToken
schemas:
ApiResponse:
type: object
required: [code, msg, data]
properties:
code:
type: integer
example: 200
msg:
type: string
example: 操作成功
data:
type: object
additionalProperties: true
HealthData:
type: object
properties:
status:
type: string
example: healthy
timestamp:
type: string
format: date-time
HelloWorldData:
type: object
properties:
message:
type: string
example: Hello, World!
timestamp:
type: string
format: date-time
status:
type: string
example: success
build_time:
type: string
nullable: true
format: date-time
CompanyInfo:
type: object
nullable: true
additionalProperties: true
UserInfo:
type: object
properties:
pb_id:
type: string
users_id:
type: string
users_type:
type: string
enum: [游客, 注册用户]
users_name:
type: string
users_phone:
type: string
users_phone_masked:
type: string
users_picture:
type: string
openid:
type: string
company_id:
type: string
company:
$ref: '#/components/schemas/CompanyInfo'
created:
type: string
updated:
type: string
PocketBaseAuthResponse:
type: object
properties:
token:
type: string
description: PocketBase 原生 auth token
record:
type: object
description: PocketBase auth record 原始对象
meta:
type: object
properties:
code:
type: integer
example: 200
msg:
type: string
example: 登录成功
data:
type: object
properties:
status:
type: string
enum: [register_success, login_success]
is_info_complete:
type: boolean
user:
$ref: '#/components/schemas/UserInfo'
WechatLoginRequest:
type: object
required: [users_wx_code]
properties:
users_wx_code:
type: string
description: 微信小程序登录临时凭证 code
example: 0a1b2c3d4e5f6g
WechatProfileRequest:
type: object
required: [users_name, users_phone_code, users_picture]
properties:
users_name:
type: string
example: 张三
users_phone_code:
type: string
example: 2b7d9f2e3c4a5b6d7e8f
users_picture:
type: string
example: https://example.com/avatar.png
WechatProfileResponseData:
type: object
properties:
status:
type: string
enum: [update_success]
user:
$ref: '#/components/schemas/UserInfo'
paths:
/api/system/test-helloworld:
post:
tags: [系统]
summary: HelloWorld 测试接口
responses:
'200':
description: 成功
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ApiResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/HelloWorldData'
/api/system/health:
post:
tags: [系统]
summary: 健康检查
responses:
'200':
description: 成功
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ApiResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/HealthData'
/api/wechat/login:
post:
tags: [微信认证]
summary: 微信登录/注册合一
description: |
使用微信 code 换取 openid。
若 `tbl_auth_users` 中不存在对应用户则自动创建 auth record随后返回 PocketBase 原生 auth token。
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WechatLoginRequest'
responses:
'200':
description: 登录或注册成功
content:
application/json:
schema:
$ref: '#/components/schemas/PocketBaseAuthResponse'
'400':
description: 参数错误
'415':
description: 请求体必须为 application/json
'429':
description: 重复请求过于频繁
/api/wechat/profile:
post:
tags: [微信认证]
summary: 更新微信用户资料
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WechatProfileRequest'
responses:
'200':
description: 更新成功
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ApiResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/WechatProfileResponseData'
'401':
description: token 无效或当前 auth record 缺少 openid
/api/wechat/refresh-token:
post:
tags: [微信认证]
summary: 刷新 PocketBase 原生 token
description: |
当前实现完全基于 PocketBase 原生鉴权,直接从当前 `Authorization` 对应的 auth record 读取 openid 并重新返回原生 auth token。
security:
- bearerAuth: []
responses:
'200':
description: 刷新成功
content:
application/json:
schema:
$ref: '#/components/schemas/PocketBaseAuthResponse'
'401':
description: token 无效或当前 auth record 缺少 openid
'404':
description: 用户不存在