'string', 'type' => 'in_list[1,2]', 'atcl_no' => 'string|max_length[10]', 'vr_sq' => 'integer', 'status' => 'in_list[save,ing,done,err]', 'try_cnt' => 'integer|less_than_equal_to[3]', 'insert_dt' => 'valid_date', 'server_nm' => 'string|max_length[20]', ]; protected $validationMessages = []; protected $skipValidation = false; protected $cleanValidationRules = true; // 콜백 protected $allowCallbacks = true; protected $beforeInsert = ['setInsertDate']; protected $afterInsert = []; protected $beforeUpdate = []; protected $afterUpdate = []; protected $beforeFind = []; protected $afterFind = []; protected $beforeDelete = []; protected $afterDelete = []; /** * 삽입 전 insert_dt 자동 설정 */ protected function setInsertDate(array $data) { if (!isset($data['data']['insert_dt'])) { $data['data']['insert_dt'] = date('Y-m-d H:i:s'); } return $data; } /** * 상태별 데이터 조회 (save, ing, done, err) */ public function getByStatus(string $status): array { return $this->where('status', $status)->findAll(); } /** * vr_sq로 데이터 조회 */ public function getByVrSq(int $vrSq): array { return $this->where('vr_sq', $vrSq)->findAll(); } /** * type과 vr_sq로 데이터 조회 */ public function getByTypeAndVrSq(string $type, int $vrSq): array { return $this->where('type', $type) ->where('vr_sq', $vrSq) ->findAll(); } /** * atcl_no로 데이터 조회 */ public function getByAtclNo(string $atclNo): array { return $this->where('atcl_no', $atclNo)->findAll(); } /** * 저장 대기 중인 데이터 조회 (save 상태) */ public function getPendingSave(): array { return $this->where('status', 'save') ->where('try_cnt <', 3) ->orderBy('insert_dt', 'ASC') ->findAll(); } /** * 저장 중인 데이터 조회 (ing 상태) */ public function getSaving(): array { return $this->where('status', 'ing')->findAll(); } /** * 저장 실패 데이터 조회 (err 상태) */ public function getErrors(): array { return $this->where('status', 'err')->findAll(); } /** * 특정 이미지 상태 업데이트 */ public function updateStatus(int $pk, string $status): bool { return $this->update($pk, ['status' => $status]); } /** * 재시도 횟수 증가 */ public function incrementTryCount(int $pk): bool { $current = $this->find($pk); if (!$current) { return false; } $tryCount = ($current['try_cnt'] ?? 0) + 1; $status = $tryCount >= 3 ? 'err' : 'save'; return $this->update($pk, [ 'try_cnt' => $tryCount, 'status' => $status, ]); } /** * 저장 완료 처리 */ public function markAsDone(int $pk): bool { return $this->update($pk, ['status' => 'done']); } /** * 저장 중 표시 */ public function markAsProcessing(int $pk): bool { return $this->update($pk, ['status' => 'ing']); } /** * 저장 실패 표시 */ public function markAsError(int $pk): bool { return $this->update($pk, ['status' => 'err']); } /** * 특정 vr_sq의 모든 이미지 저장 완료 */ public function markAllDoneByVrSq(int $vrSq): bool { return $this->where('vr_sq', $vrSq) ->set(['status' => 'done']) ->update(); } /** * type별 통계 */ public function getStatisticsByType(int $vrSq): array { $result = [ '1' => ['total' => 0, 'done' => 0, 'ing' => 0, 'save' => 0, 'err' => 0], '2' => ['total' => 0, 'done' => 0, 'ing' => 0, 'save' => 0, 'err' => 0], ]; $records = $this->where('vr_sq', $vrSq)->findAll(); foreach ($records as $record) { $type = $record['type']; if (!isset($result[$type])) { continue; } $result[$type]['total']++; $status = $record['status']; if (isset($result[$type][$status])) { $result[$type][$status]++; } } return $result; } /** * 저장할 준비된 데이터 조회 (제한 개수) */ public function getNextBatch(int $limit = 10): array { return $this->where('status', 'save') ->where('try_cnt <', 3) ->orderBy('insert_dt', 'ASC') ->limit($limit) ->findAll(); } }