【结账】期末结账
结账管理模块,由 yudao-module-fms 后端模块的 closing 包实现,前端实现在 @/views/fms/closing 目录。
期末结账把「结转方案 → 结转凭证 → 结账检查 → 结账 / 反结账」放在同一条业务链路中:先按方案生成结转凭证,再检查待审核凭证、初始余额、凭证号、损益结转和财务报表;检查通过后关闭当前期间,发现错误时按会计期间倒序反结账。结账成功后,账套当前会计期间顺延,已结账期间的凭证不能再修改。
- 结账方案:结转损益、专用结转(转出未交增值税、计提地税、计提所得税)和自定义的普通结转,都保存在
fms_closing表。 - 结账模板:预置的分录规则,只在结账方案弹窗中使用,选择后复制到方案表单。
- 结转凭证:记录方案与实际凭证的关联和结转金额。
- 结账期间:
fms_closing_period只记录已经结账的期间,没有记录即表示该期间尚未结账。
本文涉及表如下图所示:
# 1. 结账方案
结账方案,由 FmsClosingSchemeController 提供接口(/fms/closing/scheme)。账套初始化时,initializeDefaultClosingSchemes 从 fms/closing/closing-scheme-presets.json 加载预置方案。
# 1.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
CREATE TABLE `fms_closing` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`subject_id` bigint DEFAULT NULL COMMENT '科目编号',
`voucher_word_id` bigint DEFAULT NULL COMMENT '凭证字编号',
`name` varchar(255) DEFAULT NULL COMMENT '结账名称',
`type` int DEFAULT NULL COMMENT '类型',
`period_end` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否期末结转',
`formula_rule` int DEFAULT NULL COMMENT '取数规则',
`time_type` int DEFAULT NULL COMMENT '取数时间类型',
`digest` varchar(500) DEFAULT NULL COMMENT '凭证摘要',
`subject_rules` json DEFAULT NULL COMMENT '结转科目规则数组',
`reverse_balance` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否按余额反向结转',
`voucher_type` int DEFAULT NULL COMMENT '结转凭证类型',
`closing_day` int DEFAULT NULL COMMENT '结转损益日期',
`prior_year_adjustment_subject_id` bigint DEFAULT NULL COMMENT '以前年度损益调整科目',
`adjustment_closing_subject_id` bigint DEFAULT NULL COMMENT '以前年度损益调整结转科目',
`other_closing_subject_id` bigint DEFAULT NULL COMMENT '其他损益科目结转科目',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 结账方案';
① subject_id 关联 fms_subject 表的 id 字段,表示取数的来源科目;voucher_word_id 关联 fms_voucher_word 表的 id 字段,决定生成凭证使用的凭证字。
② 枚举 type 结账类型(FmsClosingTypeEnum):
| 值 | 枚举 | 说明 | 默认凭证摘要 |
|---|---|---|---|
1 | REGULAR | 常规结账 | — |
2 | PROFIT_LOSS | 结转损益 | 结转本期损益 |
3 | UNPAID_VAT | 转出未交增值税 | 转出未交增值税 |
4 | LOCAL_TAX | 计提地税 | 计提地税 |
5 | INCOME_TAX | 计提所得税 | 计提所得税 |
其中 2~5 是系统预置方案,在页面上以固定卡片展示,只能修改设置不能删除;1 常规结账是用户自建的普通结转方案。
③ formula_rule 取数规则复用枚举 FmsFormulaRuleEnum(余额、借方余额、贷方余额、借方发生额、贷方发生额、损益发生额等),含义见 《【报表】财务报表》 的公式取数规则小节。
④ 枚举 time_type 取数时间类型(FmsClosingTimeTypeEnum):1 期末、2 期初、3 年初。它决定从来源科目的哪个时点取数。
⑤ 枚举 voucher_type 结转凭证类型(FmsClosingVoucherTypeEnum),只在结转损益方案中使用:1 收益和损失分开结转、2 收益和损失同时结转。
⑥ period_end 标识「用于期末结账前生成凭证」。常规方案生成凭证时会校验该标识为 true,它不是独立的菜单或期间状态。
⑦ subject_rules 保存生成凭证时的借贷分录规则。
subject_rules JSON 字段结构
[
{
"subjectId": 3103,
"subjectCode": "3103",
"digest": "结转本期损益",
"direction": 1,
"amountRatio": 100
},
{
"subjectId": 5001,
"subjectCode": "5001",
"digest": "结转本期损益",
"direction": 2,
"amountRatio": 100
}
]
① subjectId 指向 fms_subject,subjectCode 是科目编码快照,便于追溯规则建立时的科目体系。
② direction 借贷方向(FmsDebitCreditDirectionEnum):1 借、2 贷。
③ amountRatio 是该行占结转金额的比例,取值 0~100。保存时后端校验借方规则比例合计和贷方规则比例合计分别等于 100%,且至少两条完整分录。专用结转另有约束:转出未交增值税的借方比例必须为 100%;计提地税、计提所得税要求借贷比例相等且不超过 100%,比例同时作为计税比例参与结转金额计算。
④ 这份数组由 FmsClosingSchemeDO 的内嵌对象承载,随方案整体保存,没有独立编号和生命周期。FmsClosingTemplateDO 使用完全相同的结构,选择模板时直接复制过来。
⑧ 结转损益方案额外维护三个科目:prior_year_adjustment_subject_id 以前年度损益调整科目(必须是末级损益科目)、adjustment_closing_subject_id 和 other_closing_subject_id 两个结转科目(必须是末级非损益科目)。常用科目编码由枚举 FmsClosingPresetSubjectEnum 预置,例如 3103 本年利润、310415 未分配利润、6000 以前年度损益调整、222101 应交增值税、5801 所得税费用。
# 1.2 管理后台
结账方案没有独立菜单,卡片和弹窗都在 [财务管理 -> 结账管理 -> 结账] 页面内,对应 yudao-ui-admin-vue3 项目的 @/views/fms/closing 目录。
# 方案列表
ClosingSchemeList.vue 和 ClosingSchemeCard.vue 展示结转损益和其他结转方案的待结转余额、已生成凭证编号及操作按钮。

