# 个人中心页面设计文档 ## 1. 页面概述 个人中心页面允许当前登录的用户查看和修改自己的个人信息,以及更改密码。此页面旨在提供一个简单、安全的界面来管理个人账户资料。 ## 2. 页面布局 ![个人中心页面布局示意图](https://placeholder-for-profile-page-mockup.png) ### 2.1 布局结构 页面通常采用多标签页(Tabs)布局,将不同功能的表单分开,以保持界面整洁。 - **左侧**: 用户头像和基本信息展示。 - **右侧**: 包含两个标签页: - **基本资料**: 用于修改用户名、姓名、邮箱等信息。 - **修改密码**: 用于更改当前用户的登录密码。 ## 3. 组件结构 ```vue ``` ## 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 中的用户信息是否同步更新。 - 测试修改密码的成功流程,验证是否提示成功并跳转到登录页。 - 测试修改密码的失败流程(如旧密码错误),验证是否显示正确的错误提示。 - 测试所有表单验证规则是否生效(如邮箱格式、密码长度、两次密码一致性等)。