Просмотр исходного кода

✨ feat(profile): 优化个人资料显示功能

- 实现用户无头像时显示默认头像(/images/default_avatar.jpg)
- 统一将用户名显示为"普通用户"
- 验证头像上传功能在默认头像状态下正常工作
- 添加默认头像和用户名显示测试场景

📝 docs(story): 更新个人资料显示优化故事状态

- 将故事状态从"Draft"更新为"Ready for Review"
- 标记所有任务和完成笔记列表为已完成
- 更新文件列表,标记已修改和更新的文件
yourname 3 месяцев назад
Родитель
Сommit
fda69275d5
3 измененных файлов с 118 добавлено и 31 удалено
  1. 29 28
      docs/stories/007.002.story.md
  2. 2 2
      mini/src/pages/profile/index.tsx
  3. 87 1
      mini/tests/pages/profile.test.tsx

+ 29 - 28
docs/stories/007.002.story.md

@@ -1,7 +1,7 @@
 # Story 007.002: 个人资料显示优化
 
 ## Status
-Draft
+Ready for Review
 
 ## Story
 **As a** 小程序用户,
@@ -15,23 +15,23 @@ Draft
 4. 验证个人资料显示功能正常工作
 
 ## Tasks / Subtasks
-- [ ] 修改个人中心页面头像显示逻辑 (AC: 1)
-  - [ ] 实现条件渲染:用户无头像时显示默认头像
-  - [ ] 确保默认头像路径正确(mini/images/default_avatar.jpg)
-  - [ ] 验证头像显示在各种用户状态下的正确性
-- [ ] 修改个人中心页面用户名显示逻辑 (AC: 2)
-  - [ ] 实现用户名统一显示为"普通用户"
-  - [ ] 确保现有用户名显示逻辑被正确替换
-  - [ ] 验证用户名显示在各种用户状态下的正确性
-- [ ] 验证现有头像上传功能保持完整 (AC: 3)
-  - [ ] 测试头像上传功能在默认头像显示状态下正常工作
-  - [ ] 确保上传后的头像正确替换默认头像
-  - [ ] 验证上传错误处理机制
-- [ ] 编写和更新相关测试 (AC: 4)
-  - [ ] 更新个人中心页面测试文件
-  - [ ] 添加默认头像和用户名显示测试场景
-  - [ ] 验证头像上传功能测试
-  - [ ] 确保现有功能无回归
+- [x] 修改个人中心页面头像显示逻辑 (AC: 1)
+  - [x] 实现条件渲染:用户无头像时显示默认头像
+  - [x] 确保默认头像路径正确(mini/images/default_avatar.jpg)
+  - [x] 验证头像显示在各种用户状态下的正确性
+- [x] 修改个人中心页面用户名显示逻辑 (AC: 2)
+  - [x] 实现用户名统一显示为"普通用户"
+  - [x] 确保现有用户名显示逻辑被正确替换
+  - [x] 验证用户名显示在各种用户状态下的正确性
+- [x] 验证现有头像上传功能保持完整 (AC: 3)
+  - [x] 测试头像上传功能在默认头像显示状态下正常工作
+  - [x] 确保上传后的头像正确替换默认头像
+  - [x] 验证上传错误处理机制
+- [x] 编写和更新相关测试 (AC: 4)
+  - [x] 更新个人中心页面测试文件
+  - [x] 添加默认头像和用户名显示测试场景
+  - [x] 验证头像上传功能测试
+  - [x] 确保现有功能无回归
 
 ## Dev Notes
 
@@ -157,19 +157,20 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
 - Claude Sonnet 4.5
 
 ### Completion Notes List
-- [ ] 故事需求分析和范围定义
-- [ ] 技术方案设计
-- [ ] 风险评估和兼容性检查
-- [ ] 修改个人中心页面头像显示逻辑
-- [ ] 修改个人中心页面用户名显示逻辑
-- [ ] 验证现有头像上传功能
-- [ ] 更新相关测试文件
-- [ ] 验证现有功能无回归
+- [x] 故事需求分析和范围定义
+- [x] 技术方案设计
+- [x] 风险评估和兼容性检查
+- [x] 修改个人中心页面头像显示逻辑
+- [x] 修改个人中心页面用户名显示逻辑
+- [x] 验证现有头像上传功能
+- [x] 更新相关测试文件
+- [x] 验证现有功能无回归
 
 ### File List
 - [docs/stories/007.002.story.md](docs/stories/007.002.story.md) - 用户故事文档
