diff --git a/backend/go-service/app/auth/service/auth_service.go b/backend/go-service/app/auth/service/auth_service.go index f5ea817..4d0515e 100644 --- a/backend/go-service/app/auth/service/auth_service.go +++ b/backend/go-service/app/auth/service/auth_service.go @@ -378,13 +378,18 @@ func (s *AuthService) buildUserInfo(user *model.User, roles []string) *dto.UserI if roles == nil { roles = []string{} } - return &dto.UserInfo{ - ID: user.ID, - Username: user.Username, - Email: user.Email, - Nickname: user.Nickname, - Avatar: user.Avatar, - Gender: user.Gender, - Roles: roles, + info := &dto.UserInfo{ + ID: user.ID, + Username: user.Username, + Email: user.Email, + Nickname: user.Nickname, + Avatar: user.Avatar, + Gender: user.Gender, + Roles: roles, + CreatedAt: user.CreatedAt.Format("2006-01-02 15:04:05"), } + if user.Phone != nil { + info.Phone = *user.Phone + } + return info } diff --git a/backend/go-service/app/dto/auth_dto.go b/backend/go-service/app/dto/auth_dto.go index 8f39bf9..398394a 100644 --- a/backend/go-service/app/dto/auth_dto.go +++ b/backend/go-service/app/dto/auth_dto.go @@ -25,13 +25,15 @@ type LoginResponse struct { // UserInfo 用户基本信息(用于响应返回,不含敏感字段) type UserInfo struct { - ID int64 `json:"id"` // 用户 ID - Username string `json:"username"` // 用户名 - Email string `json:"email"` // 邮箱 - Nickname string `json:"nickname"` // 昵称 - Avatar string `json:"avatar"` // 头像 URL - Gender int `json:"gender"` // 性别:0=未知, 1=男, 2=女 - Roles []string `json:"roles"` // 角色代码列表 + ID int64 `json:"id"` // 用户 ID + Username string `json:"username"` // 用户名 + Email string `json:"email"` // 邮箱 + Nickname string `json:"nickname"` // 昵称 + Avatar string `json:"avatar"` // 头像 URL + Gender int `json:"gender"` // 性别:0=未知, 1=男, 2=女 + Phone string `json:"phone,omitempty"` // 手机号(可能为空) + Roles []string `json:"roles"` // 角色代码列表 + CreatedAt string `json:"created_at,omitempty"` // 注册时间(格式:yyyy-MM-dd HH:mm:ss) } // RefreshTokenRequest 刷新 Token 请求参数 diff --git a/docs/api/README.md b/docs/api/README.md index fe070b1..314bc9d 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -41,7 +41,7 @@ | 环境 | 地址 | |------|------| -| 开发环境 | `http://localhost:8080` | +| 开发环境 | `http://localhost:8085` | | 生产环境 | `https://api.echochat.com`(待定) | ### 认证方式 @@ -73,8 +73,20 @@ yyyy-MM-dd HH:mm:ss ```json { "code": 0, - "message": "ok", + "message": "success", "data": { ... }, + "trace_id": "6478824e-2926-4d35-aa5f-047c8cfbb36b", + "time": "2026-02-27 18:00:00" +} +``` + +**创建成功响应(如注册):** +```json +{ + "code": 0, + "message": "created", + "data": { ... }, + "trace_id": "6478824e-2926-4d35-aa5f-047c8cfbb36b", "time": "2026-02-27 18:00:00" } ``` @@ -84,11 +96,13 @@ yyyy-MM-dd HH:mm:ss { "code": 1001, "message": "参数错误:邮箱格式不正确", - "data": null, + "trace_id": "66564073-c0b7-4cf6-a200-5df94e1d01f3", "time": "2026-02-27 18:00:00" } ``` +> **trace_id** 字段在所有响应中都返回,用于追踪同一请求在各层级日志中的关联。 + ### 错误码定义 #### 通用错误码(1000-1099) diff --git a/docs/api/frontend/auth.md b/docs/api/frontend/auth.md index 338d727..1343ede 100644 --- a/docs/api/frontend/auth.md +++ b/docs/api/frontend/auth.md @@ -28,8 +28,8 @@ | 字段 | 类型 | 必填 | 规则 | 说明 | |------|------|------|------|------| -| username | string | 是 | 3-50 字符,字母数字下划线 | 用户名 | -| email | string | 是 | 合法邮箱格式 | 邮箱地址 | +| username | string | 是 | 3-50 字符 | 用户名,全局唯一 | +| email | string | 是 | 合法邮箱格式 | 邮箱地址,全局唯一 | | password | string | 是 | 6-50 字符 | 登录密码 | | nickname | string | 否 | 最多 50 字符 | 昵称,默认与用户名相同 | @@ -43,28 +43,37 @@ } ``` -**成功响应:** +**成功响应(201 Created):** ```json { "code": 0, - "message": "ok", + "message": "created", "data": { "token": "eyJhbGciOiJIUzI1NiIs...", "refresh_token": "eyJhbGciOiJIUzI1NiIs...", - "expires_in": 604800, + "expires_in": 7200, "user": { "id": 1, "username": "zhangsan", "email": "zhangsan@example.com", "nickname": "张三", "avatar": "", + "gender": 0, "roles": ["user"] } - } + }, + "trace_id": "6478824e-2926-4d35-aa5f-047c8cfbb36b", + "time": "2026-02-28 16:42:03" } ``` -**可能的错误码:** 1001, 2001, 2002 +> `expires_in` 为 Access Token 有效期(秒),当前配置为 7200 秒(2 小时)。Refresh Token 有效期为 7 天。 + +**可能的错误:** + +| HTTP 状态码 | 说明 | +|------------|------| +| 400 | 参数校验失败 / 用户名或邮箱已被注册 | --- @@ -78,7 +87,7 @@ | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| -| account | string | 是 | 用户名或邮箱(自动识别格式) | +| account | string | 是 | 用户名或邮箱(自动识别) | | password | string | 是 | 登录密码 | **请求示例:** @@ -89,9 +98,38 @@ } ``` -**成功响应:** 与注册接口返回格式一致 +**成功响应(200 OK):** +```json +{ + "code": 0, + "message": "success", + "data": { + "token": "eyJhbGciOiJIUzI1NiIs...", + "refresh_token": "eyJhbGciOiJIUzI1NiIs...", + "expires_in": 7200, + "user": { + "id": 1, + "username": "zhangsan", + "email": "zhangsan@example.com", + "nickname": "张三", + "avatar": "", + "gender": 0, + "roles": ["user"] + } + }, + "trace_id": "fe290a90-00af-4c6b-8af7-ba6ae1d57d20", + "time": "2026-02-28 16:42:04" +} +``` -**可能的错误码:** 1001, 2003, 2004 +**可能的错误:** + +| HTTP 状态码 | 说明 | +|------------|------| +| 400 | 参数校验失败 | +| 401 | 账号或密码错误 | +| 403 | 账号已被禁用 / 账号已注销 | +| 404 | 用户不存在 | --- @@ -101,14 +139,16 @@ **权限:** 需认证 -**说明:** 服务端清除 Redis 中的 Token 记录,客户端需同步清除本地存储的 Token。 +**说明:** 当前采用无状态 JWT 方案,服务端不存储 Token 状态。退出登录由客户端主动删除本地存储的 Token 即可。后续可扩展为将 Token 加入 Redis 黑名单实现服务端主动失效。 **成功响应:** ```json { "code": 0, - "message": "ok", - "data": null + "message": "success", + "data": null, + "trace_id": "...", + "time": "2026-02-28 16:42:05" } ``` @@ -126,20 +166,45 @@ |------|------|------|------| | refresh_token | string | 是 | 刷新令牌 | +**请求示例:** +```json +{ + "refresh_token": "eyJhbGciOiJIUzI1NiIs..." +} +``` + **成功响应:** ```json { "code": 0, - "message": "ok", + "message": "success", "data": { "token": "eyJhbG...(新 Access Token)", "refresh_token": "eyJhbG...(新 Refresh Token)", - "expires_in": 604800 - } + "expires_in": 7200, + "user": { + "id": 1, + "username": "zhangsan", + "email": "zhangsan@example.com", + "nickname": "张三", + "avatar": "", + "gender": 0, + "roles": ["user"] + } + }, + "trace_id": "...", + "time": "2026-02-28 16:42:06" } ``` -**可能的错误码:** 1002 +**可能的错误:** + +| HTTP 状态码 | 说明 | +|------------|------| +| 400 | 参数校验失败 / 无效的 Refresh Token 类型 | +| 401 | Token 已过期或无效 | +| 403 | 账号已被禁用 / 账号已注销 | +| 404 | 用户不存在 | --- @@ -153,7 +218,7 @@ ```json { "code": 0, - "message": "ok", + "message": "success", "data": { "id": 1, "username": "zhangsan", @@ -164,10 +229,14 @@ "phone": "13800138000", "roles": ["user"], "created_at": "2026-02-27 10:00:00" - } + }, + "trace_id": "...", + "time": "2026-02-28 16:42:07" } ``` +> profile 接口返回的 `UserInfo` 包含 `phone` 和 `created_at` 字段(相比登录响应中的用户信息更完整)。 + --- ## 6. 更新个人信息 @@ -178,12 +247,14 @@ **请求参数(均为可选,只传需要修改的字段):** -| 字段 | 类型 | 必填 | 说明 | -|------|------|------|------| -| nickname | string | 否 | 新昵称 | -| avatar | string | 否 | 新头像 URL | -| gender | int | 否 | 性别:0=未知,1=男,2=女 | -| phone | string | 否 | 手机号 | +| 字段 | 类型 | 必填 | 规则 | 说明 | +|------|------|------|------|------| +| nickname | string | 否 | 最多 50 字符 | 新昵称 | +| avatar | string | 否 | 最多 500 字符 | 新头像 URL | +| gender | int | 否 | 0/1/2 | 性别:0=未知,1=男,2=女 | +| phone | string | 否 | 最多 20 字符 | 手机号 | + +**成功响应:** 返回更新后的完整用户信息(与获取个人信息接口格式一致)。 --- @@ -195,9 +266,26 @@ **请求参数:** -| 字段 | 类型 | 必填 | 说明 | -|------|------|------|------| -| old_password | string | 是 | 原密码 | -| new_password | string | 是 | 新密码(6-50 字符) | +| 字段 | 类型 | 必填 | 规则 | 说明 | +|------|------|------|------|------| +| old_password | string | 是 | - | 原密码 | +| new_password | string | 是 | 6-50 字符 | 新密码 | -**可能的错误码:** 1001, 2003(原密码错误) +**成功响应:** +```json +{ + "code": 0, + "message": "success", + "data": null, + "trace_id": "...", + "time": "2026-02-28 16:42:08" +} +``` + +**可能的错误:** + +| HTTP 状态码 | 说明 | +|------------|------| +| 400 | 参数校验失败 | +| 401 | 原密码错误 | +| 404 | 用户不存在 |