# 用户服务完整实现 **日期**: 2026-01-29 **类型**: 功能实现 **影响范围**: 用户服务 API、Model 层、测试 ## 概述 完成用户服务的完整实现,包括统一 API 响应格式、修复时区问题、更新测试代码。所有 11 个集成测试全部通过。 ## 主要变更 ### 1. 统一 API 响应格式 **修改文件**: - `server/app/api/v1/auth.py` - `server/app/api/v1/users.py` **变更内容**: - 所有 API 端点使用 `success_response()` 包装返回数据 - 移除 `response_model` 参数 - 统一响应格式:`{"code": 200, "message": "Success", "data": {...}}` - 移除不存在的 `service.close()` 调用(Session 由 FastAPI 依赖注入自动管理) **影响的端点**: - `POST /api/v1/auth/sms/send` - 发送短信验证码 - `POST /api/v1/auth/login/phone` - 手机号登录 - `POST /api/v1/auth/refresh` - 刷新 Token - `POST /api/v1/auth/logout` - 用户登出 - `GET /api/v1/users/me` - 获取当前用户信息 - `PUT /api/v1/users/me` - 更新用户信息 - `PUT /api/v1/users/me/username` - 修改用户名 - `POST /api/v1/users/me/avatar` - 上传头像 - `POST /api/v1/users/me/bind/phone` - 绑定手机号 - `POST /api/v1/users/me/bind/wechat` - 绑定微信 - `POST /api/v1/users/me/bind/email` - 绑定邮箱 - `GET /api/v1/users/me/credits` - 查询积分信息 - `DELETE /api/v1/users/me` - 删除用户 ### 2. 修复 User Model 时区问题 **修改文件**: `server/app/models/user.py` **问题**: 时间字段使用了带时区的 datetime,但未在 SQLModel 中指定 `DateTime(timezone=True)`,导致数据库操作时出现时区不匹配错误。 **修复**: ```python created_at: datetime = Field( default_factory=lambda: datetime.now(timezone.utc), sa_column=Column(DateTime(timezone=True), nullable=False), description="创建时间(UTC)" ) updated_at: datetime = Field( default_factory=lambda: datetime.now(timezone.utc), sa_column=Column(DateTime(timezone=True), nullable=False), description="更新时间(UTC)" ) deleted_at: Optional[datetime] = Field( default=None, sa_column=Column(DateTime(timezone=True), nullable=True), description="软删除时间(UTC)" ) ``` ### 3. 更新集成测试 **修改文件**: `server/tests/integration/test_user_api.py` **变更内容**: - 更新 `login_and_get_token()` 辅助函数以适配新的响应格式 - 更新 `test_phone_login()` 测试以验证统一响应格式 - 修复 `test_update_user_info()` 使用正确的 HTTP 方法(PUT 而非 PATCH) **测试结果**: ✅ 11/11 测试通过 ## 技术细节 ### 响应格式示例 **之前**: ```json { "access_token": "...", "refresh_token": "...", "user": {...} } ``` **现在**: ```json { "code": 200, "message": "Success", "data": { "access_token": "...", "refresh_token": "...", "user": {...} } } ``` ### 时区处理 - 所有时间字段使用 `datetime.now(timezone.utc)` 生成 UTC 时间 - 数据库列类型为 `TIMESTAMPTZ`(PostgreSQL) - SQLModel 使用 `DateTime(timezone=True)` 确保时区信息正确传递 ## 测试覆盖 - ✅ 健康检查 - ✅ 发送短信验证码 - ✅ 手机号登录 - ✅ 获取当前用户信息 - ✅ 更新用户信息 - ✅ 查询积分信息 - ✅ 绑定邮箱 - ✅ 用户登出 - ✅ 无效验证码登录(边界测试) - ✅ 无 Token 访问受保护路由(边界测试) - ✅ 无效 Token 访问受保护路由(边界测试) ## 相关文档 - 用户服务设计文档: `docs/requirements/backend/04-services/user/user-service.md` - 统一 API 响应规范: `docs/server/changelogs/2026-01-26-unified-api-response.md` - 时区标准: `docs/architecture/datetime-timezone-standards.md` ## 后续优化 1. 处理 Pydantic 序列化警告(Decimal 类型) 2. 实现 Token 黑名单机制(logout 端点 TODO) 3. 添加更多边界测试用例