kindergarten_java/docs/dev-logs/2026-03-20-profile-feature.md

177 lines
5.3 KiB
Markdown
Raw Permalink Normal View History

# 个人中心功能实现记录
## 日期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<UpdateProfileResponse>
export function changePassword(oldPassword: string, newPassword: string): Promise<void>
```
### 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. 更新测试日志