scaffold-finance 财务模块

模块概述

scaffold-finance 是 Scaffold v2 的财务管理模块,提供企业级财务核算能力。涵盖会计科目、会计期间、凭证管理、科目余额、辅助核算、应收/应付、收付款、费用报销、预算管理、固定资产、账龄分析、银行对账、财务报表等 16 个功能子域。采用 SPI 架构(FinanceEvent / FinanceSubjectMapper / FinanceVoucherGenerator)实现业务事件到财务凭证的自动转换,业务模块只需发布事件即可自动生成凭证和更新余额。

功能列表

  • 会计科目管理:科目树 CRUD,支持多级科目、启用/禁用
  • 会计期间管理:创建期间、开账、结账、反结账、期末结转、反结转
  • 凭证管理:手工创建/更新/审核/作废凭证,支持 BPM 审核流程
  • 科目余额查询:按期间查询科目余额,试算平衡表
  • 结算账户管理:银行/现金账户 CRUD
  • 辅助核算维度:自定义核算维度(部门/项目等),辅助余额跟踪
  • 应收账款:应收账款 CRUD
  • 应付账款:应付账款 CRUD
  • 收款管理:收款单创建(含核销应收)
  • 付款管理:付款单创建(含核销应付)
  • 费用报销:报销单 CRUD,支持 BPM 审批流程
  • 预算管理:预算编制、生效、执行跟踪
  • 固定资产:资产登记、折旧执行、处置审批
  • 账龄分析与核销:应收/应付账龄分析,核销记录查询
  • 银行对账:导入银行流水、自动对账、手工匹配
  • 财务报表:生成/查询报表快照

状态字段规范

  • is_enabled 字段(期间、账户)遵循布尔语义:1 = 启用,0 = 禁用

核心组件

分层架构

职责
Controller 16 个 Controller(见下方 API 列表) REST 接口
Service 对应 16 个 Service + FinanceEngine 业务逻辑
Repository 对应实体数量的 Repository 数据访问
Mapper 对应实体数量的 Mapper ORM 映射

数据实体(23 个)

实体 说明
FinanceSubject 会计科目
FinancePeriod 会计期间
FinanceVoucher 凭证
FinanceVoucherEntry 凭证分录
FinanceSettlement 结算账户
FinanceBalance 科目余额
FinanceAuxDimension 辅助核算维度
FinanceAuxBalance 辅助余额
FinanceReceivable 应收账款
FinancePayable 应付账款
FinanceReceipt 收款单
FinancePayment 付款单
FinanceExpenseClaim 报销单
FinanceExpenseItem 报销明细
FinanceBudget 预算
FinanceBudgetItem 预算明细
FinanceAsset 固定资产
FinanceAssetDepreciation 折旧记录
FinanceAssetDisposal 资产处置
FinanceWriteoff 核销记录
FinanceBankReconciliation 银行对账记录
FinanceBankStatement 银行流水
FinanceReportSnapshot 报表快照

SPI 架构

SPI 接口定义在 scaffold-common 模块,scaffold-finance 提供默认实现。业务模块注入 FinanceEventPublisher 即可与财务模块交互。

FinanceEvent -- 财务事件

public interface FinanceEvent {
    String getSourceType();       // 事件来源,如 "pay_order"、"refund"、"asset_depreciation"
    Long getSourceId();           // 来源业务 ID
    FinanceEventType getEventType(); // 事件类型
    Long getAmount();             // 金额(分)
    String getCurrency();         // 币种,默认 CNY
    String getSummary();          // 业务摘要
    LocalDateTime getEventTime(); // 事件时间
    Map<String, Long> getAuxAccounting(); // 辅助核算维度
}

FinanceSubjectMapper -- 科目映射

根据事件来源类型映射到借方/贷方科目编码。业务模块实现此接口定义业务到科目的映射规则。

public interface FinanceSubjectMapper {
    String supportsSourceType();
    Map<String, String> mapSubjects(FinanceEvent event); // "debit" -> 科目编码, "credit" -> 科目编码
}

FinanceVoucherGenerator -- 凭证生成器

根据事件生成凭证分录。业务模块可实现此接口自定义分录生成逻辑。

public interface FinanceVoucherGenerator {
    String supportsSourceType();
    List<VoucherEntryDTO> generateEntries(FinanceEvent event);
}

FinanceEventPublisher -- 事件发布器

public interface FinanceEventPublisher {
    void publish(FinanceEvent event);
    void publishBatch(List<FinanceEvent> events);
}
  • 默认实现:DefaultFinanceEventPublisher(委托 FinanceEngine 处理)
  • 空实现:NopFinanceEventPublisher(当 scaffold-finance 未启用时自动配置)

