# 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 设计 ```java /** * 库存服务接口 - 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 getAvailableStockMap(List 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 审批状态枚举统一 ```java /** * 统一审批状态枚举 */ 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 审批监听器统一模板 ```java /** * 跨模块审批结果监听器基类 */ 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 事件数据结构 ```java /** * 跨模块事件基类 */ @Data public abstract class CrossModuleEvent { /** 业务单据ID */ private Long businessId; /** 业务单据编码 */ private String businessCode; /** 产品ID列表 */ private List 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 quantityMap; /** 关联采购订单ID */ private Long purchaseOrderId; } ``` ### 6.3 事件发布与监听 ```java // 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、状态枚举、监听器模板 下一步需确认: - 主数据模块归属(是否新建独立模块) - 分布式事务方案选择 - 具体实施优先级排序