编辑 | blame | 历史 | 原始文档

MES/ERP/WMS/CRM 跨模块集成方案

一、整体架构概述

1.1 模块定位

模块 核心职责 业务边界
ERP 财务核算、采购销售订单管理 对外业务往来、成本核算
MES 生产执行、工艺管理、质量控制 生产过程管理
WMS 仓储管理、库存控制 实物库存管理
CRM 客户关系、销售机会、合同管理 客户侧业务管理

1.2 统一基础数据架构

采用 单一产品主数据 模式,打破模块壁垒:

┌─────────────────────────────────────────────────────────────┐
│                    基础数据层(共享)                          │
├─────────────────────────────────────────────────────────────┤
│  产品物料主数据(MD_ITEM)    ← 所有模块共用唯一产品编码        │
│  客户主数据(MD_CLIENT)      ← ERP/CRM 共用                   │
│  供应商主数据(MD_VENDOR)    ← ERP/MES 共用                   │
│  仓库主数据(MD Warehouse)   ← ERP/WMS/MES 共用               │
│  计量单位主数据(MD Unit)    ← 全局共用                       │
│  BOM 主数据(MD BOM)         ← MES/ERP 共用                   │
└─────────────────────────────────────────────────────────────┘
         ↓              ↓              ↓              ↓
    ┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐
    │   ERP   │    │   MES   │    │   WMS   │    │   CRM   │
    └─────────┘    └─────────┘    └─────────┘    └─────────┘

1.3 核心设计原则

  1. 数据唯一性:产品物料编码全局唯一,各模块通过产品ID关联
  2. 流程驱动:所有跨模块操作通过 BPM 审批流程触发
  3. 事件解耦:模块间通过事件监听机制实现联动,避免直接调用
  4. 库存中心化:WMS 作为唯一库存管理者,所有库存变动需经过 WMS

二、统一基础数据设计

2.1 产品物料主数据(核心)

表结构: md_item

字段 类型 说明 使用模块
id BIGINT 产品ID(全局唯一) 全部
code VARCHAR(64) 产品编码(全局唯一) 全部
name VARCHAR(255) 产品名称 全部
specification VARCHAR(255) 规格型号 全部
unit_measure_id BIGINT 主计量单位 全部
category_id BIGINT 产品分类 全部
item_type INT 物料类型(原料/半成品/成品/辅料) MES/ERP
is_batch_managed BOOLEAN 是否批次管理 WMS/MES
is_serial_managed BOOLEAN 是否序列号管理 WMS/MES
barcode_rule_id BIGINT 条码规则 WMS/MES
safety_stock DECIMAL 安全库存 WMS
min_order_qty DECIMAL 最小订货量 ERP
lead_time INT 采购提前期(天) ERP/MES
purchase_price DECIMAL 采购价 ERP
sales_price DECIMAL 销售价 ERP/CRM
cost_price DECIMAL 成本价 ERP
status INT 状态(启用/禁用) 全部

2.2 模块数据归属划分

数据类型 所属模块 共享范围
产品物料 MES(主)或独立模块 ERP/WMS/CRM/MES 全部共享
客户信息 CRM(主)或独立模块 ERP/MES 共享(订单/发货)
供应商信息 ERP(主)或独立模块 MES 共享(外协加工)
仓库信息 WMS(主)或独立模块 ERP/MES 共享(出入库)
BOM 信息 MES(主)或独立模块 ERP 共享(成本核算)
工艺路线 MES 独有 不共享
销售机会 CRM 独有 不共享
质检标准 MES 独有 WMS 参考

2.3 数据同步策略

┌─────────────┐     API/事件      ┌─────────────┐
│   主数据模块 │ ←──────────────→ │   业务模块   │
└─────────────┘                   └─────────────┘
       ↓                                 ↓
  数据变更事件                        本地缓存更新
       ↓                                 ↓
  发布 DomainEvent                   监听并同步

同步方式:
1. 实时同步:关键数据变更通过 Spring Event 实时通知
2. API 查询:业务模块需要详情时调用主数据模块 API
3. 本地缓存:高频访问数据在业务模块建立缓存表(仅存 ID+名称+编码)


三、跨模块业务流程集成

3.1 采购业务流程(ERP → WMS → MES)

┌─────────────────────────────────────────────────────────────────────┐
│                        采购业务完整流程                              │
└─────────────────────────────────────────────────────────────────────┘

