loadEnvironment($envPath); $this->initDefaults(); } /** * 加载环境配置 */ private function loadEnvironment(?string $envPath): void { $defaultPath = __DIR__ . '/../resources/default_environment.json'; $path = $envPath ?? $defaultPath; if (!file_exists($path)) { throw new \RuntimeException("环境配置文件不存在: {$path}"); } $content = file_get_contents($path); $this->environment = json_decode($content, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new \RuntimeException("环境配置文件解析失败: " . json_last_error_msg()); } } /** * 初始化默认值 */ private function initDefaults(): void { $this->endoscope = EndoscopeInfo::empty(); $this->reader = ReaderInfo::empty(); $this->operator = OperatorInfo::empty(); $this->storage = StorageStatus::notInStorage(); $this->morningWash = MorningWashStatus::notRequired(); $this->voice = VoiceState::empty(); $this->result = ExecutionResult::success(); $this->processStatus = ProcessStatus::empty(); $this->reminder = ReminderStatus::none(); // 从环境配置加载步骤时长 if (isset($this->environment['stepDurations'])) { $this->stepDurations = $this->environment['stepDurations']; } } /** * 创建构建器实例(静态工厂) */ public static function create(?string $envPath = null): self { return new self($envPath); } // ==================== 便捷设置方法 ==================== /** * 设置内镜(从环境配置名称) */ public function endoscope(string $name): self { $data = $this->environment['endoscopes'][$name] ?? null; if ($data === null) { throw new \InvalidArgumentException("未找到内镜配置: {$name}"); } $this->endoscope = new EndoscopeInfo( id: $data['id'], name: $data['name'], cardNo: $data['cardNo'], type: $data['type'] ); return $this; } /** * 设置自定义内镜 */ public function customEndoscope(string $id, string $name, string $cardNo, string $type = ''): self { $this->endoscope = new EndoscopeInfo( id: $id, name: $name, cardNo: $cardNo, type: $type ); return $this; } /** * 设置读卡器(从环境配置名称/类型) */ public function reader(string $typeOrName): self { $data = $this->environment['readers'][$typeOrName] ?? null; if ($data === null) { throw new \InvalidArgumentException("未找到读卡器配置: {$typeOrName}"); } $this->reader = new ReaderInfo( no: $data['no'], type: $data['type'], id: $data['id'] ); return $this; } /** * 设置自定义读卡器 */ public function customReader(string $no, string $type, string $id = ''): self { $this->reader = new ReaderInfo(no: $no, type: $type, id: $id); return $this; } /** * 设置操作员(从环境配置名称) */ public function operator(string $name): self { $data = $this->environment['operators'][$name] ?? null; if ($data === null) { throw new \InvalidArgumentException("未找到操作员配置: {$name}"); } $this->operator = new OperatorInfo( id: $data['id'], name: $data['name'], rfid: $data['rfid'] ); return $this; } /** * 设置自定义操作员 */ public function customOperator(string $id, string $name, string $rfid = ''): self { $this->operator = new OperatorInfo(id: $id, name: $name, rfid: $rfid); return $this; } /** * 设置当前步骤 */ public function currentStep(string $step): self { // 自动从环境配置加载该步骤的时长(如果未手动设置) $duration = $this->processStatus->duration; if ($duration === null && isset($this->stepDurations[$step])) { $duration = $this->stepDurations[$step]; } $this->processStatus = new ProcessStatus( currentStep: $step, processType: $this->processStatus->processType, batchNo: $this->processStatus->batchNo, actionStartTime: $this->processStatus->actionStartTime, duration: $duration, previousAction: $this->processStatus->previousAction ); return $this; } /** * 设置批次号 */ public function batchNo(string $batchNo): self { $this->processStatus = new ProcessStatus( currentStep: $this->processStatus->currentStep, processType: $this->processStatus->processType, batchNo: $batchNo, actionStartTime: $this->processStatus->actionStartTime, duration: $this->processStatus->duration, previousAction: $this->processStatus->previousAction ); return $this; } /** * 设置流程类型 */ public function processType(string $type): self { $this->processStatus = new ProcessStatus( currentStep: $this->processStatus->currentStep, processType: $type, batchNo: $this->processStatus->batchNo, actionStartTime: $this->processStatus->actionStartTime, duration: $this->processStatus->duration, previousAction: $this->processStatus->previousAction ); return $this; } /** * 设置操作时长(秒) */ public function setDuration(?int $seconds): self { $this->processStatus = new ProcessStatus( currentStep: $this->processStatus->currentStep, processType: $this->processStatus->processType, batchNo: $this->processStatus->batchNo, actionStartTime: $this->processStatus->actionStartTime, duration: $seconds, previousAction: $this->processStatus->previousAction ); return $this; } /** * 设置操作开始时间 */ public function actionStartTime(string $time): self { $this->processStatus = new ProcessStatus( currentStep: $this->processStatus->currentStep, processType: $this->processStatus->processType, batchNo: $this->processStatus->batchNo, actionStartTime: $time, duration: $this->processStatus->duration, previousAction: $this->processStatus->previousAction ); return $this; } /** * 设置上一条操作记录(虚拟) */ public function setPreviousAction(string $processName, string $batchNo = '', ?string $opEndtime = null): self { $action = new EctActions(); $action->process_name = $processName; $action->op_batchno = $batchNo ?: $this->processStatus->batchNo; $action->op_starttime = date('Y-m-d H:i:s', time() - 60); $action->op_endtime = $opEndtime; $action->action_type = $this->mapActionType($this->processStatus->processType); $action->action_type_name = $this->processStatus->processType; $this->processStatus = new ProcessStatus( currentStep: $this->processStatus->currentStep, processType: $this->processStatus->processType, batchNo: $this->processStatus->batchNo, actionStartTime: $this->processStatus->actionStartTime, duration: $this->processStatus->duration, previousAction: $action ); return $this; } /** * 映射流程类型到 action_type 数字 */ private function mapActionType(string $processType): int { return match ($processType) { '手工洗' => 1, '机洗' => 2, '手工洗(加强)' => 3, '机洗(加强)' => 4, '手工洗(晨洗)' => 5, '机洗(晨洗)' => 6, '晨洗' => 7, default => 0, }; } /** * 设置晨洗状态 - 需要晨洗 */ public function needMorningWash(int $todayRecords = 0): self { $startTime = $this->environment['config']['morningWashStartTime'] ?? '06:00:00'; $this->morningWash = MorningWashStatus::required($startTime, $todayRecords); return $this; } /** * 设置晨洗状态 - 已完成晨洗 */ public function morningWashCompleted(): self { $startTime = $this->environment['config']['morningWashStartTime'] ?? '06:00:00'; $this->morningWash = MorningWashStatus::completed($startTime); return $this; } /** * 设置晨洗状态 - 不需要晨洗 */ public function noMorningWash(): self { $this->morningWash = MorningWashStatus::notRequired(); return $this; } /** * 设置存储状态 - 在库中 */ public function inStorage(?string $inTime = null): self { $this->storage = StorageStatus::inStorage($inTime ?? date('Y-m-d H:i:s', time() - 3600)); return $this; } /** * 设置存储状态 - 已出库 */ public function outOfStorage(): self { $this->storage = StorageStatus::outOfStorage(); return $this; } /** * 设置为人员卡 */ public function asOperatorCard(): self { $this->isOperatorCard = true; return $this; } /** * 设置流程引擎配置 */ public function withEngineConfig(ProcessConfig $config): self { $this->engineConfig = $config; return $this; } /** * 设置步骤时长 */ public function setStepDuration(string $stepCode, int $duration): self { $this->stepDurations[$stepCode] = $duration; return $this; } /** * 新流程开始(清空当前步骤,生成新批次号) */ public function newProcess(): self { $machineId = $this->environment['config']['machineId'] ?? '01'; $batchNo = date('Ymd') . $machineId . str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT); $this->processStatus = new ProcessStatus( currentStep: '', processType: '', batchNo: $batchNo, actionStartTime: date('Y-m-d H:i:s'), duration: 0, previousAction: null ); return $this; } /** * 模拟结束状态 */ public function finished(): self { return $this->currentStep('结束'); } // ==================== 构建方法 ==================== /** * 构建 ProcessContext */ public function build(): ProcessContext { return new ProcessContext( endoscope: $this->endoscope, reader: $this->reader, operator: $this->operator, storage: $this->storage, morningWash: $this->morningWash, voice: $this->voice, result: $this->result, processStatus: $this->processStatus, reminder: $this->reminder, packetContext: null, engineConfig: $this->engineConfig, rawData: $this->rawData, isOperatorCard: $this->isOperatorCard, stepDurations: $this->stepDurations, ); } /** * 获取当前环境配置 */ public function getEnvironment(): array { return $this->environment; } /** * 获取读卡器配置列表 */ public function getAvailableReaders(): array { return array_keys($this->environment['readers'] ?? []); } /** * 获取内镜配置列表 */ public function getAvailableEndoscopes(): array { return array_keys($this->environment['endoscopes'] ?? []); } /** * 获取操作员配置列表 */ public function getAvailableOperators(): array { return array_keys($this->environment['operators'] ?? []); } }