Files
tcpserver-flow/app/flow/ProcessEngine.php
T
zimoyin 3471deb3f1 ai-refactor(flow): 调整抽象流程节点实现和依赖路径
- 修改 AbstractProcessNode 中 ProcessContext 的命名空间引用为 app\flow\context\ProcessContext
- 引入 app\flow\vo\CanHandleResult 用于节点处理结果表示
- 更新前置策略执行后对成功状态的判断,改为调用 isSuccess() 方法
- 增加日志记录细节,便于调试策略执行中断时的错误信息
- 优化代码注释,提升代码可读性和维护性
2026-03-11 02:40:45 +08:00

381 lines
9.8 KiB
PHP

<?php
namespace app\flow;
use app\flow\config\ProcessConfig;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\nodes\MorningWashNode;
use app\flow\nodes\ProcessNodeInterface;
use app\flow\strategies\MorningWashStrategy;
use app\flow\strategies\TimeValidationStrategy;
use app\flow\strategies\VoiceGenerationStrategy;
use app\utils\Logger;
/**
* 流程引擎类
* 组装流程链并执行流程
*/
class ProcessEngine
{
/**
* 流程配置
*/
protected ProcessConfig $config;
/**
* 流程链头节点
*/
protected ?ProcessNodeInterface $chainHead = null;
/**
* 节点映射表
*/
protected array $nodeMap = [];
/**
* 策略实例
*/
protected array $strategies = [];
/**
* 节点命名空间
*/
protected string $nodeNamespace = 'app\\flow\\nodes\\';
/**
* 构造函数
*/
public function __construct(?ProcessConfig $config = null)
{
$this->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->builder()->error(VoiceMessage::PROCESS_CHAIN_NOT_INITIALIZED)->build();
}
Logger::debug('[ProcessEngine] 开始执行流程链 readerType={} currentStep={} endoscope={}', [
$context->getReader()->type,
$context->getCurrentStep() ?: '(空)',
$context->getEndoscope()->name ?: $context->getEndoscope()->id ?: '-',
]);
$result = $this->chainHead->handle($context);
Logger::debug('[ProcessEngine] 流程执行完成 endoscope={} step={} success={} error={}', [
$result->getEndoscope()->name,
$result->getCurrentStep(),
$result->isSuccess() ? 'true' : 'false',
$result->getVoice()->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());
}
}