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:
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
use app\config\Config;
|
||||
use app\repository\EctActionsRepository;
|
||||
|
||||
/**
|
||||
* 批次号值对象
|
||||
* 封装批次号相关操作(不可变)
|
||||
*/
|
||||
readonly class BatchNo
|
||||
{
|
||||
public function __construct(
|
||||
/** 批次号值 */
|
||||
public string $value = '',
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建空批次号
|
||||
*/
|
||||
public static function empty(): self
|
||||
{
|
||||
return new self(value: '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 从字符串创建
|
||||
*/
|
||||
public static function fromString(string $value): self
|
||||
{
|
||||
return new self(value: $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成新批次号
|
||||
*/
|
||||
public static function generate(?string $machineId = null): self
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$machineId = $machineId ?? $config->machineId;
|
||||
|
||||
$existingBatchNo = EctActionsRepository::new()->findTodayActiveBatchNo($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 new self(value: $datePart . $machineId . $sequencePart);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析批次号结构
|
||||
*
|
||||
* @return array{date: string, machineId: string, sequence: int, dateFormatted: string}
|
||||
*/
|
||||
public function parse(): array
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return [
|
||||
'date' => '',
|
||||
'machineId' => '',
|
||||
'sequence' => 0,
|
||||
'dateFormatted' => '',
|
||||
];
|
||||
}
|
||||
|
||||
$datePart = substr($this->value, 0, 8);
|
||||
$machineId = substr($this->value, 8, 2);
|
||||
$sequence = (int)substr($this->value, 10, 4);
|
||||
|
||||
return [
|
||||
'date' => $datePart,
|
||||
'machineId' => $machineId,
|
||||
'sequence' => $sequence,
|
||||
'dateFormatted' => substr($datePart, 0, 4) . '-' . substr($datePart, 4, 2) . '-' . substr($datePart, 6, 2),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析批次号结构
|
||||
* @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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证批次号格式是否有效
|
||||
*/
|
||||
public function isValid(): bool
|
||||
{
|
||||
// 批次号格式: YYYYMMDD + 机器ID(2位) + 序号(4位) = 14位
|
||||
if (strlen($this->value) !== 14) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$datePart = substr($this->value, 0, 8);
|
||||
$sequencePart = substr($this->value, 10, 4);
|
||||
|
||||
// 验证日期部分
|
||||
if (!is_numeric($datePart)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 验证序号部分
|
||||
if (!is_numeric($sequencePart)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为空批次号
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日期部分
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public function getMachineId(): string
|
||||
{
|
||||
$parsed = $this->parse();
|
||||
return $parsed['machineId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取序号
|
||||
*/
|
||||
public function getSequence(): int
|
||||
{
|
||||
$parsed = $this->parse();
|
||||
return $parsed['sequence'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是今天的批次号
|
||||
*/
|
||||
public function isToday(): bool
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return false;
|
||||
}
|
||||
$datePart = substr($this->value, 0, 8);
|
||||
return $datePart === date('Ymd');
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为字符串
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
use app\flow\enum\VoiceMessage;
|
||||
|
||||
/**
|
||||
* 节点能否处理的判断结果
|
||||
* 封装 canHandle 方法的返回值(不可变)
|
||||
*/
|
||||
readonly class CanHandleResult
|
||||
{
|
||||
public function __construct(
|
||||
/** 是否能处理 */
|
||||
public bool $canHandle,
|
||||
/** 如果不能处理,期望的下一步提示 */
|
||||
public VoiceMessage $expectedNextStep = VoiceMessage::NONE,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建可以处理的结果
|
||||
*/
|
||||
public static function canHandle(): self
|
||||
{
|
||||
return new self(canHandle: true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建不能处理的结果
|
||||
*/
|
||||
public static function cannotHandle(?VoiceMessage $expectedNextStep = null): self
|
||||
{
|
||||
return new self(
|
||||
canHandle: false,
|
||||
expectedNextStep: $expectedNextStep ?? VoiceMessage::NONE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否能处理
|
||||
*/
|
||||
public function isCanHandle(): bool
|
||||
{
|
||||
return $this->canHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有期望下一步提示
|
||||
*/
|
||||
public function hasExpectedNextStep(): bool
|
||||
{
|
||||
return $this->expectedNextStep !== VoiceMessage::NONE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
/**
|
||||
* 内镜信息值对象
|
||||
* 封装内镜的基础信息,不可变对象
|
||||
*/
|
||||
readonly class EndoscopeInfo
|
||||
{
|
||||
public function __construct(
|
||||
/** 内镜ID */
|
||||
public string $id = '',
|
||||
/** 内镜名称 */
|
||||
public string $name = '',
|
||||
/** 内镜RFID卡号 */
|
||||
public string $cardNo = '',
|
||||
/** 内镜类型(胃镜/肠镜等) */
|
||||
public string $type = '',
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建空的内镜信息
|
||||
*/
|
||||
public static function empty(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断内镜信息是否为空
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断内镜信息是否有效
|
||||
*/
|
||||
public function isValid(): bool
|
||||
{
|
||||
return !empty($this->id) && !empty($this->cardNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'cardNo' => $this->cardNo,
|
||||
'type' => $this->type,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
use app\flow\enum\DbOperationType;
|
||||
|
||||
/**
|
||||
* 执行结果值对象
|
||||
* 封装流程执行的结果状态(不可变)
|
||||
*/
|
||||
readonly class ExecutionResult
|
||||
{
|
||||
public function __construct(
|
||||
/** 流程执行是否成功 */
|
||||
public bool $success = true,
|
||||
/** 是否需要操作数据库 */
|
||||
public bool $needDatabaseOperation = false,
|
||||
/** 数据库操作类型列表 */
|
||||
public array $dbOperations = [],
|
||||
/** 是否需要发送WebSocket通知 */
|
||||
public bool $needWebSocketNotify = false,
|
||||
/** 跳过节点数量 */
|
||||
public int $skipNodeCount = 0,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建成功状态
|
||||
*/
|
||||
public static function success(): self
|
||||
{
|
||||
return new self(success: true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建失败状态
|
||||
*/
|
||||
public static function failure(): self
|
||||
{
|
||||
return new self(success: false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建需要写库的状态
|
||||
*/
|
||||
public static function withDbOperation(DbOperationType $operation): self
|
||||
{
|
||||
return new self(
|
||||
success: true,
|
||||
needDatabaseOperation: true,
|
||||
dbOperations: [$operation]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数据库操作
|
||||
*/
|
||||
public function addDbOperation(DbOperationType $operation): self
|
||||
{
|
||||
return new self(
|
||||
success: $this->success,
|
||||
needDatabaseOperation: true,
|
||||
dbOperations: [...$this->dbOperations, $operation],
|
||||
needWebSocketNotify: $this->needWebSocketNotify,
|
||||
skipNodeCount: $this->skipNodeCount
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置为失败
|
||||
*/
|
||||
public function fail(): self
|
||||
{
|
||||
return new self(
|
||||
success: false,
|
||||
needDatabaseOperation: $this->needDatabaseOperation,
|
||||
dbOperations: $this->dbOperations,
|
||||
needWebSocketNotify: $this->needWebSocketNotify,
|
||||
skipNodeCount: $this->skipNodeCount
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置需要WebSocket通知
|
||||
*/
|
||||
public function withWebSocketNotify(bool $need = true): self
|
||||
{
|
||||
return new self(
|
||||
success: $this->success,
|
||||
needDatabaseOperation: $this->needDatabaseOperation,
|
||||
dbOperations: $this->dbOperations,
|
||||
needWebSocketNotify: $need,
|
||||
skipNodeCount: $this->skipNodeCount
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置跳过节点数
|
||||
*/
|
||||
public function withSkipNodeCount(int $count): self
|
||||
{
|
||||
return new self(
|
||||
success: $this->success,
|
||||
needDatabaseOperation: $this->needDatabaseOperation,
|
||||
dbOperations: $this->dbOperations,
|
||||
needWebSocketNotify: $this->needWebSocketNotify,
|
||||
skipNodeCount: $count
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有数据库操作
|
||||
*/
|
||||
public function hasDbOperations(): bool
|
||||
{
|
||||
return !empty($this->dbOperations);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库操作类型名称列表
|
||||
*/
|
||||
public function getDbOperationNames(): array
|
||||
{
|
||||
return array_map(fn(DbOperationType $op) => $op->name, $this->dbOperations);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'success' => $this->success,
|
||||
'needDatabaseOperation' => $this->needDatabaseOperation,
|
||||
'dbOperations' => $this->getDbOperationNames(),
|
||||
'needWebSocketNotify' => $this->needWebSocketNotify,
|
||||
'skipNodeCount' => $this->skipNodeCount,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
/**
|
||||
* 晨洗状态值对象
|
||||
* 封装内镜的晨洗相关状态信息,不可变对象
|
||||
*/
|
||||
readonly class MorningWashStatus
|
||||
{
|
||||
public function __construct(
|
||||
/** 是否需要晨洗 */
|
||||
public bool $needMorningWash = false,
|
||||
/** 是否已完成晨洗 */
|
||||
public bool $morningWashed = false,
|
||||
/** 晨洗开始时间(如 06:00:00) */
|
||||
public string $startTime = '00:00:00',
|
||||
/** 今天洗消记录数 */
|
||||
public int $todayWashRecords = 0,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建默认的晨洗状态(不需要晨洗)
|
||||
*/
|
||||
public static function notRequired(): self
|
||||
{
|
||||
return new self(needMorningWash: false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建需要晨洗的状态
|
||||
*/
|
||||
public static function required(string $startTime = '06:00:00', int $todayWashRecords = 0): self
|
||||
{
|
||||
return new self(
|
||||
needMorningWash: true,
|
||||
morningWashed: false,
|
||||
startTime: $startTime,
|
||||
todayWashRecords: $todayWashRecords
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建已完成晨洗的状态
|
||||
*/
|
||||
public static function completed(string $startTime = '06:00:00'): self
|
||||
{
|
||||
return new self(
|
||||
needMorningWash: true,
|
||||
morningWashed: true,
|
||||
startTime: $startTime
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否需要进行晨洗(需要且未完成)
|
||||
*/
|
||||
public function shouldDoMorningWash(): bool
|
||||
{
|
||||
return $this->needMorningWash && !$this->morningWashed;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断晨洗是否已完成
|
||||
*/
|
||||
public function isCompleted(): bool
|
||||
{
|
||||
return $this->morningWashed;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断今天是否有洗消记录
|
||||
*/
|
||||
public function hasWashRecordsToday(): bool
|
||||
{
|
||||
return $this->todayWashRecords > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'needMorningWash' => $this->needMorningWash,
|
||||
'morningWashed' => $this->morningWashed,
|
||||
'startTime' => $this->startTime,
|
||||
'todayWashRecords' => $this->todayWashRecords,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
/**
|
||||
* 操作员信息值对象
|
||||
* 封装操作员的基础信息,不可变对象
|
||||
*/
|
||||
readonly class OperatorInfo
|
||||
{
|
||||
public function __construct(
|
||||
/** 操作员ID */
|
||||
public string $id = '',
|
||||
/** 操作员姓名 */
|
||||
public string $name = '',
|
||||
/** 操作员RFID卡号 */
|
||||
public string $rfid = '',
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建空的操作员信息
|
||||
*/
|
||||
public static function empty(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断操作员信息是否为空
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断操作员信息是否完整有效
|
||||
*/
|
||||
public function isValid(): bool
|
||||
{
|
||||
return !empty($this->id) && !empty($this->name) && !empty($this->rfid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'rfid' => $this->rfid,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
use app\model\EctActions;
|
||||
|
||||
/**
|
||||
* 流程状态值对象
|
||||
* 封装流程执行过程中的状态信息(不可变)
|
||||
*/
|
||||
readonly class ProcessStatus
|
||||
{
|
||||
public function __construct(
|
||||
/** 当前操作步骤 */
|
||||
public string $currentStep = '',
|
||||
/** 流程类型 */
|
||||
public string $processType = '',
|
||||
/** 批次号 */
|
||||
public string $batchNo = '',
|
||||
/** 操作开始时间 */
|
||||
public string $actionStartTime = '',
|
||||
/** 操作时长(秒) 计算方式为上下文创建的时间减去上个操作的开始时间(此时上个操作的结束时间不存在,需要等待此次刷卡流程结束) */
|
||||
public ?int $duration = null,
|
||||
/** 上一个操作记录 */
|
||||
public ?EctActions $previousAction = null,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建空状态
|
||||
*/
|
||||
public static function empty(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否可以开始新流程
|
||||
*/
|
||||
public function canStartNewProcess(): bool
|
||||
{
|
||||
$validSteps = ['', '结束', '内镜取出', '测漏正常', '测漏异常'];
|
||||
return in_array($this->currentStep, $validSteps);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已完成清洗流程
|
||||
*/
|
||||
public function isWashProcessCompleted(): bool
|
||||
{
|
||||
return $this->currentStep === '结束';
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有上一个操作
|
||||
*/
|
||||
public function hasPreviousAction(): bool
|
||||
{
|
||||
return $this->previousAction !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'currentStep' => $this->currentStep,
|
||||
'processType' => $this->processType,
|
||||
'batchNo' => $this->batchNo,
|
||||
'actionStartTime' => $this->actionStartTime,
|
||||
'duration' => $this->duration,
|
||||
'previousActionId' => $this->previousAction?->action_id,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
/**
|
||||
* 读卡器信息值对象
|
||||
* 封装读卡器的基础信息,不可变对象
|
||||
*/
|
||||
readonly class ReaderInfo
|
||||
{
|
||||
public function __construct(
|
||||
/** 读卡器编号 */
|
||||
public string $no = '',
|
||||
/** 读卡器类型/功能(清洗/漂洗/消毒等) */
|
||||
public string $type = '',
|
||||
/** 读卡器ID */
|
||||
public string $id = '',
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建空的读卡器信息
|
||||
*/
|
||||
public static function empty(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断读卡器信息是否为空
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->no);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断读卡器类型是否匹配
|
||||
*/
|
||||
public function isType(string $type): bool
|
||||
{
|
||||
return $this->type === $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断读卡器类型是否在给定列表中
|
||||
*/
|
||||
public function isTypeIn(array $types): bool
|
||||
{
|
||||
return in_array($this->type, $types, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'no' => $this->no,
|
||||
'type' => $this->type,
|
||||
'id' => $this->id,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
/**
|
||||
* 提醒状态值对象
|
||||
* 封装流程中的各类提醒标记(不可变)
|
||||
*/
|
||||
readonly class ReminderStatus
|
||||
{
|
||||
public function __construct(
|
||||
/** 是否需要增强洗 */
|
||||
public bool $needEnhanceWash = false,
|
||||
/** 是否需要测漏提醒 */
|
||||
public bool $needLeakTestRemind = false,
|
||||
/** 是否需要存储提醒 */
|
||||
public bool $needStorageRemind = false,
|
||||
/** 是否已测漏 */
|
||||
public bool $leakTestDone = false,
|
||||
/** 测漏结果 */
|
||||
public string $leakTestResult = '',
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建默认状态(无提醒)
|
||||
*/
|
||||
public static function none(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置需要增强洗
|
||||
*/
|
||||
public function withEnhanceWash(bool $need = true): self
|
||||
{
|
||||
return new self(
|
||||
needEnhanceWash: $need,
|
||||
needLeakTestRemind: $this->needLeakTestRemind,
|
||||
needStorageRemind: $this->needStorageRemind,
|
||||
leakTestDone: $this->leakTestDone,
|
||||
leakTestResult: $this->leakTestResult
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置需要测漏提醒
|
||||
*/
|
||||
public function withLeakTestRemind(bool $need = true): self
|
||||
{
|
||||
return new self(
|
||||
needEnhanceWash: $this->needEnhanceWash,
|
||||
needLeakTestRemind: $need,
|
||||
needStorageRemind: $this->needStorageRemind,
|
||||
leakTestDone: $this->leakTestDone,
|
||||
leakTestResult: $this->leakTestResult
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置需要存储提醒
|
||||
*/
|
||||
public function withStorageRemind(bool $need = true): self
|
||||
{
|
||||
return new self(
|
||||
needEnhanceWash: $this->needEnhanceWash,
|
||||
needLeakTestRemind: $this->needLeakTestRemind,
|
||||
needStorageRemind: $need,
|
||||
leakTestDone: $this->leakTestDone,
|
||||
leakTestResult: $this->leakTestResult
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置测漏完成
|
||||
*/
|
||||
public function withLeakTestDone(string $result = ''): self
|
||||
{
|
||||
return new self(
|
||||
needEnhanceWash: $this->needEnhanceWash,
|
||||
needLeakTestRemind: $this->needLeakTestRemind,
|
||||
needStorageRemind: $this->needStorageRemind,
|
||||
leakTestDone: true,
|
||||
leakTestResult: $result
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有任何提醒
|
||||
*/
|
||||
public function hasAnyRemind(): bool
|
||||
{
|
||||
return $this->needEnhanceWash
|
||||
|| $this->needLeakTestRemind
|
||||
|| $this->needStorageRemind;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'needEnhanceWash' => $this->needEnhanceWash,
|
||||
'needLeakTestRemind' => $this->needLeakTestRemind,
|
||||
'needStorageRemind' => $this->needStorageRemind,
|
||||
'leakTestDone' => $this->leakTestDone,
|
||||
'leakTestResult' => $this->leakTestResult,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
/**
|
||||
* 存储状态值对象
|
||||
* 封装内镜的存储柜状态信息,不可变对象
|
||||
*/
|
||||
readonly class StorageStatus
|
||||
{
|
||||
public function __construct(
|
||||
/** 内镜是否在存储柜中 */
|
||||
public bool $isInStorage = false,
|
||||
/** 最后一次存储操作类型:内镜放入/内镜取出 */
|
||||
public string $lastAction = '',
|
||||
/** 存储入库时间 */
|
||||
public ?string $inTime = null,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建默认的存储状态(不在库中)
|
||||
*/
|
||||
public static function notInStorage(): self
|
||||
{
|
||||
return new self(isInStorage: false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建入库状态
|
||||
*/
|
||||
public static function inStorage(string $inTime): self
|
||||
{
|
||||
return new self(
|
||||
isInStorage: true,
|
||||
lastAction: '内镜放入',
|
||||
inTime: $inTime
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建出库状态
|
||||
*/
|
||||
public static function outOfStorage(): self
|
||||
{
|
||||
return new self(
|
||||
isInStorage: false,
|
||||
lastAction: '内镜取出',
|
||||
inTime: null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否已入库
|
||||
*/
|
||||
public function isStored(): bool
|
||||
{
|
||||
return $this->isInStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否已出库
|
||||
*/
|
||||
public function isTakenOut(): bool
|
||||
{
|
||||
return !$this->isInStorage && $this->lastAction === '内镜取出';
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'isInStorage' => $this->isInStorage,
|
||||
'lastAction' => $this->lastAction,
|
||||
'inTime' => $this->inTime,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow\context\bean;
|
||||
|
||||
use app\flow\enum\VoiceMessage;
|
||||
|
||||
/**
|
||||
* 语音状态值对象
|
||||
* 封装语音播报相关状态(不可变)
|
||||
*/
|
||||
readonly class VoiceState
|
||||
{
|
||||
public function __construct(
|
||||
/** 语音播报内容 */
|
||||
public string $message = '',
|
||||
/** 错误消息枚举 */
|
||||
public VoiceMessage $errorMessage = VoiceMessage::NONE,
|
||||
/** 期望下一步提示 */
|
||||
public VoiceMessage $expectedNextStep = VoiceMessage::NONE,
|
||||
/** 语音模板参数 */
|
||||
public array $templateParams = [],
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 创建空语音状态
|
||||
*/
|
||||
public static function empty(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从消息创建
|
||||
*/
|
||||
public static function fromMessage(string|VoiceMessage $message): self
|
||||
{
|
||||
if ($message instanceof VoiceMessage) {
|
||||
return new self(message: $message->value);
|
||||
}
|
||||
return new self(message: $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从错误枚举创建
|
||||
*/
|
||||
public static function fromError(VoiceMessage $error): self
|
||||
{
|
||||
return new self(errorMessage: $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置语音消息
|
||||
*/
|
||||
public function withMessage(string|VoiceMessage $message): self
|
||||
{
|
||||
$msg = $message instanceof VoiceMessage ? $message->value : $message;
|
||||
return new self(
|
||||
message: $msg,
|
||||
errorMessage: $this->errorMessage,
|
||||
expectedNextStep: $this->expectedNextStep,
|
||||
templateParams: $this->templateParams
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置错误消息
|
||||
*/
|
||||
public function withError(VoiceMessage $error): self
|
||||
{
|
||||
return new self(
|
||||
message: $this->message,
|
||||
errorMessage: $error,
|
||||
expectedNextStep: $this->expectedNextStep,
|
||||
templateParams: $this->templateParams
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置期望下一步
|
||||
*/
|
||||
public function withExpectedNextStep(VoiceMessage $expected): self
|
||||
{
|
||||
return new self(
|
||||
message: $this->message,
|
||||
errorMessage: $this->errorMessage,
|
||||
expectedNextStep: $expected,
|
||||
templateParams: $this->templateParams
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加语音前缀
|
||||
*/
|
||||
public function prependMessage(string $prefix): self
|
||||
{
|
||||
return new self(
|
||||
message: $prefix . $this->message,
|
||||
errorMessage: $this->errorMessage,
|
||||
expectedNextStep: $this->expectedNextStep,
|
||||
templateParams: $this->templateParams
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模板参数
|
||||
*/
|
||||
public function withTemplateParams(array $params): self
|
||||
{
|
||||
return new self(
|
||||
message: $this->message,
|
||||
errorMessage: $this->errorMessage,
|
||||
expectedNextStep: $this->expectedNextStep,
|
||||
templateParams: $params
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整语音(优先返回 message,否则返回 errorMessage)
|
||||
*/
|
||||
public function getFullVoice(): string
|
||||
{
|
||||
if (!empty($this->message)) {
|
||||
return $this->message;
|
||||
}
|
||||
return $this->errorMessage->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有错误
|
||||
*/
|
||||
public function hasError(): bool
|
||||
{
|
||||
return $this->errorMessage !== VoiceMessage::NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有期望下一步提示
|
||||
*/
|
||||
public function hasExpectedNextStep(): bool
|
||||
{
|
||||
return $this->expectedNextStep !== VoiceMessage::NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'message' => $this->message,
|
||||
'errorMessage' => $this->errorMessage->name,
|
||||
'expectedNextStep' => $this->expectedNextStep->name,
|
||||
'templateParams' => $this->templateParams,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user