第93天:架构篇:会计分录模板引擎——交易码动态解析为分录别再把会计分录写在代码里了!一个配置表搞定所有记账规则前两天我们聊了记账中心的攒批写入,把TPS从2000干到了8000+。小张接了一个任务:给银行核心系统加一个“新存款产品”。他打开代码,找到了记账逻辑——一个巨大的switch-case,里面有几十种交易类型的记账规则。存款走一套,取款走一套,转账走一套,理财走一套……小张找了半天,才找到存款的记账逻辑在哪里。他复制粘贴、改了几个字段、提交代码、走发布流程。三天后上线。两个月后,又有新需求——加一个“结构性存款”。小张又打开代码,又改了一遍……每加一个产品、每改一个规则,都要改代码、走发布、重启系统。如果有一天,业务人员能自己在后台配一下规则,不用等开发排期、不用走发布流程,是不是就爽了?
【一、传统做法vs 模板引擎】
public void generateVoucher(Transaction tx) {if (tx.getType().equals("DEPOSIT")) {voucherService.debit("库存现金", tx.getAmount());voucherService.credit("吸收存款", tx.getAmount());} else if (tx.getType().equals("WITHDRAW")) {voucherService.debit("吸收存款", tx.getAmount());voucherService.credit("库存现金", tx.getAmount());把“交易类型应该生成什么分录”存在数据库里,引擎根据交易码动态查表、生成分录。CREATE TABLE voucher_rule (txn_code VARCHAR(20) NOT NULL, -- 交易码direction VARCHAR(10) NOT NULL, -- DEBIT / CREDITsubject_expression VARCHAR(100) NOT NULL, -- 科目表达式amount_source VARCHAR(50), -- 金额来源| txn_code | direction | subject_expression | amount_source ||----------|-----------|-------------------|---------------|| DEP001 | DEBIT | 库存现金 | amount || DEP001 | CREDIT | 吸收存款 | amount || WTH001 | DEBIT | 吸收存款 | amount || WTH001 | CREDIT | 库存现金 | amount |加一个新交易,只需要INSERT两条记录。不写代码,不重启系统。这就是会计分录模板引擎的核心思想——规则存在库里,引擎负责执行。一个标准的会计分录,必须包含几个核心要素:会计科目、记账方向(借/贷)、金额,以及隐含的记账日期和业务摘要。模板引擎就是把这些要素“参数化”——把“写死”变成“配置”。【二、模板引擎长什么样?】
交易系统发来的记账指令里,带着txnCode(交易码)。引擎根据这个码去查规则表。根据交易码、产品类型、币种、机构等维度,匹配最合适的分录规则。public List generate(BookRequest request) {String txnCode = request.getTxnCode();List rules = ruleMapper.findByTxnCode(txnCode);throw new BusinessException("未配置分录规则");BigDecimal amount = resolveAmount(request, rules);String subject = resolveSubject(rules, request);List details = new ArrayList<>();for (VoucherRule rule : rules) {VoucherDetail detail = new VoucherDetail();detail.setDirection(rule.getDirection());detail.setSubjectCode(resolveSubject(rule.getSubjectExpression(), request));detail.setAmount(amount);【三、为什么“模板化”比“硬编码”好?】
新增一个交易类型,业务人员在后台点几下,配好借什么、贷什么,立马生效。不用写代码、不用发版、不用重启。会计科目调整,直接在配置表里修改,系统实时生效。不用等下一个发版窗口。存款、贷款、支付、理财……所有业务用同一套模板引擎。不用每个模块各写一套记账逻辑。所有规则变更都有记录——谁、什么时候、改了什么。审计的时候一清二楚。【四、模板引擎的“进阶玩法”】
subject_expression = '210101_{currency}_{branch}'引擎根据交易数据动态替换{currency}和{branch},生成210101_CNY_BJ001。同一个交易码,可以配置多套规则,通过优先级或条件判断选择。比如:大额和小额走不同的科目。每次修改规则,不覆盖旧记录,而是新增一条带生效日期的记录。引擎根据交易日期自动选择正确的规则版本。【五、模板引擎的“坑”】
硬编码错了,只影响一个交易。模板配置错了,可能影响所有用这个模板的交易。解决方案:规则变更走审批流程,测试环境验证通过后才能上线。什么规则都往配置表里塞,导致配置表越来越复杂,维护成本飙升。解决方案:核心规则配置化,复杂逻辑仍用代码实现。配置化是手段,不是目的。解决方案:规则配置加载到本地缓存(Caffeine),配置变更时刷新缓存。【六、今日小总结】
|--------|--------|----------|| 新增交易 | 改代码、发版、重启 | 配数据、即刻生效 || 规则变更 | 改代码、发版、重启 | 改配置、即刻生效 || 开发效率 | 低(每次都要写代码) | 高(配置化,一次开发长期复用) || 业务参与度 | 低(只能等开发) | 高(可自行配置) || 审计追溯 | 难(代码里找) | 易(配置表有记录) |会计分录模板引擎的核心思想:把“代码”变成“配置”,把“硬编码”变成“参数化”。业务人员配规则,引擎执行规则。各行其是,各得其所。明天我们继续:记账中心的异常处理——挂账与人工调账。今日互动:你写过的系统里,有没有把业务规则配置化的实践?评论区分享一下经验。