ai-refactor(flow): 调整抽象流程节点实现和依赖路径
- 修改 AbstractProcessNode 中 ProcessContext 的命名空间引用为 app\flow\context\ProcessContext - 引入 app\flow\vo\CanHandleResult 用于节点处理结果表示 - 更新前置策略执行后对成功状态的判断,改为调用 isSuccess() 方法 - 增加日志记录细节,便于调试策略执行中断时的错误信息 - 优化代码注释,提升代码可读性和维护性
This commit is contained in:
@@ -83,6 +83,10 @@ class Config
|
||||
*/
|
||||
public bool $blockMode {
|
||||
get => $this->blockMode;
|
||||
set(bool $value){
|
||||
Logger::error("禁止修改热修改阻断模式,这只是用于测试方法");
|
||||
$this->blockMode = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
模拟发包
|
||||
|
||||
内镜未刷取出就操作
|
||||
|
||||
刷两次代表加强洗
|
||||
@@ -138,7 +138,7 @@ class FlowProcessor
|
||||
$this->updateLastOperationEndTime($context, $repo);
|
||||
|
||||
// 数据库操作
|
||||
if ($context->needDatabaseOperation()) {
|
||||
if ($context->isDatabaseOperationNeeded()) {
|
||||
$this->saveToDatabase($context, $repo);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ class FlowProcessor
|
||||
$this->sendVoice($context);
|
||||
|
||||
// WebSocket通知
|
||||
if ($context->needWebSocketNotify()) {
|
||||
if ($context->isWebSocketNotifyNeeded()) {
|
||||
Logger::debug('[FlowProcessor] 发送 WebSocket 通知 endoscope={} step={}', [
|
||||
$context->getEndoscope()->name,
|
||||
$context->getCurrentStep(),
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace app\flow;
|
||||
|
||||
use app\flow\config\ProcessConfig;
|
||||
use app\flow\context\ProcessContext;
|
||||
use app\flow\enum\VoiceMessage;
|
||||
use app\flow\nodes\MorningWashNode;
|
||||
use app\flow\nodes\ProcessNodeInterface;
|
||||
use app\flow\strategies\MorningWashStrategy;
|
||||
|
||||
@@ -157,10 +157,11 @@ readonly class ProcessContext
|
||||
return $this->stepDurations;
|
||||
}
|
||||
|
||||
// ==================== 便捷查询方法 ====================
|
||||
// ==================== 便捷查询方法(带数据来源标注) ====================
|
||||
|
||||
/**
|
||||
* 获取当前步骤
|
||||
* @return string 当前步骤名称 (来源: ProcessStatus)
|
||||
*/
|
||||
public function getCurrentStep(): string
|
||||
{
|
||||
@@ -169,6 +170,7 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 获取流程类型
|
||||
* @return string 流程类型 (来源: ProcessStatus)
|
||||
*/
|
||||
public function getProcessType(): string
|
||||
{
|
||||
@@ -177,6 +179,7 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 获取批次号
|
||||
* @return string 批次号 (来源: ProcessStatus)
|
||||
*/
|
||||
public function getBatchNo(): string
|
||||
{
|
||||
@@ -185,6 +188,7 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 获取操作开始时间
|
||||
* @return string 操作开始时间 (来源: ProcessStatus)
|
||||
*/
|
||||
public function getActionStartTime(): string
|
||||
{
|
||||
@@ -193,6 +197,7 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 获取操作时长
|
||||
* @return int|null 操作时长(秒)(来源: ProcessStatus)
|
||||
*/
|
||||
public function getDuration(): ?int
|
||||
{
|
||||
@@ -201,6 +206,7 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 获取上一个操作记录
|
||||
* @return \app\model\EctActions|null 上一个操作记录 (来源: ProcessStatus)
|
||||
*/
|
||||
public function getPreviousAction(): ?\app\model\EctActions
|
||||
{
|
||||
@@ -209,6 +215,7 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 获取完整语音
|
||||
* @return string 完整语音内容 (来源: VoiceState)
|
||||
*/
|
||||
public function getFullVoice(): string
|
||||
{
|
||||
@@ -217,6 +224,7 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 流程是否成功
|
||||
* @return bool 是否成功 (来源: ExecutionResult)
|
||||
*/
|
||||
public function isSuccess(): bool
|
||||
{
|
||||
@@ -225,22 +233,25 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 是否需要操作数据库
|
||||
* @return bool 是否需要数据库操作 (来源: ExecutionResult)
|
||||
*/
|
||||
public function needDatabaseOperation(): bool
|
||||
public function isDatabaseOperationNeeded(): bool
|
||||
{
|
||||
return $this->result->needDatabaseOperation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要WebSocket通知
|
||||
* @return bool 是否需要通知 (来源: ExecutionResult)
|
||||
*/
|
||||
public function needWebSocketNotify(): bool
|
||||
public function isWebSocketNotifyNeeded(): bool
|
||||
{
|
||||
return $this->result->needWebSocketNotify;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库操作列表
|
||||
* @return array 数据库操作列表 (来源: ExecutionResult)
|
||||
*/
|
||||
public function getDbOperations(): array
|
||||
{
|
||||
@@ -249,6 +260,7 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 检查是否可以开始新流程
|
||||
* @return bool 是否可以开始新流程 (来源: ProcessStatus)
|
||||
*/
|
||||
public function canStartNewProcess(): bool
|
||||
{
|
||||
@@ -257,6 +269,7 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 检查是否已完成清洗流程
|
||||
* @return bool 是否已完成 (来源: ProcessStatus)
|
||||
*/
|
||||
public function isWashProcessCompleted(): bool
|
||||
{
|
||||
@@ -265,6 +278,7 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 是否有操作员
|
||||
* @return bool 是否有有效操作员 (来源: OperatorInfo)
|
||||
*/
|
||||
public function hasOperator(): bool
|
||||
{
|
||||
@@ -281,40 +295,45 @@ readonly class ProcessContext
|
||||
|
||||
/**
|
||||
* 是否需要增强洗
|
||||
* @return bool 是否需要增强洗 (来源: ReminderStatus)
|
||||
*/
|
||||
public function needEnhanceWash(): bool
|
||||
public function isEnhanceWashNeeded(): bool
|
||||
{
|
||||
return $this->reminder->needEnhanceWash;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要测漏提醒
|
||||
* @return bool 是否需要测漏提醒 (来源: ReminderStatus)
|
||||
*/
|
||||
public function needLeakTestRemind(): bool
|
||||
public function isLeakTestRemindNeeded(): bool
|
||||
{
|
||||
return $this->reminder->needLeakTestRemind;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要存储提醒
|
||||
* @return bool 是否需要存储提醒 (来源: ReminderStatus)
|
||||
*/
|
||||
public function needStorageRemind(): bool
|
||||
public function isStorageRemindNeeded(): bool
|
||||
{
|
||||
return $this->reminder->needStorageRemind;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否已测漏
|
||||
* @return bool 是否已测漏 (来源: ReminderStatus)
|
||||
*/
|
||||
public function isLeakTestDone(): bool
|
||||
public function isLeakTestDoneByReminder(): bool
|
||||
{
|
||||
return $this->reminder->leakTestDone;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取测漏结果
|
||||
* @return string 测漏结果 (来源: ReminderStatus)
|
||||
*/
|
||||
public function getLeakTestResult(): string
|
||||
public function getLeakTestResultByReminder(): string
|
||||
{
|
||||
return $this->reminder->leakTestResult;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ use app\flow\vo\StorageStatus;
|
||||
use app\flow\vo\VoiceState;
|
||||
use app\flow\enum\DbOperationType;
|
||||
use app\flow\enum\VoiceMessage;
|
||||
use app\flow\vo\BatchNo;
|
||||
use app\model\EctActions;
|
||||
use app\net\PacketContext;
|
||||
use app\repository\EctActionsRepository;
|
||||
@@ -316,28 +317,11 @@ class ProcessContextBuilder
|
||||
|
||||
/**
|
||||
* 生成批次号
|
||||
* @return string 批次号值
|
||||
*/
|
||||
private function generateBatchNo(): string
|
||||
{
|
||||
$existingBatchNo = null;
|
||||
if (!$this->endoscope->isEmpty()) {
|
||||
$existingBatchNo = EctActionsRepository::new()->findTodayActiveBatchNo($this->config->machineId);
|
||||
}
|
||||
|
||||
$datePart = date('Ymd');
|
||||
$sequence = 1;
|
||||
|
||||
if (!empty($existingBatchNo)) {
|
||||
$existingDatePart = substr($existingBatchNo, 0, 8);
|
||||
$existingSequence = substr($existingBatchNo, 10, 4);
|
||||
|
||||
if ($existingDatePart === $datePart && is_numeric($existingSequence)) {
|
||||
$sequence = (int)$existingSequence + 1;
|
||||
}
|
||||
}
|
||||
|
||||
$sequencePart = str_pad($sequence, 4, '0', STR_PAD_LEFT);
|
||||
return $datePart . $this->config->machineId . $sequencePart;
|
||||
return BatchNo::generate($this->config->machineId)->value;
|
||||
}
|
||||
|
||||
// ==================== 值对象设置方法 ====================
|
||||
|
||||
@@ -201,7 +201,7 @@ abstract class AbstractProcessNode implements ProcessNodeInterface
|
||||
* 1. 遍历所有已注册的策略
|
||||
* 2. 筛选出阶段为 'before' 的策略
|
||||
* 3. 依次执行策略的 execute 方法
|
||||
* 4. 如果某个策略导致上下文错误(!$context->isSuccess()),立即中断后续策略执行
|
||||
* 4. 如果某个策略导致上下文错误(!$context->isSuccessByResult()),立即中断后续策略执行
|
||||
*
|
||||
* 前置策略的应用:
|
||||
* - 时间验证:检查步骤执行时间是否符合要求
|
||||
|
||||
@@ -38,7 +38,7 @@ class CloseNode extends AbstractProcessNode
|
||||
*/
|
||||
public function canHandle(ProcessContext $context): CanHandleResult
|
||||
{
|
||||
if (!$context->isSuccess() || $context->needDatabaseOperation() || !empty($context->getVoice()->message)) {
|
||||
if (!$context->isSuccess() || $context->isDatabaseOperationNeeded() || !empty($context->getVoice()->message)) {
|
||||
return CanHandleResult::no();
|
||||
}
|
||||
return CanHandleResult::yes();
|
||||
@@ -49,7 +49,7 @@ class CloseNode extends AbstractProcessNode
|
||||
*/
|
||||
protected function doHandle(ProcessContext $context): ProcessContext
|
||||
{
|
||||
if (!$context->isSuccess() || $context->needDatabaseOperation() || !empty($context->getVoice()->message)) {
|
||||
if (!$context->isSuccess() || $context->isDatabaseOperationNeeded() || !empty($context->getVoice()->message)) {
|
||||
return $context;
|
||||
}
|
||||
// 无节点命中
|
||||
|
||||
@@ -142,11 +142,11 @@ class VoiceGenerationStrategy extends AbstractStrategy
|
||||
{
|
||||
$reminds = [];
|
||||
|
||||
if ($context->needLeakTestRemind()) {
|
||||
if ($context->isLeakTestRemindNeeded()) {
|
||||
$reminds[] = ',清洗开始前,请测漏';
|
||||
}
|
||||
|
||||
if ($context->needStorageRemind()) {
|
||||
if ($context->isStorageRemindNeeded()) {
|
||||
$reminds[] = ',未登记取出';
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ readonly class ProcessStatus
|
||||
public string $batchNo = '',
|
||||
/** 操作开始时间 */
|
||||
public string $actionStartTime = '',
|
||||
/** 操作时长(秒) */
|
||||
/** 操作时长(秒) 计算方式为上下文创建的时间减去上个操作的开始时间(此时上个操作的结束时间不存在,需要等待此次刷卡流程结束) */
|
||||
public ?int $duration = null,
|
||||
/** 上一个操作记录 */
|
||||
public ?EctActions $previousAction = null,
|
||||
|
||||
@@ -242,7 +242,7 @@ class EctActionsRepository extends BaseRepository
|
||||
'process_name' => $context->getCurrentStep(),
|
||||
'process_order' => $process_order + 1,
|
||||
'op_morning' => $context->getMorningWash()->needMorningWash ? 1 : 0,
|
||||
'op_enhance' => $context->needEnhanceWash() ? 1 : 0,
|
||||
'op_enhance' => $context->isEnhanceWashNeeded() ? 1 : 0,
|
||||
'reader_id' => (int)$context->getReader()->id ?: null,
|
||||
'reader_no' => $context->getReader()->no ?: null,
|
||||
'opuser_type' => $opuserType,
|
||||
|
||||
Reference in New Issue
Block a user