Files
tcpserver-flow/tests/flow/UsageExampleTest.php
T
2026-03-08 22:58:56 +08:00

512 lines
17 KiB
PHP

<?php
namespace tests\flow;
use app\config\Config;
use app\flow\FlowProcessor;
use app\flow\ProcessContext;
use app\flow\ProcessEngine;
use app\flow\config\ProcessConfig;
use app\net\PacketContext;
/**
* UsageExample 使用示例测试
* 验证各种流程配置和使用场景
*/
class UsageExampleTest extends TestCase
{
/**
* 测试使用 FlowProcessor 处理刷卡请求
*/
public function testFlowProcessorUsage(): void
{
// 1. 创建流程处理器(使用标准配置)
$processor = FlowProcessor::create(ProcessConfig::createStandard());
// 2. 直接使用 ProcessContext 测试(跳过 PacketContext 转换)
// TODO: 实际使用时需要通过 PacketContext 创建
$context = ProcessContext::create([
'cardNo' => '04A2AD88D0',
'readerNo' => '09E45F217B',
'readerType' => '清洗',
'endoscopeId' => '',
'endoscopeName' => '胃镜001',
'currentStep' => '',
'morningWashed' => true,
'needMorningWash' => false,
]);
// 3. 执行流程
$result = $processor->engine->execute($context);
// 4. 验证处理结果
$this->assertTrue($result->success);
$this->assertEquals('清洗', $result->currentStep);
$this->assertNotEmpty($result->voiceMessage);
}
/**
* 测试使用 FlowProcessor 处理完整流程
*/
public function testFlowProcessorCompleteProcess(): void
{
$processor = FlowProcessor::create(ProcessConfig::createStandard());
// 步骤1: 清洗
$context1 = ProcessContext::create([
'cardNo' => '04A2AD88D0',
'readerNo' => '09E45F217B',
'readerType' => '清洗',
'endoscopeId' => '',
'endoscopeName' => '胃镜001',
'currentStep' => '',
'morningWashed' => true,
'needMorningWash' => false,
]);
$result1 = $processor->engine->execute($context1);
$this->assertTrue($result1->success);
$this->assertEquals('清洗', $result1->currentStep);
$batchNo = $result1->batchNo;
// 步骤2: 漂洗(模拟时间已过)
$context2 = ProcessContext::create([
'cardNo' => '04A2AD88D0',
'readerNo' => '09E45F217B',
'readerType' => '漂洗',
'endoscopeId' => '1',
'endoscopeName' => '胃镜001',
'currentStep' => '清洗',
'batchNo' => $batchNo,
'morningWashed' => true,
'needMorningWash' => false,
]);
// 设置清洗步骤时间已满足
$context2->setStepLastTime('清洗', date('Y-m-d H:i:s', time() - 360));
$result2 = $processor->engine->execute($context2);
$this->assertTrue($result2->success);
$this->assertEquals('漂洗', $result2->currentStep);
}
/**
* 测试使用 Config 配置创建 FlowProcessor
*/
public function testFlowProcessorWithConfig(): void
{
// 从全局配置获取无晨洗配置
$globalConfig = Config::getInstance();
$hospitalConfig = $globalConfig->customProcess['no_morning_wash'] ?? null;
if ($hospitalConfig === null) {
$this->markTestSkipped('no_morning_wash 配置不存在');
}
// 使用配置创建流程处理器
$processConfig = ProcessConfig::fromArray($hospitalConfig);
$processor = new FlowProcessor($processConfig);
// 验证配置生效
$this->assertFalse($processor->engine->getNode('晨洗')->isEnabled());
// 处理刷卡
$context = ProcessContext::create([
'cardNo' => '04A2AD88D0',
'readerNo' => '09E45F217B',
'readerType' => '清洗',
'endoscopeId' => '',
'endoscopeName' => '胃镜001',
'currentStep' => '',
'morningWashed' => true,
'needMorningWash' => false,
]);
$result = $processor->engine->execute($context);
$this->assertTrue($result->success);
}
/**
* 测试从 Config 全局配置加载自定义流程
*/
public function testLoadCustomProcessFromConfig(): void
{
// 获取全局配置实例
$globalConfig = Config::getInstance();
// 验证自定义流程配置已加载
$this->assertNotEmpty($globalConfig->customProcess);
$this->assertArrayHasKey('standard', $globalConfig->customProcess);
$this->assertArrayHasKey('no_morning_wash', $globalConfig->customProcess);
$this->assertArrayHasKey('machine_wash', $globalConfig->customProcess);
}
/**
* 测试使用 Config 中的无晨洗配置创建流程
*/
public function testCreateNoMorningWashFromConfig(): void
{
$globalConfig = Config::getInstance();
// 从全局配置获取无晨洗配置
$hospitalConfig = $globalConfig->customProcess['no_morning_wash'] ?? null;
// 如果配置存在则测试
if ($hospitalConfig === null) {
$this->markTestSkipped('no_morning_wash 配置不存在');
}
// 使用配置创建流程
$processConfig = ProcessConfig::fromArray($hospitalConfig);
$engine = new ProcessEngine($processConfig);
// 验证晨洗节点被禁用
$this->assertFalse($engine->getNode('晨洗')->isEnabled());
// 执行流程
$context = ProcessContext::create([
'endoscopeName' => '测试内镜',
'readerType' => '清洗',
'currentStep' => '',
'needMorningWash' => false,
'morningWashed' => true,
]);
$result = $engine->execute($context);
$this->assertTrue($result->success);
}
/**
* 测试使用 Config 中的机洗配置创建流程
*/
public function testCreateMachineWashFromConfig(): void
{
$globalConfig = Config::getInstance();
// 从全局配置获取机洗配置
$hospitalConfig = $globalConfig->customProcess['machine_wash'] ?? null;
// 如果配置存在则测试
if ($hospitalConfig === null) {
$this->markTestSkipped('machine_wash 配置不存在');
}
// 使用配置创建流程
$processConfig = ProcessConfig::fromArray($hospitalConfig);
$engine = new ProcessEngine($processConfig);
// 验证机洗节点启用,漂洗和消毒禁用
$this->assertTrue($engine->getNode('机洗')->isEnabled());
$this->assertFalse($engine->getNode('漂洗')->isEnabled());
$this->assertFalse($engine->getNode('消毒')->isEnabled());
// 执行机洗流程
$context = ProcessContext::create([
'endoscopeName' => '测试内镜',
'readerType' => '机洗',
'currentStep' => '清洗',
'morningWashed' => true,
'needMorningWash' => false,
]);
$result = $engine->execute($context);
$this->assertTrue($result->success);
$this->assertEquals('机洗', $result->currentStep);
}
/**
* 测试使用 Config 中的义乌模式配置
*/
public function testCreateYiwuModeFromConfig(): void
{
$globalConfig = Config::getInstance();
// 从全局配置获取义乌模式配置(按存储时间判断晨洗)
$hospitalConfig = $globalConfig->customProcess['partial_morning_wash'] ?? null;
// 如果配置存在则测试
if ($hospitalConfig === null) {
$this->markTestSkipped('partial_morning_wash 配置不存在');
}
// 验证配置内容
$this->assertEquals('storage_time', $hospitalConfig['morning_wash']['mode'] ?? '');
$this->assertEquals(4, $hospitalConfig['morning_wash']['storage_threshold'] ?? 0);
// 使用配置创建流程
$processConfig = ProcessConfig::fromArray($hospitalConfig);
$engine = new ProcessEngine($processConfig);
// 验证晨洗节点启用
$this->assertTrue($engine->getNode('晨洗')->isEnabled());
}
/**
* 测试标准流程处理
*/
public function testExample1StandardProcess(): void
{
// 创建标准流程引擎
$engine = ProcessEngine::createStandard();
// 创建流程上下文(模拟刷卡数据)
$context = ProcessContext::create([
'endoscopeId' => '',
'endoscopeName' => '胃镜001',
'cardNo' => '04A2AD88D0',
'readerNo' => '09E45F217B',
'readerType' => '清洗',
'currentStep' => '',
'needMorningWash' => false,
'morningWashed' => true,
]);
// 执行流程
$result = $engine->execute($context);
// 验证结果
$this->assertTrue($result->success);
$this->assertEquals('清洗', $result->currentStep);
$this->assertNotEmpty($result->getFullVoice());
}
/**
* 测试无晨洗流程配置
*/
public function testExample2NoMorningWash(): void
{
$config = ProcessConfig::createNoMorningWash();
$engine = new ProcessEngine($config);
// 验证晨洗节点被禁用
$this->assertFalse($engine->getNode('晨洗')->isEnabled());
// 执行流程
$context = ProcessContext::create([
'endoscopeName' => '肠镜002',
'readerType' => '清洗',
'currentStep' => '',
'needMorningWash' => false,
'morningWashed' => true,
]);
$result = $engine->execute($context);
$this->assertTrue($result->success);
$this->assertEquals('清洗', $result->currentStep);
}
/**
* 测试运行时动态调整流程
*/
public function testExample3DynamicAdjust(): void
{
$engine = ProcessEngine::createStandard();
// 禁用干燥和终末漂洗步骤
$engine->disableNode('干燥');
$engine->disableNode('终末漂洗');
$this->assertFalse($engine->getNode('干燥')->isEnabled());
$this->assertFalse($engine->getNode('终末漂洗')->isEnabled());
// 重新启用
$engine->enableNode('干燥');
$this->assertTrue($engine->getNode('干燥')->isEnabled());
}
/**
* 测试自定义语音
*/
public function testExample4CustomVoice(): void
{
$engine = ProcessEngine::createStandard();
// 设置自定义语音
$engine->setStepVoice('清洗', '第一步清洗开始,请认真清洗');
$context = ProcessContext::create([
'endoscopeName' => '胃镜004',
'readerType' => '清洗',
'currentStep' => '',
'morningWashed' => true,
'needMorningWash' => false,
]);
$result = $engine->execute($context);
$this->assertTrue($result->success);
// 验证语音包含步骤完成信息
$this->assertStringContainsString('清洗', $result->getFullVoice());
}
/**
* 测试不同晨洗模式
*/
public function testExample5MorningWashModes(): void
{
// 模式1: 不需要晨洗
$config1 = ProcessConfig::createNoMorningWash();
$this->assertFalse($config1->isNodeEnabled('晨洗'));
// 模式2: 义乌模式(按存储时间)
$config2 = new ProcessConfig([
'morning_wash' => [
'mode' => 'storage_time',
'storage_threshold' => 4,
],
]);
$this->assertEquals('StorageTime', $config2->getMorningWashConfig()->mode->name);
// 模式3: 特定类型镜子需要晨洗
$config3 = new ProcessConfig([
'morning_wash' => [
'mode' => 'specific_types',
'specific_types' => ['胃镜', '十二指肠镜'],
],
]);
$this->assertEquals(['胃镜', '十二指肠镜'], $config3->getMorningWashConfig()->getExpand('specific_types', []));
}
/**
* 测试机洗流程
*/
public function testExample6MachineWash(): void
{
$config = ProcessConfig::createMachineWash();
$engine = new ProcessEngine($config);
// 场景: 清洗后刷机洗
$context = ProcessContext::create([
'endoscopeName' => '胃镜005',
'readerType' => '机洗',
'currentStep' => '清洗',
'processType' => '手工洗',
'morningWashed' => true,
'needMorningWash' => false,
]);
$result = $engine->execute($context);
$this->assertTrue($result->success);
$this->assertEquals('机洗', $result->currentStep);
$this->assertEquals('机洗', $result->processType);
}
/**
* 测试简化流程(只清洗)
*/
public function testExample7SimpleProcess(): void
{
$config = ProcessConfig::createSimple();
$engine = new ProcessEngine($config);
// 验证漂洗和消毒被禁用
$this->assertFalse($engine->getNode('漂洗')->isEnabled());
$this->assertFalse($engine->getNode('消毒')->isEnabled());
$context = ProcessContext::create([
'endoscopeName' => '胃镜006',
'readerType' => '清洗',
'currentStep' => '',
'morningWashed' => true,
'needMorningWash' => false,
]);
$result = $engine->execute($context);
$this->assertTrue($result->success);
$this->assertEquals('清洗', $result->currentStep);
}
/**
* 测试时间验证 - 正常流程(时间足够)
*/
public function testExample8TimeValidation(): void
{
$engine = ProcessEngine::createStandard();
// 先执行清洗
$context1 = ProcessContext::create([
'endoscopeName' => '胃镜007',
'readerType' => '清洗',
'currentStep' => '',
'morningWashed' => true,
'needMorningWash' => false,
]);
$result1 = $engine->execute($context1);
$this->assertTrue($result1->success);
// 清洗后时间足够(超过5分钟)再刷漂洗
$context2 = ProcessContext::create([
'endoscopeName' => '胃镜007',
'readerType' => '漂洗',
'currentStep' => '清洗',
'batchNo' => $result1->batchNo,
'morningWashed' => true,
'needMorningWash' => false,
]);
// 设置清洗步骤时间为6分钟前(超过要求的5分钟)
$context2->setStepLastTime('清洗', date('Y-m-d H:i:s', time() - 360));
$result2 = $engine->execute($context2);
// 时间足够,流程应该成功
$this->assertTrue($result2->success);
$this->assertEquals('漂洗', $result2->currentStep);
}
/**
* 测试完整的刷卡处理流程
*/
public function testExample9FullProcess(): void
{
// 1. 创建标准流程引擎
$engine = ProcessEngine::createStandard();
// 2. 模拟接收刷卡数据
$cardData = [
'cardNo' => '04A2AD88D0',
'readerNo' => '09E45F217B',
'readerType' => '清洗',
];
// 3. 模拟查询内镜信息
$endoscopeInfo = [
'endoscopeId' => '',
'endoscopeName' => '胃镜001',
'currentStep' => '',
'needMorningWash' => false,
'morningWashed' => true,
];
// 4. 创建上下文
$context = ProcessContext::create(array_merge($cardData, $endoscopeInfo));
// 5. 执行流程
$result = $engine->execute($context);
// 6. 验证结果
$this->assertTrue($result->success);
$this->assertEquals('清洗', $result->currentStep);
$this->assertTrue($result->needDatabaseOperation);
$this->assertTrue($result->needWebSocketNotify);
}
/**
* 测试多医院配置
*/
public function testExample10MultiHospital(): void
{
// 医院A使用标准流程
$hospitalA = ProcessEngine::createStandard();
$this->assertTrue($hospitalA->getNode('晨洗')->isEnabled());
// 医院B使用无晨洗流程
$hospitalB = ProcessEngine::createNoMorningWash();
$this->assertFalse($hospitalB->getNode('晨洗')->isEnabled());
// 医院C使用机洗流程
$hospitalC = ProcessEngine::createMachineWash();
$this->assertTrue($hospitalC->getNode('机洗')->isEnabled());
// 医院D使用简化流程
$hospitalD = ProcessEngine::createSimple();
$this->assertFalse($hospitalD->getNode('漂洗')->isEnabled());
}
}