142 lines
3.9 KiB
PHP
142 lines
3.9 KiB
PHP
<?php
|
||
|
||
namespace app\flow;
|
||
|
||
use app\config\Config;
|
||
use app\flow\config\ProcessConfig;
|
||
use app\net\PacketContext;
|
||
use app\utils\Logger;
|
||
|
||
/**
|
||
* FlowMain Flow入口类(单例)
|
||
*
|
||
* 职责:
|
||
* 1. 作为TCP服务器的入口点,接收刷卡事件
|
||
* 2. 管理流程处理器的生命周期(单例)
|
||
* 3. 从全局配置加载自定义流程配置
|
||
* 4. 提供配置热更新能力
|
||
*
|
||
* 与 FlowProcessor 的关系:
|
||
* - FlowMain 是入口和调度器(有状态单例)
|
||
* - FlowProcessor 是业务处理器(无状态,可被复用)
|
||
*
|
||
* @see FlowProcessor 流程处理器,处理具体业务逻辑
|
||
*/
|
||
class FlowMain
|
||
{
|
||
private FlowProcessor $flowProcessor;
|
||
|
||
/**
|
||
* 获取FlowMain实例(单例模式)
|
||
*/
|
||
private static ?FlowMain $instance = null;
|
||
|
||
|
||
public static function getInstance(): FlowMain
|
||
{
|
||
if (self::$instance === null) {
|
||
self::$instance = new self();
|
||
}
|
||
return self::$instance;
|
||
}
|
||
|
||
/**
|
||
* 私有构造函数,防止外部实例化
|
||
*/
|
||
private function __construct()
|
||
{
|
||
$this->flowProcessor = $this->createFlowProcessor();
|
||
|
||
}
|
||
|
||
/**
|
||
* 创建流程处理器
|
||
*
|
||
* 根据配置创建对应的 FlowProcessor
|
||
*/
|
||
private function createFlowProcessor(): FlowProcessor
|
||
{
|
||
$useCustomProcess = Config::getInstance()->flowUseCustomProcess;
|
||
$processConfigKey = Config::getInstance()->flowProcessConfigKey;
|
||
|
||
// 流程配置 通过流程配置可以实现,加载/卸载流程节点,添加/修改语音输出
|
||
$processConfig = null;
|
||
if ($useCustomProcess && !empty($processConfigKey)) {
|
||
// 从全局配置加载自定义流程
|
||
$globalConfig = Config::getInstance();
|
||
$customProcess = $globalConfig->customProcess;
|
||
$processConfigArray = $customProcess[$processConfigKey] ?? null;
|
||
|
||
if ($processConfigArray !== null) {
|
||
Logger::info("使用自定义流程: {}", [$processConfigKey]);
|
||
$processConfig = ProcessConfig::fromArray($processConfigArray);
|
||
return FlowProcessor::create($processConfig);
|
||
}
|
||
}
|
||
|
||
Logger::info("FlowMain 使用默认标准流程");
|
||
Logger::info("使用数据库: {}",[ Config::getInstance()->database->database]);
|
||
$processConfig = ProcessConfig::createStandard();
|
||
// 使用默认标准流程
|
||
return FlowProcessor::create($processConfig);
|
||
}
|
||
|
||
/**
|
||
* Flow主入口方法
|
||
*
|
||
* @param PacketContext $packetContext 数据包上下文
|
||
* @return ProcessContext
|
||
*/
|
||
public function main(PacketContext $packetContext): ProcessContext
|
||
{
|
||
// 调用流程处理器处理数据包并返回处理完成后的上下文
|
||
// process 参数:数据包上下文
|
||
// process 参数: 是否执行结果处理器,默认是执行
|
||
// 返回值: 处理完成后的数据包上下文
|
||
$packetContext = $this->flowProcessor->process($packetContext);
|
||
return $packetContext;
|
||
}
|
||
|
||
/**
|
||
* 获取流程处理器实例
|
||
*
|
||
* @return FlowProcessor
|
||
*/
|
||
public function getFlowProcessor(): FlowProcessor
|
||
{
|
||
return $this->flowProcessor;
|
||
}
|
||
|
||
/**
|
||
* 重新加载配置(配置热更新)
|
||
*
|
||
* @return void
|
||
*/
|
||
public function reloadConfig(): void
|
||
{
|
||
$this->flowProcessor = $this->createFlowProcessor();
|
||
}
|
||
|
||
/**
|
||
* 切换流程配置
|
||
*
|
||
* @param string $configKey 配置键名(如 'standard', 'no_morning_wash')
|
||
* @return void
|
||
*/
|
||
public function switchConfig(string $configKey): void
|
||
{
|
||
self::$processConfigKey = $configKey;
|
||
$this->reloadConfig();
|
||
}
|
||
|
||
/**
|
||
* 重置单例(主要用于测试)
|
||
*
|
||
* @return void
|
||
*/
|
||
public static function resetInstance(): void
|
||
{
|
||
self::$instance = null;
|
||
}
|
||
}
|