# 结转损益设置
点击「结转损益」方案的设置按钮,打开 ProfitLossSettingsForm.vue,填写凭证字、摘要、结转凭证类型、以前年度损益调整科目、结转科目和结转日期,由 saveProfitLossSettings 保存。

# 专用结转设置
// TODO @Codex:截图 /img/FMS财务管理/结账/专用结转设置.png —— 专用结转设置弹窗(凭证字、借贷分录规则),参考 /img/FMS财务管理/结账/结转损益设置.png。
「转出未交增值税」「计提地税」「计提所得税」由 SpecialClosingSettingsForm.vue 打开设置弹窗,维护凭证字和借贷分录规则,由 updateSpecialClosingSettings 保存,比例约束见上文 subject_rules 说明。
# 新增与修改方案
// TODO @Codex:截图 /img/FMS财务管理/结账/结转方案表单.png —— 期末结转凭证方案表单(来源科目、取数规则、分录规则),参考 /img/HRM人力资源/社保/社保方案新增.png。
点击【期末结转凭证方案】或方案卡片的设置按钮,打开 ClosingSchemeForm.vue,填写方案名称、来源科目、取数规则、时间类型、凭证字及凭证分录规则,由 createClosingScheme / updateClosingScheme 保存。
# 删除方案
deleteClosingScheme 会校验方案属于当前账套。系统预置的四类方案不提供删除。
# 2. 结账模板
结账模板,由 FmsClosingTemplateController 提供接口(/fms/closing/template)。账套初始化时,initializeClosingTemplates 从 fms/closing/closing-template-presets.json 加载预置模板。
# 2.1 表结构
CREATE TABLE `fms_closing_template` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`subject_id` bigint DEFAULT NULL COMMENT '来源科目编号',
`preset_code` varchar(64) DEFAULT NULL COMMENT '系统预置编码',
`name` varchar(255) DEFAULT NULL COMMENT '模板名称',
`category` int DEFAULT NULL COMMENT '模板分类',
`period_end` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否期末结转',
`formula_rule` int DEFAULT NULL COMMENT '取数规则',
`time_type` int DEFAULT NULL COMMENT '取数时间类型',
`subject_rules` json DEFAULT NULL COMMENT '结转科目规则数组',
`sort` int DEFAULT NULL COMMENT '显示顺序',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 结账模板';
① 模板字段是结账方案的子集:来源科目、取数规则、时间类型和 subject_rules 分录规则,不含凭证字、摘要和损益结转专用科目。选择模板后,这些字段会复制到方案表单,再由用户补齐剩余内容。
② preset_code 不为空表示系统预置模板;用户模板按账套和模板分类保存。同一账套、同一预置编码只保留一条未删除的模板。
③ 枚举 category 模板分类(FmsClosingTemplateCategoryEnum):
| 值 | 枚举 | 说明 |
|---|---|---|
1 | DAILY_EXPENSE | 日常开支 |
2 | PURCHASE_SALE | 采购销售 |
3 | CURRENT_ACCOUNT | 往来款 |
4 | TRANSFER_BUSINESS | 转账业务 |
# 2.2 管理后台

