在企业数字化转型浪潮下,财务系统作为企业运营核心,传统模式已难以适应复杂业务需求。某大型企业通过引入Dify与基于Java(Spring boot + Mybatis plus + MySQL)自建的MCP服务,成功实现财务系统智能化升级,显著提升业务效率与决策能力,以下将详细拆解这一实战案例。
一、财务系统面临的困境与挑战
随着企业规模扩张,传统财务系统问题频出。报销审核环节,员工提交的单据涵盖差旅、采购等多种费用,财务人员需人工核对发票真伪、金额准确性及报销流程合规性,平均每份单据审核耗时长达2小时,每月因审核错误引发的纠纷多达数十起。
账务查询工作也困难重重,财务数据分散于总账、明细账、报表等多个系统,当管理层或业务部门需要特定数据时,财务人员需在不同平台间反复切换、手动整理,难以快速提供准确结果,严重影响企业决策时效性。
预算分析同样面临瓶颈,传统方式依赖人工收集数据、制作表格,无法实时监控预算执行情况,预算偏差难以及时发现和调整,导致企业资源配置不合理,资金使用效率低下 。
二、技术选型:Dify与Java(Spring boot + Mybatis plus + MySQL)的完美结合
为解决上述难题,经多方调研评估,选择Dify与Java(Spring boot + Mybatis plus + MySQL)技术组合。Spring Boot可简化项目搭建与配置,快速构建应用;Mybatis Plus在MyBatis基础上增强数据库操作功能,便于与MySQL交互;MySQL作为成熟关系型数据库,能稳定存储和管理财务数据。
Dify平台则提供便捷Agent配置与大语言模型管理功能,可将用户自然语言请求转化为后端服务调用指令,实现智能交互。该组合使企业能依据自身财务业务特点,定制开发MCP服务,打造高效智能的财务系统。
三、智能报销审核:从人工繁琐核对到智能快速处理
(一)搭建开发环境与数据库设计
搭建智能报销审核系统,先完成开发环境搭建,安装Java JDK、MySQL数据库、IDEA开发工具等。在MySQL中创建财务数据库,设计核心表结构。报销单表存储报销单号、员工ID等基本信息;报销明细项表关联报销单表,记录每笔报销的具体项目、金额与发票号码;发票信息表存储发票详细信息,通过唯一索引发票号码确保快速查询发票状态。
-- 报销单表CREATE TABLE `reimbursement_form` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `form_number` varchar(64) NOT NULL COMMENT '报销单号', `employee_id` varchar(32) NOT NULL COMMENT '员工ID', `apply_date` datetime NOT NULL COMMENT '申请日期', `total_amount` decimal(10,2) NOT NULL COMMENT '报销总金额', `status` varchar(16) NOT NULL COMMENT '报销状态(待审核、审核通过、审核不通过、已付款)', `audit_opinion` text COMMENT '审核意见', PRIMARY KEY (`id`), UNIQUE KEY `idx_form_number` (`form_number`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报销单表';-- 报销明细项表CREATE TABLE `reimbursement_detail` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `reimbursement_id` bigint NOT NULL COMMENT '报销单ID', `item_name` varchar(128) NOT NULL COMMENT '报销项目名称', `amount` decimal(10,2) NOT NULL COMMENT '项目金额', `invoice_number` varchar(64) COMMENT '发票号码', PRIMARY KEY (`id`), KEY `idx_reimbursement_id` (`reimbursement_id`), CONSTRAINT `fk_reimbursement_id` FOREIGN KEY (`reimbursement_id`) REFERENCES `reimbursement_form` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报销明细项表';-- 发票信息表CREATE TABLE `invoice_info` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `invoice_number` varchar(64) NOT NULL COMMENT '发票号码', `invoice_date` datetime NOT NULL COMMENT '开票日期', `amount` decimal(10,2) NOT NULL COMMENT '发票金额', `status` varchar(16) NOT NULL COMMENT '发票状态(有效、无效、已使用)', PRIMARY KEY (`id`), UNIQUE KEY `idx_invoice_number` (`invoice_number`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='发票信息表';
(二)使用Spring boot + Mybatis plus构建MCP服务
- 创建Spring Boot项目:在Spring Initializr中勾选Spring Web、MyBatis Plus、MySQL Driver等依赖,生成项目基础架构。配置数据库连接:在
application.yml
文件中配置数据库URL、用户名、密码、驱动类名,以及Mybatis Plus的Mapper映射文件路径和实体类别名包路径。spring: datasource: url: jdbc:mysql://localhost:3306/finance_database?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Drivermybatis-plus: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.entity
- 创建实体类:依据数据库表结构,使用
@Data
和@TableName
注解创建Java实体类,方便操作数据库数据。// 报销单实体类@Data@TableName("reimbursement_form")public class ReimbursementForm { private Long id; private String formNumber; private String employeeId; private LocalDateTime applyDate; private BigDecimal totalAmount; private String status; private String auditOpinion;}// 报销明细项实体类@Data@TableName("reimbursement_detail")public class ReimbursementDetail { private Long id; private Long reimbursementId; private String itemName; private BigDecimal amount; private String invoiceNumber;}// 发票信息实体类@Data@TableName("invoice_info")public class InvoiceInfo { private Long id; private String invoiceNumber; private LocalDateTime invoiceDate; private BigDecimal amount; private String status;}
- 创建Mapper接口:继承Mybatis Plus的BaseMapper,获取通用数据操作方法,简化数据库操作。
// 报销单Mapper接口@Mapperpublic interface ReimbursementFormMapper extends BaseMapper<ReimbursementForm> {}// 报销明细项Mapper接口@Mapperpublic interface ReimbursementDetailMapper extends BaseMapper<ReimbursementDetail> {}// 发票信息Mapper接口@Mapperpublic interface InvoiceInfoMapper extends BaseMapper<InvoiceInfo> {}
- 创建Service类实现业务逻辑:在Service层注入Mapper接口实例,编写
verifyInvoice
方法验证发票真伪,auditReimbursement
方法实现报销单全流程审核。@Servicepublic class ReimbursementService { @Autowired private ReimbursementFormMapper formMapper; @Autowired private ReimbursementDetailMapper detailMapper; @Autowired private InvoiceInfoMapper invoiceMapper; // 验证发票真伪 public boolean verifyInvoice(String invoiceNumber) { InvoiceInfo invoice = invoiceMapper.selectOne(new QueryWrapper<InvoiceInfo>().eq("invoice_number", invoiceNumber)); return invoice != null && "有效".equals(invoice.getStatus()); } // 审核报销单 public String auditReimbursement(ReimbursementForm form) { List<ReimbursementDetail> details = detailMapper.selectList(new QueryWrapper<ReimbursementDetail>().eq("reimbursement_id", form.getId())); BigDecimal totalAmount = BigDecimal.ZERO; for (ReimbursementDetail detail : details) { totalAmount = totalAmount.add(detail.getAmount()); if (!verifyInvoice(detail.getInvoiceNumber())) { form.setStatus("审核不通过"); form.setAuditOpinion("发票无效"); formMapper.updateById(form); return "审核不通过"; } } if (totalAmount.compareTo(form.getTotalAmount()) != 0) { form.setStatus("审核不通过"); form.setAuditOpinion("报销总金额与明细金额不符"); formMapper.updateById(form); return "审核不通过"; } form.setStatus("审核通过"); form.setAuditOpinion("审核通过"); formMapper.updateById(form); return "审核通过"; }}
- 配置MCP服务:在配置类中,通过
MethodToolCallbackProvider.builder()
将报销审核相关Service配置为MCP服务,使其能被Dify平台调用。@Configurationpublic class McpConfig { @Bean public ToolCallbackProvider reimbursementTools(ReimbursementService reimbursementService) { return MethodToolCallbackProvider.builder() .toolObjects(reimbursementService) .build(); }}
(三)Dify平台配置:实现智能交互
- 安装MCP插件:在Dify平台安装支持MCP工具的Agent策略插件,为后续配置做准备。配置MCP服务地址:按照平台要求,以JSON格式配置MCP服务地址,明确传输协议、URL、请求头、超时时间等参数。
{ "reimbursement_service": { "transport": "sse", "url": "http://127.0.0.1:8080/reimbursement/sse", "headers": {}, "timeout": 50, "sse_read_timeout": 50 }}
- 配置Agent:创建报销审核Agent,选择合适大语言模型,配置指令。当用户提问包含“报销审核”“审核结果”等关键词时,提取报销单号调用
auditReimbursement
工具;询问发票有效性时,提取发票号码调用verifyInvoice
工具;其他情况直接回答,保证回复清晰准确。分析用户输入的{{#sys.query#}}:1. 若包含“报销审核”“审核结果”等关键词,提取报销单号,调用工具“auditReimbursement”,将报销单信息作为参数传入;2. 若询问“发票是否有效”,提取发票号码,调用工具“verifyInvoice”,将发票号码作为参数传入;3. 其他情况,直接回答用户问题。优化回复格式,确保清晰准确。
四、智能账务查询:从多系统手动检索到一键精准获取
(一)扩展数据库表与服务层功能
为实现智能账务查询,扩展数据库表结构,新增总账表和明细账表。总账表记录科目编号、名称、期初余额等信息;明细账表记录每笔交易详细信息。在Service层添加getGeneralLedgerBalance
查询总账科目余额,getSubsidiaryLedger
查询明细账等方法。
-- 总账表CREATE TABLE `general_ledger` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `account_number` varchar(32) NOT NULL COMMENT '科目编号', `account_name` varchar(128) NOT NULL COMMENT '科目名称', `beginning_balance` decimal(10,2) NOT NULL COMMENT '期初余额', `debit_amount` decimal(10,2) NOT NULL COMMENT '借方发生额', `credit_amount` decimal(10,2) NOT NULL COMMENT '贷方发生额', `ending_balance` decimal(10,2) NOT NULL COMMENT '期末余额', `accounting_period` varchar(16) NOT NULL COMMENT '会计期间', PRIMARY KEY (`id`), UNIQUE KEY `idx_account_number` (`account_number`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='总账表';-- 明细账表CREATE TABLE `subsidiary_ledger` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `transaction_id` varchar(64) NOT NULL COMMENT '交易单号', `account_number` varchar(32) NOT NULL COMMENT '科目编号', `transaction_date` datetime NOT NULL COMMENT '交易日期', `description` text COMMENT '交易描述', `debit_amount` decimal(10,2) COMMENT '借方金额', `credit_amount` decimal(10,2) COMMENT '贷方金额', PRIMARY KEY (`id`), KEY `idx_account_number` (`account_number`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='明细账表';
@Servicepublic class AccountQueryService { @Autowired private GeneralLedgerMapper ledgerMapper; @Autowired private SubsidiaryLedgerMapper subsidiaryMapper; // 查询总账科目余额 public GeneralLedger getGeneralLedgerBalance(String accountNumber, String accountingPeriod) { return ledgerMapper.selectOne(new QueryWrapper<GeneralLedger>() .eq("account_number", accountNumber) .eq("accounting_period", accountingPeriod)); } // 查询明细账 public List<SubsidiaryLedger> getSubsidiaryLedger(String accountNumber) { return subsidiaryMapper.selectList(new QueryWrapper<SubsidiaryLedger>().eq("account_number", accountNumber)); }}
(二)Dify平台配置:智能查询的实现
在Dify平台为账务查询配置Agent,设置指令。当用户询问包含“总账余额”“科目余额”等关键词时,提取科目编号和会计期间,调用getGeneralLedgerBalance
工具;询问明细账时,提取科目编号,调用getSubsidiaryLedger
工具;其他情况直接回答,并将结果整理成清晰表格返回。
分析用户输入的{{#sys.query#}}:1. 若包含“总账余额”“科目余额”等关键词,提取科目编号和会计期间,调用工具“getGeneralLedgerBalance”;2. 若询问“明细账”,提取科目编号,调用工具“getSubsidiaryLedger”;3. 其他情况,直接回答用户问题。将查询结果整理为清晰的表格形式返回。
(三)实际效果:快速响应决策需求
智能账务查询系统让管理层和业务部门能快速获取财务数据。以往需数天手动整理的数据,如今几分钟内就能得到准确结果,极大提升企业决策的及时性和准确性。例如在制定月度经营计划时,业务部门可迅速查询相关科目收支情况,为计划制定提供有力数据支持。
五、智能预算分析:从静态人工编制到动态智能监控
(一)数据库与服务层的预算相关功能开发
设计预算表结构,包含预算项目、金额、实际支出、预算期间等字段。在Service层编写createBudget
方法插入预算数据,monitorBudget
方法对比预算与实际支出,判断预算执行情况。
-- 预算表CREATE TABLE `budget` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `budget_item` varchar(128) NOT NULL COMMENT '预算项目', `budget_amount` decimal(10,2) NOT NULL COMMENT '预算金额', `actual_amount` decimal(10,2) DEFAULT '0.00' COMMENT '实际支出金额', `budget_period` varchar(16) NOT NULL COMMENT '预算期间', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='预算表';
@Servicepublic class BudgetAnalysisService { @Autowired private BudgetMapper budgetMapper; // 编制预算 public void createBudget(Budget budget) { budgetMapper.insert(budget); } // 监控预算执行情况 public String monitorBudget(String budgetItem, String budgetPeriod) { Budget budget = budgetMapper.selectOne(new QueryWrapper<Budget>() .eq("budget_item", budgetItem) .eq("budget_period", budgetPeriod)); if (budget == null) { return "无相关预算信息"; } BigDecimal deviation = budget.getBudgetAmount().subtract(budget.getActualAmount()); if (deviation.compareTo(BigDecimal.ZERO) < 0) { return "预算超支,超支金额:" + deviation.abs(); } else { return "预算执行正常,剩余金额:" + deviation; } }}
(二)Dify平台配置:智能预算交互
在Dify平台配置预算分析Agent,设置指令:
分析用户输入的{{#sys.query#}}:1. 若涉及"预算编制",提取预算项目、金额和期间,调用工具"createBudget";2. 若询问"预算执行情况",提取预算项目和期间,调用工具"monitorBudget";3. 其他情况,直接回答用户问题。
(三)实际效果:资源配置优化与成本控制
智能预算分析系统实现了预算的动态监控,能够实时对比预算与实际支出情况。通过对预算执行的精细化管理,企业在保持业务增长的同时,将成本控制在合理范围内,资源配置效率提升了25%。
六、用户模拟提问与智能回答案例
(一)智能报销审核场景
用户提问1:"我提交的报销单F20230615001审核通过了吗?"
系统回答:您好,您的报销单F20230615001已审核通过,报销总金额为2,560.00元。明细如下:
报销项目 | 金额 | 发票号码 |
---|---|---|
差旅费-机票 | 1,800 | 0012345678 |
住宿费 | 680 | 0012345679 |
市内交通费 | 80 | 0012345680 |
用户提问2:"发票0012345678是有效的吗?"
系统回答:是的,您提供的发票0012345678有效,金额为1,800.00元,开票日期为2023年6月10日。
(二)智能账务查询场景
用户提问3:"请查询一下管理费用-办公费科目在2023年第二季度的总账余额。"
系统回答:以下是管理费用-办公费(科目编号660201)在2023年第二季度的总账余额信息:
项目 | 金额(元) |
---|---|
期初余额 | 0.00 |
借方发生额 | 125,800.00 |
贷方发生额 | 0.00 |
期末余额 | 125,800.00 |
用户提问4:"请查询一下固定资产-电子设备科目的明细账。"
系统回答:以下是固定资产-电子设备(科目编号160103)的明细账记录:
交易单号 | 交易日期 | 借方金额(元) | 贷方金额(元) | 交易描述 |
---|---|---|---|---|
JY20230401001 | 2023-04-05 | 58,000.00 | 0.00 | 购买办公电脑 |
JY20230415002 | 2023-04-18 | 36,500.00 | 0.00 | 购买打印机 |
JY20230520003 | 2023-05-22 | 12,800.00 | 0.00 | 购买投影仪 |
JY20230610004 | 2023-06-15 | 0.00 | 5,800.00 | 处置旧电脑 |
(三)智能预算分析场景
用户提问5:"请帮我编制一个2023年第三季度市场推广费用的预算,预计金额为30万元。"
系统回答:已成功为您创建2023年第三季度市场推广费用预算,预算金额为300,000.00元。您可以随时通过"预算执行情况"查询功能查看预算使用进度。
用户提问6:"2023年第二季度研发费用的预算执行情况如何?"
系统回答:2023年第二季度研发费用预算执行情况如下:
- 预算金额:250,000.00元实际支出:235,800.00元预算执行率:94.32%剩余金额:14,200.00元
目前预算执行正常,未出现超支情况。建议持续监控研发项目进度,确保资源合理使用。
七、遇到的问题与解决方案
(一)系统集成挑战:多系统数据互通难题
在与企业现有ERP、OA等系统集成时,遇到了数据格式不统一、接口标准不一致等问题。通过开发数据转换中间件,实现了不同系统间的数据格式转换和接口适配,确保了数据的顺畅流通。
(二)大语言模型理解偏差:专业术语识别不准确
财务领域存在大量专业术语,大语言模型在理解时容易出现偏差。通过构建财务专业词库,对模型进行针对性训练,提高了模型对财务术语的识别准确率。同时,在Agent指令中增加了关键词提取和语义分析逻辑,进一步提升了系统的理解能力。
(三)性能优化需求:高并发下的系统响应
在报销高峰期,系统面临高并发请求的压力,导致响应速度下降。通过对数据库进行索引优化、引入缓存机制和负载均衡技术,有效提升了系统的并发处理能力,确保了在高负载情况下的稳定运行。
八、总结
Dify 与 Java 自建 MCP 服务的财务系统智能化升级项目,为企业财务数字化转型提供了可落地的参考依据。在实践过程中,技术选型与业务场景的适配是关键。Spring Boot、MyBatis Plus 和 MySQL 的组合,保障了数据处理的高效性与稳定性;Dify 平台则通过灵活的 Agent 配置,实现自然语言与财务业务逻辑的无缝衔接。同时,数据治理、用户培训等配套措施的同步推进,有效避免了 “重技术轻运营” 的常见问题。财务智能化转型需遵循三大原则:一是以业务痛点为驱动,避免技术堆砌;二是构建 “平台 + 定制” 的技术架构,兼顾标准化与个性化需求;三是重视数据资产的沉淀与治理,为智能决策奠定基础。随着人工智能与财务领域的融合不断深化,这种基于大语言模型的 MCP 服务架构,有望成为企业财务数字化升级的主流方案。