# Story 13.12: 数据统计页测试与功能修复 Status: ready-for-dev ## 元数据 - Epic: Epic 13 - 跨端数据同步测试 - 状态: ready-for-dev - 优先级: P1 - 故事点: 8 ## 用户故事 作为企业管理员,我在企业小程序的数据统计页能查看各种统计数据,包括在职人数、平均薪资、在职率、新增人数等,并且可以通过年份和月份筛选器查看不同时期的统计数据。统计数据应该从后台 API 动态获取,而非硬编码。 ## 验收标准 ### AC 1: 数据统计页可访问性和 UI 验证 **Given** 用户已登录企业小程序 **When** 用户点击底部导航的"数据"tab **Then** 应能成功导航到数据统计页 **And** 页面应显示筛选器区域(年份选择器、月份选择器) **And** 页面应显示 4 个统计卡片(在职人数、平均薪资、在职率、新增人数) **And** 页面应显示 6 个统计图表(残疾类型分布、性别分布、年龄分布、户籍省份分布、在职状态统计、薪资分布) ### AC 2: 筛选器功能验证(修复后) **Given** 用户在数据统计页 **When** 用户选择年份(如 2026) **And** 用户选择月份(如 1月) **Then** 页面应重新获取该年月的统计数据 **And** 统计卡片应显示更新后的数据 **And** 统计图表应显示更新后的数据 ### AC 3: 统计卡片数据验证(修复后) **Given** 用户在数据统计页 **When** 页面加载完成 **Then** 统计卡片应显示从 API 获取的真实数据 **And** "在职人数"应显示当前在职人员总数 **And** "平均薪资"应显示所有在职人员的平均薪资 **And** "在职率"应显示在职人数占总人数的百分比 **And** "新增人数"应显示本月新增的人员数 **And** 每个统计卡片应显示与上月对比的数据 ### AC 4: 统计图表数据验证(修复后) **Given** 用户在数据统计页 **When** 页面加载完成 **Then** "残疾类型分布"图表应显示各类残疾的人数分布 **And** "性别分布"图表应显示男女人数分布 **And** "年龄分布"图表应显示各年龄段人数分布 **And** "户籍省份分布"图表应显示各省份人数分布 **And** "在职状态统计"图表应显示各种工作状态的人数分布 **And** "薪资分布"图表应显示各薪资区间的人数分布 ### AC 5: API 支持年月查询参数(修复) **Given** 数据统计 API 端点已实现 **When** 前端请求统计数据时传递 year 和 month 参数 **Then** API 应返回该年月的统计数据 **And** 如果未传递参数,应返回当前年月的统计数据 ## 任务 ### 任务 0: Bug 修复 - 统计卡片数据硬编码问题 - [ ] 修改 `yongren-statistics-ui` 包中的统计卡片组件 - [ ] 将硬编码的数据改为从 API 获取 - [ ] 确保 API 调用正确处理响应数据 ### 任务 1: Bug 修复 - API 支持年月查询参数 - [ ] 修改 `statistics-module` 中的 API 路由 - [ ] 为所有统计 API 端点添加 year 和 month 查询参数支持 - `/api/statistics/employment-count` - `/api/statistics/average-salary` - `/api/statistics/employment-rate` - `/api/statistics/new-count` - `/api/statistics/disability-type-distribution` - `/api/statistics/gender-distribution` - [ ] 更新 API schema 以支持可选的 year 和 month 参数 - [ ] 如果未传递参数,默认使用当前年月 ### 任务 2: Bug 修复 - 筛选器连接到数据刷新逻辑 - [ ] 修改筛选器组件,监听年份和月份的变化 - [ ] 当筛选器值变化时,触发数据重新获取 - [ ] 传递选中的年月参数到 API 请求 - [ ] 显示加载状态,直到数据返回 ### 任务 3: 准备 Page Object - [ ] 在 `enterprise-mini.page.ts` 中添加数据统计页相关方法: - `navigateToStatisticsPage()` - `selectYear(year: number)` - `selectMonth(month: number)` - `getStatisticsCards()` - `expectStatisticsCardData(cardName: string, expected: any)` - `getStatisticsCharts()` - `expectChartData(chartName: string, expected: any)` ### 任务 4: 创建 E2E 测试文件 - [ ] 创建 `web/tests/e2e/specs/cross-platform/statistics-page-validation.spec.ts` ### 任务 5: 实现测试用例 - AC1 可访问性和 UI 验证 - [ ] 测试:验证数据统计页可以正常访问 - [ ] 测试:验证筛选器 UI 元素存在 - [ ] 测试:验证 4 个统计卡片显示 - [ ] 测试:验证 6 个统计图表显示 ### 任务 6: 实现测试用例 - AC2 筛选器功能验证(修复后) - [ ] 测试:选择年份后数据更新 - [ ] 测试:选择月份后数据更新 - [ ] 测试:筛选器变化后显示加载状态 ### 任务 7: 实现测试用例 - AC3 统计卡片数据验证(修复后) - [ ] 测试:验证在职人数数据正确性 - [ ] 测试:验证平均薪资数据正确性 - [ ] 测试:验证在职率数据正确性 - [ ] 测试:验证新增人数数据正确性 - [ ] 测试:验证月度对比数据显示 ### 任务 8: 实现测试用例 - AC4 统计图表数据验证(修复后) - [ ] 测试:验证残疾类型分布图表数据 - [ ] 测试:验证性别分布图表数据 - [ ] 测试:验证年龄分布图表数据 - [ ] 测试:验证户籍省份分布图表数据 - [ ] 测试:验证在职状态统计图表数据 - [ ] 测试:验证薪资分布图表数据 ### 任务 9: 实现测试用例 - AC5 API 年月参数验证 - [ ] 测试:验证 API 不传参数时返回当前年月数据 - [ ] 测试:验证 API 传递年月参数时返回对应数据 - [ ] 测试:验证边界情况(无效年月参数) ### 任务 10: 集成测试与稳定性验证 - [ ] 测试:完整的数据统计页用户流程 - [ ] 测试:快速切换年月的边界情况 - [ ] 测试:无数据时的显示状态 - [ ] 稳定性验证:连续运行 10 次,100% 通过 ## Dev Notes ### Epic 13 背景和依赖 **Epic 13: 跨端数据同步测试 (Epic E)** - **目标**: 验证后台操作后小程序端的数据同步,覆盖完整的业务流程 - **业务分组**: Epic E(跨端数据同步测试) - **背景**: 真实用户旅程跨越管理后台和小程序,需要验证数据同步的正确性和时效性 - **依赖**: - Epic 10: ✅ 已完成(订单管理 E2E 测试) - Epic 12: 🔄 进行中(小程序登录测试) ### 数据统计页 URL `/mini/#/mini/pages/yongren/statistics/index` ### 数据统计页字段清单 #### 筛选功能 - 年份选择器:2022-2026 - 月份选择器:1-12月 #### 统计卡片(4个) - 在职人数:count_employed,带月度对比 - 平均薪资:avg_salary,带月度对比 - 在职率:employment_rate,带月度对比 - 新增人数:count_new_month,带月度对比 #### 统计图表(6个) - 残疾类型分布:disabilityType(柱状图) - 性别分布:gender(柱状图) - 年龄分布:age(饼图) - 户籍省份分布:province(条形图) - 在职状态统计:employmentStatus(环形图) - 薪资分布:salary(条形图) ### 相关文件 - 页面源码: `mini/src/pages/yongren/statistics/index.tsx` - 统计UI包: `mini-ui-packages/yongren-statistics-ui/` - API 路由: `allin-packages/statistics-module/src/routes/statistics.routes.ts` - API Schema: `allin-packages/statistics-module/src/schemas/statistics.schema.ts` ### 已知问题 1. **统计卡片数据硬编码** - 当前状态:数据是硬编码在组件中 - 影响:显示的数据不是真实的统计数据 - 修复方案:调用 API 获取真实数据 2. **API 不支持年月查询参数** - 当前状态:API 端点不接受 year 和 month 参数 - 影响:无法按年月筛选统计数据 - 修复方案:为所有统计 API 添加 year 和 month 查询参数支持 3. **筛选器未连接到数据刷新逻辑** - 当前状态:切换年份和月份不会触发数据刷新 - 影响:筛选器功能无效 - 修复方案:监听筛选器变化并触发数据重新获取 ### 测试开发流程(Playwright MCP 持续验证) 本 Story 采用 **Playwright MCP 持续验证**的测试开发流程: 1. **即时验证**: 在开发过程中立即使用 Playwright MCP 验证,不等到专门的 E2E Story 2. **持续反馈**: 每完成一个功能模块立即验证,快速发现问题 3. **减少返工**: 早期发现问题可以减少后期返工成本 **任务流程**: ``` 任务 0-2 (Bug 修复) → 任务 3 (Page Object) → 任务 4-9 (E2E 测试) → 任务 10 (稳定性验证) ``` ### Page Object 设计 **EnterpriseMiniPage 扩展方法**: ```typescript // 导航到数据统计页 async navigateToStatisticsPage(): Promise // 筛选器操作 async selectYear(year: number): Promise async selectMonth(month: number): Promise // 获取统计卡片数据 async getStatisticsCards(): Promise async expectStatisticsCardData(cardName: string, expected: any): Promise // 获取统计图表数据 async getStatisticsCharts(): Promise async expectChartData(chartName: string, expected: any): Promise ``` ### E2E 测试用例设计 **AC1: 可访问性和 UI 验证** ```typescript test('应该能够访问数据统计页', async ({ enterpriseMiniPage }) => { await enterpriseMiniPage.navigateToStatisticsPage(); await expect(enterpriseMiniPage.page).toHaveURL(/\/statistics/); }); test('应该显示所有统计卡片和图表', async ({ enterpriseMiniPage }) => { await enterpriseMiniPage.navigateToStatisticsPage(); // 验证 4 个统计卡片 await expect(enterpriseMiniPage.page.getByTestId('card-count-employed')).toBeVisible(); await expect(enterpriseMiniPage.page.getByTestId('card-avg-salary')).toBeVisible(); await expect(enterpriseMiniPage.page.getByTestId('card-employment-rate')).toBeVisible(); await expect(enterpriseMiniPage.page.getByTestId('card-count-new-month')).toBeVisible(); // 验证 6 个统计图表 await expect(enterpriseMiniPage.page.getByTestId('chart-disability-type')).toBeVisible(); await expect(enterpriseMiniPage.page.getByTestId('chart-gender')).toBeVisible(); await expect(enterpriseMiniPage.page.getByTestId('chart-age')).toBeVisible(); await expect(enterpriseMiniPage.page.getByTestId('chart-province')).toBeVisible(); await expect(enterpriseMiniPage.page.getByTestId('chart-employment-status')).toBeVisible(); await expect(enterpriseMiniPage.page.getByTestId('chart-salary')).toBeVisible(); }); ``` **AC2: 筛选器功能验证** ```typescript test('选择年份后应更新统计数据', async ({ enterpriseMiniPage }) => { await enterpriseMiniPage.navigateToStatisticsPage(); await enterpriseMiniPage.selectYear(2025); // 验证数据已更新 const cards = await enterpriseMiniPage.getStatisticsCards(); expect(cards).toHaveLength(4); }); test('选择月份后应更新统计数据', async ({ enterpriseMiniPage }) => { await enterpriseMiniPage.navigateToStatisticsPage(); await enterpriseMiniPage.selectMonth(12); // 验证数据已更新 const cards = await enterpriseMiniPage.getStatisticsCards(); expect(cards).toHaveLength(4); }); ``` ### API 修复方案 **添加年月查询参数支持**: ```typescript // 更新 API Schema export const statisticsQuerySchema = z.object({ year: z.coerce.number().min(2020).max(2030).optional(), month: z.coerce.number().min(1).max(12).optional(), }); // 更新路由处理器 app.get('/api/statistics/employment-count', async (c) => { const { year, month } = c.req.query(); // 如果未传递参数,使用当前年月 const queryYear = year || new Date().getFullYear(); const queryMonth = month || new Date().getMonth() + 1; // ... 查询逻辑 }); ``` ### 前端修复方案 **连接筛选器到数据刷新**: ```typescript // 监听筛选器变化 useEffect(() => { if (selectedYear && selectedMonth) { fetchStatisticsData(selectedYear, selectedMonth); } }, [selectedYear, selectedMonth]); // 获取统计数据 const fetchStatisticsData = async (year: number, month: number) => { setLoading(true); try { const data = await api.getStatistics({ year, month }); setStatisticsData(data); } catch (error) { console.error('获取统计数据失败:', error); } finally { setLoading(false); } }; ``` ### 参考文档 **架构文档**: - `_bmad-output/planning-artifacts/epics.md#Epic 13` - `_bmad-output/project-context.md` - `docs/standards/e2e-radix-testing.md` **相关 Story 文档**: - `13-1-order-create-sync.md` (跨端测试模式参考) - `12-4-enterprise-mini-page-object.md` (企业小程序 Page Object) - `12-5-enterprise-mini-login.md` (企业小程序登录测试) ## Dev Agent Record ### Agent Model Used _Created by user request_ ### Debug Log References _Implementation phase - no debug yet_ ### Completion Notes List _Story 13.12 ready for development_ ### File List **新建的文件**: - `_bmad-output/implementation-artifacts/13-12-statistics-page-validation.md` - Story 文档 **待创建的文件**: - `web/tests/e2e/specs/cross-platform/statistics-page-validation.spec.ts` - E2E 测试文件 **待修改的文件**: - `mini/src/pages/yongren/statistics/index.tsx` - 数据统计页面 - `mini-ui-packages/yongren-statistics-ui/` - 统计 UI 组件 - `allin-packages/statistics-module/src/routes/statistics.routes.ts` - API 路由 - `allin-packages/statistics-module/src/schemas/statistics.schema.ts` - API Schema - `web/tests/e2e/pages/mini/enterprise-mini.page.ts` - Page Object 扩展 ## Change Log - 2026-01-14: Story 13.12 创建完成 - 数据统计页测试与功能修复需求 - 5 个验收标准(AC) - 11 个任务(包含 3 个 Bug 修复任务) - 状态:ready-for-dev