Status: done
作为企业管理员,我在企业小程序的数据统计页能查看各种统计数据,包括在职人数、平均薪资、在职率、新增人数等,并且可以通过年份和月份筛选器查看不同时期的统计数据。统计数据应该从后台 API 动态获取,而非硬编码。
Given 用户已登录企业小程序 When 用户点击底部导航的"数据"tab Then 应能成功导航到数据统计页 And 页面应显示筛选器区域(年份选择器、月份选择器) And 页面应显示 4 个统计卡片(在职人数、平均薪资、在职率、新增人数) And 页面应显示 6 个统计图表(残疾类型分布、性别分布、年龄分布、户籍省份分布、在职状态统计、薪资分布)
Given 用户在数据统计页 When 用户选择年份(如 2026) And 用户选择月份(如 1月) Then 页面应重新获取该年月的统计数据 And 统计卡片应显示更新后的数据 And 统计图表应显示更新后的数据
Given 用户在数据统计页 When 页面加载完成 Then 统计卡片应显示从 API 获取的真实数据 And "在职人数"应显示当前在职人员总数 And "平均薪资"应显示所有在职人员的平均薪资 And "在职率"应显示在职人数占总人数的百分比 And "新增人数"应显示本月新增的人员数 And 每个统计卡片应显示与上月对比的数据
Given 用户在数据统计页 When 页面加载完成 Then "残疾类型分布"图表应显示各类残疾的人数分布 And "性别分布"图表应显示男女人数分布 And "年龄分布"图表应显示各年龄段人数分布 And "户籍省份分布"图表应显示各省份人数分布 And "在职状态统计"图表应显示各种工作状态的人数分布 And "薪资分布"图表应显示各薪资区间的人数分布
Given 数据统计 API 端点已实现 When 前端请求统计数据时传递 year 和 month 参数 Then API 应返回该年月的统计数据 And 如果未传递参数,应返回当前年月的统计数据
yongren-statistics-ui 包中的统计卡片组件statistics-module 中的 API 路由/api/statistics/employment-count/api/statistics/average-salary/api/statistics/employment-rate/api/statistics/new-count/api/statistics/disability-type-distribution/api/statistics/gender-distributionenterprise-mini.page.ts 中添加数据统计页相关方法:
navigateToStatisticsPage()selectYear(year: number)selectMonth(month: number)getStatisticsCards()expectStatisticsCardData(cardName: string, expected: any)getStatisticsCharts()expectChartData(chartName: string, expected: any)web/tests/e2e/specs/cross-platform/statistics-page-validation.spec.tsEpic 13: 跨端数据同步测试 (Epic E)
/mini/#/mini/pages/yongren/statistics/index
mini/src/pages/yongren/statistics/index.tsxmini-ui-packages/yongren-statistics-ui/allin-packages/statistics-module/src/routes/statistics.routes.tsallin-packages/statistics-module/src/schemas/statistics.schema.ts统计卡片数据硬编码
API 不支持年月查询参数
筛选器未连接到数据刷新逻辑
本 Story 采用 Playwright MCP 持续验证的测试开发流程:
任务流程:
任务 0-2 (Bug 修复) → 任务 3 (Page Object) → 任务 4-9 (E2E 测试) → 任务 10 (稳定性验证) → 任务 11-15 (数据准确性验证)
确保统计数据从数据库到小程序展示的完整链路准确无误,验证跨系统数据一致性。
场景 1: 后台添加人员 → 小程序统计更新(任务 12)
1. 记录当前小程序统计页的在职人数、平均薪资等数据
2. 在后台管理系统添加新的残疾人记录
3. 为该人员分配订单和薪资
4. 刷新小程序统计页
5. 验证统计数据是否正确更新:
- 在职人数应该 +1
- 平均薪资应该根据新薪资重新计算
- 新增人数应该 +1(当月新增)
场景 2: 修改人员状态 → 统计数据变化(任务 13)
1. 在后台将某在职人员状态改为"离职"
2. 刷新小程序统计页
3. 验证统计数据变化:
- 在职人数应该 -1
- 在职率应该下降
- 在职状态分布图表应该更新
场景 3: 数据一致性验证(任务 15)
1. 直接查询数据库获取实际统计数据
2. 对比小程序显示的统计数据
3. 验证以下指标:
- 总人数是否一致
- 各类残疾类型分布是否一致
- 性别分布是否一致
- 薪资统计是否一致
EnterpriseMiniPage 扩展方法:
// 导航到数据统计页
async navigateToStatisticsPage(): Promise<void>
// 筛选器操作
async selectYear(year: number): Promise<void>
async selectMonth(month: number): Promise<void>
// 获取统计卡片数据
async getStatisticsCards(): Promise<StatisticsCardData[]>
async expectStatisticsCardData(cardName: string, expected: any): Promise<void>
// 获取统计图表数据
async getStatisticsCharts(): Promise<StatisticsChartData[]>
async expectChartData(chartName: string, expected: any): Promise<void>
AC1: 可访问性和 UI 验证
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: 筛选器功能验证
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 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;
// ... 查询逻辑
});
连接筛选器到数据刷新:
// 监听筛选器变化
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.mddocs/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 (企业小程序登录测试)Created by user request
Implementation phase - no debug yet
任务 0: 统计卡片数据硬编码问题修复
修改了 /mnt/code/188-179-template-6/mini-ui-packages/yongren-statistics-ui/src/api/types.ts
修改了 /mnt/code/188-179-template-6/mini-ui-packages/yongren-statistics-ui/src/pages/Statistics/Statistics.tsx
任务 1: API 支持年月查询参数
修改了 /mnt/code/188-179-template-6/allin-packages/statistics-module/src/schemas/statistics.schema.ts
修改了 /mnt/code/188-179-template-6/allin-packages/statistics-module/src/services/statistics.service.ts
修改了 /mnt/code/188-179-template-6/allin-packages/statistics-module/src/routes/statistics.routes.ts
任务 2: 筛选器连接到数据刷新逻辑
/mnt/code/188-179-template-6/mini-ui-packages/yongren-statistics-ui/src/pages/Statistics/Statistics.tsx
类型检查
待完成任务
新建的文件:
_bmad-output/implementation-artifacts/13-12-statistics-page-validation.md - Story 文档待创建的文件:
web/tests/e2e/specs/cross-platform/statistics-page-validation.spec.ts - E2E 测试文件已修改的文件:
mini-ui-packages/yongren-statistics-ui/src/api/types.ts - 添加统计卡片类型定义mini-ui-packages/yongren-statistics-ui/src/pages/Statistics/Statistics.tsx - 修复硬编码数据,连接筛选器到数据刷新allin-packages/statistics-module/src/schemas/statistics.schema.ts - 添加统计卡片 Schema 和年月查询参数allin-packages/statistics-module/src/services/statistics.service.ts - 添加统计卡片服务方法allin-packages/statistics-module/src/routes/statistics.routes.ts - 添加统计卡片 API 端点待修改的文件:
web/tests/e2e/pages/mini/enterprise-mini.page.ts - Page Object 扩展2026-01-14: Story 13.12 创建完成
2026-01-14: 任务 0-2 完成(Bug 修复阶段)
2026-01-15: 任务 3-10 完成(E2E 测试阶段)
2026-01-15: 任务 11-15 新增(数据准确性验证)
2026-01-15: 任务 12-15 完成(跨系统数据一致性验证)
2026-01-15: 代码审查完成
waitForStatisticsDataLoaded 方法 - 等待所有 4 个卡片加载完成selectYear/selectMonth 方法中的注释错误