config = $config ?? new ProcessConfig(); $this->initStrategies(); $this->buildChain(); } /** * 初始化策略 */ protected function initStrategies(): void { Logger::debug("[ProcessEngine] 初始化策略..."); // 晨洗判断策略 $this->strategies['morning_wash'] = new MorningWashStrategy( $this->config->getMorningWashConfig() ); // 时间验证策略 $this->strategies['time_validation'] = new TimeValidationStrategy( $this->config->getTimeValidationConfig() ); // 语音生成策略 $this->strategies['voice_generation'] = new VoiceGenerationStrategy( $this->config->getVoiceTemplatesConfig() ); Logger::debug("[ProcessEngine] 策略初始化完成"); } /** * 构建流程链 */ protected function buildChain(): void { Logger::debug("[ProcessEngine] 构建流程链..."); $steps = $this->config->getSteps(); $prevNode = null; foreach ($steps as $step) { $node = $this->createNode($step->class); Logger::debug("[ProcessEngine] 创建节点 {}", [$step->class]); if ($node === null) { Logger::warning("[ProcessEngine] 无法创建节点 {}", [$step->class]); continue; } // 设置节点启用状态 $node->setEnabled($step->enabled); Logger::debug(" [{}] 启用状态 {}", [$node->getName(), $step->enabled]); // 添加策略 $this->attachStrategies($node, $step->code); Logger::debug("[{}] 策略添加完成", [$node->getName()]); // 保存到映射表 $this->nodeMap[$step->code] = $node; Logger::debug("[{}] 保存到映射表", [$node->getName()]); // 构建流程链 if ($prevNode === null) { $this->chainHead = $node; } else { $prevNode->setNext($node); } // 添加配置 $node->setConfig($step); Logger::debug("[{}] 设置原始配置: {}", [$node->getName(), json_encode($step)]); $prevNode = $node; Logger::debug("[{}] 节点创建完成", [$node->getName()]); } Logger::debug("[ProcessEngine] 流程链构建完成"); } /** * 创建节点实例 */ protected function createNode(string $className): ?ProcessNodeInterface { // 添加命名空间 if (!str_contains($className, '\\')) { $className = $this->nodeNamespace . $className; } if (!class_exists($className)) { return null; } return new $className(); } /** * 为节点附加策略 */ protected function attachStrategies(ProcessNodeInterface $node, string $stepCode): void { // 晨洗节点添加晨洗判断策略 if ($stepCode === MorningWashNode::getName()) { $node->addStrategy($this->strategies['morning_wash']); Logger::debug("[{}] 添加 MorningWashStrategy", [$node->getName()]); } // 有时间要求的步骤添加时间验证策略 $timeSteps = ['清洗', '漂洗', '消毒', '终末漂洗', '干燥']; if (in_array($stepCode, $timeSteps)) { $node->addStrategy($this->strategies['time_validation']); Logger::debug("[{}] 添加 TimeValidationStrategy", [$node->getName()]); } // 除了晨洗所有节点都添加语音生成策略 if ($stepCode !== MorningWashNode::getName()) { $node->addStrategy($this->strategies['voice_generation']); Logger::debug("[{}] 添加 VoiceGenerationStrategy", [$node->getName()]); } // 存储节点添加语音生成策略 if ($stepCode === '存储') { $node->addStrategy($this->strategies['voice_generation']); Logger::debug("[{}] 存储节点配置完成", [$node->getName()]); } } /** * 执行流程 */ public function execute(ProcessContext $context): ProcessContext { if ($this->chainHead === null) { return $context->setError(VoiceMessage::PROCESS_CHAIN_NOT_INITIALIZED); } Logger::debug('[ProcessEngine] 开始执行流程链 readerType={} currentStep={} endoscope={}', [ $context->readerType, $context->currentStep ?: '(空)', $context->endoscopeName ?: $context->endoscopeId ?: '-', ]); $result = $this->chainHead->handle($context); Logger::debug('[ProcessEngine] 流程执行完成 endoscope={} step={} success={} error={}', [ $result->endoscopeName, $result->currentStep, $result->success ? 'true' : 'false', $result->errorMessage->value ?: '-', ]); return $result; } /** * 快速执行(从数组创建上下文) */ public function executeFromArray(array $data): ProcessContext { $context = ProcessContext::create($data); return $this->execute($context); } /** * 获取配置 */ public function getConfig(): ProcessConfig { return $this->config; } /** * 更新配置并重建流程链 */ public function updateConfig(ProcessConfig $config): self { $this->config = $config; $this->nodeMap = []; $this->chainHead = null; $this->initStrategies(); $this->buildChain(); return $this; } /** * 获取节点 */ public function getNode(string $code): ?ProcessNodeInterface { return $this->nodeMap[$code] ?? null; } /** * 启用节点 */ public function enableNode(string $code): self { $this->config->enableStep($code); if (isset($this->nodeMap[$code])) { $this->nodeMap[$code]->setEnabled(true); } return $this; } /** * 禁用节点 */ public function disableNode(string $code): self { $this->config->skipStep($code); if (isset($this->nodeMap[$code])) { $this->nodeMap[$code]->setEnabled(false); } return $this; } /** * 设置节点启用状态 */ public function setNodeEnabled(string $code, bool $enabled): self { return $enabled ? $this->enableNode($code) : $this->disableNode($code); } /** * 获取所有节点 */ public function getNodes(): array { return $this->nodeMap; } /** * 获取启用的节点 */ public function getEnabledNodes(): array { return array_filter($this->nodeMap, function ($node) { return $node->isEnabled(); }); } /** * 添加自定义策略 */ public function addStrategy(string $name, $strategy): self { $this->strategies[$name] = $strategy; return $this; } /** * 获取策略 */ public function getStrategy(string $name) { return $this->strategies[$name] ?? null; } /** * 设置步骤自定义语音 */ public function setStepVoice(string $stepCode, string $voice): self { $this->config->setStepVoice($stepCode, $voice); // 更新语音生成策略 if (isset($this->strategies['voice_generation'])) { $this->strategies['voice_generation']->setStepVoice($stepCode, $voice); } return $this; } /** * 设置晨洗模式 */ public function setMorningWashMode(string $mode): self { $this->config->setMorningWashMode($mode); // 更新晨洗策略 if (isset($this->strategies['morning_wash'])) { $this->strategies['morning_wash'] = new MorningWashStrategy( $this->config->getMorningWashConfig() ); } return $this; } /** * 创建引擎(静态工厂方法) */ public static function create(?ProcessConfig $config = null): self { return new self($config); } /** * 创建标准流程引擎 */ public static function createStandard(): self { return new self(ProcessConfig::createStandard()); } /** * 创建无晨洗流程引擎 */ public static function createNoMorningWash(): self { return new self(ProcessConfig::createNoMorningWash()); } /** * 创建简化流程引擎 */ public static function createSimple(): self { return new self(ProcessConfig::createSimple()); } /** * 创建机洗流程引擎 */ public static function createMachineWash(): self { return new self(ProcessConfig::createMachineWash()); } }