结账模板没有独立菜单,嵌入「期末结转凭证方案」弹窗,对应 ClosingTemplateSelect.vue 和内嵌的 ClosingTemplateForm.vue。
点击【期末结转凭证方案】后打开模板选择弹窗,模板按上述四个分类分组;点击【使用】或双击模板,会把模板规则复制到方案表单。弹窗内也可以新增、编辑和删除模板。
# 3. 结转凭证
结转凭证,由 FmsClosingVoucherController 提供接口(/fms/closing/voucher)。它记录结账方案与实际凭证的关联,本身不是凭证,真实凭证仍保存在 fms_voucher 和 fms_voucher_entry。
# 3.1 表结构
CREATE TABLE `fms_closing_voucher` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`closing_id` bigint DEFAULT NULL COMMENT '结账方案编号',
`voucher_id` bigint DEFAULT NULL COMMENT '凭证编号',
`voucher_time` datetime DEFAULT NULL COMMENT '凭证日期',
`amount` decimal(24,6) NOT NULL DEFAULT 0 COMMENT '结转金额',
`closed` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否已结账',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 结账凭证';
① closing_id 关联 fms_closing 表的 id 字段,voucher_id 关联 fms_voucher 表的 id 字段。
② closed 随期间结账更新:结账时由 updateClosingVoucherClosedByPeriod 置为 true,反结账时回退为 false。
③ 凭证页面通过 getClosingVoucherIdSet 识别结转凭证,这类凭证只读,不能编辑、审核或删除,详见 《【凭证】凭证管理》。
# 3.2 生成结转凭证

