512 lines
17 KiB
PHP
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());
|
|
}
|
|
}
|