ERP采购订单 ──(审批通过)──→ 可创建采购入库单
     ↓                         ↓
  状态变更                   ERP采购入库
     ↓                      ──(审批通过)──→
更新订单状态                    ↓
                           WMS库存增加
                                ↓
                           MES原料可用
                                ↓
                           可创建生产领料单

联动点设计:

触发点 联动操作 实现方式
ERP采购订单审批通过 订单状态=已审批,允许创建入库单 状态校验
ERP采购入库审批通过 WMS库存增加、更新采购订单已入库数量 事件监听
ERP采购入库全部完成 采购订单状态=已完成 数量判断
MES生产领料审批通过 WMS原料库存减少 事件监听

3.2 销售业务流程(CRM → ERP → WMS)

┌─────────────────────────────────────────────────────────────────────┐
│                        销售业务完整流程                              │
└─────────────────────────────────────────────────────────────────────┘

CRM销售合同 ──(审批通过)──→ 可创建ERP销售订单
     ↓                         ↓
  状态变更                   ERP销售订单
     ↓                      ──(审批通过)──→
合同履行开始                    ↓
                           可创建销售出库单
                                ↓
                           ERP销售出库
                                ↓
                           ──(审批通过)──→
                                ↓
                           WMS库存减少
                                ↓
                           ERP成本核算
                                ↓
                           CRM合同履行更新

联动点设计:

触发点 联动操作 实现方式
CRM合同审批通过 可创建ERP销售订单,关联合同ID 状态校验
ERP销售订单审批通过 订单状态=已审批,允许创建出库单 状态校验
ERP销售出库审批通过 WMS库存减少、更新销售订单已出库数量 事件监听
ERP销售出库审批通过 更新CRM合同履行进度 事件监听
ERP销售出库全部完成 销售订单状态=已完成 数量判断

3.3 生产业务流程(MES → WMS → ERP)

┌─────────────────────────────────────────────────────────────────────┐
│                        生产业务完整流程                              │
└─────────────────────────────────────────────────────────────────────┘

MES生产工单 ──(审批通过)──→ 状态=已确认
     ↓                         ↓
  自动生成BOM                可创建生产任务
     ↓                         ↓
  可创建领料单               MES生产任务执行
     ↓                      ──(任务开始)──→
MES生产领料                      ↓
     ↓                      原料消耗记录
  ──(审批通过)──→                ↓
     ↓                      ──(任务完成)──→
WMS原料库存减少                  ↓
                           MES生产入库
                                ↓
                           ──(审批通过)──→
                                ↓
                           WMS成品库存增加
                                ↓
                           ERP成本核算
                                ↓
                           MES工单完成

联动点设计:

触发点 联动操作 实现方式
MES生产工单审批通过 工单状态=已确认,可创建任务/领料单 状态校验
MES生产领料审批通过 WMS原料库存减少 事件监听
MES生产任务完成 累计生产数量、可创建入库单 状态校验
MES生产入库审批通过 WMS成品库存增加、工单生产数量累加 事件监听
MES生产入库审批通过 ERP成本核算(可选) 事件监听
MES工单全部完成 工单状态=已完成 数量判断

3.4 退货业务流程

┌─────────────────────────────────────────────────────────────────────┐
│                        退货业务流程                                  │
└─────────────────────────────────────────────────────────────────────┘

ERP采购退货 ──(审批通过)──→ WMS库存减少
     ↓
  更新采购订单退货数量

ERP销售退货 ──(审批通过)──→ WMS库存增加
     ↓
  更新销售订单退货数量

四、库存管理统一设计

4.1 库存数据模型

核心表: wms_stock

字段 类型 说明
id BIGINT 主键
item_id BIGINT 产品ID(关联 md_item)
warehouse_id BIGINT 仓库ID
location_id BIGINT 库位ID
batch_code VARCHAR(64) 批次号
quantity DECIMAL 当前库存数量
quantity_locked DECIMAL 锁定数量
quantity_available DECIMAL 可用数量 = quantity - quantity_locked
unit_measure_id BIGINT 计量单位

4.2 库存变动来源

变动类型 增减方向 来源模块 触发条件
采购入库 + ERP 采购入库单审批通过

