# 个人中心页面设计文档
## 1. 页面概述
个人中心页面允许当前登录的用户查看和修改自己的个人信息,以及更改密码。此页面旨在提供一个简单、安全的界面来管理个人账户资料。
## 2. 页面布局

### 2.1 布局结构
页面通常采用多标签页(Tabs)布局,将不同功能的表单分开,以保持界面整洁。
- **左侧**: 用户头像和基本信息展示。
- **右侧**: 包含两个标签页:
- **基本资料**: 用于修改用户名、姓名、邮箱等信息。
- **修改密码**: 用于更改当前用户的登录密码。
## 3. 组件结构
```vue
{{ user.name?.[0] }}
{{ user.name }}
{{ user.role }}
保存更改
确认修改
```
## 4. 数据结构
```typescript
// 用户信息 (来自 Store)
interface UserProfile {
id: number;
username: string;
name: string;
email: string;
role: string;
avatarUrl?: string;
}
// 修改密码表单
interface PasswordForm {
oldPassword: string;
newPassword: string;
confirmPassword: string;
}
```
## 5. 状态管理
```typescript
// 组件内状态
const activeTab = ref('profile');
const profileForm = ref>({});
const passwordForm = ref({ oldPassword: '', newPassword: '', confirmPassword: '' });
const profileLoading = ref(false);
const passwordLoading = ref(false);
const profileFormRef = ref();
const passwordFormRef = ref();
// 全局状态 (Pinia Store)
const authStore = useAuthStore();
const { user } = storeToRefs(authStore);
// 当 user 数据从 store 加载后,填充表单
watch(user, (currentUser) => {
if (currentUser) {
profileForm.value = { ...currentUser };
}
}, { immediate: true });
```
## 6. 交互逻辑
### 6.1 更新个人资料
```typescript
const updateProfile = async () => {
await profileFormRef.value?.validate(async (valid) => {
if (!valid) return;
profileLoading.value = true;
try {
await authStore.updateProfile({
name: profileForm.value.name,
email: profileForm.value.email,
});
ElMessage.success('个人资料更新成功');
} finally {
profileLoading.value = false;
}
});
};
```
### 6.2 修改密码
```typescript
const changePassword = async () => {
await passwordFormRef.value?.validate(async (valid) => {
if (!valid) return;
passwordLoading.value = true;
try {
await authStore.changePassword(passwordForm.value);
ElMessage.success('密码修改成功,请重新登录');
// 密码修改成功后通常需要用户重新登录
authStore.logout();
router.push('/auth/login');
} catch (error) {
ElMessage.error(error.response?.data?.message || '密码修改失败');
} finally {
passwordLoading.value = false;
}
});
};
// 自定义密码验证规则
const validateConfirmPassword = (rule: any, value: any, callback: any) => {
if (value !== passwordForm.value.newPassword) {
callback(new Error('两次输入的新密码不一致'));
} else {
callback();
}
};
const passwordRules = {
// ... oldPassword 和 newPassword 的必填和长度规则
confirmPassword: [
{ required: true, message: '请再次输入新密码', trigger: 'blur' },
{ validator: validateConfirmPassword, trigger: 'blur' }
]
};
```
## 7. API 调用
```typescript
// api/me.ts
export const meApi = {
getProfile: () => apiClient.get('/me'),
updateProfile: (data: Partial) => apiClient.put('/me', data),
changePassword: (data: PasswordForm) => apiClient.post('/me/change-password', data),
};
// stores/auth.ts
export const useAuthStore = defineStore('auth', {
// ... state, getters
actions: {
async fetchUserProfile() {
// (在App启动或登录后调用)
const { data } = await meApi.getProfile();
this.user = data;
},
async updateProfile(data) {
const { data: updatedUser } = await meApi.updateProfile(data);
this.user = { ...this.user, ...updatedUser };
},
async changePassword(data) {
await meApi.changePassword(data);
}
}
});
```
## 8. 样式设计
```scss
.profile-page {
padding: 24px;
.page-container {
margin-top: 24px;
}
.user-card {
text-align: center;
.user-avatar {
margin-bottom: 20px;
}
.user-info h2 {
font-size: 20px;
margin-bottom: 8px;
}
.user-info p {
color: #909399;
}
}
}
```
## 9. 测试用例
1. **集成测试**:
- 测试页面是否能正确显示当前用户的个人信息。
- 测试更新个人资料功能是否成功,并验证 store 中的用户信息是否同步更新。
- 测试修改密码的成功流程,验证是否提示成功并跳转到登录页。
- 测试修改密码的失败流程(如旧密码错误),验证是否显示正确的错误提示。
- 测试所有表单验证规则是否生效(如邮箱格式、密码长度、两次密码一致性等)。