【设置】币别、科目、辅助核算、初始余额
币别、科目、辅助核算和财务初始余额模块,由 yudao-module-fms 后端模块的 config 包实现,前端实现在 @/views/fms/config/currency、@/views/fms/config/auxiliary、@/views/fms/config/subject 和 @/views/fms/config/initial-balance 目录。
这四类资料属于设置管理中的核算基础,需要按「币别 → 辅助核算 → 会计科目 → 财务初始余额」的顺序配置,后一步依赖前一步的结果。凭证字、常用摘要和凭证模板不参与建账,只服务于录凭证,见 《【设置】凭证字、常用摘要、凭证模板》。
- 币别:维护本位币和外币,供科目的外币核算使用。
- 辅助核算:按客户、供应商、职员、项目、部门、存货等类别维护核算项目,科目绑定后形成核算维度。
- 会计科目:账套的科目树,决定凭证可选科目、余额方向、数量核算和外币核算。
- 财务初始余额:录入启用期间的科目期初余额、本年累计和辅助明细,试算平衡是结账的硬性前置条件。
各配置记录都通过 account_set_id 隔离账套,系统预置数据在账套初始化时建立;凭证分录使用末级科目和辅助项目,账簿、报表与结账服务读取本篇配置和初始余额。
本文涉及表如下图所示:
# 1. 币别
币别,由 FmsCurrencyController 提供接口(/fms/config/currency)。
# 1.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
CREATE TABLE `fms_currency` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`code` varchar(64) DEFAULT NULL COMMENT '编码',
`name` varchar(255) DEFAULT NULL COMMENT '币种名称',
`exchange_rate` decimal(18,6) NOT NULL DEFAULT 0.000000 COMMENT '汇率',
`standard` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否本位币',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 币种';
① account_set_id 关联 fms_account_set 表的 id 字段。同一账套下可以维护本位币和外币,本位币由账套初始化创建,预置内容对应枚举 FmsCurrencyPresetEnum:编码 RMB、名称人民币、汇率 1。
② exchange_rate 是相对本位币的汇率,精度为 6 位小数。当前凭证主表和凭证分录没有原币金额字段,币别由账套初始化和科目的外币核算使用。
③ standard 标识本位币。页面不允许把第二条币别设置为本位币,也不允许删除本位币。
# 1.2 管理后台
对应 [财务管理 -> 设置管理 -> 币别] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/fms/config/currency 目录。
# 列表
展示币别编码、币别名称、汇率、本位币标记和创建时间。

# 新增与修改
点击【新增】或【编辑】打开 FmsCurrencyForm.vue,填写币别编码、币别名称和汇率。修改外币只影响币别主数据,不会回写历史凭证。
打开新增表单后,维护币别编码、名称和汇率;本位币由账套初始化确定,外币在此处补充。

