# 个人中心功能实现记录 ## 日期:2026-03-20 ## 实现内容 ### 需求目标 在个人中心页面新增: 1. **密码修改功能**:输入旧密码和新密码进行修改 2. **信息编辑功能**:可修改姓名、手机号、邮箱 --- ## 后端实现 ### 1. 新建 DTO 文件 #### `UpdateProfileRequest.java` - 路径:`reading-platform-java/src/main/java/com/reading/platform/dto/request/UpdateProfileRequest.java` - 字段:name(姓名)、phone(手机号)、email(邮箱) - 校验注解: - name: `@Pattern(regexp = "^[\u4e00-\u9fa5a-zA-Z\s]{2,20}$")` - phone: `@Pattern(regexp = "^1[3-9]\d{9}$")` - email: `@Email` #### `UpdateProfileResponse.java` - 路径:`reading-platform-java/src/main/java/com/reading/platform/dto/response/UpdateProfileResponse.java` - 字段:userInfo(用户信息)、token(新 token) ### 2. 修改 Service 接口 #### `AuthService.java` 新增方法: ```java UpdateProfileResponse updateProfile(UpdateProfileRequest request); void changePassword(String oldPassword, String newPassword, String currentToken); ``` ### 3. 修改 Service 实现 #### `AuthServiceImpl.java` - 新增 `updateProfile()` 方法: - 根据当前用户角色更新对应表(AdminUser/Tenant/Teacher/Parent) - 学校管理员(Tenant)更新 `contactName/contactPhone/contactEmail` 字段 - 其他角色更新 `name/phone/email` 字段 - 生成新 token 并更新 Redis - 返回更新后的用户信息和新 token - 新增 `changePassword(String oldPassword, String newPassword, String currentToken)` 方法: - 调用原有 `changePassword()` 方法修改密码 - 将当前 token 加入黑名单(使旧 token 失效) - 新增 `convertToUserInfoResponse(Object userInfo, String role)` 私有方法: - 将 Entity 对象转换为 UserInfoResponse ### 4. 修改 Controller #### `AuthController.java` - 新增接口 `PUT /api/v1/auth/profile`:修改个人信息 - 修改接口 `POST /api/v1/auth/change-password`:增加 HttpServletRequest 参数获取 token - 新增 `resolveToken(HttpServletRequest request)` 辅助方法:从 Authorization header 获取 token ### 5. 扩展 JwtTokenProvider #### `JwtTokenProvider.java` 新增方法: ```java public long getRemainingExpiration(String token) ``` - 用于获取 token 剩余过期时间(秒) - 用于将 token 加入黑名单时设置过期时间 --- ## 前端实现 ### 1. 扩展 API 文件 #### `src/api/auth.ts` 新增类型和方法: ```typescript export interface UpdateProfileDto { name?: string; phone?: string; email?: string; } export interface UpdateProfileResponse { userInfo: UserProfile; token: string; } export function updateProfile(data: UpdateProfileDto): Promise export function changePassword(oldPassword: string, newPassword: string): Promise ``` ### 2. 修改个人中心页面 #### `src/views/profile/ProfileView.vue` - 新增「编辑资料」按钮:点击后弹出编辑弹窗 - 新增「修改密码」按钮:点击后弹出密码修改弹窗 - 编辑表单: - 姓名输入框(必填,2-20 位中文或英文) - 手机号输入框(选填,11 位数字正则校验) - 邮箱输入框(选填,email 格式校验) - 密码修改表单: - 旧密码输入框(必填) - 新密码输入框(必填,最少 6 位) - 确认密码输入框(必填,与 new password 一致) - 修改信息成功后:刷新本地用户信息 - 修改密码成功后:清除 token 和用户信息,跳转到登录页 --- ## 后端 API 列表 | 接口 | 方法 | 路径 | 说明 | |------|------|------|------| | 获取个人信息 | GET | `/api/v1/auth/profile` | 已有 | | 修改个人信息 | PUT | `/api/v1/auth/profile` | 新增,返回新 token | | 修改密码 | POST | `/api/v1/auth/change-password` | 已有,修改后 token 失效 | --- ## 验证方案 ### 后端验证 1. 启动后端服务(端口 8480) 2. 使用 Swagger 测试接口: - `GET /api/v1/auth/profile` - 获取个人信息 - `PUT /api/v1/auth/profile` - 修改个人信息 - `POST /api/v1/auth/change-password?oldPassword=xxx&newPassword=yyy` - 修改密码 ### 前端验证 1. 启动前端服务(端口 5173) 2. 登录任意角色账户 3. 访问个人中心页面 4. 测试编辑信息功能 5. 测试修改密码功能 --- ## 注意事项 1. **字段映射**: - 前端统一使用 `name/phone/email` - 后端 Service 层根据角色映射到对应字段 - 学校管理员(Tenant)映射到 `contactName/contactPhone/contactEmail` 2. **Token 处理**: - 修改个人信息:返回新 token,前端替换 localStorage 中的旧 token - 修改密码:将当前 token 加入黑名单,前端清除 token 并跳转到登录页 3. **表单校验**: - 前端:手机号正则 `/^1[3-9]\d{9}$/`,邮箱使用 Ant Design 内置校验 - 后端:使用 `@Valid` + `@Pattern`/`@Email` 注解校验 --- ## 待验证事项 - [ ] 超管角色修改信息功能 - [ ] 学校管理员修改信息功能 - [ ] 教师角色修改信息功能 - [ ] 家长角色修改信息功能 - [ ] 所有角色修改密码功能 - [ ] 修改信息后 token 是否正确刷新 - [ ] 修改密码后 token 是否失效并需重新登录 --- ## 下一步计划 1. 启动服务进行功能验证 2. 修复可能发现的问题 3. 更新测试日志