点击单个方案的【生成】或勾选多个方案后点击【生成凭证】,前端按方案类型调用对应方法:结转损益用 generateProfitLossVoucher,普通或专用方案用 generateClosingSchemeVoucher,批量用 generateClosingVoucherList。
生成时会校验当前会计期间未结账、凭证字存在、方案属于当前账套,并删除同期间旧的结转凭证后重新生成。生成成功后页面刷新方案余额和凭证编号,点击凭证编号可跳转到凭证详情。
生成前置条件
只能为当前会计期间生成结转凭证。如果期间已经结账、方案未配置、凭证字不存在或借贷规则不完整,后端会拒绝生成。
# 4. 期末结账
结账期间,由 FmsClosingPeriodController 提供接口(/fms/closing/period)。
# 4.1 表结构
CREATE TABLE `fms_closing_period` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`closing_time` datetime DEFAULT NULL COMMENT '结账时间(已经结账的)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 结账期间';
① 该表只记录已经结账的月份,closing_time 保存被结账的那个月份。查不到记录即表示该期间尚未结账。
② 账套的当前会计期间由最近一条记录加一个月计算(getCurrentMonth);账套尚无记录时使用账套的启用期间。
③ 上述所有关联字段都由 Service 校验账套归属,不能仅根据前端传入的方案编号跨账套生成凭证或结账。
# 4.2 状态流转
会计期间的状态由 fms_closing_period 中是否存在记录决定,流转由 FmsClosingPeriodServiceImpl 控制:
| 状态 | 判断依据 | 可执行操作 |
|---|---|---|
| 未结账 | fms_closing_period 无记录 | 录入 / 修改 / 审核凭证、生成结转凭证、结账 |
| 已结账 | fms_closing_period 有记录 | 反结账、只读查询 |
状态流转说明
未结账期间 ──检查通过──→ 生成结转凭证 ──结账──→ 已结账期间
↑ │
└────────────── 反结账 ───────────────┘
- 检查(
getClosingOverview):汇总待审核凭证、初始余额试算、凭证号连续性、损益余额和财务报表检查结果,见 §4.3 检查规则。 - 生成凭证:结转损益或结账方案生成凭证,并在
fms_closing_voucher建立方案与凭证的关联。 - 结账(
closePeriod):所有检查通过后写入fms_closing_period,并把当期结转凭证的closed更新为true。结账到未来期间时,中间月份也必须逐月通过检查。 - 反结账(
cancelClosePeriod):从最近已结账期间开始倒序删除目标期间及之后的记录,并把关联结转凭证恢复为未结账。 - 期间锁定对凭证的影响由
validatePeriodOpen落实:已结账期间的凭证不能新增、修改、删除、审核、反审核、移动和整理。
# 4.3 检查规则
结账概况汇总以下检查项,全部通过后 canClose 才为 true:
| 检查项 | 通过条件 | 处理入口 |
|---|---|---|
| 凭证审核 | 财务参数未要求审核,或期间没有待审核凭证 | 凭证管理 -> 查凭证 |
| 初始余额 | 试算平衡 | 设置管理 -> 财务初始余额 |
| 凭证编号 | 每个凭证字从 1 开始连续递增 | 凭证管理 -> 查凭证 -> 整理凭证 |
| 损益结转 | 有损益发生额时已生成结转损益凭证,损益余额为 0 | 结账 -> 结转损益 |
| 利润表 | 勾稽平衡且没有未映射一级科目 | 报表管理 -> 利润表 |
| 资产负债表 | 损益已结转、资产负债平衡且没有未映射科目 | 报表管理 -> 资产负债表 |
检查说明
「凭证审核」这一项受财务参数的 voucher_review_required 控制,关闭后未审核凭证不再阻断结账,详见 《【设置】账套管理、财务参数、财务指标》。
结转凭证由结账流程生成,不计入待审核凭证数量。检查失败时,先按页面提示处理对应业务,再重新刷新概况。
# 4.4 管理后台
对应 [财务管理 -> 结账管理 -> 结账] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/fms/closing 目录。
# 结账概况
选择会计期间后,ClosingStatusCard.vue 展示凭证审核、初始余额、凭证编号、损益结转、利润表检查、资产负债平衡和期间状态。只有当前账套的可写成员(主管、会计)才可以执行结账或反结账。

# 结账
// TODO @Codex:重截 /img/FMS财务管理/结账/结账成功.png —— 结账后概况卡全部通过、期间状态为已结账,不要截未结账页。
【结账】按钮只有在 canClose 为 true 时可用。用户确认后,服务从当前会计期间逐月执行检查并写入结账记录,页面状态从未结账切换为已结账。
# 反结账
// TODO @Codex:截图 /img/FMS财务管理/结账/反结账.png —— 已结账期间可点【反结账】,或反结账确认提示,参考 /img/FMS财务管理/结账/结账成功.png。
选择已结账期间后点击【反结账】,删除目标期间及之后的结账记录,并把关联结转凭证恢复为未结账。页面会提示反结账可能影响历史报表数据,请谨慎操作。