FinanceEngine -- 财务引擎

核心处理流程:接收事件 -> 查找 SPI 映射 -> 校验期间 -> 校验借贷平衡 -> 生成凭证 -> 更新余额 -> 更新辅助余额。

  1. 根据 sourceType 查找 FinanceSubjectMapperFinanceVoucherGenerator
  2. 校验当前是否有已开账的会计期间
  3. 调用 VoucherGenerator.generateEntries() 生成分录
  4. 校验借贷平衡(借方合计 = 贷方合计)
  5. 创建凭证和分录记录
  6. 更新科目余额(期初/本期/期末)
  7. 更新辅助核算余额

配置参数

配置前缀:scaffold.finance

参数 类型 默认值 说明
enabled boolean true 模块开关
default-currency String CNY 默认币种
voucher-number-pattern String PZ{year}{month}{seq} 凭证编号格式,支持 {year}、{month}、{seq} 占位符

API 接口列表

FinanceSubjectController -- 会计科目管理 (/v1/finance/subject)

方法 路径 说明
POST /page 分页查询科目
POST /create 创建科目
POST /update 更新科目
GET /detail?id= 科目详情
POST /delete?id= 删除科目
POST /toggle-enabled?id= 切换启用状态

FinancePeriodController -- 会计期间管理 (/v1/finance/period)

方法 路径 说明
POST /page 分页查询期间
POST /create 创建期间
GET /detail?id= 期间详情
POST /open?id= 开账
POST /close?id= 结账
POST /reopen?id= 反结账
POST /settle?id= 期末结转
POST /unsettle?id= 反结转

FinanceVoucherController -- 凭证管理 (/v1/finance/voucher)

方法 路径 说明
POST /page 分页查询凭证
POST /create 手工创建凭证
POST /update 更新凭证(仅草稿/已驳回)
GET /detail?id= 凭证详情(含分录)
POST /audit 审核/作废凭证
POST /delete?id= 删除凭证(仅草稿)
POST /submit-audit?id= 提交 BPM 审核
POST /auditCallback BPM 审核回调

FinanceSettlementController -- 结算账户管理 (/v1/finance/settlement)

方法 路径 说明
POST /page 分页查询结算账户
POST /create 创建结算账户
POST /update 更新结算账户
GET /detail?id= 结算账户详情
POST /delete?id= 删除结算账户
POST /toggle-enabled?id= 切换启用状态

FinanceBalanceController -- 科目余额查询 (/v1/finance/balance)

方法 路径 说明
POST /page 分页查询科目余额
POST /trial-balance 试算平衡表

FinanceAuxDimensionController -- 辅助核算维度管理 (/v1/finance/aux-dimension)

方法 路径 说明
POST /page 分页查询维度
POST /create 创建维度
POST /update 更新维度
GET /detail?id= 维度详情
POST /delete?id= 删除维度

FinanceReceivableController -- 应收账款管理 (/v1/finance/receivable)

方法 路径 说明
POST /page 分页查询应收账款
POST /create 创建应收账款
GET /detail?id= 应收账款详情
POST /delete?id= 删除应收账款

FinancePayableController -- 应付账款管理 (/v1/finance/payable)

方法 路径 说明
POST /page 分页查询应付账款
POST /create 创建应付账款
GET /detail?id= 应付账款详情
POST /delete?id= 删除应付账款

FinanceReceiptController -- 收款管理 (/v1/finance/receipt)

方法 路径 说明
POST /page 分页查询收款单
POST /create 创建收款单(含核销)
GET /detail?id= 收款单详情
POST /delete?id= 删除收款单

FinancePaymentController -- 付款管理 (/v1/finance/payment)

方法 路径 说明
POST /page 分页查询付款单
POST /create 创建付款单(含核销)
GET /detail?id= 付款单详情
POST /delete?id= 删除付款单

FinanceExpenseClaimController -- 费用报销管理 (/v1/finance/expense)

方法 路径 说明
POST /page 分页查询报销单
POST /create 创建报销单
GET /detail?id= 报销单详情
POST /delete?id= 删除报销单
POST /submit-audit?id= 提交审批

FinanceBudgetController -- 预算管理 (/v1/finance/budget)

方法 路径 说明
POST /page 分页查询预算
POST /create 创建预算
GET /detail?id= 预算详情
POST /delete?id= 删除预算
POST /activate?id= 预算生效

FinanceReportController -- 财务报表管理 (/v1/finance/report)

方法 路径 说明
POST /generate 生成报表
GET /snapshot 查询报表快照

