ai-chore(config): 调整流程配置及改进测试代码

- 将 FLOW_USE_CUSTOM_PROCESS 从 true 改为 false,禁用自定义流程
- 在 BlockTest 测试用例中改用 setBlockMode 方法设置阻断模式
- 设置统一的错误处理,将错误转为异常抛出
- 重命名 BlockTest 测试文件路径,优化测试组织结构
- 更新 IDE php include paths,调整依赖包引用顺序
- 删除无用的 tests/flow/Test.php 测试文件
- 微调 start.php、webman、windows.php 配置或代码模块
This commit is contained in:
zimoyin
2026-03-11 13:48:40 +08:00
parent 6c874221ad
commit f2ff4ae123
42 changed files with 246 additions and 158 deletions
+1
View File
@@ -4,6 +4,7 @@ namespace app\flow;
use app\config\Config;
use app\flow\config\ProcessConfig;
use app\flow\context\ProcessContext;
use app\net\PacketContext;
use app\utils\Logger;
+1 -1
View File
@@ -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\vo\OperatorInfo(
$context = $context->builder()->withOperator(new \app\flow\context\bean\OperatorInfo(
id: $op['id'],
name: $op['name'],
rfid: $op['rfid']
+8 -2
View File
@@ -103,7 +103,13 @@ class OperatorSessionManager
*/
public function hasOperator(string $readerId): bool
{
return isset($this->sessions[$readerId]);
$cache = $this->sessions[$readerId] ?? null;
if (empty($cache)) return false;
// 如果时间过去了,返回没有
if ($this->expire > 0 && isset($cache['time']) && (time() - $cache['time']) > $this->expire) {
return false;
}
return true;
}
/**
@@ -124,7 +130,7 @@ class OperatorSessionManager
public function pop(string $readerId): ?array
{
$op = $this->getOperator($readerId);
$op = $this->sessions[$readerId] ?? null;
$this->clearOperator($readerId);
return $op;
}
+12 -11
View File
@@ -3,15 +3,16 @@
namespace app\flow\context;
use app\flow\config\ProcessConfig;
use app\flow\vo\EndoscopeInfo;
use app\flow\vo\ExecutionResult;
use app\flow\vo\MorningWashStatus;
use app\flow\vo\OperatorInfo;
use app\flow\vo\ProcessStatus;
use app\flow\vo\ReaderInfo;
use app\flow\vo\ReminderStatus;
use app\flow\vo\StorageStatus;
use app\flow\vo\VoiceState;
use app\flow\context\bean\EndoscopeInfo;
use app\flow\context\bean\ExecutionResult;
use app\flow\context\bean\MorningWashStatus;
use app\flow\context\bean\OperatorInfo;
use app\flow\context\bean\ProcessStatus;
use app\flow\context\bean\ReaderInfo;
use app\flow\context\bean\ReminderStatus;
use app\flow\context\bean\StorageStatus;
use app\flow\context\bean\VoiceState;
use app\model\EctActions;
use app\net\PacketContext;
/**
@@ -206,9 +207,9 @@ readonly class ProcessContext
/**
* 获取上一个操作记录
* @return \app\model\EctActions|null 上一个操作记录 (来源: ProcessStatus)
* @return EctActions|null 上一个操作记录 (来源: ProcessStatus)
*/
public function getPreviousAction(): ?\app\model\EctActions
public function getPreviousAction(): ?EctActions
{
return $this->processStatus->previousAction;
}
+12 -10
View File
@@ -4,18 +4,18 @@ namespace app\flow\context;
use app\config\Config;
use app\flow\config\ProcessConfig;
use app\flow\vo\EndoscopeInfo;
use app\flow\vo\ExecutionResult;
use app\flow\vo\MorningWashStatus;
use app\flow\vo\OperatorInfo;
use app\flow\vo\ProcessStatus;
use app\flow\vo\ReaderInfo;
use app\flow\vo\ReminderStatus;
use app\flow\vo\StorageStatus;
use app\flow\vo\VoiceState;
use app\flow\context\bean\EndoscopeInfo;
use app\flow\context\bean\ExecutionResult;
use app\flow\context\bean\MorningWashStatus;
use app\flow\context\bean\OperatorInfo;
use app\flow\context\bean\ProcessStatus;
use app\flow\context\bean\ReaderInfo;
use app\flow\context\bean\ReminderStatus;
use app\flow\context\bean\StorageStatus;
use app\flow\context\bean\VoiceState;
use app\flow\enum\DbOperationType;
use app\flow\enum\VoiceMessage;
use app\flow\vo\BatchNo;
use app\flow\context\bean\BatchNo;
use app\model\EctActions;
use app\net\PacketContext;
use app\repository\EctActionsRepository;
@@ -79,6 +79,7 @@ class ProcessContextBuilder
$builder = new self();
$builder->packetContext = $packetContext;
$builder->engineConfig = $additionalData['engineConfig'] ?? null;
if (empty($builder->engineConfig)) Logger::warn("fromPacketContext 需要通过 additionalData 传递 engineConfig");
// 获取原始卡号和读卡器编号
$cardNo = $packetContext->packet->card ?? '';
@@ -228,6 +229,7 @@ class ProcessContextBuilder
// 查询今日洗消记录数(晨洗判断)
$todayWashRecords = $actionsRepo->countTodayActions($this->endoscope->id, $this->morningStartTime, [0, 7, 8]);
Logger::debug("{} 内镜今日洗消记录数: {}", [$this->endoscope->name,$todayWashRecords]);
$this->morningWash = new MorningWashStatus(
needMorningWash: $this->morningWash->needMorningWash,
morningWashed: $this->morningWash->morningWashed,
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
use app\config\Config;
use app\repository\EctActionsRepository;
@@ -14,7 +14,9 @@ readonly class BatchNo
public function __construct(
/** 批次号值 */
public string $value = '',
) {}
)
{
}
/**
* 创建空批次号
@@ -60,7 +62,7 @@ readonly class BatchNo
/**
* 解析批次号结构
*
*
* @return array{date: string, machineId: string, sequence: int, dateFormatted: string}
*/
public function parse(): array
@@ -86,6 +88,20 @@ readonly class BatchNo
];
}
/**
* 解析批次号结构
* @deprecated
* @return array{date: string, machineId: string, sequence: int, dateFormatted: string}
*/
public static function parseBatchNo(string $batchNo): array
{
$batch = BatchNo::fromString($batchNo);
if (!$batch->isValid()) {
throw new \InvalidArgumentException('Invalid batch string: ' . $batchNo);
}
return $batch->parse();
}
/**
* 验证批次号格式是否有效
*/
@@ -123,12 +139,23 @@ readonly class BatchNo
/**
* 获取日期部分
*/
public function getDate(): string
public function getDateStr(): string
{
$parsed = $this->parse();
return $parsed['dateFormatted'];
}
/**
* 获取时间戳
* @return int|false
*/
public function getTimestamp(): int|false
{
$parsed = $this->parse();
return strtotime($parsed['dateFormatted']);
}
/**
* 获取机器ID
*/
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
use app\flow\enum\VoiceMessage;
@@ -20,7 +20,7 @@ readonly class CanHandleResult
/**
* 创建可以处理的结果
*/
public static function yes(): self
public static function canHandle(): self
{
return new self(canHandle: true);
}
@@ -28,7 +28,7 @@ readonly class CanHandleResult
/**
* 创建不能处理的结果
*/
public static function no(?VoiceMessage $expectedNextStep = null): self
public static function cannotHandle(?VoiceMessage $expectedNextStep = null): self
{
return new self(
canHandle: false,
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
/**
* 内镜信息值对象
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
use app\flow\enum\DbOperationType;
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
/**
* 晨洗状态值对象
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
/**
* 操作员信息值对象
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
use app\model\EctActions;
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
/**
* 读卡器信息值对象
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
/**
* 提醒状态值对象
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
/**
* 存储状态值对象
@@ -1,6 +1,6 @@
<?php
namespace app\flow\vo;
namespace app\flow\context\bean;
use app\flow\enum\VoiceMessage;
+3 -1
View File
@@ -44,7 +44,9 @@ enum VoiceMessage: string
case PLEASE_SWIPE_MORNING_WASH = '请刷消毒或机洗,开启晨洗流程';
// 流程链未初始化
case PROCESS_CHAIN_NOT_INITIALIZED = '流程链未初始化';
case UNKNOWN_ERROR = '未知错误';
// 未知错误,通常是无节点匹配的时候
case UNKNOWN_ERROR = '未知错误,无匹配的节点';
// 卡号未绑定
case CARD_NOT_BOUND = '卡号未绑定';
+3 -3
View File
@@ -5,7 +5,7 @@ namespace app\flow\nodes;
use app\flow\config\StepConfig;
use app\flow\context\ProcessContext;
use app\flow\strategies\ProcessStrategyInterface;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
use app\utils\Logger;
/**
@@ -302,9 +302,9 @@ abstract class AbstractProcessNode implements ProcessNodeInterface
public function canHandle(ProcessContext $context): CanHandleResult
{
if ($context->getCurrentStep() === $this->getCode()) {
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
/**
+3 -3
View File
@@ -5,7 +5,7 @@ namespace app\flow\nodes;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
use app\repository\EctActionsRepository;
use app\utils\Logger;
@@ -39,9 +39,9 @@ class CloseNode extends AbstractProcessNode
public function canHandle(ProcessContext $context): CanHandleResult
{
if (!$context->isSuccess() || $context->isDatabaseOperationNeeded() || !empty($context->getVoice()->message)) {
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
/**
+6 -6
View File
@@ -5,7 +5,7 @@ namespace app\flow\nodes;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
/**
* 消毒节点
@@ -36,22 +36,22 @@ class DisinfectNode extends AbstractProcessNode
{
// 如果内镜未取出
if ($context->getStorage()->isInStorage) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
}
if (!$this->isMatchReaderType($context)) {
if ($context->getCurrentStep() === RinseNode::getName()) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_DISINFECT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_DISINFECT);
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 上一个步骤必须是漂洗 或者 晨洗
if (!$this->isRequiredNode($context->getCurrentStep(), [RinseNode::getName(), MorningWashNode::getName()])) {
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
/**
+6 -6
View File
@@ -5,7 +5,7 @@ namespace app\flow\nodes;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
use app\utils\Logger;
/**
@@ -40,23 +40,23 @@ class DryNode extends AbstractProcessNode
{
// 如果内镜未取出
if ($context->getStorage()->isInStorage) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
}
if (!$this->isMatchReaderType($context)) {
if ($context->getCurrentStep() === FinalRinseNode::getName()) {
if (!$context->isSuccess()) Logger::debug("[DryNode] 刷卡错误,当前步骤是终末漂洗,但是刷的读卡器类型不是终末漂洗,对用户进行语音提示刷终末漂洗读卡器");
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_DRY);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_DRY);
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 上一个步骤必须是终末漂洗
if (!$this->isRequiredNode($context->getCurrentStep(), [FinalRinseNode::getName()])) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_DISINFECT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_DISINFECT);
}
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
/**
+3 -3
View File
@@ -5,7 +5,7 @@ namespace app\flow\nodes;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
use app\repository\EctActionsRepository;
use app\utils\Logger;
@@ -40,9 +40,9 @@ class DuplicateCheckNode extends AbstractProcessNode
public function canHandle(ProcessContext $context): CanHandleResult
{
if ($context->getPreviousAction()?->process_name === $context->getReader()->type) {
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
/**
+9 -10
View File
@@ -5,7 +5,7 @@ namespace app\flow\nodes;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
/**
* 结束节点
@@ -36,26 +36,25 @@ class EndNode extends AbstractProcessNode
{
// 如果内镜未取出
if ($context->getStorage()->isInStorage) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
}
if (!$this->isMatchReaderType($context)) {
if ($context->getCurrentStep() === DryNode::getName() && $context->getCurrentStep() === FinalRinseNode::getName()) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_END);
if ($context->getCurrentStep() === DryNode::getName() || $context->getCurrentStep() === FinalRinseNode::getName()) {
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_END);
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 上一个步骤必须是干燥、终末漂洗或机洗
$validSteps = ['干燥', '终末漂洗', '机洗'];
if ($this->isRequiredNode($context->getCurrentStep(), ['干燥', '终末漂洗', '机洗'])) {
if (!$this->isRequiredNode($context->getCurrentStep(), ['干燥', '终末漂洗', '机洗'])) {
if ($context->getCurrentStep() === FinalRinseNode::getName()) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_WASH);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_WASH);
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
/**
+6 -6
View File
@@ -5,7 +5,7 @@ namespace app\flow\nodes;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
use app\utils\Logger;
/**
@@ -39,22 +39,22 @@ class FinalRinseNode extends AbstractProcessNode
{
// 如果内镜未取出
if ($context->getStorage()->isInStorage) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
}
if (!$this->isMatchReaderType($context)) {
if ($context->getCurrentStep() === DisinfectNode::getName()) {
if (!$context->isSuccess()) Logger::debug("[FinalRinseNode] 刷卡错误,当前步骤是消毒,但是刷的读卡器类型不是消毒,对用户进行语音提示刷消毒读卡器");
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_FINAL_RINSE);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_FINAL_RINSE);
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 上一个步骤必须是消毒或机洗
if ($this->isRequiredNode($context->getCurrentStep(), ['消毒', '机洗'])) {
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
/**
+8 -8
View File
@@ -5,7 +5,7 @@ namespace app\flow\nodes;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
/**
* 机洗节点
@@ -36,30 +36,30 @@ class MachineWashNode extends AbstractProcessNode
{
// 如果内镜未取出
if ($context->getStorage()->isInStorage) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
}
if (!$this->isMatchReaderType($context)) {
if ($context->getCurrentStep() === WashNode::getName()) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_MACHINE_WASH);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_MACHINE_WASH);
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 需要晨洗但未完成:提示先进行晨洗
if ($context->getMorningWash()->needMorningWash && !$context->getMorningWash()->morningWashed) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_MORNING_WASH);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_MORNING_WASH);
}
// 机洗可以在多个步骤后执行:空步骤(新流程)、结束、内镜取出、清洗,晨洗
if (!$this->isRequiredNode($context->getCurrentStep(), ['', '结束', '内镜取出', '清洗', MachineWashNode::getName()])) {
if ($context->getCurrentStep() === EndNode::getName()) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_MACHINE_WASH);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_MACHINE_WASH);
}
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_END);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_END);
}
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
/**
+6 -6
View File
@@ -5,8 +5,8 @@ namespace app\flow\nodes;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\vo\MorningWashStatus;
use app\flow\context\bean\CanHandleResult;
use app\flow\context\bean\MorningWashStatus;
use app\utils\Logger;
/**
@@ -38,19 +38,19 @@ class MorningWashNode extends AbstractProcessNode
{
// 如果内镜未取出
if ($context->getStorage()->isInStorage) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
}
// 只有需要晨洗且未完成晨洗时才处理
if (!$context->getMorningWash()->needMorningWash || $context->getMorningWash()->morningWashed) {
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 检查当前读卡器类型是否匹配
if (!$this->isRequiredNode($context->getReader()->type, ['漂洗', '机洗'])){
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_MORNING_WASH);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_MORNING_WASH);
}
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
/**
+1 -1
View File
@@ -3,7 +3,7 @@
namespace app\flow\nodes;
use app\flow\context\ProcessContext;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
/**
* 流程节点接口
+6 -6
View File
@@ -5,7 +5,7 @@ namespace app\flow\nodes;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
/**
* 漂洗节点
@@ -38,24 +38,24 @@ class RinseNode extends AbstractProcessNode
{
// 如果内镜未取出
if ($context->getStorage()->isInStorage) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
}
// 期望当前读卡器为漂洗
if (!$this->isMatchReaderType($context)) {
// 当前步骤是清洗且读卡器不符:说明清洗完了应该刷漂洗
if ($context->getCurrentStep() === WashNode::getName()) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_RINSE);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_RINSE);
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 上一个步骤必须是清洗
if (!$this->isRequiredNode($context->getCurrentStep(), [WashNode::getName()])) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_WASH);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_WASH);
}
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
/**
+7 -7
View File
@@ -6,8 +6,8 @@ use app\config\Config;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\vo\StorageStatus;
use app\flow\context\bean\CanHandleResult;
use app\flow\context\bean\StorageStatus;
use app\utils\Logger;
/**
@@ -44,12 +44,12 @@ class StorageInNode extends AbstractProcessNode
// 单读卡器模式不处理,由 StorageNode 统一处理
if ($singleReaderMode) {
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 读卡器不是内镜放入类型,不处理
if (!$this->isMatchReaderType($context)) {
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 获取内镜当前存储状态
@@ -58,17 +58,17 @@ class StorageInNode extends AbstractProcessNode
// 如果内镜已在库中,则当前应该是出库操作,不处理
if ($isInStorage) {
Logger::debug('[StorageInNode] 内镜已在库中,转由出库节点处理');
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 检查前置步骤要求
$validSteps = ['', '结束', '内镜取出', '测漏正常', '测漏异常'];
if (!in_array($context->getCurrentStep(), $validSteps)) {
Logger::debug('[StorageInNode] 当前步骤 {} 不符合入库条件', [$context->getCurrentStep()]);
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
/**
+7 -7
View File
@@ -6,8 +6,8 @@ use app\config\Config;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\vo\StorageStatus;
use app\flow\context\bean\CanHandleResult;
use app\flow\context\bean\StorageStatus;
use app\utils\Logger;
/**
@@ -47,12 +47,12 @@ class StorageNode extends AbstractProcessNode
// 非单读卡器模式不处理
if (!$singleReaderMode) {
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 读卡器类型必须是'内镜放入'或'内镜取出'
if (!in_array($context->getReader()->type, ['内镜放入', '内镜取出'])) {
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
$isInStorage = $context->getStorage()->isInStorage;
@@ -62,18 +62,18 @@ class StorageNode extends AbstractProcessNode
$validSteps = ['内镜放入', '结束'];
if (!in_array($context->getCurrentStep(), $validSteps)) {
Logger::debug('[StorageNode] 当前步骤 {} 不符合出库条件', [$context->getCurrentStep()]);
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
} else {
// 内镜不在库中,执行入库
$validSteps = ['', '结束', '内镜取出', '测漏正常', '测漏异常'];
if (!in_array($context->getCurrentStep(), $validSteps)) {
Logger::debug('[StorageNode] 当前步骤 {} 不符合入库条件', [$context->getCurrentStep()]);
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
}
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
/**
+7 -7
View File
@@ -6,8 +6,8 @@ use app\config\Config;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\vo\StorageStatus;
use app\flow\context\bean\CanHandleResult;
use app\flow\context\bean\StorageStatus;
use app\utils\Logger;
/**
@@ -44,12 +44,12 @@ class StorageOutNode extends AbstractProcessNode
// 单读卡器模式不处理,由 StorageNode 统一处理
if ($singleReaderMode) {
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 读卡器不是内镜取出类型,不处理
if (!$this->isMatchReaderType($context)) {
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 获取内镜当前存储状态
@@ -58,17 +58,17 @@ class StorageOutNode extends AbstractProcessNode
// 如果内镜不在库中,则当前应该是入库操作,不处理
if (!$isInStorage) {
Logger::debug('[StorageOutNode] 内镜不在库中,转由入库节点处理');
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
// 检查前置步骤要求:必须在库中才能出库
$validSteps = ['内镜放入', '结束'];
if (!in_array($context->getCurrentStep(), $validSteps)) {
Logger::debug('[StorageOutNode] 当前步骤 {} 不符合出库条件', [$context->getCurrentStep()]);
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
/**
+5 -5
View File
@@ -6,7 +6,7 @@ use app\config\Config;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
/**
* 虚拟清洗机节点
@@ -37,18 +37,18 @@ class VirtualWashMachineNode extends AbstractProcessNode
{
// 如果内镜未取出
if ($context->getStorage()->isInStorage) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
}
// 如果不是机洗
if ($context->getReader()->type !== MachineWashNode::getName()) {
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
if (Config::getInstance()->enableVirtualCleanerParser) {
return CanHandleResult::yes();
return CanHandleResult::canHandle();
}
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
/**
+11 -9
View File
@@ -5,7 +5,7 @@ namespace app\flow\nodes;
use app\flow\enum\DbOperationType;
use app\flow\context\ProcessContext;
use app\flow\enum\VoiceMessage;
use app\flow\vo\CanHandleResult;
use app\flow\context\bean\CanHandleResult;
use app\utils\Logger;
/**
@@ -39,26 +39,28 @@ class WashNode extends AbstractProcessNode
// 如果内镜未取出
if ($context->getStorage()->isInStorage) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_STORAGE_OUT);
}
// 读卡器不是本节点,不处理
if (!$this->isMatchReaderType($context)) {
return CanHandleResult::no();
}
// 需要晨洗但未完成:提示先进行晨洗
if ($context->getMorningWash()->needMorningWash && !$context->getMorningWash()->morningWashed) {
return CanHandleResult::no(VoiceMessage::PLEASE_SWIPE_MORNING_WASH);
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_MORNING_WASH);
}
$validCurrentSteps = ['', '结束', '内镜取出', '内镜放入', '测漏正常', '晨洗'];
if (!in_array($context->getCurrentStep(), $validCurrentSteps)) {
// 读卡器是清洗但步骤不对(如终末漂洗时刷清洗),提示应该先刷结束
return CanHandleResult::no();
return CanHandleResult::cannotHandle();
}
return CanHandleResult::yes();
// 读卡器不是本节点,不处理
if (!$this->isMatchReaderType($context)) {
return CanHandleResult::cannotHandle(VoiceMessage::PLEASE_SWIPE_WASH);
}
return CanHandleResult::canHandle();
}
/**
+1 -1
View File
@@ -6,7 +6,7 @@ use app\flow\config\MorningMode;
use app\flow\config\MorningWashConfig;
use app\flow\context\ProcessContext;
use app\flow\nodes\ProcessNodeInterface;
use app\flow\vo\MorningWashStatus;
use app\flow\context\bean\MorningWashStatus;
use app\utils\Logger;
/**
@@ -59,15 +59,16 @@ class TimeValidationStrategy extends AbstractStrategy
/**
* 执行时间验证
* 验证上一步骤(currentStep)的时长是否达标
*/
protected function doExecute(ProcessContext $context, ProcessNodeInterface $node): ProcessContext
{
$stepCode = $node->getCode();
$currentStep = $context->getCurrentStep();
// 验证的是上一步骤(currentStep)的时长,而不是当前节点
$stepCode = $context->getCurrentStep();
$processType = $context->getProcessType();
Logger::debug("开始执行时间验证策略,步骤:{$stepCode},流程类型:{$processType}");
$configDuration = $this->timeValidationConfig->getDuration($stepCode,$processType);
$configDuration = $this->timeValidationConfig->getDuration($stepCode, $processType);
Logger::debug("步骤:{$stepCode},流程类型:{$processType},配置时长:{$configDuration}s");
if ($configDuration > 0) {
@@ -76,7 +77,7 @@ class TimeValidationStrategy extends AbstractStrategy
} else {
Logger::debug("步骤:{$stepCode},流程类型:{$processType},无配置时长,从数据库查询");
// 从数据库按流程类型精确查询
$requiredDuration = $this->getDurationFromDb($stepCode, $context->getProcessType());
$requiredDuration = $this->getDurationFromDb($stepCode, $processType);
if ($requiredDuration > 0) {
$context = $context->builder()->withStepDuration($stepCode, $requiredDuration)->build();
} else {
@@ -116,11 +117,13 @@ class TimeValidationStrategy extends AbstractStrategy
/**
* 判断策略是否适用
* 只有在 timeValidationConfig 中登记的步骤才参与时间验证
* 验证的是上一步骤(currentStep)的时长
*/
public function isApplicable(ProcessContext $context, ProcessNodeInterface $node): bool
{
if ($context->getCurrentStep() != $context->getPreviousAction()?->process_name) return false;
if (!$this->timeValidationConfig->hasStep($node->getCode(), $context->getProcessType())) return false;
// 检查的是 currentStep(上一步骤)是否有时间配置
if (!$this->timeValidationConfig->hasStep($context->getCurrentStep(), $context->getProcessType())) return false;
return true;
}