Status: ready-for-dev
作为企业管理员,我在企业小程序的数据统计页能查看各种统计数据,包括在职人数、平均薪资、在职率、新增人数等,并且可以通过年份和月份筛选器查看不同时期的统计数据。统计数据应该从后台 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 (稳定性验证)
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
Story 13.12 ready for development
新建的文件:
_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 Schemaweb/tests/e2e/pages/mini/enterprise-mini.page.ts - Page Object 扩展