FinanceAssetController -- 固定资产管理 (/v1/finance/asset)

方法 路径 说明
POST /page 分页查询资产
POST /create 新增资产
GET /detail?id= 资产详情
POST /depreciation/execute 执行折旧
GET /depreciation/history?assetId= 折旧历史
POST /disposal/create 提交处置
POST /disposal/page 处置记录分页
POST /disposal/auditCallback?disposalId=&approved= 处置审批回调

FinanceAgingController -- 账龄分析与核销查询 (/v1/finance/aging)

方法 路径 说明
POST /analyze 账龄分析
POST /writeoff/page 核销记录分页查询

FinanceBankReconciliationController -- 银行对账管理 (/v1/finance/bank)

方法 路径 说明
POST /statement/import 导入银行流水
POST /statement/page 银行流水分页
POST /reconciliation/auto?periodId=&settlementId= 触发自动对账
POST /reconciliation/page 对账结果分页
POST /reconciliation/manual 手工匹配

使用示例

1. 通过 SPI 发布财务事件

业务模块(如支付模块)支付成功后自动生成凭证:

@Autowired
private FinanceEventPublisher financeEventPublisher;

public void onPaySuccess(PayOrder order) {
    FinanceEvent event = new FinanceEvent() {
        public String getSourceType() { return "pay_order"; }
        public Long getSourceId() { return order.getId(); }
        public FinanceEventType getEventType() { return FinanceEventType.INCOME; }
        public Long getAmount() { return order.getAmount(); }
        public String getSummary() { return "订单支付入账: " + order.getOrderNo(); }
        public LocalDateTime getEventTime() { return LocalDateTime.now(); }
    };
    financeEventPublisher.publish(event);
}

2. 实现科目映射 SPI

@Component
public class PayOrderSubjectMapper implements FinanceSubjectMapper {
    @Override
    public String supportsSourceType() { return "pay_order"; }

    @Override
    public Map<String, String> mapSubjects(FinanceEvent event) {
        return Map.of("debit", "1002", "credit", "6001"); // 银行存款 / 主营业务收入
    }
}

3. 实现凭证生成器 SPI

@Component
public class PayOrderVoucherGenerator implements FinanceVoucherGenerator {
    @Override
    public String supportsSourceType() { return "pay_order"; }

    @Override
    public List<VoucherEntryDTO> generateEntries(FinanceEvent event) {
        return List.of(
            VoucherEntryDTO.builder().subjectCode("1002").debit(event.getAmount()).summary("收款").build(),
            VoucherEntryDTO.builder().subjectCode("6001").credit(event.getAmount()).summary("收入").build()
        );
    }
}

4. 手工创建凭证

POST /v1/finance/voucher/create
{
  "periodId": 100,
  "voucherDate": "2026-04-26",
  "summary": "手工调整凭证",
  "entries": [
    {"subjectCode": "1002", "debit": 10000, "credit": 0, "summary": "借记银行存款"},
    {"subjectCode": "6001", "debit": 0, "credit": 10000, "summary": "贷记主营业务收入"}
  ]
}

注意事项

  1. SPI 自动发现:FinanceSubjectMapper 和 FinanceVoucherGenerator 实现类需标记 @Component,FinanceEngine 通过 Spring 自动注入 List<FinanceSubjectMapper>List<FinanceVoucherGenerator> 进行匹配
  2. 期间校验:自动生成凭证时,必须存在已开账的会计期间且事件日期在期间范围内
  3. 借贷平衡:每张凭证的借方合计必须等于贷方合计,否则 FinanceEngine 会抛出 BusinessException
  4. 凭证编号:按 scaffold.finance.voucher-number-pattern 格式自动生成,默认 PZ{year}{month}{seq}
  5. 金额单位:所有金额字段统一使用分为单位(Long 类型),与支付模块保持一致
  6. BPM 集成:凭证审核和费用报销均支持 BPM 审批流程,通过 BpmIntegrationService 可插拔集成
  7. 模块降级:当 scaffold-finance 未启用时,scaffold-common 自动配置 NopFinanceEventPublisher(空实现),不会影响业务模块编译和运行
  8. 状态枚举
    • is_enabled 字段(期间、账户)遵循布尔语义:1 = 启用,0 = 禁用
    • VoucherStatusPeriodStatusReceivableStatusPayableStatusExpenseStatusBudgetStatusMatchStatus 等为多态状态机,不遵循布尔语义规范

待完善功能

  • 费用报销 BPM 审批流程集成(FinanceExpenseClaimServiceImpl 中的 TODO:调用 BPM 发起审批流程)