Files
X-Financial/document/development/财务看板排行口径与部门人员占比/CONCEPT.md

154 lines
5.8 KiB
Markdown
Raw Normal View History

# 财务看板排行口径与部门人员占比
## 功能一句话
在分析看板的财务看板中补齐部门人员报销占比,并让部门、个人、高额单据使用统一的排行时间筛选口径。
## 背景与问题
当前财务看板已有部门报销排行、个人报销排行和本月高额单据,但存在三个问题:
- 部门排行的时间筛选只有本周、本月、本季度,缺少本年和全部。
- 个人报销排行标题固定为“本月”,实际无法由用户切换本月、本季度、本年和全部。
- 高额单据旁缺少部门内人员报销构成,财务人员难以判断高额单据是否集中在少数人员或单一部门。
## 目标与非目标
目标:
- 新增“部门人员报销占比”饼图,放在“本月高额单据”左侧,并与排行时间筛选口径联动。
- 部门报销排行增加参与人员数量,卡片空间完整展示排行内容。
- 个人报销排行增加报销笔数和所属部门信息,卡片空间完整展示排行内容。
- 部门排行、个人排行、高额单据、部门人员占比统一支持:本月、本季度、本年、全部。
非目标:
- 不新增独立页面。
- 不重做顶部 KPI、趋势图、预算指标和系统/风险/数字员工看板。
- 不引入新的图表库,继续复用现有 ECharts 封装组件。
## 用户与场景
用户:
- 高级财务人员、预算监控员、管理员。
场景:
- 财务人员进入分析看板后,查看不同时间口径下的部门费用集中度。
- 财务人员切换本季度、本年或全部后,对比部门排行、个人排行、高额单据和人员占比。
- 财务人员判断某部门报销金额高,是因为多人正常报销,还是少数人集中报销。
## 功能能力
输入:
- `department_range` 查询参数,取值:`本月``本季度``本年``全部`
输出:
- `department_ranking`:部门报销排行,新增 `employeeCount`
- `employee_ranking`:个人报销排行,保留金额、笔数、部门,并随筛选口径变化。
- `top_claims`:高额单据,随筛选口径变化,标题不再固定为本月。
- `department_employee_mix`:部门人员报销占比饼图数据。
状态与边界:
- 没有真实数据时返回空数组或“暂无数据”占位。
- 草稿、删除等非支出口径状态不参与金额排行。
- 缺失部门或人员名称的数据不进入排行和占比图。
- `全部` 表示所有可用报销单据,不按日期裁剪。
## 方案设计
后端:
-`FinanceDashboardService` 中扩展排行时间范围解析。
-`department_range` 作为排行分析窗口,统一供部门排行、个人排行、高额单据和部门人员占比使用。
- 部门排行按部门聚合金额、单据数、待付款金额和人员数量。
- 部门人员占比按“部门 + 人员”聚合金额,展示排名靠前的人员构成,名称格式为 `部门 · 人员`
接口:
- `GET /api/v1/analytics/finance-dashboard` 保持原路径。
- `department_range` 支持 `本月``本季度``本年``全部`
- 响应体新增 `department_employee_mix`
前端:
- `analytics.js` 增加 `departmentEmployeeMix` 归一化。
- `metrics.js``departmentRangeOptions` 改为 `本月 / 本季度 / 本年 / 全部`
- `useOverviewView.js` 新增部门人员占比 legend并让部门/个人排行读取新增字段。
- `OverviewView.vue` 调整财务看板底部布局:
- 部门排行占更宽区域,并保留筛选器。
- 个人排行占更宽区域,并增加相同筛选器。
- 高额单据卡片左侧放部门人员报销占比饼图,右侧放高额单据列表。
- 样式继续沿用企业 SaaS 直角、低饱和、Element Plus 控件和已有 `DonutChart` / `BarChart`
## 算法与公式
支出金额:
$$
amount_i = claim_i.amount
$$
部门金额:
$$
departmentAmount_d = \sum_{i \in claims(d)} amount_i
$$
部门人员数:
$$
employeeCount_d = \left| distinct(employeeName_i), i \in claims(d) \right|
$$
个人金额:
$$
employeeAmount_e = \sum_{i \in claims(e)} amount_i
$$
部门人员报销占比:
$$
share_{d,e} = \frac{\sum_{i \in claims(d,e)} amount_i}{\sum_{i \in rankingClaims} amount_i}
$$
其中 `rankingClaims` 为当前 `department_range` 时间口径下过滤后的有效报销单据。
## 测试方案
- 后端单元测试:
- 覆盖 `department_range=本年``department_range=全部`
- 验证部门排行返回 `employeeCount`
- 验证个人排行随口径变化。
- 验证 `department_employee_mix` 返回正确人员占比数据。
- 前端源码测试:
- 验证筛选选项包含本月、本季度、本年、全部。
- 验证个人排行和部门排行都有筛选器。
- 验证高额单据卡片包含部门人员报销占比图。
- 验证服务层归一化新增字段。
- 构建验证:
- `npm.cmd --prefix web run build`
- 容器验证:
- 后端测试在 `x-financial-main:/app` 中运行,超时不超过 60s。
- 可用时通过接口检查 `department_employee_mix``employeeCount``department_range=全部`
## 指标与验收
- 财务看板接口返回 `department_employee_mix`
- 部门排行每项返回 `employeeCount`
- 部门排行和个人排行都可选择本月、本季度、本年、全部。
- 个人排行标题不再固定“本月”。
- 高额单据卡片左侧显示部门人员报销占比饼图。
- 定向后端测试和前端构建通过。
## 风险与开放问题
- 当前工作区存在大量未提交变更,提交时必须只纳入本次相关文件。
- 如果浏览器自动化不可用,前端以源码测试、构建和接口验证为主要证据。
- `全部` 口径数据量可能更大,当前实现继续沿用内存聚合;后续数据量过大时再考虑 SQL 聚合优化。