# 项目架构说明文档 ## 📋 项目主体架构 ### 核心主体:TaskExecutionEngine(任务执行引擎) **位置**:`com.mes.task.service.TaskExecutionEngine` **职责**:多设备任务执行的核心引擎,负责: - 串行/并行执行模式控制 - 设备步骤执行调度 - 设备协调检查 - 错误处理和重试 - 实时状态通知 ## 🔄 调用流程 ### 1. 任务启动流程 ``` 用户请求 (Controller) ↓ MultiDeviceTaskServiceImpl.startTask() ├─ 验证设备组 ├─ 获取设备列表 ├─ 创建任务记录 (PENDING) └─ 异步执行 executeTaskAsync() ↓ TaskExecutionEngine.execute() ├─ 设备协调检查 (DeviceCoordinationService) ├─ 确定执行模式 (串行/并行) └─ 执行设备步骤 ``` ### 2. 设备步骤执行流程 ``` TaskExecutionEngine.executeStep() ↓ 检查是否有 DeviceInteraction ├─ 有 → executeInteractionStepWithRetry() │ ↓ │ DeviceInteraction.execute(InteractionContext) │ ↓ │ 具体设备交互实现(如 LoadVehicleInteraction) │ ↓ │ 调用 DeviceInteractionService │ ↓ │ 最终调用 DeviceLogicHandler │ └─ 无 → 直接调用 DeviceLogicHandler ↓ DeviceLogicHandlerFactory.getHandler(deviceType) ↓ BaseDeviceLogicHandler.execute() ↓ 子类实现 doExecute() ``` ### 3. 两种执行路径 #### 路径A:通过 DeviceInteraction(推荐用于复杂设备) ``` TaskExecutionEngine ↓ DeviceInteraction.execute(InteractionContext) ↓ 具体实现类(如 LoadVehicleInteraction) ├─ 状态检查 ├─ 设备选择(多实例协调) ├─ 数据准备 └─ 调用 DeviceInteractionService ↓ DeviceLogicHandler.execute() ``` **适用场景**: - 需要多实例协调的设备(如大车设备) - 需要复杂前置检查的设备 - 需要数据转换和准备的设备 #### 路径B:直接调用 DeviceLogicHandler(简单设备) ``` TaskExecutionEngine ↓ DeviceLogicHandlerFactory.getHandler(deviceType) ↓ BaseDeviceLogicHandler.execute() ├─ 参数解析 ├─ 逻辑参数提取 (extraParams.deviceLogic) └─ 子类实现 doExecute() ``` **适用场景**: - 简单设备,逻辑单一 - 不需要复杂协调的设备 ## 🏗️ 分层架构 ### 第一层:Controller 层(API入口) **位置**:`com.mes.task.controller.*` **职责**: - 接收HTTP请求 - 参数验证 - 调用Service层 **主要类**: - `MultiDeviceTaskController` - 任务管理API - `TaskStatusNotificationController` - SSE实时通知API ### 第二层:Service 层(业务逻辑) **位置**:`com.mes.task.service.*` **职责**: - 业务逻辑处理 - 事务管理 - 调用执行引擎 **主要类**: - `MultiDeviceTaskServiceImpl` - 任务服务实现 - 创建任务记录 - 异步执行任务 - 任务状态管理 - `TaskExecutionEngine` - **核心执行引擎** - 设备协调检查 - 执行模式判断(串行/并行) - 步骤执行调度 - 重试机制 ### 第三层:Interaction 层(设备交互) **位置**:`com.mes.interaction.*` **职责**: - 设备交互逻辑封装 - 多设备协调 - 数据传递 **主要组件**: #### 3.1 DeviceInteraction(设备交互接口) **接口**:`com.mes.interaction.DeviceInteraction` **实现类示例**: - `LoadVehicleInteraction` - 大车设备交互 - `LargeGlassInteraction` - 大理片笼交互 - `GlassStorageInteraction` - 玻璃存储交互 **注册机制**: - `DeviceInteractionRegistry` - 自动注册所有 `@Component` 的 `DeviceInteraction` 实现 #### 3.2 DeviceLogicHandler(设备逻辑处理器) **接口**:`com.mes.interaction.DeviceLogicHandler` **基类**:`BaseDeviceLogicHandler` - 提供通用功能: - 参数解析 - 逻辑参数提取(从 `extraParams.deviceLogic`) - 错误处理 **实现类示例**: - `LoadVehicleLogicHandler` - 大车设备逻辑 - `HorizontalScannerLogicHandler` - 卧转立扫码逻辑 - `HorizontalTransferLogicHandler` - 卧转立逻辑 - `LargeGlassLogicHandler` - 大理片笼逻辑 **注册机制**: - `DeviceLogicHandlerFactory` - 自动注册所有 `DeviceLogicHandler` 实现 - 通过 `@PostConstruct` 初始化映射表 ### 第四层:Coordination 层(设备协调) **位置**:`com.mes.device.service.*` 和 `com.mes.interaction.*.coordination.*` **职责**: - 设备间数据传递 - 设备状态同步 - 设备依赖管理 - 多实例协调 **主要类**: - `DeviceCoordinationService` - 通用设备协调服务 - `VehicleCoordinationService` - 大车设备协调服务 - `VehicleStatusManager` - 大车状态管理器 ### 第五层:PLC 操作层(硬件通信) **位置**:`com.mes.device.service.DevicePlcOperationService` **职责**: - PLC读写操作 - 地址映射 - 通信管理 ## 📦 如何添加新设备 ### 步骤1:定义设备类型常量 在 `DeviceConfig.DeviceType` 中添加: ```java public static final class DeviceType { public static final String NEW_DEVICE = "新设备类型"; } ``` ### 步骤2:创建设备逻辑处理器(必须) **位置**:`com.mes.interaction.*.handler.NewDeviceLogicHandler` ```java @Component public class NewDeviceLogicHandler extends BaseDeviceLogicHandler { @Override public String getDeviceType() { return DeviceConfig.DeviceType.NEW_DEVICE; } @Override protected DevicePlcVO.OperationResult doExecute( DeviceConfig deviceConfig, String operation, Map params, Map logicParams) { // 1. 从 logicParams 中获取配置参数 Integer timeout = getLogicParam(logicParams, "timeout", 5000); String mode = getLogicParam(logicParams, "mode", "default"); // 2. 从 params 中获取运行时参数 String glassId = (String) params.get("glassId"); // 3. 执行设备逻辑 // ... 具体实现 // 4. 调用PLC操作 Map plcParams = new HashMap<>(); plcParams.put("field1", value1); DevicePlcVO.OperationResult result = devicePlcOperationService.writePlcData(deviceConfig, plcParams); return result; } @Override protected Map getDefaultLogicParams() { Map defaults = new HashMap<>(); defaults.put("timeout", 5000); defaults.put("mode", "default"); return defaults; } } ``` **自动注册**: - 实现 `DeviceLogicHandler` 接口 - 添加 `@Component` 注解 - `DeviceLogicHandlerFactory` 会自动发现并注册 ### 步骤3:创建设备交互类(可选,复杂设备推荐) **位置**:`com.mes.interaction.*.flow.NewDeviceInteraction` ```java @Component public class NewDeviceInteraction implements DeviceInteraction { @Override public String getDeviceType() { return DeviceConfig.DeviceType.NEW_DEVICE; } @Override public InteractionResult execute(InteractionContext context) { DeviceConfig device = context.getCurrentDevice(); // 1. 前置条件检查 if (device == null) { return InteractionResult.fail("设备配置不存在"); } // 2. 数据准备 List glassIds = context.getParameters().getGlassIds(); // 3. 调用设备逻辑处理器 DeviceInteractionService service = ...; Map params = new HashMap<>(); params.put("glassIds", glassIds); DevicePlcVO.OperationResult result = service.executeDeviceOperation(device, "operationName", params); if (result.isSuccess()) { // 4. 数据传递到下一个设备 context.getSharedData().put("processedGlasses", glassIds); return InteractionResult.success("执行成功", result.getData()); } else { return InteractionResult.fail(result.getMessage()); } } } ``` **自动注册**: - 实现 `DeviceInteraction` 接口 - 添加 `@Component` 注解 - `DeviceInteractionRegistry` 会自动发现并注册 ### 步骤4:配置设备逻辑参数(前端) 在设备配置的 `extraParams.deviceLogic` 中配置: ```json { "deviceLogic": { "timeout": 5000, "mode": "default", "customParam1": "value1" } } ``` ### 步骤5:设备组织方式选择 #### 简单设备(推荐放在通用包) ``` interaction/ └── impl/ └── NewDeviceLogicHandler.java ``` #### 复杂设备(需要协调、状态管理等) ``` interaction/ └── newdevice/ ├── handler/ │ └── NewDeviceLogicHandler.java ├── flow/ │ └── NewDeviceInteraction.java ├── coordination/ (可选) │ └── NewDeviceCoordinationService.java └── model/ (可选) └── NewDeviceStatus.java ``` ## 🔍 执行流程详解 ### 串行执行模式 ``` TaskExecutionEngine.execute() ↓ for (每个设备) { 1. 创建步骤记录 (TaskStepDetail) 2. executeStep() ↓ 3. 检查是否有 DeviceInteraction ├─ 有 → DeviceInteraction.execute() │ ↓ │ 调用 DeviceLogicHandler │ └─ 无 → 直接调用 DeviceLogicHandler ↓ BaseDeviceLogicHandler.execute() ↓ 子类 doExecute() 4. 更新步骤状态 5. 传递数据到下一个设备 } ``` ### 并行执行模式 ``` TaskExecutionEngine.execute() ↓ 创建线程池任务列表 ↓ for (每个设备) { 提交到线程池执行 ↓ executeStep() (同上) } ↓ 等待所有任务完成 ↓ 汇总结果 ``` ## 📝 关键接口说明 ### DeviceLogicHandler **接口方法**: ```java DevicePlcVO.OperationResult execute( DeviceConfig deviceConfig, String operation, Map params ); ``` **调用时机**: - 任务执行引擎直接调用 - 或通过 DeviceInteraction 间接调用 ### DeviceInteraction **接口方法**: ```java InteractionResult execute(InteractionContext context); ``` **调用时机**: - 任务执行引擎优先检查是否有 DeviceInteraction - 如果有,优先使用 DeviceInteraction - 如果没有,直接调用 DeviceLogicHandler ### InteractionContext **包含内容**: - `currentDevice` - 当前设备配置 - `taskContext` - 任务上下文 - `parameters` - 任务参数 - `sharedData` - 设备间共享数据 ## 🎯 最佳实践 ### 1. 何时使用 DeviceInteraction? **使用场景**: - ✅ 需要多实例协调(如大车设备) - ✅ 需要复杂前置检查 - ✅ 需要数据转换和准备 - ✅ 需要状态管理 **不使用场景**: - ❌ 简单设备,逻辑单一 - ❌ 不需要协调的设备 ### 2. 参数设计 **logicParams(逻辑参数)**: - 从 `extraParams.deviceLogic` 中读取 - 设备配置时设置,运行时不变 - 如:超时时间、模式、容量等 **params(运行时参数)**: - 任务执行时动态传入 - 如:玻璃ID、位置、数量等 ### 3. 错误处理 **在 BaseDeviceLogicHandler 中**: - 自动捕获异常 - 返回统一的错误格式 **在子类中**: - 可以抛出业务异常 - 会被基类捕获并转换 ### 4. 数据传递 **通过 InteractionContext.sharedData**: ```java // 在设备A中设置 context.getSharedData().put("glassIds", glassIds); // 在设备B中获取 List glassIds = (List) context.getSharedData().get("glassIds"); ``` ## 📚 相关文件位置 ### 核心文件 - `TaskExecutionEngine.java` - 任务执行引擎 - `MultiDeviceTaskServiceImpl.java` - 任务服务 - `DeviceLogicHandlerFactory.java` - 处理器工厂 - `DeviceInteractionRegistry.java` - 交互注册中心 ### 基类 - `BaseDeviceLogicHandler.java` - 逻辑处理器基类 - `DeviceInteraction.java` - 交互接口 ### 示例实现 - `LoadVehicleLogicHandler.java` - 大车设备逻辑处理器 - `LoadVehicleInteraction.java` - 大车设备交互 - `HorizontalScannerLogicHandler.java` - 卧转立扫码处理器 ## 🔧 调试技巧 ### 1. 查看注册的设备处理器 ```java @Autowired private DeviceLogicHandlerFactory factory; // 查看所有已注册的设备类型 Set types = factory.getSupportedDeviceTypes(); ``` ### 2. 查看注册的设备交互 ```java @Autowired private DeviceInteractionRegistry registry; // 查看所有已注册的交互 Map interactions = registry.getInteractions(); ``` ### 3. 日志输出 - 任务执行:查看 `TaskExecutionEngine` 日志 - 设备执行:查看具体 Handler 日志 - 协调服务:查看 `DeviceCoordinationService` 日志 ## ✅ 总结 1. **项目主体**:`TaskExecutionEngine` 是核心执行引擎 2. **调用流程**:Controller → Service → Engine → Interaction/Handler → PLC 3. **分层架构**:Controller → Service → Interaction → Coordination → PLC 4. **添加设备**:实现 `DeviceLogicHandler`(必须)+ `DeviceInteraction`(可选) 5. **自动注册**:通过 Spring 的 `@Component` 和工厂类自动发现和注册