# 删除
前端二次确认后,后端校验该币别不是账套本位币,且没有被会计科目的 currency_ids 引用(getSubjectCountByCurrencyId),否则拒绝删除。
# 2. 辅助核算
辅助核算类别,由 FmsAuxiliaryTypeController 提供接口(/fms/config/auxiliary-type);辅助核算项目,由 FmsAuxiliaryItemController 提供接口(/fms/config/auxiliary-item)。
# 2.1 主表表结构
CREATE TABLE `fms_auxiliary_type` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`name` varchar(255) DEFAULT NULL COMMENT '辅助核算名称',
`type` int DEFAULT NULL COMMENT '类型',
`system_preset` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否系统预置',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_business` (`account_set_id`, `name`, `deleted`, `tenant_id`)
) ENGINE=InnoDB COMMENT='FMS 辅助核算类别';
① account_set_id 关联 fms_account_set 表的 id 字段,类别名称在同一账套内不能重复。
② 枚举 type 辅助核算类别(FmsAuxiliaryTypeEnum):
| 值 | 枚举 | 说明 | 额外字段 |
|---|---|---|---|
1 | CUSTOMER | 客户 | 备注 |
2 | SUPPLIER | 供应商 | 备注 |
3 | EMPLOYEE | 职员 | — |
4 | PROJECT | 项目 | — |
5 | DEPARTMENT | 部门 | — |
6 | INVENTORY | 存货 | 规格、单位 |
7 | CUSTOM | 自定义 | — |
③ system_preset = 1 的类别由账套初始化建立。系统预置类别可以维护名称和项目,但删除前必须先解除科目和期初余额引用(getSubjectCountByAuxiliaryTypeId、getInitialBalanceCountByAuxiliaryTypeId)。
该表包含一个子表:
fms_auxiliary_item(辅助核算项目):在辅助核算页面右侧的项目面板中维护。
# 2.2 子表结构
CREATE TABLE `fms_auxiliary_item` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`auxiliary_type_id` bigint DEFAULT NULL COMMENT '辅助核算类别编号',
`code` varchar(64) DEFAULT NULL COMMENT '编码',
`name` varchar(255) DEFAULT NULL COMMENT '名称',
`status` int DEFAULT NULL COMMENT '状态',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`specification` varchar(255) DEFAULT NULL COMMENT '规格(存货)',
`unit` varchar(255) DEFAULT NULL COMMENT '单位(存货)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_business` (`account_set_id`, `auxiliary_type_id`, `code`, `deleted`, `tenant_id`)
) ENGINE=InnoDB COMMENT='FMS 辅助核算项目';
① auxiliary_type_id 关联 fms_auxiliary_type 表的 id 字段。同一账套、同一类别下,项目编码必须唯一。
② status 使用通用状态:0 正常、1 停用。停用项目不再出现在凭证分录的选择器中,但历史凭证的项目名称快照不受影响。
③ 普通类别只需要编码和名称;存货类别额外维护 specification 规格和 unit 单位;客户、供应商类别额外维护 remark 备注。辅助项目的导出表头和导入模板会根据类别类型动态变化。
# 2.3 辅助核算组合
科目绑定多个辅助核算类别后,「科目 + 一组辅助项目」构成一个可复用的核算维度,保存在 fms_assist_combination 表。它没有独立菜单:用户在科目、凭证或初始余额页面选择项目后,由 FmsAuxiliaryCombinationService 按账套和科目复用或创建组合。
CREATE TABLE `fms_assist_combination` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`subject_id` bigint DEFAULT NULL COMMENT '科目编号',
`items` json DEFAULT NULL COMMENT '辅助核算项目数组',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_account_subject` (`account_set_id`, `subject_id`, `deleted`, `tenant_id`)
) ENGINE=InnoDB COMMENT='FMS 辅助核算组合';
① subject_id 关联 fms_subject 表的 id 字段。凭证分录通过 assist_combination_id 指向组合,核算项目明细账和核算项目余额表按组合聚合。
② items 保存这组核算维度包含的辅助项目。
items JSON 字段结构
[
{
"type": 1,
"typeId": 12,
"itemId": 105,
"name": "杭州芋道科技"
},
{
"type": 4,
"typeId": 15,
"itemId": 208,
"name": "ERP 实施项目"
}
]
① type 辅助核算类别(FmsAuxiliaryTypeEnum):1 客户、2 供应商、3 职员、4 项目、5 部门、6 存货、7 自定义。
② typeId 指向 fms_auxiliary_type,itemId 指向 fms_auxiliary_item;name 是项目名称快照,即使项目后续改名,历史组合仍展示当时的名称。
③ 这份数组没有独立编号和生命周期,由 FmsAuxiliaryCombinationDO 的内嵌对象承载,随组合整体保存。同一科目下项目集合相同的分录会复用同一条组合记录。
# 2.4 管理后台
对应 [财务管理 -> 设置管理 -> 辅助核算] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/fms/config/auxiliary 目录。页面左侧是类别列表,右侧是当前类别的项目列表。
# 类别维护
FmsAuxiliaryTypeForm.vue 维护类别名称和类型。系统预置类别带有标识,删除前会校验科目和初始余额引用。
点击类别列表的【新增】,在弹窗中填写类别名称和类型,保存后即可在右侧维护项目。

# 项目维护
右侧 FmsAuxiliaryItemPanel.vue 按当前类别加载项目,支持关键词筛选、新增、编辑、批量删除和批量停用。项目列表按编码倒序、编号倒序查询和导出。

# 导入与导出
FmsAuxiliaryItemImportForm.vue 先下载模板再上传 Excel,模板表头按当前类别类型生成(存货类别包含规格、单位)。导出同样只包含当前类别的项目。
# 3. 会计科目
会计科目,由 FmsSubjectController 提供接口(/fms/config/subject)。
# 3.1 表结构
CREATE TABLE `fms_subject` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`parent_id` bigint NOT NULL DEFAULT 0 COMMENT '上级科目',
`code` varchar(64) DEFAULT NULL COMMENT '科目编码',
`name` varchar(255) DEFAULT NULL COMMENT '科目名称',
`type` int DEFAULT NULL COMMENT '类型',
`category` int DEFAULT NULL COMMENT '科目类别',
`balance_direction` int DEFAULT NULL COMMENT '余额方向',
`level` int DEFAULT NULL COMMENT '层级',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态',
`cash` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否现金科目',
`quantity_accounting` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否启用数量核算',
`quantity_unit` varchar(255) DEFAULT NULL COMMENT '数量核算计量单位',
`auxiliary_type_ids` json DEFAULT NULL COMMENT '辅助核算类别编号数组',
`currency_ids` json DEFAULT NULL COMMENT '核算币种编号数组',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 会计科目';
① parent_id 自关联 fms_subject 表的 id 字段,值为 0 表示根科目。科目编码按财务参数的级次和编码长度生成,新增子科目时页面会根据上级科目提示下一个编码。
② 枚举 type 科目类型(FmsSubjectTypeEnum):1 资产、2 负债、3 所有者权益、4 成本、5 损益、6 共同。
③ 枚举 category 科目类别(FmsSubjectCategoryEnum),对应字典 fms_subject_category。它是 type 的细分,两者组合唯一:
| type | category | 枚举 | 说明 |
|---|---|---|---|
| 1 | 1 | CURRENT_ASSET | 流动资产 |
| 1 | 2 | NON_CURRENT_ASSET | 非流动资产 |
| 2 | 1 | CURRENT_LIABILITY | 流动负债 |
| 2 | 2 | NON_CURRENT_LIABILITY | 非流动负债 |
| 3 | 1 | EQUITY | 所有者权益 |
| 4 | 1 | COST | 成本 |
| 5 | 1 | OPERATING_INCOME | 营业收入 |
| 5 | 2 | OTHER_INCOME | 其他收益 |
| 5 | 3 | PERIOD_EXPENSE | 期间费用 |
| 5 | 4 | OTHER_LOSS | 其他损失 |
| 5 | 5 | OPERATING_COST_AND_TAX | 营业成本及税金 |
| 5 | 6 | PRIOR_YEAR_ADJUSTMENT | 以前年度损益调整 |
| 5 | 7 | INCOME_TAX | 所得税 |
| 6 | 1 | COMMON | 共同 |
④ 枚举 balance_direction 余额方向(FmsDebitCreditDirectionEnum),对应字典 fms_debit_credit_direction:1 借、2 贷。账簿页面按财务参数的账簿余额方向模式决定显示口径。
⑤ cash = 1 标记现金及现金等价物科目,用于现金流量口径的科目标注。上级科目勾选后,下级科目会自动继承且不可取消;当前该属性只在科目页面展示和维护,现金流量表的金额仍由公式取数决定。
⑥ status 使用通用状态:0 开启、1 关闭。批量停用不会删除历史凭证,只会阻止后续选择。
⑦ auxiliary_type_ids 和 currency_ids 都是 JSON 数组,分别保存绑定的辅助核算类别编号和可核算币别编号。启用数量核算时必须填写 quantity_unit;数量金额明细账和数量金额总账只读取 quantity_accounting = 1 的科目。
auxiliary_type_ids 与 currency_ids JSON 字段结构
两个字段都是简单的编号数组,没有内嵌对象:
{
"auxiliaryTypeIds": [12, 15],
"currencyIds": [1, 3]
}
① auxiliaryTypeIds 中的编号指向 fms_auxiliary_type。数组顺序即分录中辅助项目的填写顺序,凭证保存时会按该顺序校验项目是否完整。
② currencyIds 中的编号指向 fms_currency。删除币别前会通过 getSubjectCountByCurrencyId 检查这里是否仍有引用。
③ 修改科目时如果去掉了某个辅助核算类别,页面会清理已不存在的项目映射;历史凭证分录中的项目快照不受影响。
科目还有一张系统预置模板表 fms_subject_template,它不属于任何账套,只保存会计制度的预置科目:
CREATE TABLE `fms_subject_template` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`parent_id` bigint NOT NULL DEFAULT 0 COMMENT '上级科目',
`code` varchar(64) DEFAULT NULL COMMENT '科目编码',
`name` varchar(255) DEFAULT NULL COMMENT '科目名称',
`type` int DEFAULT NULL COMMENT '类型',
`category` int DEFAULT NULL COMMENT '科目类别',
`balance_direction` int DEFAULT NULL COMMENT '余额方向',
`level` int DEFAULT NULL COMMENT '层级',
`status` int DEFAULT NULL COMMENT '状态',
`cash` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否现金科目',
`quantity_accounting` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否启用数量核算',
`quantity_unit` varchar(255) DEFAULT NULL COMMENT '数量核算计量单位',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 科目模板';
账套初始化时,initializeDefaultSubjects 按会计制度把模板树复制到 fms_subject 并补上 account_set_id。后续修改科目只影响当前账套,不会回写模板。
# 3.2 管理后台
对应 [财务管理 -> 设置管理 -> 科目设置] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/fms/config/subject 目录。
# 列表
按科目树展示编码、名称、类别、余额方向、辅助核算、数量、现金项和状态。顶部的「科目类别」筛选会重新加载当前账套的科目树;父科目和末级科目使用同一张表,前端按 parentId 组装树结构。

# 新增
点击【新增】新建根科目,点击某一行的【新增下级】则以该行作为 parentId。FmsSubjectForm.vue 依次维护科目编码、名称、类别、余额方向、辅助核算、外币核算、数量核算、数量单位和现金项。科目编码必须符合当前财务参数的级次和编码长度。

# 修改与停用
修改已使用科目时,后端会根据使用情况限制编码、类别、余额方向等关键字段。批量停用只阻止后续选择,不影响历史凭证。
# 删除
删除前先调用 getSubjectUsage 查询使用情况(下级科目、凭证分录、初始余额、辅助组合和数量数据),已经被业务使用的科目不能删除。需要调整科目体系时,应新增或迁移到新的末级科目。
# 导入与导出
点击【导入】打开 FmsSubjectImportForm.vue,先下载模板,再上传 Excel。importSubjectList 逐行校验编码、父科目、类别、余额方向、辅助核算类别和币别,返回成功编码数组和失败原因,导入失败行不会静默写入。点击【导出】按当前科目类别导出完整树。

# 4. 财务初始余额
财务初始余额,由 FmsInitialBalanceController 提供接口(/fms/config/initial-balance)。它保存启用期间的科目余额,是账簿期初和结账检查的取数来源。
# 4.1 表结构
CREATE TABLE `fms_initial_balance` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`account_set_id` bigint DEFAULT NULL COMMENT '账套编号',
`subject_id` bigint DEFAULT NULL COMMENT '科目编号',
`auxiliary_accounting` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否启用辅助核算',
`opening_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '期初金额',
`opening_quantity` decimal(18,4) NOT NULL DEFAULT 0.0000 COMMENT '期初数量',
`year_debit_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '本年累计借方金额',
`year_debit_quantity` decimal(18,4) NOT NULL DEFAULT 0.0000 COMMENT '本年累计借方数量',
`year_credit_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '本年累计贷方金额',
`year_credit_quantity` decimal(18,4) NOT NULL DEFAULT 0.0000 COMMENT '本年累计贷方数量',
`year_opening_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '年初金额',
`year_opening_quantity` decimal(18,4) NOT NULL DEFAULT 0.0000 COMMENT '年初数量',
`profit_loss_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '实际损益发生额',
`profit_loss_quantity` decimal(18,4) NOT NULL DEFAULT 0.0000 COMMENT '实际损益发生数量',
`assist_balances` json DEFAULT NULL COMMENT '辅助核算余额数组',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='FMS 科目期初余额';
① subject_id 关联 fms_subject 表的 id 字段。页面只允许对末级科目录入,父科目金额由子级汇总,不直接编辑。
② 每个科目同时保存期初余额、本年累计借方、本年累计贷方、年初余额和实际损益发生额五组数据;数量核算科目额外保存对应的数量列,非数量科目不应填入数量。
③ auxiliary_accounting = 1 时,明细金额保存在 assist_balances 中,主行金额是各组辅助余额的合计。
assist_balances JSON 字段结构
[
{
"assistCombinationId": 66,
"auxiliaries": [
{
"type": 1,
"typeId": 12,
"itemId": 105,
"name": "杭州芋道科技"
}
],
"openingAmount": 120000.00,
"openingQuantity": 0.0000,
"yearDebitAmount": 300000.00,
"yearDebitQuantity": 0.0000,
"yearCreditAmount": 180000.00,
"yearCreditQuantity": 0.0000,
"yearOpeningAmount": 0.00,
"yearOpeningQuantity": 0.0000,
"profitLossAmount": 0.00,
"profitLossQuantity": 0.0000
}
]
① 数组中每个元素是一组辅助项目组合的余额。assistCombinationId 指向 fms_assist_combination,auxiliaries 是该组合包含的项目快照,字段含义与 §2.3 辅助核算组合 的 items 一致。
② 金额和数量字段与主行一一对应,可以独立录入;主行展示的是各组的合计值。
③ 这份数组由 FmsInitialBalanceDO 的内嵌对象承载,随科目行整体保存。删除某个辅助项目前,后端会通过 getInitialBalanceCountByAuxiliaryItemIds 检查这里是否仍有引用。
# 4.2 管理后台
对应 [财务管理 -> 设置管理 -> 财务初始余额] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/fms/config/initial-balance 目录。
# 录入
① 在顶部选择科目类别,页面调用 getInitialBalanceList 加载对应科目行。
② 普通科目直接填写金额;启用辅助核算的科目点击【辅助明细】,在 FmsInitialAssistForm.vue 中按辅助类别选择项目组合并逐组录入。
启用辅助核算的科目点击【添加明细】,在弹窗中选择客户等辅助项目,再录入对应金额。

③ 数量核算科目同时填写数量和金额,系统按余额方向显示借方或贷方金额。修改金额后,父科目汇总行和底部合计会实时刷新。
④ 点击【保存】调用 saveInitialBalance,后端按账套和科目整体保存主行及辅助余额。页面有未保存修改时离开会提示确认。

# 导入与导出
点击【导入】打开 FmsInitialBalanceImportForm.vue,先下载当前账套模板再上传 Excel,导入内容仍按科目、辅助核算和数量字段校验。点击【导出】导出当前账套全部初始余额。
# 试算平衡
点击【试算平衡】打开 FmsTrialBalanceDialog.vue,由 getTrialBalance 比较期初借贷、本年累计借贷和差额。balanced = true 时才满足结账前的初始余额检查。

前置依赖与期间锁定
初始余额不是【开始记账】弹窗中的一步。必须先完成辅助类别、项目和会计科目,页面才有可录入的科目行;如果科目开启辅助核算或数量核算,还必须补齐对应明细。
结账后,当前期间的初始余额进入只读状态,不能通过页面绕过期间锁定;需要修改时先按期间倒序反结账,详见 《【结账】期末结账》。