【报表】财务报表
报表管理模块,由 yudao-module-fms 后端模块的 report 包实现,前端实现在 @/views/fms/report 目录。
资产负债表、利润表和现金流量表按当前账套和会计期间生成,支持公式修改、勾稽检查、导出和打印。模块采用「配置 + 期间快照」的设计:配置表保存报表项目和公式,期间表保存查询该期间时使用的公式快照及人工调整数据,金额仍根据当前账套的期初余额和凭证实时计算。
- 资产负债表:展示资产、负债和所有者权益的期末余额、年初余额,并支持勾稽检查。
- 利润表:展示本期金额、本年累计金额,并检查净利润与未分配利润变动。
- 现金流量表:按资产负债表、利润表和现金流量辅助数据计算,额外提供辅助数据和非公式项目的人工调整。
本文涉及表如下图所示:
# 1. 报表模板与公式
三张报表共用一张系统预置模板表 fms_report_template,以及一套公式取数规则。
# 1.1 模板表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
CREATE TABLE `fms_report_template` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`type` int DEFAULT NULL COMMENT '类型',
`category` int DEFAULT NULL COMMENT '类别',
`row_id` int DEFAULT NULL COMMENT '行编号',
`row_no` int DEFAULT NULL COMMENT '行次',
`name` varchar(255) DEFAULT NULL COMMENT '配置名称',
`formula` text COMMENT '公式',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`editable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否可编辑',
`level` int DEFAULT NULL COMMENT '层级',
`sort` int DEFAULT NULL COMMENT '显示顺序',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 报表模板';
① 模板表不带 account_set_id,不对应任何菜单。首次查询某张报表时,服务把对应模板复制到该账套的配置表(fms_balance_sheet_config、fms_income_statement_config、fms_cash_flow_statement_config、fms_cash_flow_extend_config)。
② 枚举 type 报表类型(FmsReportTypeEnum):
| 值 | 枚举 | 说明 |
|---|---|---|
1 | BALANCE_SHEET | 资产负债表 |
2 | INCOME_STATEMENT | 利润表 |
3 | CASH_FLOW_STATEMENT | 现金流量表 |
4 | CASH_FLOW_ADJUSTMENT | 现金流量辅助数据 |
③ row_no 是打印在报表上的行次,row_id 是行的稳定编号:资产负债表用它把左右两侧的资产项目和负债权益项目配对到同一行。
④ editable 决定该行公式和金额是否允许用户修改。合计行、小计行通常不可编辑。
# 1.2 公式取数规则
formula 支持两类写法:行次公式(例如 L1+L2-L3,引用同表其它行次)和科目公式(按科目编码取数)。科目公式的取数规则由枚举 FmsFormulaRuleEnum 定义:
| 值 | 枚举 | 说明 |
|---|---|---|
0 | BALANCE | 余额 |
1 | DEBIT_BALANCE | 借方余额 |
2 | CREDIT_BALANCE | 贷方余额 |
3 | SUBJECT_DEBIT_BALANCE | 科目借方余额 |
4 | SUBJECT_CREDIT_BALANCE | 科目贷方余额 |
5 | DEBIT_AMOUNT | 借方发生额 |
6 | CREDIT_AMOUNT | 贷方发生额 |
7 | PROFIT_LOSS_AMOUNT | 损益发生额 |
资产负债表主要使用余额类规则,利润表主要使用发生额类规则(借方发生额、贷方发生额、损益发生额)。公式表达式由 Aviator 求值。
现金流量表的公式还可以引用其它报表的取数,前缀由枚举 FmsCashFlowParamTypeEnum 定义:
| 前缀 | 枚举 | 说明 |
|---|---|---|
BA | BALANCE | 资产负债取数 |
IN | INCOME | 利润表取数 |
EX | EXTEND | 辅助数据取数 |
L | LINE | 行次取数 |
保存公式时,后端会校验账套和项目归属,绑定当前账套的科目编号,并更新当前期间快照及后续配置;无效格式不能保存。
# 2. 资产负债表
资产负债表,由 FmsBalanceSheetController 提供接口(/fms/report/balance-sheet),配置和期间数据由 FmsBalanceSheetService 维护。
# 2.1 表结构
CREATE TABLE `fms_balance_sheet_config` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`row_id` int DEFAULT NULL COMMENT '行编号',
`row_no` int DEFAULT NULL COMMENT '行次',
`name` varchar(255) DEFAULT NULL COMMENT '配置名称',
`formula` text COMMENT '公式',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`editable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否可编辑',
`level` int DEFAULT NULL COMMENT '层级',
`sort` int DEFAULT NULL COMMENT '显示顺序',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 资产负债表配置';
CREATE TABLE `fms_balance_sheet_report` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`type` int DEFAULT NULL COMMENT '类型',
`from_period` int DEFAULT NULL COMMENT '开始会计期间,格式为 yyyyMM',
`to_period` int DEFAULT NULL COMMENT '结束会计期间,格式为 yyyyMM',
`row_id` int DEFAULT NULL COMMENT '行编号',
`row_no` int DEFAULT NULL COMMENT '行次',
`name` varchar(255) DEFAULT NULL COMMENT '配置名称',
`formula` text COMMENT '公式',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`editable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否可编辑',
`opening_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '期初金额',
`closing_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '期末金额',
`settled` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否已结账',
`level` int DEFAULT NULL COMMENT '层级',
`sort` int DEFAULT NULL COMMENT '显示顺序',
PRIMARY KEY (`id`),
KEY `idx_account_period` (`account_set_id`, `type`, `from_period`, `to_period`)
) ENGINE=InnoDB COMMENT='FMS 资产负债表数据';
① 配置表是账套当前生效的公式,期间表是某个查询期间的快照:from_period、to_period 标识期间,opening_amount 是年初余额,closing_amount 是期末余额。
② row_id 用于把资产项目与负债权益项目配对到同一行展示。
③ settled 标识该期间快照是否已随期末结账固化,详见 《【结账】期末结账》。
# 2.2 管理后台
对应 [财务管理 -> 报表管理 -> 资产负债表] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/fms/report/balance-sheet 目录。
# 列表
页面由 FmsReportPeriodBar.vue、FmsReportCheckAlert.vue 和 FmsReportPrintButton.vue 组成。选择月报或季报后调用 getBalanceSheet 和 checkBalanceSheet,表格左右两侧分别展示资产和负债、所有者权益的期末余额与年初余额。

// TODO @AI:资产负债表截图仍需在有数据的会计期间重新截取,并展开「FMS 财务管理 -> 报表管理」高亮「资产负债表」。
# 编辑公式
点击可编辑项目旁的编辑图标,打开 FmsReportFormulaForm.vue,选择科目、取数规则和运算符后由 updateBalanceSheetFormula 保存。保存会同时更新配置和当前期间快照。

// TODO @AI:资产负债表公式截图仍需在有数据的会计期间重新截取,并展开「FMS 财务管理 -> 报表管理」高亮「资产负债表」。
# 检查
// TODO @Codex:截图 /img/FMS财务管理/报表/报表检查.png —— 资产负债表检查结果(勾稽差额或未映射科目),参考 /img/HRM人力资源/薪资/核算准备提醒.png。
checkBalanceSheet 检查初始余额是否试算平衡,以及资产合计与负债所有者权益合计的差额,并返回尚未纳入公式的一级科目。
# 3. 利润表
利润表,由 FmsIncomeStatementController 提供接口(/fms/report/income-statement),配置和期间数据由 FmsIncomeStatementService 维护。
# 3.1 表结构
CREATE TABLE `fms_income_statement_config` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`row_no` int DEFAULT NULL COMMENT '行次',
`name` varchar(255) DEFAULT NULL COMMENT '配置名称',
`formula` text COMMENT '公式',
`editable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否可编辑',
`level` int DEFAULT NULL COMMENT '层级',
`sort` int DEFAULT NULL COMMENT '显示顺序',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 利润表配置';
CREATE TABLE `fms_income_statement_report` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`type` int DEFAULT NULL COMMENT '类型',
`from_period` int DEFAULT NULL COMMENT '开始会计期间,格式为 yyyyMM',
`to_period` int DEFAULT NULL COMMENT '结束会计期间,格式为 yyyyMM',
`row_no` int DEFAULT NULL COMMENT '行次',
`name` varchar(255) DEFAULT NULL COMMENT '配置名称',
`formula` text COMMENT '公式',
`editable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否可编辑',
`current_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '本期金额',
`year_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '本年累计金额',
`settled` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否已结账',
`level` int DEFAULT NULL COMMENT '层级',
`sort` int DEFAULT NULL COMMENT '显示顺序',
PRIMARY KEY (`id`),
KEY `idx_account_period` (`account_set_id`, `type`, `from_period`, `to_period`)
) ENGINE=InnoDB COMMENT='FMS 利润表数据';
① current_amount 是本期金额,year_amount 是本年累计金额。两者使用同一条公式,但取数区间不同:本期取查询期间的发生额,本年累计取自然年年初至查询期间的发生额。
② 利润表没有左右配对结构,因此不需要 row_id。
# 3.2 管理后台
对应 [财务管理 -> 报表管理 -> 利润表] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/fms/report/income-statement 目录。
# 列表
选择期间后调用 getIncomeStatement 和 checkIncomeStatement,展示项目、本年累计金额和本期金额。

# 编辑公式
点击项目旁的编辑图标打开 FmsReportFormulaForm.vue,利润表使用借方发生额、贷方发生额或损益发生额取数规则,由 updateIncomeStatementFormula 保存。
# 检查
checkIncomeStatement 检查净利润与未分配利润变动的勾稽差额,并返回尚未纳入公式的一级科目。
# 4. 现金流量表
现金流量表,由 FmsCashFlowStatementController 提供接口(/fms/report/cash-flow-statement)。它由主表和辅助数据两部分组成,共同由 FmsCashFlowStatementService 计算。
# 4.1 主表表结构
CREATE TABLE `fms_cash_flow_statement_config` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`category` int DEFAULT NULL COMMENT '现金流量表分类',
`row_no` int DEFAULT NULL COMMENT '行次',
`name` varchar(255) DEFAULT NULL COMMENT '配置名称',
`formula` text COMMENT '公式',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`editable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否可编辑',
`level` int DEFAULT NULL COMMENT '层级',
`sort` int DEFAULT NULL COMMENT '显示顺序',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 现金流量表配置';
CREATE TABLE `fms_cash_flow_statement_report` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`type` int DEFAULT NULL COMMENT '类型',
`category` int DEFAULT NULL COMMENT '现金流量表分类',
`from_period` int DEFAULT NULL COMMENT '开始会计期间,格式为 yyyyMM',
`to_period` int DEFAULT NULL COMMENT '结束会计期间,格式为 yyyyMM',
`row_no` int DEFAULT NULL COMMENT '行次',
`name` varchar(255) DEFAULT NULL COMMENT '配置名称',
`formula` text COMMENT '公式',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`editable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否可编辑',
`current_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '本期金额',
`year_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '本年累计金额',
`level` int DEFAULT NULL COMMENT '层级',
`sort` int DEFAULT NULL COMMENT '显示顺序',
PRIMARY KEY (`id`),
KEY `idx_account_period` (`account_set_id`, `type`, `from_period`, `to_period`)
) ENGINE=InnoDB COMMENT='FMS 现金流量表数据';
① category 是现金流量表的分区标识,用于把项目归入经营活动、投资活动、筹资活动等分组展示。
② 现金流量表自身没有平衡关系,它的检查复用资产负债表检查,用于确认主表满足取数条件。
③ 未明确归类的经营活动现金流会被归入「其他经营活动现金」:服务按资产负债表的货币资金期末余额倒挤差额,差额为正时覆盖原计算值,并重算受影响的行次公式项目。
# 4.2 辅助数据表结构
现金流量表的部分项目无法直接从科目取数(例如折旧、摊销、存货变动),需要人工提供辅助数据:
CREATE TABLE `fms_cash_flow_extend_config` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`type` int DEFAULT NULL COMMENT '类型',
`category` int DEFAULT NULL COMMENT '表格标识',
`row_no` int DEFAULT NULL COMMENT '行次',
`name` varchar(255) DEFAULT NULL COMMENT '配置名称',
`formula` text COMMENT '公式',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`current_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '本期金额',
`year_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '本年累计金额',
`editable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否可编辑',
`level` int DEFAULT NULL COMMENT '层级',
`sort` int DEFAULT NULL COMMENT '显示顺序',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 现金流量辅助配置';
CREATE TABLE `fms_cash_flow_extend_data` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`type` int DEFAULT NULL COMMENT '类型',
`category` int DEFAULT NULL COMMENT '表格标识',
`from_period` int DEFAULT NULL COMMENT '开始会计期间,格式为 yyyyMM',
`to_period` int DEFAULT NULL COMMENT '结束会计期间,格式为 yyyyMM',
`row_no` int DEFAULT NULL COMMENT '行次',
`name` varchar(255) DEFAULT NULL COMMENT '配置名称',
`formula` text COMMENT '公式',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`current_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '本期金额',
`year_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '本年累计金额',
`editable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否可编辑',
`level` int DEFAULT NULL COMMENT '层级',
`sort` int DEFAULT NULL COMMENT '显示顺序',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 现金流量辅助数据';
① 辅助配置同样在首次查询时从 fms_report_template 初始化(type = 4),辅助数据按账套、期间和类型保存用户填写的金额。
② 枚举 type 辅助数据类型(FmsCashFlowExtendTypeEnum):0 用户配置、1 固定公式。固定公式行由系统计算,用户配置行才允许直接填金额。
③ 主表公式通过 EX 前缀引用辅助数据的行,因此必须先调整辅助数据,再看主表金额。
# 4.3 管理后台
对应 [财务管理 -> 报表管理 -> 现金流量表] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/fms/report/cash-flow-statement 目录。三个环节共用同一个页面,通过状态切换。
# 列表
选择期间后调用 getCashFlowStatement 和 checkCashFlowStatement,展示本期金额和本年累计金额。
// TODO @AI:当前截图保留了有数据的现金流量表,但左侧菜单未完整展示「FMS 财务管理 -> 报表管理 -> 现金流量表」,需在有数据期间重新截取后再标记完成。

// TODO @AI:现金流量表截图仍需在有数据的会计期间重新截取,并展开「FMS 财务管理 -> 报表管理」高亮「现金流量表」。
# 调整辅助数据
点击【调整】进入辅助数据模式,由 getCashFlowAdjustmentList 加载辅助数据行。允许编辑的行可以修改本期、本年金额,也可以打开 FmsReportFormulaForm.vue 修改公式(updateCashFlowAdjustmentFormula)。点击【下一步】由 updateCashFlowAdjustment 保存。

# 调整报表金额
下一步后进入人工调整模式,只有非行次公式项目可以直接编辑。点击【保存】由 updateCashFlowStatement 写入金额;把金额清零后,下一次查询会重新按公式计算。

# 5. 查询、检查、导出与打印
# 5.1 查询期间
三个页面共用 FmsReportPeriodBar.vue,期间类型对应枚举 FmsReportPeriodTypeEnum:1 月度、2 季度。月报传递相同的开始、结束期间,季报按所选月份计算季度起止期间。可选月份受账套启用期间和当前会计期间限制。
# 5.2 检查
FmsReportCheckAlert.vue 展示各报表 check 方法的结果:资产负债表检查初始余额和期末差额,利润表检查勾稽差额,现金流量表复用资产负债表检查。
报表检查说明
检查失败时,请按提示先处理初始余额、凭证结转或公式覆盖,再刷新当前报表。检查结果本身不修改报表金额;首次检查或首次查询某个期间时,服务可能初始化对应的配置和期间快照。
# 5.3 导出与打印
// TODO @Codex:截图 /img/FMS财务管理/报表/报表打印预览.png —— 资产负债表打印预览,参考 /img/FMS财务管理/凭证/凭证汇总打印预览.png。
导出由各 Controller 的 export 方法使用 ExcelUtils 写出 .xls。打印由 FmsReportPrintButton.vue 和 FmsPrintPreview.vue 在浏览器端完成,不新增后端打印接口。