# 登录接口统一定义文档 ## 版本信息 - **版本**: v1.0 - **创建日期**: 2026-01-15 - **最后更新**: 2026-01-15 ## 概述 本文档定义了 RMDC 系统登录接口的统一结构体规范,确保前端和后端之间的数据交互一致性。 ## 后端定义 (Go) ### 文件位置 `rmdc-user-auth/internal/model/dto/auth_dto.go` ### 结构体定义 #### LoginRequest - 登录请求 ```go type LoginRequest struct { Username string `json:"username" binding:"required"` // 用户名(中文真实姓名) Password string `json:"password"` // 明文密码(已废弃,保持兼容) EncryptedPassword string `json:"encrypted_password" binding:"required"` // RSA加密后的密码 } ``` #### LoginResponse - 登录响应 ```go type LoginResponse struct { Token string `json:"token"` // JWT令牌 User *UserDTO `json:"user"` // 用户信息 MustChangePassword bool `json:"must_change_password"` // 是否必须修改密码 PasswordExpireDays int `json:"password_expire_days"` // 密码剩余天数(7天内提醒) } ``` #### UserDTO - 用户信息传输对象 ```go type UserDTO struct { ID int64 `json:"id"` // 用户ID Username string `json:"username"` // 中文真实姓名 EnglishUsername string `json:"english_username"` // 英文用户名 AvatarID string `json:"avatar_id"` // 头像ID AvatarFrameID string `json:"avatar_frame_id"` // 头像框ID Gender string `json:"gender"` // 性别: male/female Email string `json:"email"` // 邮箱 Phone string `json:"phone"` // 手机号 ShortNumber string `json:"short_number,omitempty"` // 短号 WorkID string `json:"work_id,omitempty"` // 工号 GroupName string `json:"group_name,omitempty"` // 所属小组 Company string `json:"company"` // 公司名称 DevRole string `json:"dev_role"` // 开发角色: backend/frontend/testing/devops Role string `json:"role"` // RMDC系统角色: superadmin/admin/normal/third Status string `json:"status"` // 状态: active/locked/disabled RegisteredByID int64 `json:"registered_by_id"` // 注册人ID CreatedAt time.Time `json:"created_at"` // 注册时间 UpdatedAt time.Time `json:"updated_at"` // 更新时间 DeletedAt *time.Time `json:"deleted_at,omitempty"` // 删除时间 LastLoginAt *time.Time `json:"last_login_at,omitempty"` // 最后登录时间 PasswordExpires *time.Time `json:"password_expires,omitempty"` // 密码过期时间 } ``` ## 前端定义 (TypeScript) ### 文件位置 `frontend/src/types/api.ts` ### 接口定义 #### LoginResponse - 登录响应 ```typescript export interface LoginResponse { token: string // JWT令牌 user: User // 用户信息 must_change_password: boolean // 是否必须修改密码 password_expire_days: number // 密码剩余天数(7天内提醒) } ``` #### User - 用户信息 ```typescript export interface User { id: number username: string // 中文真实姓名 english_username: string // 英文用户名 avatar_id: string // 头像ID avatar_frame_id: string // 头像框ID gender: string // 性别: male/female email: string // 邮箱 phone: string // 手机号 short_number?: string // 短号 work_id?: string // 工号 group_name?: string // 所属小组 company: string // 公司名称 dev_role: string // 开发角色: backend/frontend/testing/devops role: string // 用户角色: superadmin/admin/normal/third status: string // 用户状态: active/locked/disabled registered_by_id: number // 注册人ID created_at: string // 注册时间 updated_at: string // 更新时间 deleted_at?: string // 删除时间 last_login_at?: string // 最后登录时间 password_expires?: string // 密码过期时间 } ``` ## API 接口规范 ### 请求端点 ``` POST /api/auth/login ``` ### 请求体示例 ```json { "username": "张三", "encrypted_password": "RSA加密后的密码字符串" } ``` ### 响应示例 #### 成功响应 (HTTP 200) ```json { "code": 0, "status": 200, "timestamp": "2026-01-15T17:40:00Z", "message": "success", "data": { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "id": 1, "username": "张三", "english_username": "zhangsan", "avatar_id": "default_1", "avatar_frame_id": "default", "gender": "male", "email": "zhangsan@example.com", "phone": "13800138000", "company": "示例公司", "dev_role": "backend", "role": "admin", "status": "active", "registered_by_id": 1, "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-15T17:40:00Z" }, "must_change_password": false, "password_expire_days": 30 } } ``` #### 失败响应 (HTTP 401) ```json { "code": 10003, "status": 401, "timestamp": "2026-01-15T17:40:00Z", "message": "用户名或密码错误", "data": null, "error": "invalid credentials" } ``` ## 字段映射对照表 | 后端字段 (Go) | 前端字段 (TypeScript) | 字段说明 | 必填 | |--------------|---------------------|----------|------| | ID | id | 用户ID | ✓ | | Username | username | 中文真实姓名 | ✓ | | EnglishUsername | english_username | 英文用户名 | ✓ | | AvatarID | avatar_id | 头像ID | ✓ | | AvatarFrameID | avatar_frame_id | 头像框ID | ✓ | | Gender | gender | 性别 | ✓ | | Email | email | 邮箱 | ✓ | | Phone | phone | 手机号 | ✓ | | ShortNumber | short_number | 短号 | × | | WorkID | work_id | 工号 | × | | GroupName | group_name | 所属小组 | × | | Company | company | 公司名称 | ✓ | | DevRole | dev_role | 开发角色 | ✓ | | Role | role | 用户角色 | ✓ | | Status | status | 用户状态 | ✓ | | RegisteredByID | registered_by_id | 注册人ID | ✓ | | CreatedAt | created_at | 注册时间 | ✓ | | UpdatedAt | updated_at | 更新时间 | ✓ | | DeletedAt | deleted_at | 删除时间 | × | | LastLoginAt | last_login_at | 最后登录时间 | × | | PasswordExpires | password_expires | 密码过期时间 | × | ## 关键改进点 ### 1. 统一命名规范 - **前后端一致性**: 所有字段名统一使用 snake_case (下划线命名) - **修正**: `avatar_frame` → `avatar_frame_id`(与后端保持一致) ### 2. 新增字段 - `short_number`: 短号(可选) - `work_id`: 工号(可选) - `password_expires`: 密码过期时间(可选) ### 3. 标准化响应结构 - **后端**: 使用 `dto.LoginResponse` 替代 `gin.H` 直接返回 - **前端**: 从 `ApiResponse` 中提取 `data` 字段 ### 4. 类型安全 - 后端使用强类型 DTO 结构体 - 前端使用 TypeScript 接口定义 - 消除了隐式类型转换的风险 ### 5. 密码安全 - 统一使用 RSA 加密传输密码 - 移除明文密码支持(保持向后兼容) ## 使用示例 ### 后端 Handler 实现 ```go func (h *AuthHandler) Login(c *gin.Context) { var req dto.LoginRequest if err := c.ShouldBindJSON(&req); err != nil { wdd_res.ResponseErrorWithDetail(c, wdd_res.CodeValidationFail, "请求参数错误", err) return } // ... 业务逻辑 ... resp := dto.LoginResponse{ Token: token, User: userDTO, MustChangePassword: mustChangePassword, PasswordExpireDays: passwordExpireDays, } wdd_res.ResponseSuccess(c, resp) } ``` ### 前端 Store 实现 ```typescript async login(username: string, password: string): Promise { const requestBody = { username, encrypted_password: await encryptPasswordWithPublicKey(password) } const apiResponse = await api.post('/auth/login', requestBody) if (apiResponse.code !== 0) { console.error('Login failed:', apiResponse.message) return false } const response = apiResponse.data this.token = response.token this.user = response.user this.mustChangePassword = response.must_change_password this.passwordExpireDays = response.password_expire_days localStorage.setItem('token', this.token) localStorage.setItem('user', JSON.stringify(this.user)) return true } ``` ## 相关文件清单 ### 后端文件 - `rmdc-user-auth/internal/model/dto/auth_dto.go` - 登录相关 DTO 定义 - `rmdc-user-auth/internal/handler/auth_handler.go` - 登录处理器 - `rmdc-user-auth/internal/model/entity/user.go` - 用户实体 ### 前端文件 - `frontend/src/types/api.ts` - API 类型定义 - `frontend/src/store/auth.ts` - 认证状态管理 - `frontend/src/api/index.ts` - API 请求封装 ## 遵循的规范文档 - `3-api-development-prompt.md` - API 开发规范 - `go-gin-gorm-style.md` - Go/Gin/GORM 编码规范 - `vue3-typescript-stye.md` - Vue3/TypeScript 编码规范 ## 版本历史 | 版本 | 日期 | 变更说明 | |------|------|----------| | v1.0 | 2026-01-15 | 初始版本,统一前后端登录接口定义 |