Przeglądaj źródła

feat(mini): 使用 usePullDownRefresh 修复下拉刷新回位问题 (Story 13.27)

将 ScrollView refresher (局部刷新) 改为 Taro usePullDownRefresh (页面级刷新),
解决小程序中下拉刷新后页面位置无法自动回到顶部的问题。

变更范围:
- 首页 (Dashboard.tsx)
- 人才列表页 (TalentManagement.tsx)
- 订单列表页 (OrderList.tsx)

代码审查修复:
- console.log/debug 规范化
- 纯函数移到组件外部 (性能优化)
- 删除未使用代码

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 1 tydzień temu
rodzic
commit
840ff6b756

+ 17 - 1
_bmad-output/implementation-artifacts/13-27-fix-pulldown-refresh-rebound.md

@@ -1,6 +1,6 @@
 # Story 13.27: 修复小程序列表页面下拉刷新回位问题
 # Story 13.27: 修复小程序列表页面下拉刷新回位问题
 
 
-Status: review
+Status: done
 
 
 <!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
 <!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
 
 
@@ -231,6 +231,22 @@ None
 - 三个小程序 UI 包类型检查全部通过
 - 三个小程序 UI 包类型检查全部通过
 - 无限滚动功能保留 (onScrollToLower 属性保留)
 - 无限滚动功能保留 (onScrollToLower 属性保留)
 
 
+---
+
+**代码审查修复 (2026-01-19):**
+
+**HIGH 优先级修复:**
+1. OrderList.tsx - 将 3 处 `console.log` 改为 `console.debug` (行 313, 330, 348)
+2. OrderList.tsx - 将 `console.error` 改为 `console.debug` (行 306)
+3. TalentManagement.tsx - 将 `console.error` 改为 `console.debug` (行 122)
+
+**MEDIUM 优先级修复:**
+4. OrderList.tsx - 将纯函数 `getStatusLabel`、`getStatusClass`、`getEnterpriseUserInfo` 移到组件外部以提高性能
+5. Dashboard.tsx - 删除未使用的注释代码 (行 168)
+
+**类型检查验证:**
+- 所有修改的 UI 包类型检查通过
+
 ### File List
 ### File List
 
 
 **修改的文件:**
 **修改的文件:**

+ 1 - 1
_bmad-output/implementation-artifacts/sprint-status.yaml

@@ -261,7 +261,7 @@ development_status:
   13-24-statistics-methods-unify-workstatus: done   # 统一统计方法使用 orderPerson.workStatus(2026-01-18 新增)- 修复 6 个统计方法(残疾类型、性别、年龄、户籍、薪资分布、在职率)使用错误的统计口径,统一使用 order_person.work_status='working' ✅ 完成 (2026-01-18) - 所有方法已重构,类型检查和构建通过
   13-24-statistics-methods-unify-workstatus: done   # 统一统计方法使用 orderPerson.workStatus(2026-01-18 新增)- 修复 6 个统计方法(残疾类型、性别、年龄、户籍、薪资分布、在职率)使用错误的统计口径,统一使用 order_person.work_status='working' ✅ 完成 (2026-01-18) - 所有方法已重构,类型检查和构建通过
   13-25-jobstatus-distribution-refactor: done   # 重构 getJobStatusDistribution 使用 orderPerson.workStatus(2026-01-18 新增)- 修复在职状态分布图使用旧字段 jobStatus(二元状态)改为使用 work_status 枚举 ✅ 完成 (2026-01-18) - 从二元状态改为多状态枚举,支持 4 种工作状态
   13-25-jobstatus-distribution-refactor: done   # 重构 getJobStatusDistribution 使用 orderPerson.workStatus(2026-01-18 新增)- 修复在职状态分布图使用旧字段 jobStatus(二元状态)改为使用 work_status 枚举 ✅ 完成 (2026-01-18) - 从二元状态改为多状态枚举,支持 4 种工作状态
   13-26-statistics-data-consistency-validation: ready-for-dev   # 统计模块数据一致性验证与回归测试(2026-01-18 新增)- 全面验证所有统计方法使用统一统计口径,确保各分布图数据一致、与首页仪表板一致
   13-26-statistics-data-consistency-validation: ready-for-dev   # 统计模块数据一致性验证与回归测试(2026-01-18 新增)- 全面验证所有统计方法使用统一统计口径,确保各分布图数据一致、与首页仪表板一致