| 销售出库 | - | ERP | 销售出库单审批通过 |
| 生产入库 | + | MES | 生产入库单审批通过 |
| 生产领料 | - | MES | 生产领料单审批通过 |
| 生产退料 | + | MES | 生产退料单审批通过 |
| 采购退货 | - | ERP | 采购退货单审批通过 |
| 销售退货 | + | ERP | 销售退货单审批通过 |
| 调拨入库 | + | WMS | 调拨单审批通过(目标仓) |
| 调拨出库 | - | WMS | 调拨单审批通过(源仓) |
| 盘盈 | + | WMS | 盘点单审批通过 |
| 盘亏 | - | WMS | 盘点单审批通过 |

4.3 库存服务 API 设计

/**
 * 库存服务接口 - WMS 模块提供,其他模块调用
 */
public interface WmsStockApi {
    
    /**
     * 创建库存记录(入库)
     */
    Long createStockRecord(StockRecordCreateDTO dto);
    
    /**
     * 锁定库存
     */
    void lockStock(Long itemId, Long warehouseId, BigDecimal quantity);
    
    /**
     * 解锁库存
     */
    void unlockStock(Long itemId, Long warehouseId, BigDecimal quantity);
    
    /**
     * 查询可用库存
     */
    BigDecimal getAvailableStock(Long itemId, Long warehouseId);
    
    /**
     * 批量查询库存
     */
    Map<Long, BigDecimal> getAvailableStockMap(List<Long> itemIds, Long warehouseId);
    
    /**
     * 校验库存充足
     */
    void validateStockEnough(Long itemId, Long warehouseId, BigDecimal quantity);
}

4.4 库存预警机制

预警类型 触发条件 通知对象
库存不足 可用库存 < 安全库存 ERP采购、MES计划
库存积压 库存 > 最高库存阈值 ERP销售
效期预警 批次效期 < 30天 WMS、MES质量
锁定超时 锁定时间 > 配置阈值 相关业务人员

五、BPM 审批流程统一设计

5.1 审批流程标识规范

模块 业务单据 流程 KEY
ERP 采购订单 erp-purchase-order-audit
ERP 销售订单 erp-sale-order-audit
ERP 采购入库 erp-purchase-in-audit
ERP 销售出库 erp-sale-out-audit
ERP 采购退货 erp-purchase-return-audit
ERP 销售退货 erp-sale-return-audit
MES 生产工单 mes-pro-work-order-audit
MES 生产领料 mes-material-issue-audit
MES 生产入库 mes-material-receive-audit
WMS 库存调拨 wms-stock-transfer-audit
WMS 库存盘点 wms-stock-check-audit
CRM 销售合同 crm-sale-contract-audit
CRM 销售报价 crm-sale-quotation-audit

5.2 审批状态枚举统一

/**
 * 统一审批状态枚举
 */
public enum AuditStatusEnum {
    DRAFT(0, "草稿"),           // 新建状态
    AUDITING(1, "审批中"),       // 已提交审批
    APPROVED(20, "已审批"),      // 审批通过
    REJECTED(30, "已拒绝"),      // 审批不通过
    CANCELLED(40, "已取消");     // 审批取消
    
    // BPM 流程状态对应:
    // BPM_RESULT_PASS = 2    → APPROVED
    // BPM_RESULT_REJECT = 3 → REJECTED
    // BPM_RESULT_CANCEL = 4 → DRAFT(退回草稿)
}

5.3 审批监听器统一模板

/**
 * 跨模块审批结果监听器基类
 */
public abstract class CrossModuleAuditListener extends BpmProcessInstanceStatusEventListener {
    
    @Override
    protected void onEvent(BpmProcessInstanceStatusEvent event) {
        // 1. 更新本模块单据状态
        updateAuditStatus(event.getBusinessKey(), event.getStatus());
        
        // 2. 触发跨模块联动(通过事件发布)
        if (event.getStatus() == 2) { // 审批通过
            publishCrossModuleEvent(event.getBusinessKey());
        }
    }
    
    /**
     * 发布跨模块联动事件
     */
    protected abstract void publishCrossModuleEvent(String businessKey);
}

六、跨模块事件机制设计

6.1 事件类型定义

事件类型 发布模块 监听模块 说明
PurchaseInApprovedEvent ERP WMS, ERP-PO 采购入库审批通过
SaleOutApprovedEvent ERP WMS, ERP-SO, CRM 销售出库审批通过
MaterialIssueApprovedEvent MES WMS 生产领料审批通过
MaterialReceiveApprovedEvent MES WMS, MES-WO 生产入库审批通过
WorkOrderApprovedEvent MES MES-Task 生产工单审批通过
ContractApprovedEvent CRM ERP 销售合同审批通过