-- [mini/src/pages/profile/index.tsx](mini/src/pages/profile/index.tsx) - 个人中心页面
-- [mini/tests/pages/profile.test.tsx](mini/tests/pages/profile.test.tsx) - 个人中心页面测试文件
+- [mini/src/pages/profile/index.tsx](mini/src/pages/profile/index.tsx) - 个人中心页面(已修改)
+- [mini/tests/pages/profile.test.tsx](mini/tests/pages/profile.test.tsx) - 个人中心页面测试文件(已更新)
+- [mini/images/default_avatar.jpg](mini/images/default_avatar.jpg) - 默认头像文件
 
 ### Debug Log References
 - 待开发代理填充

+ 2 - 2
mini/src/pages/profile/index.tsx

@@ -228,7 +228,7 @@ const ProfilePage: React.FC = () => {
           <View className="flex items-center">
             <View className="relative mr-[32rpx]">
               <AvatarUpload
-                currentAvatar={userProfile.avatarFile?.fullUrl}
+                currentAvatar={userProfile.avatarFile?.fullUrl || '/images/default_avatar.jpg'}
                 onUploadSuccess={handleAvatarUpload}
                 onUploadError={handleAvatarUploadError}
                 size={100}
@@ -238,7 +238,7 @@ const ProfilePage: React.FC = () => {
             </View>
 
             <View className="flex-1">
-              <Text className="text-[32rpx] font-bold text-white">{userProfile.username}</Text>
+              <Text className="text-[32rpx] font-bold text-white">普通用户</Text>
               <Text className="text-[22rpx] opacity-80 mt-1">
                 ID: {String(userProfile.id).slice(-4)}
               </Text>

+ 87 - 1
mini/tests/pages/profile.test.tsx

@@ -175,7 +175,7 @@ describe('个人中心页面测试', () => {
     expect(screen.getByText('个人中心')).toBeInTheDocument()
 
     // 检查用户信息
-    expect(screen.getByText('测试用户')).toBeInTheDocument()
+    expect(screen.getByText('普通用户')).toBeInTheDocument()
     expect(screen.getByText('ID: 1')).toBeInTheDocument()
 
     // 检查功能菜单
@@ -449,4 +449,90 @@ describe('个人中心页面测试', () => {
     expect(navbar).toHaveAttribute('data-text-color', 'text-white')
     expect(navbar).toHaveAttribute('data-border', 'false')
   })
+
+  test('应该显示默认头像当用户无头像时', () => {
+    // 模拟用户无头像的情况
+    const mockUseAuth = jest.requireMock('@/utils/auth').useAuth
+    mockUseAuth.mockImplementation(() => ({
+      user: {
+        ...mockUser,
+        avatarFile: null
+      },
+      logout: mockLogout,
+      isLoading: false,
+      updateUser: mockUpdateUser
+    }))
+
+    render(
+      <Wrapper>
+        <ProfilePage />
+      </Wrapper>
+    )
+
+    // 检查默认头像路径
+    const avatarUpload = screen.getByTestId('avatar-upload')
+    expect(avatarUpload).toHaveAttribute('data-current-avatar', '/images/default_avatar.jpg')
+  })
+
+  test('应该显示默认用户名', () => {
+    // 模拟用户无用户名的情况
+    const mockUseAuth = jest.requireMock('@/utils/auth').useAuth
+    mockUseAuth.mockImplementation(() => ({
+      user: {
+        ...mockUser,
+        username: ''
+      },
+      logout: mockLogout,
+      isLoading: false,
+      updateUser: mockUpdateUser
+    }))
+
+    render(
+      <Wrapper>
+        <ProfilePage />
+      </Wrapper>
+    )
+
+    // 检查用户名显示为"普通用户"
+    expect(screen.getByText('普通用户')).toBeInTheDocument()
+  })
+
+  test('头像上传功能应该在默认头像状态下正常工作', async () => {
+    // 模拟用户无头像的情况
+    const mockUseAuth = jest.requireMock('@/utils/auth').useAuth
+    mockUseAuth.mockImplementation(() => ({
+      user: {
+        ...mockUser,
+        avatarFile: null
+      },
+      logout: mockLogout,
+      isLoading: false,
+      updateUser: mockUpdateUser
+    }))
+
+    render(
+      <Wrapper>
+        <ProfilePage />
+      </Wrapper>
+    )
+
+    // 点击头像上传成功按钮
+    const uploadButton = screen.getByTestId('avatar-upload-button')
+    fireEvent.click(uploadButton)
+
+    // 检查上传成功处理
+    await waitFor(() => {
+      expect(taroMock.showLoading).toHaveBeenCalledWith({ title: '更新头像...' })
+      expect(taroMock.hideLoading).toHaveBeenCalled()
+      expect(taroMock.showToast).toHaveBeenCalledWith({
+        title: '头像更新成功',
+        icon: 'success'
+      })
+      expect(mockUpdateUser).toHaveBeenCalledWith({
+        ...mockUser,
+        avatarFile: null,
+        avatarFileId: 'test-file-id'
+      })
+    })
+  })
 })