-  13-27-fix-pulldown-refresh-rebound: review   # 修复小程序列表页面下拉刷新回位问题(2026-01-19 新增)- 将 ScrollView refresher (局部刷新) 改为使用 Taro 的 usePullDownRefresh (页面级刷新),修复首页、人才列表页、订单列表页的下拉刷新回位问题
+  13-27-fix-pulldown-refresh-rebound: done   # 修复小程序列表页面下拉刷新回位问题(2026-01-19 新增)- 将 ScrollView refresher (局部刷新) 改为使用 Taro 的 usePullDownRefresh (页面级刷新),修复首页、人才列表页、订单列表页的下拉刷新回位问题
   13-28-work-status-labels-unify: done   # 统一工作状态显示名称(2026-01-19 新增)- 统一管理后台与企业小程序的工作状态显示名称(待入职、在职、已离职、未就业)✅ 完成 (2026-01-19) - 修改 4 个文件,类型检查通过,E2E 测试验证通过
   13-28-work-status-labels-unify: done   # 统一工作状态显示名称(2026-01-19 新增)- 统一管理后台与企业小程序的工作状态显示名称(待入职、在职、已离职、未就业)✅ 完成 (2026-01-19) - 修改 4 个文件,类型检查通过,E2E 测试验证通过
   epic-13-retrospective: optional
   epic-13-retrospective: optional
 
 

+ 0 - 2
mini-ui-packages/yongren-dashboard-ui/src/pages/Dashboard/Dashboard.tsx

@@ -165,8 +165,6 @@ const Dashboard: React.FC = () => {
     })
     })
   }
   }
 
 
-  // const isLoading = overviewLoading || allocationsLoading // 未使用
-
   return (
   return (
     <YongrenTabBarLayout activeKey="dashboard">
     <YongrenTabBarLayout activeKey="dashboard">
       <ScrollView
       <ScrollView

+ 54 - 54
mini-ui-packages/yongren-order-management-ui/src/pages/OrderList/OrderList.tsx

@@ -157,6 +157,57 @@ const OrderCard: React.FC<OrderCardProps> = ({ order, onViewDetail }) => {
   )
   )
 }
 }
 
 