6.2 事件数据结构

/**
 * 跨模块事件基类
 */
@Data
public abstract class CrossModuleEvent {
    /** 业务单据ID */
    private Long businessId;
    /** 业务单据编码 */
    private String businessCode;
    /** 产品ID列表 */
    private List<Long> itemIds;
    /** 仓库ID */
    private Long warehouseId;
    /** 操作时间 */
    private LocalDateTime eventTime;
    /** 操作用户ID */
    private Long userId;
    /** 租户ID */
    private Long tenantId;
}

/**
 * 采购入库审批通过事件
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class PurchaseInApprovedEvent extends CrossModuleEvent {
    /** 入库数量(按产品) */
    private Map<Long, BigDecimal> quantityMap;
    /** 关联采购订单ID */
    private Long purchaseOrderId;
}

6.3 事件发布与监听

// ERP 模块发布事件
@Component
public class ErpPurchaseInStatusListener extends CrossModuleAuditListener {
    
    @Resource
    private ApplicationEventPublisher eventPublisher;
    
    @Override
    protected void publishCrossModuleEvent(String businessKey) {
        ErpPurchaseInDO purchaseIn = purchaseInService.getPurchaseIn(Long.parseLong(businessKey));
        
        // 发布事件供其他模块监听
        eventPublisher.publishEvent(new PurchaseInApprovedEvent()
            .setBusinessId(purchaseIn.getId())
            .setItemIds(extractItemIds(purchaseIn))
            .setQuantityMap(extractQuantityMap(purchaseIn))
            .setWarehouseId(purchaseIn.getWarehouseId()));
    }
}

// WMS 模块监听事件
@Component
public class WmsStockEventListener {
    
    @EventListener
    public void onPurchaseInApproved(PurchaseInApprovedEvent event) {
        // 增加库存
        event.getQuantityMap().forEach((itemId, quantity) -> {
            stockService.createStockRecord(new StockRecordCreateDTO()
                .setItemId(itemId)
                .setWarehouseId(event.getWarehouseId())
                .setQuantity(quantity)
                .setBizType(StockBizTypeEnum.PURCHASE_IN));
        });
    }
}

// ERP 采购订单模块监听事件
@Component
public class ErpPurchaseOrderEventListener {
    
    @EventListener
    public void onPurchaseInApproved(PurchaseInApprovedEvent event) {
        // 更新采购订单已入库数量
        purchaseOrderService.updateInQuantity(event.getPurchaseOrderId(), event.getQuantityMap());
    }
}

七、实施计划

7.1 分批次实施顺序

批次 内容 模块 预估工作量
1 基础数据统一 全部 3天
2 库存服务 API WMS 2天
3 采购业务联动 ERP/WMS 2天
4 销售业务联动 ERP/WMS/CRM 2天
5 生产业务联动 MES/WMS 3天
6 退货业务联动 ERP/WMS 1天
7 事件机制完善 全部 2天
8 流程定义配置 BPM 2天
9 前端页面调整 全部 3天
10 联调测试 全部 3天

7.2 技术要点

  1. Spring Event 异步处理:跨模块事件使用 @Async 异步执行,避免事务嵌套
  2. 分布式事务:关键操作考虑使用 Seata 或本地消息表保证一致性
  3. 幂等设计:事件监听器需支持幂等,防止重复执行
  4. 租户隔离:事件数据携带 tenantId,监听时过滤

八、风险与对策

风险点 影响 对策
数据不一致 库存与实际不符 事件幂等+补偿机制+定期盘点
流程死锁 审批卡住 设置审批超时自动处理
性能瓶颈 事件队列阻塞 异步队列+批量处理
跨租户数据泄露 安全风险 事件携带租户ID+严格校验

九、总结

本方案通过以下机制实现模块间打通:

  1. 统一基础数据:产品/客户/供应商/仓库等主数据全局共享
  2. 事件驱动联动:审批通过触发跨模块事件,解耦模块依赖
  3. 库存中心化:WMS 作为唯一库存管理者,所有变动通过 API/事件
  4. 流程标准化:统一的 BPM 流程 KEY、状态枚举、监听器模板

下一步需确认:
- 主数据模块归属(是否新建独立模块)
- 分布式事务方案选择
- 具体实施优先级排序