# Story 13.22: 数据统计页面年月筛选器移除 - 简化为当前数据视图 Status: done ## Story 作为企业用户, 我想要查看当前在职人员的实时统计数据, 以便了解企业当前的人员状况,避免因历史数据查询功能名不副实造成的困惑。 ## 问题背景 企业小程序数据统计页面的年月筛选器存在设计与实现不一致的问题: 1. **原型设计**:有年月筛选器,显示"比上月增加2人"等对比数据 2. **技术现实**:数据库不支持历史数据查询(无历史状态表、无入职/离职时间) 3. **代码问题**: - `getEmploymentCount` 等方法接收了 year/month 参数,但变量名错误(`targetYear` vs `_targetYear`) - 构建的日期范围未在查询中使用 - "上月在职人数"直接等于"当月在职人数"(`previousCount = currentCount`) - 分布图方法根本不接收 year/month 参数 4. **用户困惑**:选择历史月份时,数据显示的还是当前在职人数,功能名不副实 ## Acceptance Criteria 1. **Given** 用户是企业用户 **When** 用户访问数据统计页面 **Then** 页面只显示当前统计数据 **And** 没有年月筛选器 UI 2. **Given** 用户访问数据统计页面 **When** 页面加载完成 **Then** 统计卡片只显示当前数值 **And** 没有显示"比上月"对比数据 3. **Given** 用户查看统计卡片 **When** 查看在职人数、平均薪资、在职率 **Then** 只显示当前数值 **And** 不显示环比变化数据 4. **Given** 用户访问数据统计页面或首页看板 **When** 查看统计卡片 **Then** 不显示"新增人数"卡片 **And** 只显示:在职人数、平均薪资、在职率 5. **Given** 后端统计 API **When** 前端调用统计接口 **Then** 返回简化的响应数据(只包含当前值) **And** 不包含 previousCount、previousAverage、previousRate、change 等字段 6. **Given** 数据统计页面 **When** 用户查看分布图(残疾类型、性别、年龄等) **Then** 分布图显示当前在职人员的统计 **And** 数据准确反映当前在职人员情况 ## Tasks / Subtasks - [ ] **Task 1: 后端 API 简化** (AC: #5) - [ ] Subtask 1.1: 修改 `statistics.schema.ts` - 移除 `YearMonthQuery` 类型 - [ ] Subtask 1.2: 修改响应 Schema - 移除 `previousCount`、`change` 等字段 - [ ] Subtask 1.3: 修改 `statistics.service.ts` - 简化方法签名,移除 `query` 参数 - [ ] Subtask 1.4: 移除未使用的变量(`_targetYear`、`_targetMonth`、`_previousYear` 等) - [ ] Subtask 1.5: 移除"上月"相关逻辑(`previousCount = currentCount` 等) - [ ] Subtask 1.6: 修改 `statistics.routes.ts` - 移除 `query` 参数传递 - [ ] Subtask 1.7: 更新后端单元测试 - [ ] **Task 2: 前端 UI 简化** (AC: #1, #2, #3) - [ ] Subtask 2.1: 移除年月选择器 UI(`years`、`months` 状态和 Picker 组件) - [ ] Subtask 2.2: 移除 `timeFilter` 状态和 `setTimeFilter` 处理函数 - [ ] Subtask 2.3: 移除 `queryFilters` 相关代码 - [ ] Subtask 2.4: 移除所有 useQuery 中的 `queryFilters` 依赖 - [ ] Subtask 2.5: 修改统计卡片 - 移除"比上月"对比数据显示 - [ ] Subtask 2.6: 更新 TypeScript 类型定义(移除 change、previousCount 等字段) - [ ] **Task 3: 移除"新增人数"指标** (AC: #4) - [ ] Subtask 3.1: 后端 - 移除 `getNewCount` 方法 - [ ] Subtask 3.2: 后端 - 移除 `/new-count` 路由 - [ ] Subtask 3.3: 后端 - 移除 `NewCountResponseSchema` - [ ] Subtask 3.4: 前端 - 移除"新增人数"卡片组件 - [ ] Subtask 3.5: 前端 - 移除 `getNewCount` API 调用 - [ ] Subtask 3.6: 前端 - 移除首页看板中的"新增人数"卡片 - [ ] Subtask 3.7: 更新后端单元测试 - [ ] **Task 4: E2E 测试更新** (AC: #6) - [ ] Subtask 4.1: 更新现有的数据统计页 E2E 测试 - [ ] Subtask 4.2: 移除年月筛选相关的测试用例 - [ ] Subtask 4.3: 移除"新增人数"相关的测试用例 - [ ] Subtask 4.4: 验证页面只显示三个统计卡片(在职人数、平均薪资、在职率) - [ ] Subtask 4.5: 使用 Playwright MCP 验证页面简化后的效果 - [ ] **Task 5: 验证与文档** (AC: 全部) - [ ] Subtask 5.1: 手动验证页面显示正确 - [ ] Subtask 5.2: 运行 E2E 测试确保无回归 - [ ] Subtask 5.3: 检查控制台无错误警告 ## Dev Notes ### 移除"新增人数"的原因 调查发现"新增人数"指标存在业务逻辑问题: - **名称误导**: 名称暗示"本月新增"(增量数据) - **实际统计**: 实际统计的是所有历史数据(存量数据) - **SQL 实现**: `SELECT COUNT(DISTINCT dp.id) FROM employment_order ... WHERE eo.company_id = ?` - **缺少时间筛选**: 没有时间筛选条件,不是真正的"新增" - **用户体验差**: 容易误导用户 决定先移除此指标,等产品和技术理清楚业务需求后再决定是否恢复。如果需要恢复,应该: 1. 明确业务需求(新增人数的定义是什么?) 2. 添加必要的数据支持(如入职时间字段) 3. 实现正确的时间筛选逻辑 ### 问题分析 根据代码分析,当前实现存在以下问题: 1. **后端问题** (`statistics.service.ts`): - `getEmploymentCount` 接收 `year/month` 参数但未使用(lines 382-397) - 变量命名不一致:`targetYear` vs `_targetYear` - 构建的日期范围 `_startDate`、`_endDate` 完全未在查询中使用 - `previousCount = currentCount` 导致 change 永远为 0 - `getEmploymentRate` 有未使用的变量 `_targetYear`、`_targetMonth` 2. **前端问题** (`Statistics.tsx`): - 年月选择器 UI 存在但功能无效(lines 70-83, 114-124, 278-307) - `queryFilters` 传递到后端但后端未实际使用 - "比上月"对比数据显示但永远是 0 3. **API 层问题**: - `EnterpriseStatisticsQuerySchema` 扩展自 `YearMonthQuerySchema` - 路由定义接收 `query` 参数但服务层忽略 ### 解决方案 **方案 A: 移除年月筛选器(采用)** - 简化 UI,移除误导性的筛选器 - 简化 API,移除无用参数 - 只显示当前数据,清晰明了 **方案 B: 实现历史数据查询(不采用)** - 需要添加历史状态表 - 需要记录入职/离职时间 - 工作量大,当前不需要 ### 项目结构说明 - **后端模块**: `allin-packages/statistics-module/` - `src/services/statistics.service.ts` - 统计服务 - `src/schemas/statistics.schema.ts` - Zod Schema 定义 - `src/routes/statistics.routes.ts` - API 路由 - `tests/integration/statistics.integration.test.ts` - 集成测试 - **前端模块**: `mini-ui-packages/yongren-statistics-ui/` - `src/pages/Statistics/Statistics.tsx` - 数据统计页面 - `src/api/enterpriseStatisticsClient.ts` - API 客户端 - **E2E 测试**: `web/tests/e2e/mini-enterprise/` - `statistics-page.spec.ts` - 数据统计页 E2E 测试(在 Story 13.12 中创建) ### 技术实现细节 1. **Schema 修改**: ```typescript // 移除 YearMonthQuerySchema(可保留以备将来使用,但当前不使用) // 简化响应 Schema export const EmploymentCountResponseSchema = z.object({ companyId: z.number().int().positive(), count: z.number().int().min(0) // 移除 previousCount, change }); ``` 2. **Service 修改**: ```typescript // 简化方法签名 async getEmploymentCount(companyId: number): Promise<{ companyId: number; count: number; }> { // 移除所有日期相关变量和逻辑 } ``` 3. **前端修改**: ```typescript // 移除时间筛选状态 const [timeFilter, setTimeFilter] = useState(...) const [showDatePicker, setShowDatePicker] = useState(...) const years = ... const months = ... // 移除 queryFilters const queryFilters = useMemo(...) // 移除对比数据显示 ↑ 比上月增加{change}人 ``` ### 测试策略 1. **后端单元测试**: - 更新 `statistics.integration.test.ts` - 验证返回的响应不包含 `previousCount`、`change` 字段 - 验证方法只返回当前统计数据 2. **E2E 测试**: - 复用 Story 13.12 创建的测试文件 - 移除年月筛选相关测试 - 验证页面无筛选器 UI - 验证卡片只显示数值,无对比数据 3. **Playwright MCP 验证**: - 使用 Playwright MCP 截图验证页面简化效果 - 确认无年月选择器 - 确认卡片显示正确 ### Project Structure Notes 遵循项目统一结构: - TypeScript 严格模式,无 `any` 类型 - 使用 Zod Schema 验证所有输入输出 - 使用 `parseWithAwait` 验证响应 - 测试文件与源文件同级目录 ### References - **后端服务**: `/mnt/code/188-179-template-6/allin-packages/statistics-module/src/services/statistics.service.ts` - **前端页面**: `/mnt/code/188-179-template-6/mini-ui-packages/yongren-statistics-ui/src/pages/Statistics/Statistics.tsx` - **Schema 定义**: `/mnt/code/188-179-template-6/allin-packages/statistics-module/src/schemas/statistics.schema.ts` - **API 路由**: `/mnt/code/188-179-template-6/allin-packages/statistics-module/src/routes/statistics.routes.ts` - **E2E 测试**: `/mnt/code/188-179-template-6/web/tests/e2e/mini-enterprise/statistics-page.spec.ts` (Story 13.12) - **Epic 13**: `_bmad-output/planning-artifacts/epics.md` (Epic 13: 跨端数据同步测试) - **项目上下文**: `_bmad-output/project-context.md` ## Dev Agent Record ### Agent Model Used Claude Opus 4.5 (claude-opus-4-5-20251101) ### Debug Log References ### Completion Notes List ### File List #### 需要修改的文件: 1. `allin-packages/statistics-module/src/schemas/statistics.schema.ts` - 简化响应 Schema,移除 NewCountResponseSchema 2. `allin-packages/statistics-module/src/services/statistics.service.ts` - 简化服务方法,移除 getNewCount 方法 3. `allin-packages/statistics-module/src/routes/statistics.routes.ts` - 移除 query 参数和 /new-count 路由 4. `allin-packages/statistics-module/tests/integration/statistics.integration.test.ts` - 更新测试 5. `mini-ui-packages/yongren-statistics-ui/src/pages/Statistics/Statistics.tsx` - 简化 UI,移除"新增人数"卡片 6. `mini-ui-packages/yongren-dashboard-ui/src/components/NewCountCard.tsx` - 移除"新增人数"卡片组件(如果存在) 7. `mini-ui-packages/yongren-statistics-ui/src/api/enterpriseStatisticsClient.ts` - 移除 getNewCount API 调用 #### 可能需要更新的文件: - `mini-ui-packages/yongren-statistics-ui/src/api/types.ts` - 类型定义 - `web/tests/e2e/mini-enterprise/statistics-page.spec.ts` - E2E 测试(Story 13.12) - `mini-ui-packages/yongren-dashboard-ui/src/pages/Dashboard/Dashboard.tsx` - 首页看板(如果有"新增人数"卡片)