+// 状态标签和样式辅助函数(移到组件外部以提高性能)
+const getStatusLabel = (status: string): string => {
+  switch (status) {
+    case 'draft': return '草稿'
+    case 'confirmed': return '已确认'
+    case 'in_progress': return '进行中'
+    case 'completed': return '已完成'
+    case 'cancelled': return '已取消'
+    default: return status
+  }
+}
+
+const getStatusClass = (status: string): string => {
+  switch (status) {
+    case 'draft': return 'bg-gray-100 text-gray-800'
+    case 'confirmed': return 'bg-blue-100 text-blue-800'
+    case 'in_progress': return 'bg-green-100 text-green-800'
+    case 'completed': return 'bg-purple-100 text-purple-800'
+    case 'cancelled': return 'bg-red-100 text-red-800'
+    default: return 'bg-gray-100 text-gray-800'
+  }
+}
+
+// 获取企业用户信息的辅助函数(移到组件外部以提高性能)
+const getEnterpriseUserInfo = () => {
+  try {
+    const userInfoStr = Taro.getStorageSync('enterpriseUserInfo')
+    if (!userInfoStr) return null
+
+    // 尝试解析JSON字符串
+    let userInfo = userInfoStr
+    if (typeof userInfoStr === 'string') {
+      userInfo = JSON.parse(userInfoStr)
+    }
+
+    // 处理双重编码情况:{"data": "{\"id\":2,...}"}
+    if (userInfo && typeof userInfo === 'object' && userInfo.data) {
+      if (typeof userInfo.data === 'string') {
+        userInfo = JSON.parse(userInfo.data)
+      } else {
+        userInfo = userInfo.data
+      }
+    }
+
+    return userInfo || null
+  } catch (error) {
+    console.debug('获取企业用户信息失败:', error)
+    return null
+  }
+}
+
 const OrderList: React.FC = () => {
 const OrderList: React.FC = () => {
   const [activeStatus, setActiveStatus] = useState<OrderStatus>('all')
   const [activeStatus, setActiveStatus] = useState<OrderStatus>('all')
   const [searchKeyword, setSearchKeyword] = useState('')
   const [searchKeyword, setSearchKeyword] = useState('')
@@ -257,60 +308,9 @@ const OrderList: React.FC = () => {
     { key: 'cancelled', label: '已取消', activeClass: 'bg-gray-100 text-gray-800', inactiveClass: 'bg-gray-100 text-gray-800' },
     { key: 'cancelled', label: '已取消', activeClass: 'bg-gray-100 text-gray-800', inactiveClass: 'bg-gray-100 text-gray-800' },
   ]
   ]
 
 
-  // 状态标签和样式辅助函数
-  const getStatusLabel = (status: string) => {
-    switch (status) {
-      case 'draft': return '草稿'
-      case 'confirmed': return '已确认'
-      case 'in_progress': return '进行中'
-      case 'completed': return '已完成'
-      case 'cancelled': return '已取消'
-      default: return status
-    }
-  }
-
-  const getStatusClass = (status: string) => {
-    switch (status) {
-      case 'draft': return 'bg-gray-100 text-gray-800'
-      case 'confirmed': return 'bg-blue-100 text-blue-800'
-      case 'in_progress': return 'bg-green-100 text-green-800'
-      case 'completed': return 'bg-purple-100 text-purple-800'
-      case 'cancelled': return 'bg-red-100 text-red-800'
-      default: return 'bg-gray-100 text-gray-800'
-    }
-  }
-
-  // 获取企业用户信息
-  const getEnterpriseUserInfo = () => {
-    try {
-      const userInfoStr = Taro.getStorageSync('enterpriseUserInfo')
-      if (!userInfoStr) return null
-
-      // 尝试解析JSON字符串
-      let userInfo = userInfoStr
-      if (typeof userInfoStr === 'string') {
-        userInfo = JSON.parse(userInfoStr)
-      }
-
-      // 处理双重编码情况:{"data": "{\"id\":2,...}"}
-      if (userInfo && typeof userInfo === 'object' && userInfo.data) {
-        if (typeof userInfo.data === 'string') {
-          userInfo = JSON.parse(userInfo.data)
-        } else {
-          userInfo = userInfo.data
-        }
-      }
-
-      return userInfo || null
-    } catch (error) {
-      console.error('获取企业用户信息失败:', error)
-      return null
-    }
-  }
-
   // 页面显示时自动刷新(从详情页返回时触发)
   // 页面显示时自动刷新(从详情页返回时触发)
   useDidShow(() => {
   useDidShow(() => {
-    console.log('订单列表页显示,自动刷新数据')
+    console.debug('订单列表页显示,自动刷新数据')
     // 使用 invalidateQueries 触发重新获取数据
     // 使用 invalidateQueries 触发重新获取数据
     // refetch() 会使用缓存数据,而 invalidateQueries 会强制重新获取
     // refetch() 会使用缓存数据,而 invalidateQueries 会强制重新获取
     refetch()
     refetch()
@@ -327,7 +327,7 @@ const OrderList: React.FC = () => {
 
 
 
 
   const handleSearch = () => {
   const handleSearch = () => {
-    console.log('搜索关键词:', searchKeyword)
+    console.debug('搜索关键词:', searchKeyword)
     // 使用refetch重新获取数据,queryKey变化会自动触发重新查询
     // 使用refetch重新获取数据,queryKey变化会自动触发重新查询
     refetch()
     refetch()
   }
   }
@@ -345,7 +345,7 @@ const OrderList: React.FC = () => {
   }
   }
 
 
   const handleViewDetail = (orderId: number) => {
   const handleViewDetail = (orderId: number) => {
-    console.log('查看订单详情:', orderId)
+    console.debug('查看订单详情:', orderId)
     // 跳转到订单详情页
     // 跳转到订单详情页
     Taro.navigateTo({
     Taro.navigateTo({
       url: `/pages/yongren/order/detail/index?id=${orderId}`
       url: `/pages/yongren/order/detail/index?id=${orderId}`

+ 1 - 1
mini-ui-packages/yongren-talent-management-ui/src/pages/TalentManagement/TalentManagement.tsx

@@ -119,7 +119,7 @@ const TalentManagement: React.FC<TalentManagementProps> = () => {
     try {
     try {
       await refetch()
       await refetch()
     } catch (error) {
     } catch (error) {
-      console.error('刷新失败:', error)
+      console.debug('刷新失败:', error)
     } finally {
     } finally {
       Taro.stopPullDownRefresh()
       Taro.stopPullDownRefresh()
     }
     }