From 177c3ae9b248d8f070431f0b4322bb78cd89303b Mon Sep 17 00:00:00 2001 From: zimoyin <2556608754@qq.com> Date: Fri, 13 Mar 2026 18:51:02 +0800 Subject: [PATCH] =?UTF-8?q?refactor(context):=20=E9=87=8D=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E4=B8=8A=E4=B8=8B=E6=96=87=E6=9E=84=E5=BB=BA=E5=99=A8?= =?UTF-8?q?=E5=8F=8A=E6=9B=B4=E6=96=B0=E7=9B=B8=E5=85=B3=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 ProcessContext 中的 builder() 重命名为 createModifyBuilder() 并添加调用栈日志 - ProcessContextBuilder 中所有 with* 方法统一改为 set* 命名风格 - Flow 各节点及流程处理器中调用 builder() 替换为 createModifyBuilder() - 虚拟测试环境相关 ContextBuilder 中方法同步改名保持一致 - 优化流程节点中上下文修改代码调用,提升代码规范性 - 添加Config中加载自定义流程配置的占位注释及代码 - 无功能改动,纯代码风格及命名规范调整 --- .phpunit.cache/test-results | 2 +- app/config/Config.php | 2 + app/config/TODO.md | 4 +- app/flow/FlowMain.php | 3 +- app/flow/FlowProcessor.php | 10 +- app/flow/ProcessEngine.php | 2 +- app/flow/context/ProcessContext.php | 8 +- app/flow/context/ProcessContextBuilder.php | 54 ++++++----- app/flow/nodes/AbstractProcessNode.php | 6 +- app/flow/nodes/CloseNode.php | 4 +- app/flow/nodes/DisinfectNode.php | 10 +- app/flow/nodes/DryNode.php | 10 +- app/flow/nodes/DuplicateCheckNode.php | 2 +- app/flow/nodes/EndNode.php | 10 +- app/flow/nodes/FinalRinseNode.php | 10 +- app/flow/nodes/MachineWashNode.php | 14 +-- app/flow/nodes/MorningWashNode.php | 14 +-- app/flow/nodes/RinseNode.php | 10 +- app/flow/nodes/StorageInNode.php | 14 +-- app/flow/nodes/StorageNode.php | 16 ++-- app/flow/nodes/StorageOutNode.php | 14 +-- app/flow/nodes/WashNode.php | 12 +-- app/flow/strategies/MorningWashStrategy.php | 2 +- .../strategies/TimeValidationStrategy.php | 4 +- .../strategies/VoiceGenerationStrategy.php | 4 +- tests/flow/VirtualContextBuilder.php | 4 +- tests/flow/VirtualityFlowProcessor.php | 94 ++++++++++--------- 27 files changed, 176 insertions(+), 163 deletions(-) diff --git a/.phpunit.cache/test-results b/.phpunit.cache/test-results index c2fe452..230e444 100644 --- a/.phpunit.cache/test-results +++ b/.phpunit.cache/test-results @@ -1 +1 @@ -{"version":2,"defects":{"tests\\flow\\FlowProcessorTest::testCreateProcessor":8,"tests\\flow\\FlowProcessorTest::testCreateProcessorWithConfig":8,"tests\\flow\\FlowProcessorTest::testUpdateConfig":8,"tests\\flow\\FlowProcessorTest::testBatchNoConsistency":8,"tests\\flow\\FlowProcessorTest::testBatchNoConsistencyInCompleteProcess":8,"tests\\flow\\FlowProcessorTest::testDatabaseOperationFlags":8,"tests\\flow\\FlowProcessorTest::testWebSocketNotifyFlag":8,"tests\\flow\\FlowProcessorTest::testVoiceGeneration":8,"tests\\flow\\FlowProcessorTest::testErrorVoiceGeneration":7,"tests\\flow\\FlowProcessorTest::testMultiHospitalConfig":8,"tests\\flow\\FlowProcessorTest::testSpecialHospitalConfig":8,"tests\\flow\\ProcessEngineTest::testTimeValidationFailure":8,"tests\\flow\\ProcessEngineTest::testWrongStep":7,"tests\\flow\\strategies\\TimeValidationStrategyTest::testCustomDuration":7,"tests\\flow\\ProcessEngineTest::testSkipStep":7,"tests\\flow\\BatchConsistencyTest::testBatchNoPreservedOnError":8,"tests\\flow\\BatchConsistencyTest::testBatchNoWithDifferentProcessTypes":8,"tests\\flow\\EdgeCaseTest::testBatchNoGenerationEdgeCases":7,"tests\\flow\\PerformanceTest::testContextCreationPerformance":7,"tests\\flow\\PerformanceTest::testStrategyExecutionPerformance":7,"tests\\flow\\PerformanceTest::testChainTraversalPerformance":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleMorningWashReader":7,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcess":7,"tests\\flow\\nodes\\MorningWashNodeTest::testGenerateBatchNo":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleDisinfectReaderForMorningWash":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleMachineWashReaderForMorningWash":8,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcessWithDisinfect":8,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcessWithMachineWash":8,"tests\\flow\\EdgeCaseTest::testConcurrentBatchNoGeneration":7,"tests\\flow\\ProcessEngineTest::testDisinfectAfterWash":7,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterWash":8,"tests\\flow\\nodes\\DryNodeTest::testCanHandleAfterDisinfect":8,"tests\\flow\\UsageExampleTest::testExample4CustomVoice":8,"tests\\flow\\UsageExampleTest::testExample8TimeValidation":8,"tests\\flow\\UsageExampleTest::testLoadCustomProcessFromConfig":8,"tests\\flow\\UsageExampleTest::testCreateNoMorningWashFromConfig":8,"tests\\flow\\UsageExampleTest::testCreateMachineWashFromConfig":8,"tests\\flow\\UsageExampleTest::testCreateYiwuModeFromConfig":8,"tests\\flow\\UsageExampleTest::testExample1StandardProcess":8,"tests\\flow\\UsageExampleTest::testExample2NoMorningWash":8,"tests\\flow\\UsageExampleTest::testExample3DynamicAdjust":8,"tests\\flow\\UsageExampleTest::testExample5MorningWashModes":8,"tests\\flow\\UsageExampleTest::testExample6MachineWash":8,"tests\\flow\\UsageExampleTest::testExample7SimpleProcess":8,"tests\\flow\\UsageExampleTest::testExample9FullProcess":8,"tests\\flow\\UsageExampleTest::testExample10MultiHospital":8,"tests\\flow\\UsageExampleTest::testFlowProcessorUsage":8,"tests\\flow\\UsageExampleTest::testFlowProcessorCompleteProcess":8,"tests\\flow\\UsageExampleTest::testFlowProcessorWithConfig":8,"tests\\flow\\BatchConsistencyTest::testSingleMachineBatchConsistency":8,"tests\\flow\\BatchConsistencyTest::testMultiEndoscopeBatchUniqueness":8,"tests\\flow\\BatchConsistencyTest::testBatchNoStability":8,"tests\\flow\\BatchConsistencyTest::testNewProcessGeneratesNewBatchNo":8,"tests\\flow\\BatchConsistencyTest::testDistributedBatchConsistency":8,"tests\\flow\\PerformanceTest::testSingleExecutionPerformance":8,"tests\\flow\\PerformanceTest::testCompleteProcessPerformance":8,"tests\\flow\\PerformanceTest::testEngineCreationPerformance":8,"tests\\flow\\PerformanceTest::testConcurrentProcessingSimulation":8,"tests\\flow\\ProcessEngineTest::testCreateStandardEngine":8,"tests\\flow\\ProcessEngineTest::testCreateNoMorningWashEngine":8,"tests\\flow\\ProcessEngineTest::testCreateSimpleEngine":8,"tests\\flow\\ProcessEngineTest::testCompleteWashProcess":8,"tests\\flow\\ProcessEngineTest::testStandardWashRinseDisinfectFlow":8,"tests\\flow\\ProcessEngineTest::testDisableNode":8,"tests\\flow\\ProcessEngineTest::testGetNodes":8,"tests\\flow\\ProcessEngineTest::testGetEnabledNodes":8,"tests\\flow\\ProcessEngineTest::testUpdateConfig":8,"tests\\flow\\ProcessEngineTest::testMachineWashProcess":8,"tests\\db\\DBC::testDBConnect":8,"tests\\db\\DBC::testGenTables":7,"tests\\db\\DBC::testModel":5,"tests\\flow\\nodes\\DisinfectNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterRinse":8,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterFinalRinse":8,"tests\\flow\\nodes\\DisinfectNodeTest::testCannotHandleNonDisinfectReader":8,"tests\\flow\\nodes\\DisinfectNodeTest::testCannotHandleAfterDisinfect":8,"tests\\flow\\nodes\\DisinfectNodeTest::testHandleProcess":8,"tests\\flow\\nodes\\DisinfectNodeTest::testDatabaseOperationFlags":7,"tests\\flow\\nodes\\DisinfectNodeTest::testWebSocketNotifyFlag":8,"tests\\flow\\nodes\\DryNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\DryNodeTest::testCanHandleAfterFinalRinse":7,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleAfterRinse":8,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleNonDryReader":8,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleAfterDry":7,"tests\\flow\\nodes\\DryNodeTest::testHandleProcess":7,"tests\\flow\\nodes\\DryNodeTest::testDatabaseOperationFlags":7,"tests\\flow\\nodes\\DryNodeTest::testWebSocketNotifyFlag":7,"tests\\flow\\nodes\\DryNodeTest::testKeepExistingBatchNo":8,"tests\\flow\\nodes\\MorningWashNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleWhenNoNeed":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleNonDisinfectMachineReader":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleWhenAlreadyWashed":8,"tests\\flow\\nodes\\EndNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterDry":8,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterDisinfect":7,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterFinalRinse":8,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterMachineWash":8,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleNonEndReader":8,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleAfterWash":8,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleAfterRinse":8,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleWithEmptyStep":8,"tests\\flow\\nodes\\EndNodeTest::testHandleProcess":8,"tests\\flow\\nodes\\EndNodeTest::testDatabaseOperationIsUpdate":7,"tests\\flow\\nodes\\EndNodeTest::testWebSocketNotifyFlag":8,"tests\\flow\\nodes\\EndNodeTest::testActionEndTimeIsSet":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testCanHandleAfterDisinfect":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testCanHandleAfterMachineWashByDefault":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleAfterMachineWashWhenDisabled":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleNonFinalRinseReader":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testHandleProcess":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleAfterWash":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testDatabaseOperationFlags":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testWebSocketNotifyFlag":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\MachineWashNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterWash":8,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterRinse":7,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterDisinfect":7,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleWithEmptyStep":7,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterEnd":7,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterEndoscopeOut":8,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleNonMachineWashReader":8,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleAfterFinalRinse":8,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleAfterDry":8,"tests\\flow\\nodes\\MachineWashNodeTest::testHandleProcess":8,"tests\\flow\\nodes\\MachineWashNodeTest::testDatabaseOperationFlags":7,"tests\\flow\\nodes\\MachineWashNodeTest::testWebSocketNotifyFlag":8,"tests\\flow\\nodes\\RinseNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\RinseNodeTest::testCanHandleAfterWash":7,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleNonRinseReader":8,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleAfterDisinfect":7,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleWithEmptyStep":7,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleAfterRinse":7,"tests\\flow\\nodes\\RinseNodeTest::testHandleProcess":7,"tests\\flow\\nodes\\RinseNodeTest::testDatabaseOperationFlags":7,"tests\\flow\\nodes\\RinseNodeTest::testWebSocketNotifyFlag":7,"tests\\flow\\nodes\\RinseNodeTest::testDisabledNodeSkips":8,"tests\\flow\\nodes\\WashNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\WashNodeTest::testCanHandleWashReader":8,"tests\\flow\\nodes\\WashNodeTest::testCannotHandleNonWashReader":8,"tests\\flow\\nodes\\WashNodeTest::testCanStartNewWashProcess":8,"tests\\flow\\nodes\\WashNodeTest::testCannotWashWithoutMorningWash":8,"tests\\flow\\nodes\\WashNodeTest::testHandleProcess":8,"tests\\flow\\nodes\\WashNodeTest::testGenerateBatchNo":7,"tests\\flow\\nodes\\WashNodeTest::testKeepExistingBatchNo":8,"tests\\flow\\strategies\\TimeValidationStrategyTest::testTimeRequirementNotMet":7,"tests\\flow\\strategies\\TimeValidationStrategyTest::testSetStepDuration":7,"tests\\flow\\FlowProcessorTest::testSuccessfulFlowSavesToDatabase":8,"tests\\flow\\FlowProcessorTest::testEndOperationIsUpdate":8,"tests\\flow\\FlowProcessorTest::testGetActionTypeMapping":8,"tests\\flow\\EdgeCaseTest::testLongEndoscopeName":7,"tests\\flow\\EdgeCaseTest::testSpecialCharactersInName":7,"tests\\flow\\ProcessContextTest::testGetFullVoice":7,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testFullVoiceIncludesEndoscopeName":7,"tests\\flow\\FlowProcessorTest::testSuccessfulFlowSendsVoice":8,"tests\\flow\\FlowProcessorTest::testFailedFlowDoesNotSaveToDatabase":8,"tests\\flow\\FlowProcessorTest::testFailedFlowStillSendsVoice":8,"tests\\flow\\FlowProcessorTest::testWebSocketNotificationSentWhenNeeded":8,"tests\\flow\\FlowProcessorTest::testWebSocketNotificationNotSentWhenNotNeeded":8,"tests\\flow\\FlowProcessorTest::testStaticFactoryCreate":8,"tests\\flow\\EdgeCaseTest::testAllNodesDisabled":8,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testFinalRinseVoice":8,"tests\\flow\\ProcessSimulationTest::testDuplicateCheckNode":7,"tests\\flow\\FullProcessTest::testCompleteManualWashProcess":7,"tests\\flow\\FullProcessTest::testSwipeEndoscopeWithoutOperator":7,"tests\\flow\\cases\\BlockTest::testProcessChainExecution":5,"tests\\flow\\cases\\BlockTest::testDisabledNodeSkipped":5,"tests\\flow\\cases\\BlockTest::testTimeValidationBlockWithBlockModeOn":5,"tests\\flow\\cases\\BlockTest::testTimeValidationWithBlockModeOff":5,"tests\\flow\\cases\\BlockTest::testDuplicateSwipeBlock":5,"tests\\flow\\cases\\BlockTest::testTimeValidationPass":5,"tests\\flow\\cases\\ManualWashTest::testCompleteManualWashProcess":8},"times":{"tests\\flow\\FlowProcessorTest::testCreateProcessor":0.006,"tests\\flow\\FlowProcessorTest::testCreateProcessorWithConfig":0.006,"tests\\flow\\FlowProcessorTest::testStaticFactory":0.006,"tests\\flow\\FlowProcessorTest::testUpdateConfig":0.009,"tests\\flow\\FlowProcessorTest::testBatchNoConsistency":0.006,"tests\\flow\\FlowProcessorTest::testBatchNoConsistencyInCompleteProcess":0.008,"tests\\flow\\FlowProcessorTest::testDatabaseOperationFlags":0.006,"tests\\flow\\FlowProcessorTest::testWebSocketNotifyFlag":0.005,"tests\\flow\\FlowProcessorTest::testVoiceGeneration":0.007,"tests\\flow\\FlowProcessorTest::testErrorVoiceGeneration":0.006,"tests\\flow\\FlowProcessorTest::testMultiHospitalConfig":0.007,"tests\\flow\\FlowProcessorTest::testSpecialHospitalConfig":0.006,"tests\\flow\\ProcessContextTest::testCreateContext":0.005,"tests\\flow\\ProcessContextTest::testSetError":0.006,"tests\\flow\\ProcessContextTest::testSetVoice":0.006,"tests\\flow\\ProcessContextTest::testGetFullVoice":0.006,"tests\\flow\\ProcessContextTest::testStepTimeManagement":0.006,"tests\\flow\\ProcessContextTest::testStepDurationManagement":0.005,"tests\\flow\\ProcessContextTest::testDefaultStepDuration":0.007,"tests\\flow\\ProcessContextTest::testGenerateBatchNo":0.006,"tests\\flow\\ProcessContextTest::testBatchNoUniqueness":0.006,"tests\\flow\\ProcessContextTest::testCanStartNewProcess":0.006,"tests\\flow\\ProcessContextTest::testIsWashProcessCompleted":0.006,"tests\\flow\\ProcessContextTest::testChaining":0.005,"tests\\flow\\ProcessEngineTest::testCreateStandardEngine":0.006,"tests\\flow\\ProcessEngineTest::testCreateNoMorningWashEngine":0.006,"tests\\flow\\ProcessEngineTest::testCreateSimpleEngine":0.006,"tests\\flow\\ProcessEngineTest::testCompleteWashProcess":0.045,"tests\\flow\\ProcessEngineTest::testTimeValidationFailure":0.005,"tests\\flow\\ProcessEngineTest::testWrongStep":0.01,"tests\\flow\\ProcessEngineTest::testDisableNode":0.005,"tests\\flow\\ProcessEngineTest::testGetNodes":0.006,"tests\\flow\\ProcessEngineTest::testGetEnabledNodes":0.005,"tests\\flow\\ProcessEngineTest::testUpdateConfig":0.006,"tests\\flow\\ProcessEngineTest::testMachineWashProcess":0.033,"tests\\flow\\nodes\\FinalRinseNodeTest::testCanHandleAfterDisinfect":0.007,"tests\\flow\\nodes\\FinalRinseNodeTest::testCanHandleAfterMachineWashByDefault":0.005,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleAfterMachineWashWhenDisabled":0.008,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleNonFinalRinseReader":0.008,"tests\\flow\\nodes\\FinalRinseNodeTest::testHandleProcess":0.01,"tests\\flow\\nodes\\WashNodeTest::testNodeIdentity":0.006,"tests\\flow\\nodes\\WashNodeTest::testCanHandleWashReader":0.006,"tests\\flow\\nodes\\WashNodeTest::testCannotHandleNonWashReader":0.005,"tests\\flow\\nodes\\WashNodeTest::testCanStartNewWashProcess":0.005,"tests\\flow\\nodes\\WashNodeTest::testCannotWashWithoutMorningWash":0.006,"tests\\flow\\nodes\\WashNodeTest::testHandleProcess":0.009,"tests\\flow\\nodes\\WashNodeTest::testGenerateBatchNo":0.008,"tests\\flow\\nodes\\WashNodeTest::testKeepExistingBatchNo":0.006,"tests\\flow\\strategies\\MorningWashStrategyTest::testNoneMode":0.006,"tests\\flow\\strategies\\MorningWashStrategyTest::testAllMode":0.005,"tests\\flow\\strategies\\MorningWashStrategyTest::testDailyFirstModeWithNoRecords":0.005,"tests\\flow\\strategies\\MorningWashStrategyTest::testDailyFirstModeWithRecords":0.006,"tests\\flow\\strategies\\MorningWashStrategyTest::testSpecificTypesMode":0.005,"tests\\flow\\strategies\\MorningWashStrategyTest::testStorageTimeMode":0.006,"tests\\flow\\strategies\\MorningWashStrategyTest::testStrategyName":0.005,"tests\\flow\\strategies\\TimeValidationStrategyTest::testNoTimeLimitForFirstTime":0.005,"tests\\flow\\strategies\\TimeValidationStrategyTest::testTimeRequirementMet":0.006,"tests\\flow\\strategies\\TimeValidationStrategyTest::testTimeRequirementNotMet":0.005,"tests\\flow\\strategies\\TimeValidationStrategyTest::testCustomDuration":0.006,"tests\\flow\\strategies\\TimeValidationStrategyTest::testIsApplicable":0.006,"tests\\flow\\strategies\\TimeValidationStrategyTest::testStrategyName":0.006,"tests\\flow\\strategies\\TimeValidationStrategyTest::testStrategyPhase":0.005,"tests\\flow\\ProcessEngineTest::testSkipStep":0.012,"tests\\flow\\ProcessEngineTest::testDisinfectAfterWash":0.005,"tests\\flow\\BatchConsistencyTest::testSingleMachineBatchConsistency":0.046,"tests\\flow\\BatchConsistencyTest::testMultiEndoscopeBatchUniqueness":0.036,"tests\\flow\\BatchConsistencyTest::testBatchNoFormat":0.008,"tests\\flow\\BatchConsistencyTest::testBatchNoStability":0.02,"tests\\flow\\BatchConsistencyTest::testNewProcessGeneratesNewBatchNo":0.024,"tests\\flow\\BatchConsistencyTest::testDistributedBatchConsistency":0.057,"tests\\flow\\BatchConsistencyTest::testBatchNoPreservedOnError":0.024,"tests\\flow\\BatchConsistencyTest::testBatchNoWithDifferentProcessTypes":0.022,"tests\\flow\\EdgeCaseTest::testEmptyContext":0.005,"tests\\flow\\EdgeCaseTest::testLongEndoscopeName":0.006,"tests\\flow\\EdgeCaseTest::testSpecialCharactersInName":0.006,"tests\\flow\\EdgeCaseTest::testBatchNoGenerationEdgeCases":0.006,"tests\\flow\\EdgeCaseTest::testTimeBoundaryValues":0.006,"tests\\flow\\EdgeCaseTest::testEmptyChain":0.005,"tests\\flow\\EdgeCaseTest::testAllNodesDisabled":0.021,"tests\\flow\\EdgeCaseTest::testRepeatedStepTimeSetting":0.006,"tests\\flow\\EdgeCaseTest::testChainingEdgeCases":0.006,"tests\\flow\\EdgeCaseTest::testErrorStateOverwrite":0.006,"tests\\flow\\EdgeCaseTest::testRecoveryFromError":0.005,"tests\\flow\\EdgeCaseTest::testInvalidConfigItems":0.007,"tests\\flow\\EdgeCaseTest::testConcurrentBatchNoGeneration":0.011,"tests\\flow\\EdgeCaseTest::testMorningWashBoundaryTime":0.006,"tests\\flow\\EdgeCaseTest::testStorageTimeBoundary":0.007,"tests\\flow\\EdgeCaseTest::testStorageTimeOverThreshold":0.005,"tests\\flow\\PerformanceTest::testSingleExecutionPerformance":0.011,"tests\\flow\\PerformanceTest::testCompleteProcessPerformance":0.039,"tests\\flow\\PerformanceTest::testBatchNoGenerationPerformance":0.023,"tests\\flow\\PerformanceTest::testEngineCreationPerformance":0.094,"tests\\flow\\PerformanceTest::testConfigLoadingPerformance":0.023,"tests\\flow\\PerformanceTest::testContextCreationPerformance":0.258,"tests\\flow\\PerformanceTest::testStrategyExecutionPerformance":0.156,"tests\\flow\\PerformanceTest::testMemoryUsage":0.226,"tests\\flow\\PerformanceTest::testConcurrentProcessingSimulation":0.058,"tests\\flow\\PerformanceTest::testChainTraversalPerformance":5.796,"tests\\flow\\config\\ProcessConfigTest::testCreateDefaultConfig":0.007,"tests\\flow\\config\\ProcessConfigTest::testFromArray":0.006,"tests\\flow\\config\\ProcessConfigTest::testGetEnabledSteps":0.007,"tests\\flow\\config\\ProcessConfigTest::testAddStep":0.006,"tests\\flow\\config\\ProcessConfigTest::testRemoveStep":0.005,"tests\\flow\\config\\ProcessConfigTest::testSetNodeEnabled":0.008,"tests\\flow\\config\\ProcessConfigTest::testMorningWashConfig":0.006,"tests\\flow\\config\\ProcessConfigTest::testTimeValidationConfig":0.007,"tests\\flow\\config\\ProcessConfigTest::testVoiceTemplateConfig":0.005,"tests\\flow\\config\\ProcessConfigTest::testSetStepVoice":0.006,"tests\\flow\\config\\ProcessConfigTest::testToArray":0.007,"tests\\flow\\config\\ProcessConfigTest::testCreateStandard":0.006,"tests\\flow\\config\\ProcessConfigTest::testCreateNoMorningWash":0.007,"tests\\flow\\config\\ProcessConfigTest::testCreateSimple":0.006,"tests\\flow\\config\\ProcessConfigTest::testCreateMachineWash":0.005,"tests\\flow\\config\\ProcessConfigTest::testCreateNoDry":0.006,"tests\\flow\\config\\ProcessConfigTest::testCreateDryOnly":0.005,"tests\\flow\\config\\ProcessConfigTest::testChaining":0.006,"tests\\flow\\nodes\\DisinfectNodeTest::testNodeIdentity":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterRinse":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterFinalRinse":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterWash":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testCannotHandleNonDisinfectReader":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testCannotHandleAfterDisinfect":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testHandleProcess":0.009,"tests\\flow\\nodes\\DisinfectNodeTest::testDatabaseOperationFlags":0.008,"tests\\flow\\nodes\\DisinfectNodeTest::testWebSocketNotifyFlag":0.008,"tests\\flow\\nodes\\MorningWashNodeTest::testNodeIdentity":0.005,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleMorningWashReader":0.021,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleWhenNoNeed":0.006,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleNonMorningWashReader":0.005,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleWhenAlreadyWashed":0.005,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcess":0.008,"tests\\flow\\nodes\\MorningWashNodeTest::testGenerateBatchNo":0.009,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleDisinfectReaderForMorningWash":0.006,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleMachineWashReaderForMorningWash":0.005,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleNonDisinfectMachineReader":0.006,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcessWithDisinfect":0.009,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcessWithMachineWash":0.009,"tests\\flow\\nodes\\DryNodeTest::testNodeIdentity":0.006,"tests\\flow\\nodes\\DryNodeTest::testCanHandleAfterFinalRinse":0.007,"tests\\flow\\nodes\\DryNodeTest::testCanHandleAfterDisinfect":0.006,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleAfterRinse":0.005,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleNonDryReader":0.007,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleAfterDry":0.006,"tests\\flow\\nodes\\DryNodeTest::testHandleProcess":0.008,"tests\\flow\\nodes\\DryNodeTest::testDatabaseOperationFlags":0.009,"tests\\flow\\nodes\\DryNodeTest::testWebSocketNotifyFlag":0.008,"tests\\flow\\nodes\\DryNodeTest::testKeepExistingBatchNo":0.01,"tests\\flow\\ProcessEngineTest::testStandardWashRinseDisinfectFlow":0.023,"tests\\flow\\UsageExampleTest::testExample1StandardProcess":0.022,"tests\\flow\\UsageExampleTest::testExample2NoMorningWash":0.025,"tests\\flow\\UsageExampleTest::testExample3DynamicAdjust":0.048,"tests\\flow\\UsageExampleTest::testExample4CustomVoice":0.022,"tests\\flow\\UsageExampleTest::testExample5MorningWashModes":0.033,"tests\\flow\\UsageExampleTest::testExample6MachineWash":0.022,"tests\\flow\\UsageExampleTest::testExample7SimpleProcess":0.021,"tests\\flow\\UsageExampleTest::testExample8TimeValidation":0.021,"tests\\flow\\UsageExampleTest::testExample9FullProcess":0.021,"tests\\flow\\UsageExampleTest::testExample10MultiHospital":0.046,"tests\\flow\\UsageExampleTest::testLoadCustomProcessFromConfig":0.007,"tests\\flow\\UsageExampleTest::testCreateNoMorningWashFromConfig":0.042,"tests\\flow\\UsageExampleTest::testCreateMachineWashFromConfig":0.036,"tests\\flow\\UsageExampleTest::testCreateYiwuModeFromConfig":0.015,"tests\\flow\\UsageExampleTest::testFlowProcessorUsage":0.045,"tests\\flow\\UsageExampleTest::testFlowProcessorCompleteProcess":0.021,"tests\\flow\\UsageExampleTest::testFlowProcessorWithConfig":0.037,"tests\\db\\DBC::testDBConnect":0.113,"tests\\db\\DBC::testGenTables":0.416,"tests\\db\\DBC::testModel":0.171,"tests\\flow\\nodes\\EndNodeTest::testNodeIdentity":0.006,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterDry":0.006,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterDisinfect":0.005,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterFinalRinse":0.005,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterMachineWash":0.005,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleNonEndReader":0.005,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleAfterWash":0.007,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleAfterRinse":0.006,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleWithEmptyStep":0.005,"tests\\flow\\nodes\\EndNodeTest::testHandleProcess":0.009,"tests\\flow\\nodes\\EndNodeTest::testDatabaseOperationIsUpdate":0.011,"tests\\flow\\nodes\\EndNodeTest::testWebSocketNotifyFlag":0.009,"tests\\flow\\nodes\\EndNodeTest::testActionEndTimeIsSet":0.009,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleAfterWash":0.006,"tests\\flow\\nodes\\FinalRinseNodeTest::testDatabaseOperationFlags":0.008,"tests\\flow\\nodes\\FinalRinseNodeTest::testWebSocketNotifyFlag":0.009,"tests\\flow\\nodes\\FinalRinseNodeTest::testNodeIdentity":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testNodeIdentity":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterWash":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterRinse":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterDisinfect":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleWithEmptyStep":0.006,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterEnd":0.006,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterEndoscopeOut":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleNonMachineWashReader":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleAfterFinalRinse":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleAfterDry":0.006,"tests\\flow\\nodes\\MachineWashNodeTest::testHandleProcess":0.008,"tests\\flow\\nodes\\MachineWashNodeTest::testDatabaseOperationFlags":0.01,"tests\\flow\\nodes\\MachineWashNodeTest::testWebSocketNotifyFlag":0.008,"tests\\flow\\nodes\\RinseNodeTest::testNodeIdentity":0.005,"tests\\flow\\nodes\\RinseNodeTest::testCanHandleAfterWash":0.007,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleNonRinseReader":0.007,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleAfterDisinfect":0.006,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleWithEmptyStep":0.006,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleAfterRinse":0.005,"tests\\flow\\nodes\\RinseNodeTest::testHandleProcess":0.01,"tests\\flow\\nodes\\RinseNodeTest::testDatabaseOperationFlags":0.009,"tests\\flow\\nodes\\RinseNodeTest::testWebSocketNotifyFlag":0.009,"tests\\flow\\nodes\\RinseNodeTest::testDisabledNodeSkips":0.009,"tests\\flow\\strategies\\TimeValidationStrategyTest::testNonDurationStepIsSkipped":0.008,"tests\\flow\\strategies\\TimeValidationStrategyTest::testSetStepDuration":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testStrategyName":0.007,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testStrategyPhaseIsAfter":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testIsAlwaysApplicable":0.007,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testNormalWashVoice":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testNormalRinseVoice":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testNormalDisinfectVoice":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testFinalRinseVoice":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testDryVoice":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testEndVoice":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testMachineWashVoice":0.007,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testMorningWashVoice":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testMachineMorningWashVoice":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testErrorStateGeneratesErrorVoice":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testFullVoiceIncludesEndoscopeName":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testLeakTestRemindAppended":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testStorageRemindAppended":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testCustomVoiceTemplate":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testSetStepVoice":0.005,"tests\\flow\\FlowProcessorTest::testSuccessfulFlowSavesToDatabase":0.011,"tests\\flow\\FlowProcessorTest::testSuccessfulFlowSendsVoice":0.008,"tests\\flow\\FlowProcessorTest::testFailedFlowDoesNotSaveToDatabase":0.007,"tests\\flow\\FlowProcessorTest::testFailedFlowStillSendsVoice":0.008,"tests\\flow\\FlowProcessorTest::testWebSocketNotificationSentWhenNeeded":0.01,"tests\\flow\\FlowProcessorTest::testWebSocketNotificationNotSentWhenNotNeeded":0.008,"tests\\flow\\FlowProcessorTest::testEndOperationIsUpdate":0.01,"tests\\flow\\FlowProcessorTest::testGetActionTypeMapping":0.107,"tests\\flow\\FlowProcessorTest::testStaticFactoryCreate":0.007,"tests\\flow\\ProcessSimulationTest::testBasicManualWashWithoutDatabase":0.287,"tests\\flow\\ProcessSimulationTest::testNodeChainConstruction":0.264,"tests\\flow\\ProcessSimulationTest::testMorningWashNodeConfiguration":0.278,"tests\\flow\\ProcessSimulationTest::testMachineWashNodeConfiguration":0.271,"tests\\flow\\ProcessSimulationTest::testStorageNodeConfiguration":0.273,"tests\\flow\\ProcessSimulationTest::testDuplicateCheckNode":0.522,"tests\\flow\\ProcessSimulationTest::testCloseNode":0.268,"tests\\flow\\ProcessSimulationTest::testNodeEnableDisable":0.268,"tests\\flow\\ProcessSimulationTest::testConfigUpdate":0.522,"tests\\flow\\ProcessSimulationTest::testStrategyInitialization":0.291,"tests\\flow\\FullProcessTest::testCompleteManualWashProcess":0.09,"tests\\flow\\FullProcessTest::testCompleteManualWashProcessUsingHelper":0.285,"tests\\flow\\FullProcessTest::testMorningWashRequired":0.262,"tests\\flow\\FullProcessTest::testManualWashAfterMorningWash":0.269,"tests\\flow\\FullProcessTest::testMachineWashProcess":0.281,"tests\\flow\\FullProcessTest::testMachineWashProcessUsingHelper":0.286,"tests\\flow\\FullProcessTest::testMorningWashThenMachineWash":0.275,"tests\\flow\\FullProcessTest::testSwipeEndoscopeWithoutOperator":0.02,"tests\\flow\\FullProcessTest::testWrongStepOrder":0.078,"tests\\flow\\FullProcessTest::testDuplicateSwipe":0.142,"tests\\flow\\FullProcessTest::testUnboundReader":0.273,"tests\\flow\\FullProcessTest::testUnboundEndoscope":0.323,"tests\\flow\\FullProcessTest::testDifferentOperatorContinueProcess":0.124,"tests\\flow\\FullProcessTest::testWashStepVoice":0.074,"tests\\flow\\FullProcessTest::testDisinfectStepVoice":0.182,"tests\\flow\\FullProcessTest::testOperatorCardVoice":0.02,"tests\\flow\\FullProcessTest::testErrorVoice":0.021,"tests\\flow\\FullProcessTest::testVoiceTemplateParams":0.077,"tests\\flow\\FullProcessTest::testProcessChainExecution":0.236,"tests\\flow\\FullProcessTest::testDisabledNodeSkipped":0.277,"tests\\flow\\FullProcessTest::testTimeValidationBlock":0.265,"tests\\flow\\FullProcessTest::testDuplicateSwipeBlock":0.201,"tests\\flow\\FullProcessTest::testNewProcessAfterComplete":0.331,"tests\\flow\\FullProcessTest::testConcurrentProcessIsolation":0.174,"tests\\flow\\FullProcessTest::testProcessorReset":0.081,"tests\\flow\\FullProcessTest::testVirtualContextBuilder":0.017,"tests\\flow\\FullProcessTest::testEnvironmentConfig":0.007,"tests\\flow\\Test::testExample":0.005,"tests\\flow\\cases\\BlockTest::testProcessChainExecution":0.239,"tests\\flow\\cases\\BlockTest::testDisabledNodeSkipped":0.288,"tests\\flow\\cases\\BlockTest::testTimeValidationBlockWithBlockModeOn":0.263,"tests\\flow\\cases\\BlockTest::testTimeValidationWithBlockModeOff":0.282,"tests\\flow\\cases\\BlockTest::testDuplicateSwipeBlock":0.193,"tests\\flow\\cases\\BlockTest::testTimeValidationPass":0.281,"tests\\flow\\cases\\ErrorFlowTest::testSwipeEndoscopeWithoutOperator":0.008,"tests\\flow\\cases\\ErrorFlowTest::testWrongStepOrder":0.069,"tests\\flow\\cases\\ErrorFlowTest::testDuplicateSwipe":0.109,"tests\\flow\\cases\\ErrorFlowTest::testUnboundReader":0.276,"tests\\flow\\cases\\ErrorFlowTest::testUnboundEndoscope":0.27,"tests\\flow\\cases\\HelperTest::testProcessorReset":0.063,"tests\\flow\\cases\\HelperTest::testVirtualContextBuilder":0.007,"tests\\flow\\cases\\HelperTest::testEnvironmentConfig":0.006,"tests\\flow\\cases\\MachineWashTest::testMachineWashProcess":0.06,"tests\\flow\\cases\\MachineWashTest::testMachineWashProcessUsingHelper":0.06,"tests\\flow\\cases\\MachineWashTest::testMorningWashThenMachineWash":0.059,"tests\\flow\\cases\\MachineWashTest::testMultipleEndoscopeMachineWash":0.112,"tests\\flow\\cases\\ManualWashTest::testCompleteManualWashProcess":0.031,"tests\\flow\\cases\\ManualWashTest::testCompleteManualWashProcessUsingHelper":0.436,"tests\\flow\\cases\\ManualWashTest::testMorningWashRequired":0.316,"tests\\flow\\cases\\ManualWashTest::testManualWashAfterMorningWash":0.403,"tests\\flow\\cases\\ManualWashTest::testDifferentOperatorContinueProcess":0.138,"tests\\flow\\cases\\ManualWashTest::testNewProcessAfterComplete":0.443,"tests\\flow\\cases\\ManualWashTest::testConcurrentProcessIsolation":0.201,"tests\\flow\\cases\\VoiceTest::testWashStepVoice":0.064,"tests\\flow\\cases\\VoiceTest::testDisinfectStepVoice":0.2,"tests\\flow\\cases\\VoiceTest::testOperatorCardVoice":0.008,"tests\\flow\\cases\\VoiceTest::testErrorVoice":0.008,"tests\\flow\\cases\\VoiceTest::testWashDurationInsufficientVoice":0.276}} \ No newline at end of file +{"version":2,"defects":{"tests\\flow\\FlowProcessorTest::testCreateProcessor":8,"tests\\flow\\FlowProcessorTest::testCreateProcessorWithConfig":8,"tests\\flow\\FlowProcessorTest::testUpdateConfig":8,"tests\\flow\\FlowProcessorTest::testBatchNoConsistency":8,"tests\\flow\\FlowProcessorTest::testBatchNoConsistencyInCompleteProcess":8,"tests\\flow\\FlowProcessorTest::testDatabaseOperationFlags":8,"tests\\flow\\FlowProcessorTest::testWebSocketNotifyFlag":8,"tests\\flow\\FlowProcessorTest::testVoiceGeneration":8,"tests\\flow\\FlowProcessorTest::testErrorVoiceGeneration":7,"tests\\flow\\FlowProcessorTest::testMultiHospitalConfig":8,"tests\\flow\\FlowProcessorTest::testSpecialHospitalConfig":8,"tests\\flow\\ProcessEngineTest::testTimeValidationFailure":8,"tests\\flow\\ProcessEngineTest::testWrongStep":7,"tests\\flow\\strategies\\TimeValidationStrategyTest::testCustomDuration":7,"tests\\flow\\ProcessEngineTest::testSkipStep":7,"tests\\flow\\BatchConsistencyTest::testBatchNoPreservedOnError":8,"tests\\flow\\BatchConsistencyTest::testBatchNoWithDifferentProcessTypes":8,"tests\\flow\\EdgeCaseTest::testBatchNoGenerationEdgeCases":7,"tests\\flow\\PerformanceTest::testContextCreationPerformance":7,"tests\\flow\\PerformanceTest::testStrategyExecutionPerformance":7,"tests\\flow\\PerformanceTest::testChainTraversalPerformance":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleMorningWashReader":7,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcess":7,"tests\\flow\\nodes\\MorningWashNodeTest::testGenerateBatchNo":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleDisinfectReaderForMorningWash":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleMachineWashReaderForMorningWash":8,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcessWithDisinfect":8,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcessWithMachineWash":8,"tests\\flow\\EdgeCaseTest::testConcurrentBatchNoGeneration":7,"tests\\flow\\ProcessEngineTest::testDisinfectAfterWash":7,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterWash":8,"tests\\flow\\nodes\\DryNodeTest::testCanHandleAfterDisinfect":8,"tests\\flow\\UsageExampleTest::testExample4CustomVoice":8,"tests\\flow\\UsageExampleTest::testExample8TimeValidation":8,"tests\\flow\\UsageExampleTest::testLoadCustomProcessFromConfig":8,"tests\\flow\\UsageExampleTest::testCreateNoMorningWashFromConfig":8,"tests\\flow\\UsageExampleTest::testCreateMachineWashFromConfig":8,"tests\\flow\\UsageExampleTest::testCreateYiwuModeFromConfig":8,"tests\\flow\\UsageExampleTest::testExample1StandardProcess":8,"tests\\flow\\UsageExampleTest::testExample2NoMorningWash":8,"tests\\flow\\UsageExampleTest::testExample3DynamicAdjust":8,"tests\\flow\\UsageExampleTest::testExample5MorningWashModes":8,"tests\\flow\\UsageExampleTest::testExample6MachineWash":8,"tests\\flow\\UsageExampleTest::testExample7SimpleProcess":8,"tests\\flow\\UsageExampleTest::testExample9FullProcess":8,"tests\\flow\\UsageExampleTest::testExample10MultiHospital":8,"tests\\flow\\UsageExampleTest::testFlowProcessorUsage":8,"tests\\flow\\UsageExampleTest::testFlowProcessorCompleteProcess":8,"tests\\flow\\UsageExampleTest::testFlowProcessorWithConfig":8,"tests\\flow\\BatchConsistencyTest::testSingleMachineBatchConsistency":8,"tests\\flow\\BatchConsistencyTest::testMultiEndoscopeBatchUniqueness":8,"tests\\flow\\BatchConsistencyTest::testBatchNoStability":8,"tests\\flow\\BatchConsistencyTest::testNewProcessGeneratesNewBatchNo":8,"tests\\flow\\BatchConsistencyTest::testDistributedBatchConsistency":8,"tests\\flow\\PerformanceTest::testSingleExecutionPerformance":8,"tests\\flow\\PerformanceTest::testCompleteProcessPerformance":8,"tests\\flow\\PerformanceTest::testEngineCreationPerformance":8,"tests\\flow\\PerformanceTest::testConcurrentProcessingSimulation":8,"tests\\flow\\ProcessEngineTest::testCreateStandardEngine":8,"tests\\flow\\ProcessEngineTest::testCreateNoMorningWashEngine":8,"tests\\flow\\ProcessEngineTest::testCreateSimpleEngine":8,"tests\\flow\\ProcessEngineTest::testCompleteWashProcess":8,"tests\\flow\\ProcessEngineTest::testStandardWashRinseDisinfectFlow":8,"tests\\flow\\ProcessEngineTest::testDisableNode":8,"tests\\flow\\ProcessEngineTest::testGetNodes":8,"tests\\flow\\ProcessEngineTest::testGetEnabledNodes":8,"tests\\flow\\ProcessEngineTest::testUpdateConfig":8,"tests\\flow\\ProcessEngineTest::testMachineWashProcess":8,"tests\\db\\DBC::testDBConnect":8,"tests\\db\\DBC::testGenTables":7,"tests\\db\\DBC::testModel":5,"tests\\flow\\nodes\\DisinfectNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterRinse":8,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterFinalRinse":8,"tests\\flow\\nodes\\DisinfectNodeTest::testCannotHandleNonDisinfectReader":8,"tests\\flow\\nodes\\DisinfectNodeTest::testCannotHandleAfterDisinfect":8,"tests\\flow\\nodes\\DisinfectNodeTest::testHandleProcess":8,"tests\\flow\\nodes\\DisinfectNodeTest::testDatabaseOperationFlags":7,"tests\\flow\\nodes\\DisinfectNodeTest::testWebSocketNotifyFlag":8,"tests\\flow\\nodes\\DryNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\DryNodeTest::testCanHandleAfterFinalRinse":7,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleAfterRinse":8,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleNonDryReader":8,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleAfterDry":7,"tests\\flow\\nodes\\DryNodeTest::testHandleProcess":7,"tests\\flow\\nodes\\DryNodeTest::testDatabaseOperationFlags":7,"tests\\flow\\nodes\\DryNodeTest::testWebSocketNotifyFlag":7,"tests\\flow\\nodes\\DryNodeTest::testKeepExistingBatchNo":8,"tests\\flow\\nodes\\MorningWashNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleWhenNoNeed":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleNonDisinfectMachineReader":8,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleWhenAlreadyWashed":8,"tests\\flow\\nodes\\EndNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterDry":8,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterDisinfect":7,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterFinalRinse":8,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterMachineWash":8,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleNonEndReader":8,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleAfterWash":8,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleAfterRinse":8,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleWithEmptyStep":8,"tests\\flow\\nodes\\EndNodeTest::testHandleProcess":8,"tests\\flow\\nodes\\EndNodeTest::testDatabaseOperationIsUpdate":7,"tests\\flow\\nodes\\EndNodeTest::testWebSocketNotifyFlag":8,"tests\\flow\\nodes\\EndNodeTest::testActionEndTimeIsSet":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testCanHandleAfterDisinfect":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testCanHandleAfterMachineWashByDefault":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleAfterMachineWashWhenDisabled":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleNonFinalRinseReader":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testHandleProcess":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleAfterWash":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testDatabaseOperationFlags":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testWebSocketNotifyFlag":8,"tests\\flow\\nodes\\FinalRinseNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\MachineWashNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterWash":8,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterRinse":7,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterDisinfect":7,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleWithEmptyStep":7,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterEnd":7,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterEndoscopeOut":8,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleNonMachineWashReader":8,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleAfterFinalRinse":8,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleAfterDry":8,"tests\\flow\\nodes\\MachineWashNodeTest::testHandleProcess":8,"tests\\flow\\nodes\\MachineWashNodeTest::testDatabaseOperationFlags":7,"tests\\flow\\nodes\\MachineWashNodeTest::testWebSocketNotifyFlag":8,"tests\\flow\\nodes\\RinseNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\RinseNodeTest::testCanHandleAfterWash":7,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleNonRinseReader":8,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleAfterDisinfect":7,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleWithEmptyStep":7,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleAfterRinse":7,"tests\\flow\\nodes\\RinseNodeTest::testHandleProcess":7,"tests\\flow\\nodes\\RinseNodeTest::testDatabaseOperationFlags":7,"tests\\flow\\nodes\\RinseNodeTest::testWebSocketNotifyFlag":7,"tests\\flow\\nodes\\RinseNodeTest::testDisabledNodeSkips":8,"tests\\flow\\nodes\\WashNodeTest::testNodeIdentity":8,"tests\\flow\\nodes\\WashNodeTest::testCanHandleWashReader":8,"tests\\flow\\nodes\\WashNodeTest::testCannotHandleNonWashReader":8,"tests\\flow\\nodes\\WashNodeTest::testCanStartNewWashProcess":8,"tests\\flow\\nodes\\WashNodeTest::testCannotWashWithoutMorningWash":8,"tests\\flow\\nodes\\WashNodeTest::testHandleProcess":8,"tests\\flow\\nodes\\WashNodeTest::testGenerateBatchNo":7,"tests\\flow\\nodes\\WashNodeTest::testKeepExistingBatchNo":8,"tests\\flow\\strategies\\TimeValidationStrategyTest::testTimeRequirementNotMet":7,"tests\\flow\\strategies\\TimeValidationStrategyTest::testSetStepDuration":7,"tests\\flow\\FlowProcessorTest::testSuccessfulFlowSavesToDatabase":8,"tests\\flow\\FlowProcessorTest::testEndOperationIsUpdate":8,"tests\\flow\\FlowProcessorTest::testGetActionTypeMapping":8,"tests\\flow\\EdgeCaseTest::testLongEndoscopeName":7,"tests\\flow\\EdgeCaseTest::testSpecialCharactersInName":7,"tests\\flow\\ProcessContextTest::testGetFullVoice":7,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testFullVoiceIncludesEndoscopeName":7,"tests\\flow\\FlowProcessorTest::testSuccessfulFlowSendsVoice":8,"tests\\flow\\FlowProcessorTest::testFailedFlowDoesNotSaveToDatabase":8,"tests\\flow\\FlowProcessorTest::testFailedFlowStillSendsVoice":8,"tests\\flow\\FlowProcessorTest::testWebSocketNotificationSentWhenNeeded":8,"tests\\flow\\FlowProcessorTest::testWebSocketNotificationNotSentWhenNotNeeded":8,"tests\\flow\\FlowProcessorTest::testStaticFactoryCreate":8,"tests\\flow\\EdgeCaseTest::testAllNodesDisabled":8,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testFinalRinseVoice":8,"tests\\flow\\ProcessSimulationTest::testDuplicateCheckNode":7,"tests\\flow\\FullProcessTest::testCompleteManualWashProcess":7,"tests\\flow\\FullProcessTest::testSwipeEndoscopeWithoutOperator":7,"tests\\flow\\cases\\BlockTest::testProcessChainExecution":5,"tests\\flow\\cases\\BlockTest::testDisabledNodeSkipped":5,"tests\\flow\\cases\\BlockTest::testTimeValidationBlockWithBlockModeOn":5,"tests\\flow\\cases\\BlockTest::testTimeValidationWithBlockModeOff":5,"tests\\flow\\cases\\BlockTest::testDuplicateSwipeBlock":5,"tests\\flow\\cases\\BlockTest::testTimeValidationPass":5,"tests\\flow\\cases\\ManualWashTest::testCompleteManualWashProcess":8},"times":{"tests\\flow\\FlowProcessorTest::testCreateProcessor":0.006,"tests\\flow\\FlowProcessorTest::testCreateProcessorWithConfig":0.006,"tests\\flow\\FlowProcessorTest::testStaticFactory":0.006,"tests\\flow\\FlowProcessorTest::testUpdateConfig":0.009,"tests\\flow\\FlowProcessorTest::testBatchNoConsistency":0.006,"tests\\flow\\FlowProcessorTest::testBatchNoConsistencyInCompleteProcess":0.008,"tests\\flow\\FlowProcessorTest::testDatabaseOperationFlags":0.006,"tests\\flow\\FlowProcessorTest::testWebSocketNotifyFlag":0.005,"tests\\flow\\FlowProcessorTest::testVoiceGeneration":0.007,"tests\\flow\\FlowProcessorTest::testErrorVoiceGeneration":0.006,"tests\\flow\\FlowProcessorTest::testMultiHospitalConfig":0.007,"tests\\flow\\FlowProcessorTest::testSpecialHospitalConfig":0.006,"tests\\flow\\ProcessContextTest::testCreateContext":0.005,"tests\\flow\\ProcessContextTest::testSetError":0.006,"tests\\flow\\ProcessContextTest::testSetVoice":0.006,"tests\\flow\\ProcessContextTest::testGetFullVoice":0.006,"tests\\flow\\ProcessContextTest::testStepTimeManagement":0.006,"tests\\flow\\ProcessContextTest::testStepDurationManagement":0.005,"tests\\flow\\ProcessContextTest::testDefaultStepDuration":0.007,"tests\\flow\\ProcessContextTest::testGenerateBatchNo":0.006,"tests\\flow\\ProcessContextTest::testBatchNoUniqueness":0.006,"tests\\flow\\ProcessContextTest::testCanStartNewProcess":0.006,"tests\\flow\\ProcessContextTest::testIsWashProcessCompleted":0.006,"tests\\flow\\ProcessContextTest::testChaining":0.005,"tests\\flow\\ProcessEngineTest::testCreateStandardEngine":0.006,"tests\\flow\\ProcessEngineTest::testCreateNoMorningWashEngine":0.006,"tests\\flow\\ProcessEngineTest::testCreateSimpleEngine":0.006,"tests\\flow\\ProcessEngineTest::testCompleteWashProcess":0.045,"tests\\flow\\ProcessEngineTest::testTimeValidationFailure":0.005,"tests\\flow\\ProcessEngineTest::testWrongStep":0.01,"tests\\flow\\ProcessEngineTest::testDisableNode":0.005,"tests\\flow\\ProcessEngineTest::testGetNodes":0.006,"tests\\flow\\ProcessEngineTest::testGetEnabledNodes":0.005,"tests\\flow\\ProcessEngineTest::testUpdateConfig":0.006,"tests\\flow\\ProcessEngineTest::testMachineWashProcess":0.033,"tests\\flow\\nodes\\FinalRinseNodeTest::testCanHandleAfterDisinfect":0.007,"tests\\flow\\nodes\\FinalRinseNodeTest::testCanHandleAfterMachineWashByDefault":0.005,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleAfterMachineWashWhenDisabled":0.008,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleNonFinalRinseReader":0.008,"tests\\flow\\nodes\\FinalRinseNodeTest::testHandleProcess":0.01,"tests\\flow\\nodes\\WashNodeTest::testNodeIdentity":0.006,"tests\\flow\\nodes\\WashNodeTest::testCanHandleWashReader":0.006,"tests\\flow\\nodes\\WashNodeTest::testCannotHandleNonWashReader":0.005,"tests\\flow\\nodes\\WashNodeTest::testCanStartNewWashProcess":0.005,"tests\\flow\\nodes\\WashNodeTest::testCannotWashWithoutMorningWash":0.006,"tests\\flow\\nodes\\WashNodeTest::testHandleProcess":0.009,"tests\\flow\\nodes\\WashNodeTest::testGenerateBatchNo":0.008,"tests\\flow\\nodes\\WashNodeTest::testKeepExistingBatchNo":0.006,"tests\\flow\\strategies\\MorningWashStrategyTest::testNoneMode":0.006,"tests\\flow\\strategies\\MorningWashStrategyTest::testAllMode":0.005,"tests\\flow\\strategies\\MorningWashStrategyTest::testDailyFirstModeWithNoRecords":0.005,"tests\\flow\\strategies\\MorningWashStrategyTest::testDailyFirstModeWithRecords":0.006,"tests\\flow\\strategies\\MorningWashStrategyTest::testSpecificTypesMode":0.005,"tests\\flow\\strategies\\MorningWashStrategyTest::testStorageTimeMode":0.006,"tests\\flow\\strategies\\MorningWashStrategyTest::testStrategyName":0.005,"tests\\flow\\strategies\\TimeValidationStrategyTest::testNoTimeLimitForFirstTime":0.005,"tests\\flow\\strategies\\TimeValidationStrategyTest::testTimeRequirementMet":0.006,"tests\\flow\\strategies\\TimeValidationStrategyTest::testTimeRequirementNotMet":0.005,"tests\\flow\\strategies\\TimeValidationStrategyTest::testCustomDuration":0.006,"tests\\flow\\strategies\\TimeValidationStrategyTest::testIsApplicable":0.006,"tests\\flow\\strategies\\TimeValidationStrategyTest::testStrategyName":0.006,"tests\\flow\\strategies\\TimeValidationStrategyTest::testStrategyPhase":0.005,"tests\\flow\\ProcessEngineTest::testSkipStep":0.012,"tests\\flow\\ProcessEngineTest::testDisinfectAfterWash":0.005,"tests\\flow\\BatchConsistencyTest::testSingleMachineBatchConsistency":0.046,"tests\\flow\\BatchConsistencyTest::testMultiEndoscopeBatchUniqueness":0.036,"tests\\flow\\BatchConsistencyTest::testBatchNoFormat":0.008,"tests\\flow\\BatchConsistencyTest::testBatchNoStability":0.02,"tests\\flow\\BatchConsistencyTest::testNewProcessGeneratesNewBatchNo":0.024,"tests\\flow\\BatchConsistencyTest::testDistributedBatchConsistency":0.057,"tests\\flow\\BatchConsistencyTest::testBatchNoPreservedOnError":0.024,"tests\\flow\\BatchConsistencyTest::testBatchNoWithDifferentProcessTypes":0.022,"tests\\flow\\EdgeCaseTest::testEmptyContext":0.005,"tests\\flow\\EdgeCaseTest::testLongEndoscopeName":0.006,"tests\\flow\\EdgeCaseTest::testSpecialCharactersInName":0.006,"tests\\flow\\EdgeCaseTest::testBatchNoGenerationEdgeCases":0.006,"tests\\flow\\EdgeCaseTest::testTimeBoundaryValues":0.006,"tests\\flow\\EdgeCaseTest::testEmptyChain":0.005,"tests\\flow\\EdgeCaseTest::testAllNodesDisabled":0.021,"tests\\flow\\EdgeCaseTest::testRepeatedStepTimeSetting":0.006,"tests\\flow\\EdgeCaseTest::testChainingEdgeCases":0.006,"tests\\flow\\EdgeCaseTest::testErrorStateOverwrite":0.006,"tests\\flow\\EdgeCaseTest::testRecoveryFromError":0.005,"tests\\flow\\EdgeCaseTest::testInvalidConfigItems":0.007,"tests\\flow\\EdgeCaseTest::testConcurrentBatchNoGeneration":0.011,"tests\\flow\\EdgeCaseTest::testMorningWashBoundaryTime":0.006,"tests\\flow\\EdgeCaseTest::testStorageTimeBoundary":0.007,"tests\\flow\\EdgeCaseTest::testStorageTimeOverThreshold":0.005,"tests\\flow\\PerformanceTest::testSingleExecutionPerformance":0.011,"tests\\flow\\PerformanceTest::testCompleteProcessPerformance":0.039,"tests\\flow\\PerformanceTest::testBatchNoGenerationPerformance":0.023,"tests\\flow\\PerformanceTest::testEngineCreationPerformance":0.094,"tests\\flow\\PerformanceTest::testConfigLoadingPerformance":0.023,"tests\\flow\\PerformanceTest::testContextCreationPerformance":0.258,"tests\\flow\\PerformanceTest::testStrategyExecutionPerformance":0.156,"tests\\flow\\PerformanceTest::testMemoryUsage":0.226,"tests\\flow\\PerformanceTest::testConcurrentProcessingSimulation":0.058,"tests\\flow\\PerformanceTest::testChainTraversalPerformance":5.796,"tests\\flow\\config\\ProcessConfigTest::testCreateDefaultConfig":0.007,"tests\\flow\\config\\ProcessConfigTest::testFromArray":0.006,"tests\\flow\\config\\ProcessConfigTest::testGetEnabledSteps":0.007,"tests\\flow\\config\\ProcessConfigTest::testAddStep":0.006,"tests\\flow\\config\\ProcessConfigTest::testRemoveStep":0.005,"tests\\flow\\config\\ProcessConfigTest::testSetNodeEnabled":0.008,"tests\\flow\\config\\ProcessConfigTest::testMorningWashConfig":0.006,"tests\\flow\\config\\ProcessConfigTest::testTimeValidationConfig":0.007,"tests\\flow\\config\\ProcessConfigTest::testVoiceTemplateConfig":0.005,"tests\\flow\\config\\ProcessConfigTest::testSetStepVoice":0.006,"tests\\flow\\config\\ProcessConfigTest::testToArray":0.007,"tests\\flow\\config\\ProcessConfigTest::testCreateStandard":0.006,"tests\\flow\\config\\ProcessConfigTest::testCreateNoMorningWash":0.007,"tests\\flow\\config\\ProcessConfigTest::testCreateSimple":0.006,"tests\\flow\\config\\ProcessConfigTest::testCreateMachineWash":0.005,"tests\\flow\\config\\ProcessConfigTest::testCreateNoDry":0.006,"tests\\flow\\config\\ProcessConfigTest::testCreateDryOnly":0.005,"tests\\flow\\config\\ProcessConfigTest::testChaining":0.006,"tests\\flow\\nodes\\DisinfectNodeTest::testNodeIdentity":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterRinse":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterFinalRinse":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testCanHandleAfterWash":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testCannotHandleNonDisinfectReader":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testCannotHandleAfterDisinfect":0.005,"tests\\flow\\nodes\\DisinfectNodeTest::testHandleProcess":0.009,"tests\\flow\\nodes\\DisinfectNodeTest::testDatabaseOperationFlags":0.008,"tests\\flow\\nodes\\DisinfectNodeTest::testWebSocketNotifyFlag":0.008,"tests\\flow\\nodes\\MorningWashNodeTest::testNodeIdentity":0.005,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleMorningWashReader":0.021,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleWhenNoNeed":0.006,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleNonMorningWashReader":0.005,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleWhenAlreadyWashed":0.005,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcess":0.008,"tests\\flow\\nodes\\MorningWashNodeTest::testGenerateBatchNo":0.009,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleDisinfectReaderForMorningWash":0.006,"tests\\flow\\nodes\\MorningWashNodeTest::testCanHandleMachineWashReaderForMorningWash":0.005,"tests\\flow\\nodes\\MorningWashNodeTest::testCannotHandleNonDisinfectMachineReader":0.006,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcessWithDisinfect":0.009,"tests\\flow\\nodes\\MorningWashNodeTest::testHandleProcessWithMachineWash":0.009,"tests\\flow\\nodes\\DryNodeTest::testNodeIdentity":0.006,"tests\\flow\\nodes\\DryNodeTest::testCanHandleAfterFinalRinse":0.007,"tests\\flow\\nodes\\DryNodeTest::testCanHandleAfterDisinfect":0.006,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleAfterRinse":0.005,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleNonDryReader":0.007,"tests\\flow\\nodes\\DryNodeTest::testCannotHandleAfterDry":0.006,"tests\\flow\\nodes\\DryNodeTest::testHandleProcess":0.008,"tests\\flow\\nodes\\DryNodeTest::testDatabaseOperationFlags":0.009,"tests\\flow\\nodes\\DryNodeTest::testWebSocketNotifyFlag":0.008,"tests\\flow\\nodes\\DryNodeTest::testKeepExistingBatchNo":0.01,"tests\\flow\\ProcessEngineTest::testStandardWashRinseDisinfectFlow":0.023,"tests\\flow\\UsageExampleTest::testExample1StandardProcess":0.022,"tests\\flow\\UsageExampleTest::testExample2NoMorningWash":0.025,"tests\\flow\\UsageExampleTest::testExample3DynamicAdjust":0.048,"tests\\flow\\UsageExampleTest::testExample4CustomVoice":0.022,"tests\\flow\\UsageExampleTest::testExample5MorningWashModes":0.033,"tests\\flow\\UsageExampleTest::testExample6MachineWash":0.022,"tests\\flow\\UsageExampleTest::testExample7SimpleProcess":0.021,"tests\\flow\\UsageExampleTest::testExample8TimeValidation":0.021,"tests\\flow\\UsageExampleTest::testExample9FullProcess":0.021,"tests\\flow\\UsageExampleTest::testExample10MultiHospital":0.046,"tests\\flow\\UsageExampleTest::testLoadCustomProcessFromConfig":0.007,"tests\\flow\\UsageExampleTest::testCreateNoMorningWashFromConfig":0.042,"tests\\flow\\UsageExampleTest::testCreateMachineWashFromConfig":0.036,"tests\\flow\\UsageExampleTest::testCreateYiwuModeFromConfig":0.015,"tests\\flow\\UsageExampleTest::testFlowProcessorUsage":0.045,"tests\\flow\\UsageExampleTest::testFlowProcessorCompleteProcess":0.021,"tests\\flow\\UsageExampleTest::testFlowProcessorWithConfig":0.037,"tests\\db\\DBC::testDBConnect":0.113,"tests\\db\\DBC::testGenTables":0.416,"tests\\db\\DBC::testModel":0.171,"tests\\flow\\nodes\\EndNodeTest::testNodeIdentity":0.006,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterDry":0.006,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterDisinfect":0.005,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterFinalRinse":0.005,"tests\\flow\\nodes\\EndNodeTest::testCanHandleAfterMachineWash":0.005,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleNonEndReader":0.005,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleAfterWash":0.007,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleAfterRinse":0.006,"tests\\flow\\nodes\\EndNodeTest::testCannotHandleWithEmptyStep":0.005,"tests\\flow\\nodes\\EndNodeTest::testHandleProcess":0.009,"tests\\flow\\nodes\\EndNodeTest::testDatabaseOperationIsUpdate":0.011,"tests\\flow\\nodes\\EndNodeTest::testWebSocketNotifyFlag":0.009,"tests\\flow\\nodes\\EndNodeTest::testActionEndTimeIsSet":0.009,"tests\\flow\\nodes\\FinalRinseNodeTest::testCannotHandleAfterWash":0.006,"tests\\flow\\nodes\\FinalRinseNodeTest::testDatabaseOperationFlags":0.008,"tests\\flow\\nodes\\FinalRinseNodeTest::testWebSocketNotifyFlag":0.009,"tests\\flow\\nodes\\FinalRinseNodeTest::testNodeIdentity":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testNodeIdentity":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterWash":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterRinse":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterDisinfect":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleWithEmptyStep":0.006,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterEnd":0.006,"tests\\flow\\nodes\\MachineWashNodeTest::testCanHandleAfterEndoscopeOut":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleNonMachineWashReader":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleAfterFinalRinse":0.005,"tests\\flow\\nodes\\MachineWashNodeTest::testCannotHandleAfterDry":0.006,"tests\\flow\\nodes\\MachineWashNodeTest::testHandleProcess":0.008,"tests\\flow\\nodes\\MachineWashNodeTest::testDatabaseOperationFlags":0.01,"tests\\flow\\nodes\\MachineWashNodeTest::testWebSocketNotifyFlag":0.008,"tests\\flow\\nodes\\RinseNodeTest::testNodeIdentity":0.005,"tests\\flow\\nodes\\RinseNodeTest::testCanHandleAfterWash":0.007,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleNonRinseReader":0.007,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleAfterDisinfect":0.006,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleWithEmptyStep":0.006,"tests\\flow\\nodes\\RinseNodeTest::testCannotHandleAfterRinse":0.005,"tests\\flow\\nodes\\RinseNodeTest::testHandleProcess":0.01,"tests\\flow\\nodes\\RinseNodeTest::testDatabaseOperationFlags":0.009,"tests\\flow\\nodes\\RinseNodeTest::testWebSocketNotifyFlag":0.009,"tests\\flow\\nodes\\RinseNodeTest::testDisabledNodeSkips":0.009,"tests\\flow\\strategies\\TimeValidationStrategyTest::testNonDurationStepIsSkipped":0.008,"tests\\flow\\strategies\\TimeValidationStrategyTest::testSetStepDuration":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testStrategyName":0.007,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testStrategyPhaseIsAfter":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testIsAlwaysApplicable":0.007,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testNormalWashVoice":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testNormalRinseVoice":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testNormalDisinfectVoice":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testFinalRinseVoice":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testDryVoice":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testEndVoice":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testMachineWashVoice":0.007,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testMorningWashVoice":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testMachineMorningWashVoice":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testErrorStateGeneratesErrorVoice":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testFullVoiceIncludesEndoscopeName":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testLeakTestRemindAppended":0.006,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testStorageRemindAppended":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testCustomVoiceTemplate":0.005,"tests\\flow\\strategies\\VoiceGenerationStrategyTest::testSetStepVoice":0.005,"tests\\flow\\FlowProcessorTest::testSuccessfulFlowSavesToDatabase":0.011,"tests\\flow\\FlowProcessorTest::testSuccessfulFlowSendsVoice":0.008,"tests\\flow\\FlowProcessorTest::testFailedFlowDoesNotSaveToDatabase":0.007,"tests\\flow\\FlowProcessorTest::testFailedFlowStillSendsVoice":0.008,"tests\\flow\\FlowProcessorTest::testWebSocketNotificationSentWhenNeeded":0.01,"tests\\flow\\FlowProcessorTest::testWebSocketNotificationNotSentWhenNotNeeded":0.008,"tests\\flow\\FlowProcessorTest::testEndOperationIsUpdate":0.01,"tests\\flow\\FlowProcessorTest::testGetActionTypeMapping":0.107,"tests\\flow\\FlowProcessorTest::testStaticFactoryCreate":0.007,"tests\\flow\\ProcessSimulationTest::testBasicManualWashWithoutDatabase":0.287,"tests\\flow\\ProcessSimulationTest::testNodeChainConstruction":0.264,"tests\\flow\\ProcessSimulationTest::testMorningWashNodeConfiguration":0.278,"tests\\flow\\ProcessSimulationTest::testMachineWashNodeConfiguration":0.271,"tests\\flow\\ProcessSimulationTest::testStorageNodeConfiguration":0.273,"tests\\flow\\ProcessSimulationTest::testDuplicateCheckNode":0.522,"tests\\flow\\ProcessSimulationTest::testCloseNode":0.268,"tests\\flow\\ProcessSimulationTest::testNodeEnableDisable":0.268,"tests\\flow\\ProcessSimulationTest::testConfigUpdate":0.522,"tests\\flow\\ProcessSimulationTest::testStrategyInitialization":0.291,"tests\\flow\\FullProcessTest::testCompleteManualWashProcess":0.09,"tests\\flow\\FullProcessTest::testCompleteManualWashProcessUsingHelper":0.285,"tests\\flow\\FullProcessTest::testMorningWashRequired":0.262,"tests\\flow\\FullProcessTest::testManualWashAfterMorningWash":0.269,"tests\\flow\\FullProcessTest::testMachineWashProcess":0.281,"tests\\flow\\FullProcessTest::testMachineWashProcessUsingHelper":0.286,"tests\\flow\\FullProcessTest::testMorningWashThenMachineWash":0.275,"tests\\flow\\FullProcessTest::testSwipeEndoscopeWithoutOperator":0.02,"tests\\flow\\FullProcessTest::testWrongStepOrder":0.078,"tests\\flow\\FullProcessTest::testDuplicateSwipe":0.142,"tests\\flow\\FullProcessTest::testUnboundReader":0.273,"tests\\flow\\FullProcessTest::testUnboundEndoscope":0.323,"tests\\flow\\FullProcessTest::testDifferentOperatorContinueProcess":0.124,"tests\\flow\\FullProcessTest::testWashStepVoice":0.074,"tests\\flow\\FullProcessTest::testDisinfectStepVoice":0.182,"tests\\flow\\FullProcessTest::testOperatorCardVoice":0.02,"tests\\flow\\FullProcessTest::testErrorVoice":0.021,"tests\\flow\\FullProcessTest::testVoiceTemplateParams":0.077,"tests\\flow\\FullProcessTest::testProcessChainExecution":0.236,"tests\\flow\\FullProcessTest::testDisabledNodeSkipped":0.277,"tests\\flow\\FullProcessTest::testTimeValidationBlock":0.265,"tests\\flow\\FullProcessTest::testDuplicateSwipeBlock":0.201,"tests\\flow\\FullProcessTest::testNewProcessAfterComplete":0.331,"tests\\flow\\FullProcessTest::testConcurrentProcessIsolation":0.174,"tests\\flow\\FullProcessTest::testProcessorReset":0.081,"tests\\flow\\FullProcessTest::testVirtualContextBuilder":0.017,"tests\\flow\\FullProcessTest::testEnvironmentConfig":0.007,"tests\\flow\\Test::testExample":0.005,"tests\\flow\\cases\\BlockTest::testProcessChainExecution":0.239,"tests\\flow\\cases\\BlockTest::testDisabledNodeSkipped":0.288,"tests\\flow\\cases\\BlockTest::testTimeValidationBlockWithBlockModeOn":0.263,"tests\\flow\\cases\\BlockTest::testTimeValidationWithBlockModeOff":0.282,"tests\\flow\\cases\\BlockTest::testDuplicateSwipeBlock":0.193,"tests\\flow\\cases\\BlockTest::testTimeValidationPass":0.281,"tests\\flow\\cases\\ErrorFlowTest::testSwipeEndoscopeWithoutOperator":0.008,"tests\\flow\\cases\\ErrorFlowTest::testWrongStepOrder":0.069,"tests\\flow\\cases\\ErrorFlowTest::testDuplicateSwipe":0.109,"tests\\flow\\cases\\ErrorFlowTest::testUnboundReader":0.276,"tests\\flow\\cases\\ErrorFlowTest::testUnboundEndoscope":0.27,"tests\\flow\\cases\\HelperTest::testProcessorReset":0.063,"tests\\flow\\cases\\HelperTest::testVirtualContextBuilder":0.007,"tests\\flow\\cases\\HelperTest::testEnvironmentConfig":0.006,"tests\\flow\\cases\\MachineWashTest::testMachineWashProcess":0.06,"tests\\flow\\cases\\MachineWashTest::testMachineWashProcessUsingHelper":0.06,"tests\\flow\\cases\\MachineWashTest::testMorningWashThenMachineWash":0.059,"tests\\flow\\cases\\MachineWashTest::testMultipleEndoscopeMachineWash":0.112,"tests\\flow\\cases\\ManualWashTest::testCompleteManualWashProcess":0.432,"tests\\flow\\cases\\ManualWashTest::testCompleteManualWashProcessUsingHelper":0.436,"tests\\flow\\cases\\ManualWashTest::testMorningWashRequired":0.316,"tests\\flow\\cases\\ManualWashTest::testManualWashAfterMorningWash":0.403,"tests\\flow\\cases\\ManualWashTest::testDifferentOperatorContinueProcess":0.138,"tests\\flow\\cases\\ManualWashTest::testNewProcessAfterComplete":0.443,"tests\\flow\\cases\\ManualWashTest::testConcurrentProcessIsolation":0.201,"tests\\flow\\cases\\VoiceTest::testWashStepVoice":0.064,"tests\\flow\\cases\\VoiceTest::testDisinfectStepVoice":0.2,"tests\\flow\\cases\\VoiceTest::testOperatorCardVoice":0.008,"tests\\flow\\cases\\VoiceTest::testErrorVoice":0.008,"tests\\flow\\cases\\VoiceTest::testWashDurationInsufficientVoice":0.276}} \ No newline at end of file diff --git a/app/config/Config.php b/app/config/Config.php index 953ab76..6805198 100644 --- a/app/config/Config.php +++ b/app/config/Config.php @@ -116,6 +116,8 @@ class Config { $this->detectCircularDependency(); $this->database = new DatabaseConfig(); + // TODO 加载自定义流程配置 + // 加载根目录的 $this->customProcess = require __DIR__ . '/custom_process_config.php'; $this->machineId = self::getStringEnv("MACHINE_ID", "0"); if (empty($this->machineId) || $this->machineId == '0') { diff --git a/app/config/TODO.md b/app/config/TODO.md index 0ed004f..a7ceabc 100644 --- a/app/config/TODO.md +++ b/app/config/TODO.md @@ -8,4 +8,6 @@ 动态提示请刷XXX -配置文件 required 无法生效 \ No newline at end of file +配置文件 required 无法生效 + +干燥 \ No newline at end of file diff --git a/app/flow/FlowMain.php b/app/flow/FlowMain.php index af57654..de9e851 100644 --- a/app/flow/FlowMain.php +++ b/app/flow/FlowMain.php @@ -64,8 +64,7 @@ class FlowMain $processConfig = null; if ($useCustomProcess && !empty($processConfigKey)) { // 从全局配置加载自定义流程 - $globalConfig = Config::getInstance(); - $customProcess = $globalConfig->customProcess; + $customProcess = Config::getInstance()->customProcess; $processConfigArray = $customProcess[$processConfigKey] ?? null; if ($processConfigArray !== null) { diff --git a/app/flow/FlowProcessor.php b/app/flow/FlowProcessor.php index d50b774..27eca9e 100644 --- a/app/flow/FlowProcessor.php +++ b/app/flow/FlowProcessor.php @@ -62,7 +62,7 @@ class FlowProcessor // 读卡器未绑定 if (empty($context->getReader()->id)) { Logger::error('读卡器未绑定,放弃处理 card={}', [$context->isOperatorCard() ? $context->getOperator()->rfid : $context->getEndoscope()->cardNo]); - $context = $context->builder()->error(VoiceMessage::READER_NOT_BOUND)->build(); + $context = $context->createModifyBuilder()->error(VoiceMessage::READER_NOT_BOUND)->build(); $this->sendVoice($context); return $context; } @@ -76,7 +76,7 @@ class FlowProcessor $context->getOperator()->name, $context->getOperator()->rfid ); - $context = $context->builder()->error(VoiceMessage::PLEASE_SWIPE_ENDOSCOPE)->build(); + $context = $context->createModifyBuilder()->error(VoiceMessage::PLEASE_SWIPE_ENDOSCOPE)->build(); $this->sendVoice($context); return $context; } @@ -84,7 +84,7 @@ class FlowProcessor // 如果内镜未绑定,返回错误 if ($context->getEndoscope()->isEmpty()) { Logger::error('内镜未绑定,放弃处理 card={}', [$context->getEndoscope()->cardNo]); - $context = $context->builder()->error(VoiceMessage::CARD_NOT_BOUND)->build(); + $context = $context->createModifyBuilder()->error(VoiceMessage::CARD_NOT_BOUND)->build(); $this->sendVoice($context); return $context; } @@ -94,7 +94,7 @@ class FlowProcessor if ($mgr->hasOperator($context->getReader()->id) || $context->hasOperator()) { if ($mgr->hasOperator($context->getReader()->id)) { $op = $mgr->getOperator($context->getReader()->id, $context->getReader()->type); - $context = $context->builder()->withOperator(new \app\flow\context\bean\OperatorInfo( + $context = $context->createModifyBuilder()->setOperator(new \app\flow\context\bean\OperatorInfo( id: $op['id'], name: $op['name'], rfid: $op['rfid'] @@ -107,7 +107,7 @@ class FlowProcessor $context->getEndoscope()->cardNo, ]); // 处理这个错误 - $context = $context->builder()->error(VoiceMessage::PLEASE_SWIPE_OPERATOR)->build(); + $context = $context->createModifyBuilder()->error(VoiceMessage::PLEASE_SWIPE_OPERATOR)->build(); $this->handleResult($context); return $context; } diff --git a/app/flow/ProcessEngine.php b/app/flow/ProcessEngine.php index b530f28..10b0c97 100644 --- a/app/flow/ProcessEngine.php +++ b/app/flow/ProcessEngine.php @@ -176,7 +176,7 @@ class ProcessEngine public function execute(ProcessContext $context): ProcessContext { if ($this->chainHead === null) { - return $context->builder()->error(VoiceMessage::PROCESS_CHAIN_NOT_INITIALIZED)->build(); + return $context->createModifyBuilder()->error(VoiceMessage::PROCESS_CHAIN_NOT_INITIALIZED)->build(); } Logger::debug('[ProcessEngine] 开始执行流程链 readerType={} currentStep={} endoscope={}', [ diff --git a/app/flow/context/ProcessContext.php b/app/flow/context/ProcessContext.php index 0936685..b49d1be 100644 --- a/app/flow/context/ProcessContext.php +++ b/app/flow/context/ProcessContext.php @@ -14,6 +14,7 @@ use app\flow\context\bean\StorageStatus; use app\flow\context\bean\VoiceState; use app\model\EctActions; use app\net\PacketContext; +use app\utils\Logger; /** * 流程上下文类(不可变) @@ -81,8 +82,13 @@ readonly class ProcessContext * 创建一个基于当前上下文的 Builder * 用于创建修改后的新上下文实例 */ - public function builder(): ProcessContextBuilder + public function createModifyBuilder(): ProcessContextBuilder { + $caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]; + $callerClass = $caller['class']; + $callerMethod = $caller['function']; + $callerLine = $caller['line']; + Logger::debug("上下文请求修改构建器: class={}, method={}, line={}", [$callerClass, $callerMethod, $callerLine]); return ProcessContextBuilder::from($this); } diff --git a/app/flow/context/ProcessContextBuilder.php b/app/flow/context/ProcessContextBuilder.php index 4d66ca2..de64d5f 100644 --- a/app/flow/context/ProcessContextBuilder.php +++ b/app/flow/context/ProcessContextBuilder.php @@ -328,55 +328,55 @@ class ProcessContextBuilder // ==================== 值对象设置方法 ==================== - public function withEndoscope(EndoscopeInfo $endoscope): self + public function setEndoscope(EndoscopeInfo $endoscope): self { $this->endoscope = $endoscope; return $this; } - public function withReader(ReaderInfo $reader): self + public function setReader(ReaderInfo $reader): self { $this->reader = $reader; return $this; } - public function withOperator(OperatorInfo $operator): self + public function setOperator(OperatorInfo $operator): self { $this->operator = $operator; return $this; } - public function withStorage(StorageStatus $storage): self + public function setStorage(StorageStatus $storage): self { $this->storage = $storage; return $this; } - public function withMorningWash(MorningWashStatus $morningWash): self + public function setMorningWash(MorningWashStatus $morningWash): self { $this->morningWash = $morningWash; return $this; } - public function withVoice(VoiceState $voice): self + public function setVoiceState(VoiceState $voice): self { $this->voice = $voice; return $this; } - public function withResult(ExecutionResult $result): self + public function setResult(ExecutionResult $result): self { $this->result = $result; return $this; } - public function withProcessStatus(ProcessStatus $processStatus): self + public function setProcessStatus(ProcessStatus $processStatus): self { $this->processStatus = $processStatus; return $this; } - public function withReminder(ReminderStatus $reminder): self + public function setReminder(ReminderStatus $reminder): self { $this->reminder = $reminder; return $this; @@ -384,7 +384,7 @@ class ProcessContextBuilder // ==================== 流程状态便捷设置方法 ==================== - public function withCurrentStep(string $currentStep): self + public function setCurrentStep(string $currentStep): self { $this->processStatus = new ProcessStatus( currentStep: $currentStep, @@ -397,7 +397,7 @@ class ProcessContextBuilder return $this; } - public function withProcessType(string $processType): self + public function setProcessType(string $processType): self { $this->processStatus = new ProcessStatus( currentStep: $this->processStatus->currentStep, @@ -410,7 +410,7 @@ class ProcessContextBuilder return $this; } - public function withBatchNo(string $batchNo): self + public function setBatchNo(string $batchNo): self { $this->processStatus = new ProcessStatus( currentStep: $this->processStatus->currentStep, @@ -423,8 +423,10 @@ class ProcessContextBuilder return $this; } - public function withDuration(?int $duration): self + public function setDuration(?int $duration = null): self { + if (empty($duration)) $duration = time() - strtotime($this->processStatus->actionStartTime); + $this->processStatus = new ProcessStatus( currentStep: $this->processStatus->currentStep, processType: $this->processStatus->processType, @@ -436,7 +438,7 @@ class ProcessContextBuilder return $this; } - public function withPreviousAction(?EctActions $action): self + public function setPreviousAction(?EctActions $action): self { $this->processStatus = new ProcessStatus( currentStep: $this->processStatus->currentStep, @@ -473,7 +475,7 @@ class ProcessContextBuilder /** * 设置自定义错误 */ - public function customError(string $message): self + public function setCustomError(string $message): self { $this->voice = $this->voice->withMessage($message)->withError(VoiceMessage::CUSTOM); $this->result = $this->result->fail(); @@ -483,7 +485,7 @@ class ProcessContextBuilder /** * 设置语音消息 */ - public function voiceMessage(string|VoiceMessage $message): self + public function setVoiceMessage(string|VoiceMessage $message): self { $this->voice = $this->voice->withMessage($message); return $this; @@ -492,7 +494,7 @@ class ProcessContextBuilder /** * 设置期望下一步 */ - public function expectedNextStep(VoiceMessage $expected): self + public function setExpectedNextStep(VoiceMessage $expected): self { $this->voice = $this->voice->withExpectedNextStep($expected); return $this; @@ -501,7 +503,7 @@ class ProcessContextBuilder /** * 添加数据库操作 */ - public function dbOperation(DbOperationType $operation): self + public function setDbOperation(DbOperationType $operation): self { $this->result = $this->result->addDbOperation($operation); return $this; @@ -510,7 +512,7 @@ class ProcessContextBuilder /** * 设置需要数据库操作 */ - public function needDatabaseOperation(bool $need = true): self + public function setNeedDatabaseOperation(bool $need = true): self { $this->result = new ExecutionResult( success: $this->result->success, @@ -525,7 +527,7 @@ class ProcessContextBuilder /** * 设置需要WebSocket通知 */ - public function needWebSocketNotify(bool $need = true): self + public function setNeedWebSocketNotify(bool $need = true): self { $this->result = $this->result->withWebSocketNotify($need); return $this; @@ -542,25 +544,25 @@ class ProcessContextBuilder // ==================== 提醒状态便捷设置方法 ==================== - public function withNeedEnhanceWash(bool $need): self + public function setNeedEnhanceWash(bool $need): self { $this->reminder = $this->reminder->withEnhanceWash($need); return $this; } - public function withNeedLeakTestRemind(bool $need): self + public function setNeedLeakTestRemind(bool $need): self { $this->reminder = $this->reminder->withLeakTestRemind($need); return $this; } - public function withNeedStorageRemind(bool $need): self + public function setNeedStorageRemind(bool $need): self { $this->reminder = $this->reminder->withStorageRemind($need); return $this; } - public function withLeakTestDone(bool $done, string $result = ''): self + public function setLeakTestDone(bool $done, string $result = ''): self { $this->reminder = $this->reminder->withLeakTestDone($result); return $this; @@ -568,13 +570,13 @@ class ProcessContextBuilder // ==================== 标记设置方法 ==================== - public function withIsOperatorCard(bool $isOperatorCard): self + public function setIsOperatorCard(bool $isOperatorCard): self { $this->isOperatorCard = $isOperatorCard; return $this; } - public function withStepDuration(string $stepCode, int $duration): self + public function setStepDuration(string $stepCode, int $duration): self { $this->stepDurations[$stepCode] = $duration; return $this; diff --git a/app/flow/nodes/AbstractProcessNode.php b/app/flow/nodes/AbstractProcessNode.php index 07297ed..d5fb482 100644 --- a/app/flow/nodes/AbstractProcessNode.php +++ b/app/flow/nodes/AbstractProcessNode.php @@ -83,8 +83,8 @@ abstract class AbstractProcessNode implements ProcessNodeInterface Logger::debug('[{}-Node] 不能处理当前步骤,跳过', [$this->getCode()]); // 如果有期望下一步提示,设置到上下文 if ($canHandleResult->hasExpectedNextStep()) { - $context = $context->builder() - ->expectedNextStep($canHandleResult->expectedNextStep) + $context = $context->createModifyBuilder() + ->setExpectedNextStep($canHandleResult->expectedNextStep) ->build(); } return $this->passToNext($context); @@ -181,7 +181,7 @@ abstract class AbstractProcessNode implements ProcessNodeInterface */ protected function stopNext(ProcessContext $context): ProcessContext { - return $context->builder() + return $context->createModifyBuilder() ->skipNodeCount(count($this->getChildNodes())) ->build(); } diff --git a/app/flow/nodes/CloseNode.php b/app/flow/nodes/CloseNode.php index 0f57aa1..aeaca61 100644 --- a/app/flow/nodes/CloseNode.php +++ b/app/flow/nodes/CloseNode.php @@ -61,10 +61,10 @@ class CloseNode extends AbstractProcessNode // 如果有预期的下一步,则返回错误 if ($context->getVoice()->hasExpectedNextStep()) { Logger::debug("节点期望: {$context->getVoice()->expectedNextStep->value}"); - return $context->builder()->error($context->getVoice()->expectedNextStep)->build(); + return $context->createModifyBuilder()->error($context->getVoice()->expectedNextStep)->build(); } // 异常流程 Logger::error("异常流程,所有节点处理完成,无匹配节点并且无预期的下一步"); - return $context->builder()->error(VoiceMessage::UNKNOWN_ERROR)->build(); + return $context->createModifyBuilder()->error(VoiceMessage::UNKNOWN_ERROR)->build(); } } diff --git a/app/flow/nodes/DisinfectNode.php b/app/flow/nodes/DisinfectNode.php index e0c5791..9ae65ca 100644 --- a/app/flow/nodes/DisinfectNode.php +++ b/app/flow/nodes/DisinfectNode.php @@ -59,11 +59,11 @@ class DisinfectNode extends AbstractProcessNode */ protected function doHandle(ProcessContext $context): ProcessContext { - return $context->builder() - ->withCurrentStep('消毒') - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->needWebSocketNotify() + return $context->createModifyBuilder() + ->setCurrentStep('消毒') + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/nodes/DryNode.php b/app/flow/nodes/DryNode.php index 988eb0a..a81877f 100644 --- a/app/flow/nodes/DryNode.php +++ b/app/flow/nodes/DryNode.php @@ -64,11 +64,11 @@ class DryNode extends AbstractProcessNode */ protected function doHandle(ProcessContext $context): ProcessContext { - return $context->builder() - ->withCurrentStep('干燥') - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->needWebSocketNotify() + return $context->createModifyBuilder() + ->setCurrentStep('干燥') + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/nodes/DuplicateCheckNode.php b/app/flow/nodes/DuplicateCheckNode.php index 4db2ae1..c2bcbea 100644 --- a/app/flow/nodes/DuplicateCheckNode.php +++ b/app/flow/nodes/DuplicateCheckNode.php @@ -50,6 +50,6 @@ class DuplicateCheckNode extends AbstractProcessNode */ protected function doHandle(ProcessContext $context): ProcessContext { - return $context->builder()->error(VoiceMessage::DUPLICATE_SWIPING)->build(); + return $context->createModifyBuilder()->error(VoiceMessage::DUPLICATE_SWIPING)->build(); } } diff --git a/app/flow/nodes/EndNode.php b/app/flow/nodes/EndNode.php index 150a97c..e0e230e 100644 --- a/app/flow/nodes/EndNode.php +++ b/app/flow/nodes/EndNode.php @@ -62,11 +62,11 @@ class EndNode extends AbstractProcessNode */ protected function doHandle(ProcessContext $context): ProcessContext { - return $context->builder() - ->withCurrentStep('结束') - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->needWebSocketNotify() + return $context->createModifyBuilder() + ->setCurrentStep('结束') + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/nodes/FinalRinseNode.php b/app/flow/nodes/FinalRinseNode.php index 281dff7..ad40cd8 100644 --- a/app/flow/nodes/FinalRinseNode.php +++ b/app/flow/nodes/FinalRinseNode.php @@ -62,11 +62,11 @@ class FinalRinseNode extends AbstractProcessNode */ protected function doHandle(ProcessContext $context): ProcessContext { - return $context->builder() - ->withCurrentStep('终末漂洗') - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->needWebSocketNotify() + return $context->createModifyBuilder() + ->setCurrentStep('终末漂洗') + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/nodes/MachineWashNode.php b/app/flow/nodes/MachineWashNode.php index bc48526..43d1e93 100644 --- a/app/flow/nodes/MachineWashNode.php +++ b/app/flow/nodes/MachineWashNode.php @@ -67,13 +67,13 @@ class MachineWashNode extends AbstractProcessNode */ protected function doHandle(ProcessContext $context): ProcessContext { - return $context->builder() - ->withProcessType('机洗') - ->withCurrentStep('机洗') - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->dbOperation(DbOperationType::UPDATE) - ->needWebSocketNotify() + return $context->createModifyBuilder() + ->setProcessType('机洗') + ->setCurrentStep('机洗') + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setDbOperation(DbOperationType::UPDATE) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/nodes/MorningWashNode.php b/app/flow/nodes/MorningWashNode.php index 6076257..c912e11 100644 --- a/app/flow/nodes/MorningWashNode.php +++ b/app/flow/nodes/MorningWashNode.php @@ -71,13 +71,13 @@ class MorningWashNode extends AbstractProcessNode // 设置流程类型 $processType = $context->getReader()->type === '机洗' ? '机洗(晨洗)' : '手工洗(晨洗)'; - return $context->builder() - ->withMorningWash($morningWash) - ->withProcessType($processType) - ->withCurrentStep(self::getName()) - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->needWebSocketNotify() + return $context->createModifyBuilder() + ->setMorningWash($morningWash) + ->setProcessType($processType) + ->setCurrentStep(self::getName()) + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/nodes/RinseNode.php b/app/flow/nodes/RinseNode.php index 3955c81..d56da89 100644 --- a/app/flow/nodes/RinseNode.php +++ b/app/flow/nodes/RinseNode.php @@ -63,11 +63,11 @@ class RinseNode extends AbstractProcessNode */ protected function doHandle(ProcessContext $context): ProcessContext { - return $context->builder() - ->withCurrentStep('漂洗') - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->needWebSocketNotify() + return $context->createModifyBuilder() + ->setCurrentStep('漂洗') + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/nodes/StorageInNode.php b/app/flow/nodes/StorageInNode.php index 69a8969..672213d 100644 --- a/app/flow/nodes/StorageInNode.php +++ b/app/flow/nodes/StorageInNode.php @@ -78,13 +78,13 @@ class StorageInNode extends AbstractProcessNode { Logger::debug('[StorageInNode] 内镜入库成功 endoscope={}', [$context->getEndoscope()->name]); - return $context->builder() - ->withProcessType('存储') - ->withCurrentStep(self::getName()) - ->withStorage(StorageStatus::inStorage(date('Y-m-d H:i:s'))) - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->needWebSocketNotify() + return $context->createModifyBuilder() + ->setProcessType('存储') + ->setCurrentStep(self::getName()) + ->setStorage(StorageStatus::inStorage(date('Y-m-d H:i:s'))) + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/nodes/StorageNode.php b/app/flow/nodes/StorageNode.php index 83048cc..818627f 100644 --- a/app/flow/nodes/StorageNode.php +++ b/app/flow/nodes/StorageNode.php @@ -82,25 +82,25 @@ class StorageNode extends AbstractProcessNode */ protected function doHandle(ProcessContext $context): ProcessContext { - $builder = $context->builder()->withProcessType('存储'); + $builder = $context->createModifyBuilder()->setProcessType('存储'); // 根据当前状态判断执行入库还是出库(canHandle 已经验证过状态) if (!$context->getStorage()->isInStorage) { // 入库操作 Logger::debug('[StorageNode] 内镜入库成功 endoscope={}', [$context->getEndoscope()->name]); - $builder->withCurrentStep('内镜放入') - ->withStorage(StorageStatus::inStorage(date('Y-m-d H:i:s'))); + $builder->setCurrentStep('内镜放入') + ->setStorage(StorageStatus::inStorage(date('Y-m-d H:i:s'))); } else { // 出库操作 Logger::debug('[StorageNode] 内镜出库成功 endoscope={}', [$context->getEndoscope()->name]); - $builder->withCurrentStep('内镜取出') - ->withStorage(StorageStatus::outOfStorage()); + $builder->setCurrentStep('内镜取出') + ->setStorage(StorageStatus::outOfStorage()); } return $builder - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->needWebSocketNotify() + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/nodes/StorageOutNode.php b/app/flow/nodes/StorageOutNode.php index 7f79cac..321de3a 100644 --- a/app/flow/nodes/StorageOutNode.php +++ b/app/flow/nodes/StorageOutNode.php @@ -78,13 +78,13 @@ class StorageOutNode extends AbstractProcessNode { Logger::debug('[StorageOutNode] 内镜出库成功 endoscope={}', [$context->getEndoscope()->name]); - return $context->builder() - ->withProcessType('存储') - ->withCurrentStep(self::getName()) - ->withStorage(StorageStatus::outOfStorage()) - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->needWebSocketNotify() + return $context->createModifyBuilder() + ->setProcessType('存储') + ->setCurrentStep(self::getName()) + ->setStorage(StorageStatus::outOfStorage()) + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/nodes/WashNode.php b/app/flow/nodes/WashNode.php index 4b845cc..1c50f74 100644 --- a/app/flow/nodes/WashNode.php +++ b/app/flow/nodes/WashNode.php @@ -70,18 +70,18 @@ class WashNode extends AbstractProcessNode */ protected function doHandle(ProcessContext $context): ProcessContext { - $builder = $context->builder(); + $builder = $context->createModifyBuilder(); // 设置流程类型 if (empty($context->getProcessType()) || $context->getProcessType() === '晨洗') { - $builder->withProcessType('手工洗'); + $builder->setProcessType('手工洗'); } return $builder - ->withCurrentStep(self::getName()) - ->needDatabaseOperation() - ->dbOperation(DbOperationType::INSERT) - ->needWebSocketNotify() + ->setCurrentStep(self::getName()) + ->setNeedDatabaseOperation() + ->setDbOperation(DbOperationType::INSERT) + ->setNeedWebSocketNotify() ->build(); } } diff --git a/app/flow/strategies/MorningWashStrategy.php b/app/flow/strategies/MorningWashStrategy.php index 2819875..27fade1 100644 --- a/app/flow/strategies/MorningWashStrategy.php +++ b/app/flow/strategies/MorningWashStrategy.php @@ -41,7 +41,7 @@ class MorningWashStrategy extends AbstractStrategy todayWashRecords: $context->getMorningWash()->todayWashRecords ); - return $context->builder()->withMorningWash($morningWash)->build(); + return $context->createModifyBuilder()->setMorningWash($morningWash)->build(); } /** diff --git a/app/flow/strategies/TimeValidationStrategy.php b/app/flow/strategies/TimeValidationStrategy.php index 1bc2863..7cbd9f3 100644 --- a/app/flow/strategies/TimeValidationStrategy.php +++ b/app/flow/strategies/TimeValidationStrategy.php @@ -79,7 +79,7 @@ class TimeValidationStrategy extends AbstractStrategy // 从数据库按流程类型精确查询 $requiredDuration = $this->getDurationFromDb($stepCode, $processType); if ($requiredDuration > 0) { - $context = $context->builder()->withStepDuration($stepCode, $requiredDuration)->build(); + $context = $context->createModifyBuilder()->setStepDuration($stepCode, $requiredDuration)->build(); } else { // 最后使用上下文已缓存值 $requiredDuration = $context->getStepDuration($stepCode); @@ -106,7 +106,7 @@ class TimeValidationStrategy extends AbstractStrategy $voice = VoiceMessage::NOT_ENOUGH_TIME->value; $voice = str_replace('{step}', $stepCode, $voice); $voice = str_replace('{time}', $requiredDuration - $duration, $voice); - $context = $context->builder()->customError($voice)->build(); + $context = $context->createModifyBuilder()->setCustomError($voice)->build(); } return $context; } diff --git a/app/flow/strategies/VoiceGenerationStrategy.php b/app/flow/strategies/VoiceGenerationStrategy.php index 69738b5..74018ce 100644 --- a/app/flow/strategies/VoiceGenerationStrategy.php +++ b/app/flow/strategies/VoiceGenerationStrategy.php @@ -36,7 +36,7 @@ class VoiceGenerationStrategy extends AbstractStrategy "流程中存在自定义语音或存在多次设置语音,语音应该在 VoiceGenerationStrategy 策略中配置,否则不能拦截与自定义配置", new IllegalUsageException("In the existing process, there is custom voice, which should be configured in the VoiceGenerationStrategy strategy; otherwise, it cannot be intercepted and customized") ); - return $context->builder()->voiceMessage($context->getVoice()->message)->build(); + return $context->createModifyBuilder()->setVoiceMessage($context->getVoice()->message)->build(); } // 如果已经有错误,生成错误语音 @@ -56,7 +56,7 @@ class VoiceGenerationStrategy extends AbstractStrategy } Logger::debug("应用语音模板后的内容: {$voice}"); - return $context->builder()->voiceMessage($voice)->build(); + return $context->createModifyBuilder()->setVoiceMessage($voice)->build(); } /** diff --git a/tests/flow/VirtualContextBuilder.php b/tests/flow/VirtualContextBuilder.php index af37f75..2201791 100644 --- a/tests/flow/VirtualContextBuilder.php +++ b/tests/flow/VirtualContextBuilder.php @@ -245,7 +245,7 @@ class VirtualContextBuilder /** * 设置操作时长(秒) */ - public function duration(int $seconds): self + public function setDuration(int $seconds): self { $this->processStatus = new ProcessStatus( currentStep: $this->processStatus->currentStep, @@ -277,7 +277,7 @@ class VirtualContextBuilder /** * 设置上一条操作记录(虚拟) */ - public function previousAction(string $processName, string $batchNo = '', ?string $opEndtime = null): self + public function setPreviousAction(string $processName, string $batchNo = '', ?string $opEndtime = null): self { $action = new EctActions(); $action->process_name = $processName; diff --git a/tests/flow/VirtualityFlowProcessor.php b/tests/flow/VirtualityFlowProcessor.php index 5327421..0165fa8 100644 --- a/tests/flow/VirtualityFlowProcessor.php +++ b/tests/flow/VirtualityFlowProcessor.php @@ -12,7 +12,7 @@ use app\utils\Logger; /** * 虚拟流程处理器 - * + * * 用于测试环境的刷卡流程模拟器。 * 不依赖真实的 FlowProcessor,不连接数据库,不发送语音。 * 支持完整的刷卡流程模拟和验证。 @@ -22,19 +22,19 @@ class VirtualityFlowProcessor private ProcessEngine $engine; private array $environment; private string $envPath; - + /** @var array 当前操作员会话缓存 (readerId => operatorInfo) */ private array $operatorSessions = []; - + /** @var ProcessContext[] 执行历史 */ private array $history = []; - + /** @var array 当前内镜的流程状态 (endoscopeId => ProcessContext) */ private array $endoscopeStates = []; /** * 构造函数 - * + * * @param ProcessConfig|null $config 流程配置 * @param string|null $envPath 环境配置文件路径 */ @@ -53,10 +53,10 @@ class VirtualityFlowProcessor if (!file_exists($this->envPath)) { throw new \RuntimeException("环境配置文件不存在: {$this->envPath}"); } - + $content = file_get_contents($this->envPath); $this->environment = json_decode($content, true); - + if (json_last_error() !== JSON_ERROR_NONE) { throw new \RuntimeException("环境配置文件解析失败: " . json_last_error_msg()); } @@ -100,21 +100,21 @@ class VirtualityFlowProcessor /** * 模拟刷人员卡 - * + * * @param string $operatorName 操作员名称(环境配置中定义) * @param string $readerType 读卡器类型 * @return ProcessContext */ public function swipeOperatorCard(string $operatorName, string $readerType = '清洗'): ProcessContext { - $operatorData = $this->environment['operators'][$operatorName] + $operatorData = $this->environment['operators'][$operatorName] ?? throw new \InvalidArgumentException("未找到操作员: {$operatorName}"); - $readerData = $this->environment['readers'][$readerType] + $readerData = $this->environment['readers'][$readerType] ?? throw new \InvalidArgumentException("未找到读卡器: {$readerType}"); - + // 保存操作员会话 $this->operatorSessions[$readerData['id']] = $operatorData; - + // 构建上下文 $context = VirtualContextBuilder::create($this->envPath) ->operator($operatorName) @@ -122,92 +122,94 @@ class VirtualityFlowProcessor ->asOperatorCard() ->withEngineConfig($this->engine->getConfig()) ->build(); - + // 人员卡不走流程链,直接返回 - $result = $context->builder() - ->voiceMessage('请刷内镜卡') + $result = $context->createModifyBuilder() + ->setVoiceMessage('请刷内镜卡') ->build(); - + $this->history[] = $result; return $result; } /** * 模拟刷内镜卡 - * + * * @param string $endoscopeName 内镜名称(环境配置中定义) * @param string $readerType 读卡器类型 * @return ProcessContext */ public function swipeEndoscopeCard(string $endoscopeName, string $readerType): ProcessContext { - $readerData = $this->environment['readers'][$readerType] + $readerData = $this->environment['readers'][$readerType] ?? throw new \InvalidArgumentException("未找到读卡器: {$readerType}"); - $endoscopeData = $this->environment['endoscopes'][$endoscopeName] + $endoscopeData = $this->environment['endoscopes'][$endoscopeName] ?? throw new \InvalidArgumentException("未找到内镜: {$endoscopeName}"); - + // 获取内镜当前状态 + /** @var ProcessContext $currentState */ $currentState = $this->endoscopeStates[$endoscopeData['id']] ?? null; - + // 构建上下文 $builder = VirtualContextBuilder::create($this->envPath) ->endoscope($endoscopeName) ->reader($readerType) ->withEngineConfig($this->engine->getConfig()); - + // 如果有操作员会话,添加操作员信息 if (isset($this->operatorSessions[$readerData['id']])) { $opData = $this->operatorSessions[$readerData['id']]; $builder->customOperator($opData['id'], $opData['name'], $opData['rfid']); } - + // 继承之前的流程状态 if ($currentState !== null) { $builder->currentStep($currentState->getCurrentStep()) - ->batchNo($currentState->getBatchNo()) - ->processType($currentState->getProcessType()); - + ->batchNo($currentState->getBatchNo()) + ->setDuration(time() - strtotime($currentState->getActionStartTime())) + ->processType($currentState->getProcessType()); + // 设置 previousAction:上一步骤名称就是当前状态的 currentStep if (!empty($currentState->getCurrentStep())) { - $builder->previousAction($currentState->getCurrentStep(), $currentState->getBatchNo()); + $builder->setPreviousAction($currentState->getCurrentStep(), $currentState->getBatchNo()); } } else { // 新流程 $builder->newProcess(); } - + $context = $builder->build(); - + // 未刷人员卡检查 if (!$context->hasOperator() && !isset($this->operatorSessions[$readerData['id']])) { - $result = $context->builder() + $result = $context->createModifyBuilder() ->error(\app\flow\enum\VoiceMessage::PLEASE_SWIPE_OPERATOR) ->build(); $this->history[] = $result; return $result; } - + // 执行流程 $result = $this->engine->execute($context); - + // 确保 previousAction 在结果中正确设置 // 如果执行成功且有上一步骤信息,确保 previousAction 被保留 if ($result->isSuccess() && $context->getPreviousAction() !== null && $result->getPreviousAction() === null) { - $result = $result->builder() - ->withPreviousAction($context->getPreviousAction()) + $result = $result->createModifyBuilder() + ->setPreviousAction($context->getPreviousAction()) ->build(); } - + // 保存状态 $this->endoscopeStates[$endoscopeData['id']] = $result; $this->history[] = $result; - + return $result; } /** * 快捷方法:完整刷卡(先刷人员卡再刷内镜卡) - * + * * @param string $operatorName 操作员名称 * @param string $endoscopeName 内镜名称 * @param string $readerType 读卡器类型 @@ -220,23 +222,23 @@ class VirtualityFlowProcessor $result = $this->swipeOperatorCard($operatorName, $readerType); // 当前语音 Logger::info("当前语音:{$result->getFullVoice()}"); - + // 刷内镜卡 Logger::info("测试刷卡:{$endoscopeName}, {$readerType}"); - $result = $this->swipeEndoscopeCard($endoscopeName, $readerType); + $result = $this->swipeEndoscopeCard($endoscopeName, $readerType); Logger::info("当前流程:{}", [$result->getProcessType()]); Logger::info("当前批次号:{}", [$result->getBatchNo()]); Logger::info("当前步骤:{}", [$result->getCurrentStep()]); - Logger::info("上一个步骤类型:{}", [$result->getPreviousAction()->action_type_name?? "null"]); - Logger::info("上一个步骤:{}", [$result->getPreviousAction()->process_name??"null"]); - Logger::info("时长:{}", [$result->getDuration()?? "null"]); + Logger::info("上一个步骤类型:{}", [$result->getPreviousAction()->action_type_name ?? "null"]); + Logger::info("上一个步骤:{}", [$result->getPreviousAction()->process_name ?? "null"]); + Logger::info("时长:{}", [$result->getDuration() ?? "null"]); Logger::info("当前语音:{$result->getFullVoice()}\n"); return $result; } /** * 执行完整的手工洗流程 - * + * * @param string $operatorName 操作员名称 * @param string $endoscopeName 内镜名称 * @return array 每个步骤的执行结果 @@ -245,17 +247,17 @@ class VirtualityFlowProcessor { $steps = ['清洗', '漂洗', '消毒', '终末漂洗', '干燥']; $results = []; - + foreach ($steps as $step) { $results[$step] = $this->swipe($operatorName, $endoscopeName, $step); } - + return $results; } /** * 执行完整的机洗流程 - * + * * @param string $operatorName 操作员名称 * @param string $endoscopeName 内镜名称 * @return ProcessContext