From da33e34d4fc763e5604336840d3a147c453861f7 Mon Sep 17 00:00:00 2001 From: jjstyle Date: Mon, 5 Jan 2026 15:11:12 +0900 Subject: [PATCH] api --- app/Commands/NaverWorker.php | 136 +----------- app/Helpers/log_helper.php | 24 +- app/Models/Entities/V2chghistoryModel.php | 59 +++++ app/Models/Entities/V2chgstatModel.php | 50 +++++ app/Models/Entities/V2stdailyModel.php | 50 +++++ app/Services/NaverService.php | 256 +++++++++++++--------- 6 files changed, 330 insertions(+), 245 deletions(-) create mode 100644 app/Models/Entities/V2chghistoryModel.php create mode 100644 app/Models/Entities/V2chgstatModel.php create mode 100644 app/Models/Entities/V2stdailyModel.php diff --git a/app/Commands/NaverWorker.php b/app/Commands/NaverWorker.php index 1105b26..18e73a1 100644 --- a/app/Commands/NaverWorker.php +++ b/app/Commands/NaverWorker.php @@ -81,139 +81,5 @@ class NaverWorker extends BaseCommand } } - private function insertVrfc($payload) - { - // 1. 필수 데이터 검증 - if (empty($payload['articleNumber']) || empty($payload['requestType'])) { - throw new \Exception("필수 파라미터 누락"); - } - - $articleNumber = $payload['articleNumber']; - $requestType = $payload['requestType']; - $requestDatetime = date('Y-m-d H:i:s', strtotime($payload['requestDatetime'])); - - $vrfcModel = model(\App\Models\VrfcReqModel::class); - // 중복 요청 체크 - $existing = $vrfcModel->where('atcl_no', $articleNumber) - ->where('req_type', $requestType) - ->first(); - if ($existing) { - throw new \Exception("중복 요청: " . $articleNumber . " / " . $requestType); - } - - // 2. 네이버 API 클라이언트 초기화 - $naverClient = new \App\Libraries\NaverApiClient(); - // 매물 정보 조회 - $articleInfojson = $naverClient->getArticleInfo($articleNumber); - // if (!$articleInfojson || !isset($articleInfojson['data']) || empty($articleInfojson['code'] !== 'success')) { - // throw new \Exception("매물 정보 조회 실패: $articleNumber ::: message : " . ($articleInfojson['message'] ?? 'No response')); - // } - - if (!$articleInfojson || !isset($articleInfojson['data']) || $articleInfojson['code'] !== 'success') { - $msg = $articleInfojson['message'] ?? 'No message'; - throw new \Exception("네이버 API 응답 에러: $articleNumber | 메시지: $msg"); - } - - $articleInfo = $articleInfojson['data']; - - // 받아온 정보 로그 기록 - CLI::write("DEBUG: write_custom_log 호출 직전"); - write_custom_log("ARTICLE_INFO | ArticleNumber: $articleNumber | Info: " . json_encode($articleInfo , JSON_UNESCAPED_UNICODE), 'INFO', 'service'); - CLI::write("DEBUG: write_custom_log 호출 완료"); - - /** - * $articleInfo['verificationTypeCode'] - * S : 현장확인매물 - * D : 홍보확인서 - * N : 신홍보확인서 - * M : 모바일 - * T : 전화 - * O : 모바일확인V2 - * - * S - reciept , result 테이블 사용 - * D,N,M,T,O - v2_vrfc_req , v2_article_info , v2_article_info_etc , v2_article_fail 테이블 사용 - */ - - // {"code":"success","message":"","data":{"articleNumber":"2500000001","realEstateType":"빌라/연립","realEstateTypeCode":"C02","cpId":"toad","cpArticleNumber":"15882606","tradeType":"전세","tradeTypeCode":"B1","statusTypeCode":"E12","verificationTypeCode":"M","isUnregisteredVerificationRequested":false,"isBuildingRegisterAreaCheckRequested":false,"isAutoVerificationRequested":false,"exposureStartDateTime":"2025-01-02 09:12:02","facilities":{"roomCount":2,"bathroomCount":1},"address":{"legalDivision":{"cityNumber":"1100000000","divisionNumber":"1168000000","sectorNumber":"1168010700","legalDivisionAddress":"서울특별시 강남구 신사동"},"isVirtualAddress":false,"correspondenceFloorCount":2,"longitude":0.0,"latitude":0.0},"space":{"totalSpace":34.5,"groundSpace":34.5,"buildingSpace":34.5,"supplySpace":34.5,"exclusiveSpace":34.5},"price":{"dealAmount":777777777,"warrantyAmount":2999999999,"leaseAmount":7777777},"floor":{"correspondenceFloorCount":2,"totalFloorCount":3,"undergroundFloorCount":null}}} - $comp_sq = '2'; - $rcpt_rating = '3'; - - $files = $articleInfo['files'] ?? []; - $certRegister = []; - $confirm_doc_img_url = []; - $referenceFileUrl = []; - foreach ($files as $file) { - // 파일 처리 로직 - $fileTypeCode = $file['fileTypeCode']; - if ( $fileTypeCode == 'RCDOC' ) { - $certRegister[] = $file['fileUrl']; - } elseif ( $fileTypeCode == 'ADDOC' ) { - $confirm_doc_img_url[] = $file['fileUrl']; - } elseif ( $fileTypeCode == 'REFER') { - $referenceFileUrl[] = $file['fileUrl']; - } - } - - $vrfc_params = [ - 'reqSeq' => '', - 'atcl_no' => $articleInfo['articleNumber'], - 'step' => '', - 'cpid' => $articleInfo['cpId'], - 'cp_atcl_id' => $articleInfo['cpArticleNumber'], - 'trade_type' => $articleInfo['tradeTypeCode'], - 'realtor_nm' => $articleInfo['realtor']['realtorName'], - 'realtor_tel_no' => $articleInfo['realtor']['representativeCellphoneNumber'], - 'seller_tel_no' => $articleInfo['seller']['sellerTelephoneNumber'], - 'vrfc_type' => $articleInfo['verificationTypeCode'], - 'rgbk_confirm' => $articleInfo['isUnregisteredVerificationRequested'] ? 'Y' : 'N', - 'req_type' => '', - 'rdate' => $requestDatetime ?? db_now('Y-m-d H:i:s'), - 'cpTelNo' => $articleInfo['seller']['sellerTelephoneNumber'], - 'stat_cd' => '10', - 'try_cnt' => '0', - 'insert_user' => 'admin', - 'insert_tm' => db_now(), - 'memo' => '', - 'contact_fail_cnt' => '0', - 'sync_yn' => 'N', - 'reg_try_cnt' => '0', - 'tel_fail_cause' => null, - 'rgbk_confirm_owner_nm' => $articleInfo['seller']['ownerName'] ?? null, - 'direct_trad_yn' => $articleInfo['seller']['isDirectTrade'] === true ? 'Y' : 'N', - 'confirm_doc_img_url' => json_encode($confirm_doc_img_url, JSON_UNESCAPED_UNICODE), - 'confirm_doc_owner_check_yn' => '', - 'owner_verifiable' => null, - 'vrfc_cmpl_type' => null, - 'rgbk_doc_img_url' => null, - 'certRegister' => json_encode($certRegister, JSON_UNESCAPED_UNICODE), - 'referenceFileUrl' => json_encode($referenceFileUrl, JSON_UNESCAPED_UNICODE), - ]; - - write_custom_log("VRFC_PARAMS | " . json_encode($vrfc_params , JSON_UNESCAPED_UNICODE), 'INFO', 'service'); - - - // if ($articleInfo['verificationTypeCode'] == 'S') { // 현장확인매물 - // // 현장확인매물 처리 로직 - - // } else { // 그외 일반매물 - // // V2 매물 처리 로직 - // $v2ArticleModel = model(\App\Models\V2ArticleModel::class); - // // 매물 번호로 중복 체크 - // $existingV2 = $v2ArticleModel->where('atcl_no', $articleInfo['articleNumber'])->first(); - // if ($existingV2) { - // throw new \Exception("중복 매물 번호: " . $articleInfo['articleNumber']); - // } - - - // $v2ArticleModel->insert($vrfc_params); - // $vr_sq = $v2ArticleModel->getInsertID(); // 방금 삽입한 vr_sq 값 가져오기 - // CLI::write("Inserted V2 Article with vr_sq: " . $vr_sq); - // // 오류 처리 - // if ($v2ArticleModel->errors()) { - // $errorMessages = implode(', ', $v2ArticleModel->errors()); - // throw new \Exception("V2 매물 삽입 오류: " . $errorMessages); - // } - - // } - } + } \ No newline at end of file diff --git a/app/Helpers/log_helper.php b/app/Helpers/log_helper.php index 50c982e..b054581 100644 --- a/app/Helpers/log_helper.php +++ b/app/Helpers/log_helper.php @@ -11,12 +11,34 @@ if (! function_exists('write_custom_log')) { @mkdir($logDir, 0777, true); } + // --- 호출 위치 추적 로직 추가 --- + // debug_backtrace는 호출 스택을 가져옵니다. + // [0]은 현재 함수(write_custom_log), [1]은 이 함수를 호출한 곳입니다. + $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); + $caller = $bt[1] ?? null; + $fileInfo = $bt[0] ?? null; // 파일명과 라인수는 호출 시점인 0번 인덱스에 들어있음 + + $location = 'unknown'; + if ($caller) { + $class = $caller['class'] ?? ''; + $func = $caller['function'] ?? ''; + $line = $fileInfo['line'] ?? '0'; + + // 클래스명에서 Namespace 제외하고 클래스명만 짧게 가져오기 (선택 사항) + $classShort = substr(strrchr($class, "\\"), 1) ?: $class; + + $location = "{$classShort}::{$func}:{$line}"; + } + // ---------------------------- + $suffix = ($type === 'failed') ? '_failed' : ''; $logFile = $logDir . '/' . date('Y-m-d') . $suffix . '.log'; $timestamp = date('Y-m-d H:i:s'); $singleLine = str_replace(["\r", "\n", "\t"], " ", $message); - $formatted = "[$timestamp] [$level] $singleLine" . PHP_EOL; + + // 포맷에 [$location] 추가 + $formatted = "[$timestamp] [$level] [$location] $singleLine" . PHP_EOL; @file_put_contents($logFile, $formatted, FILE_APPEND); } diff --git a/app/Models/Entities/V2chghistoryModel.php b/app/Models/Entities/V2chghistoryModel.php new file mode 100644 index 0000000..935a14d --- /dev/null +++ b/app/Models/Entities/V2chghistoryModel.php @@ -0,0 +1,59 @@ +CREATE TABLE `v2_chg_history` ( + `seq` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '순번', + `vr_sq` BIGINT(20) UNSIGNED NOT NULL COMMENT '검증요청순번', + `stat_cd` VARCHAR(6) NOT NULL COMMENT '상태코드' COLLATE 'utf8mb3_uca1400_ai_ci', + `chg_type` VARCHAR(10) NOT NULL COMMENT '변경유형' COLLATE 'utf8mb3_uca1400_ai_ci', + `memo` TEXT NULL DEFAULT NULL COMMENT '메모' COLLATE 'utf8mb3_uca1400_ai_ci', + `insert_id` VARCHAR(60) NOT NULL COMMENT '등록자ID' COLLATE 'utf8mb3_uca1400_ai_ci', + `insert_tm` DATETIME NOT NULL COMMENT '등록시간', + PRIMARY KEY (`seq`) USING BTREE, + INDEX `vr_sq` (`vr_sq`) USING BTREE +) +COMMENT='변경이력' +COLLATE='utf8mb3_uca1400_ai_ci' +ENGINE=InnoDB +AUTO_INCREMENT=81103559 +; + 값, 'stat_cd' => 값, ...] + * @param string $saveType 'I'(Upsert), 'U'(Update) + */ + public function v2_savehistory(array $data ) + { + $payload = [ + 'vr_sq' => $data['vr_sq'], + 'stat_cd' => $data['stat_cd'], + 'chg_type' => $data['chg_type'], + 'memo' => $data['memo'] ?? '', + 'insert_id' => $data['insert_id'] ?? '0', + 'insert_tm' => $data['insert_tm'] ?? db_now(), + ]; + + // insert 수행 + if (!$this->insert($payload)) { + return [ + 'error' => [ + 'code' => $this->db->error()['code'], + 'message' => $this->db->error()['message'], + ], + 'query' => (string)$this->getLastQuery() + ]; + } + + return ['error' => ['code' => 0, 'message' => ''], 'id' => $this->getInsertID()]; + } +} \ No newline at end of file diff --git a/app/Models/Entities/V2chgstatModel.php b/app/Models/Entities/V2chgstatModel.php new file mode 100644 index 0000000..7372f4e --- /dev/null +++ b/app/Models/Entities/V2chgstatModel.php @@ -0,0 +1,50 @@ + 값, 'stat_cd' => 값, ...] + * @param string $saveType 'I'(Upsert), 'U'(Update) + */ + public function saveChgstat(array $data, string $saveType) + { + // 1. 기본값 세팅 (데이터 유연성 확보) + $payload = [ + 'vr_sq' => $data['vr_sq'] ?? null, + 'stat_cd' => $data['stat_cd'] ?? '10', // 기본값 30 + 'insert_user' => $data['insert_user'] ?? 0, + 'insert_tm' => $data['insert_tm'] ?? date('Y-m-d H:i:s'), + ]; + + if (empty($payload['vr_sq'])) { + throw new \Exception("V2chgstatModel Error: vr_sq is required."); + } + + if ($saveType === 'I') { + // CI2 방식의 ON DUPLICATE KEY UPDATE 유지 (seq 번호 보존을 위해) + $sql = "INSERT INTO v2_chg_stat (vr_sq, stat_cd, insert_user, insert_tm) + VALUES (:vr_sq:, :stat_cd:, :insert_user:, :insert_tm:) + ON DUPLICATE KEY UPDATE + insert_user = VALUES(insert_user), + insert_tm = VALUES(insert_tm)"; + + return $this->db->query($sql, $payload); + } else { + // Update 방식 + return $this->where('vr_sq', $payload['vr_sq']) + ->where('stat_cd', $payload['stat_cd']) + ->set($payload) + ->update(); + } + } +} \ No newline at end of file diff --git a/app/Models/Entities/V2stdailyModel.php b/app/Models/Entities/V2stdailyModel.php new file mode 100644 index 0000000..e74f6df --- /dev/null +++ b/app/Models/Entities/V2stdailyModel.php @@ -0,0 +1,50 @@ +db->query($sql, $data); + + return [ + 'status' => $result ? true : false, + 'error' => $this->db->error(), // ['code', 'message'] + 'last_query' => (string)$this->db->getLastQuery() // 디버깅용 + ]; + } + +} \ No newline at end of file diff --git a/app/Services/NaverService.php b/app/Services/NaverService.php index 5bb571d..150d37b 100644 --- a/app/Services/NaverService.php +++ b/app/Services/NaverService.php @@ -3,89 +3,180 @@ namespace App\Services; use App\Libraries\NaverApiClient; -use App\Models\Entities\V2ArticleModel; use App\Models\Entities\VrfcReqModel; -use App\Models\Entities\NaverWorkerLogModel; // 새로 만든 테이블용 모델 +use App\Models\Entities\V2stdailyModel; +use App\Models\Entities\V2chgstatModel; +use App\Models\Entities\V2chghistoryModel; class NaverService { - protected $naverClient; - protected $VrfcReqModel; + protected $naverClient, $VrfcReqModel, $V2stdailyModel, $V2chgstatModel, $V2chghistoryModel; public function __construct() { $this->naverClient = new NaverApiClient(); $this->VrfcReqModel = model(VrfcReqModel::class); - helper('log'); // 헬퍼 로드 + $this->V2stdailyModel = model(V2stdailyModel::class); + $this->V2chgstatModel = model(V2chgstatModel::class); + $this->V2chghistoryModel = model(V2chghistoryModel::class); + helper('log'); } /** - * 매물 정보를 처리하고 DB에 저장하는 메인 함수 - * @param array $payload 큐에서 꺼낸 원본 데이터 - * requestType - * REG:수동검증요청 - * MOD:매물정보수정-매물제공업체의 매물정보수정으로 재검증요청1차실패 후재검증요청 - * CNC:사용자취소 - * FIN 서비스-서비스 노출/대기검수완료상태,필요한상태인지확인필요 + * 메인 프로세스: 요청 타입에 따른 분기 처리 */ - public function processArticle(array $payload) { $articleNumber = $payload['articleNumber']; - $requestDatetime = date('Y-m-d H:i:s', strtotime($payload['requestDatetime'] ?? 'now')); - $requestType = $payload['requestType'] ?? ''; // REG:등록 , + $requestType = $payload['requestType'] ?? ''; // 1. 네이버 API 호출 $response = $this->naverClient->getArticleInfo($articleNumber); - - if (!$response || !isset($response['data']) || $response['code'] !== 'success') { - $msg = $response['message'] ?? 'No message'; - throw new \Exception("네이버 API 응답 에러: $articleNumber | 메시지: $msg"); + if (!$response || $response['code'] !== 'success') { + throw new \Exception("네이버 API 응답 에러: $articleNumber"); } - $articleInfo = $response['data']; - // 로그 기록 - write_custom_log("ARTICLE_INFO | ArticleNumber: $articleNumber", 'INFO', 'service'); - // 2. 가공 로직 (insertVrfc에 있던 긴 배열 생성 로직) - $vrfcParams = $this->mapToDatabaseParams($articleInfo, $payload); - write_custom_log("VRFC_PARAMS | " . json_encode($vrfcParams, JSON_UNESCAPED_UNICODE), 'INFO', 'service'); + $vrfcParams = $this->mapToDatabaseParams($response['data'], $payload); + write_custom_log("PROCESS_START | Type: $requestType | Atcl: $articleNumber", 'INFO', 'service'); switch ($requestType) { - case 'REG': - $vrfcParams['req_type'] = '10'; - return $this->handleRegistration($articleNumber, $vrfcParams); + case 'REG': // 신규 등록 + $vr_sq = $this->insertVrfcReq($articleNumber, $vrfcParams); + if ($vr_sq) $this->V2stdailyModel->set_v2_st_daily(null, $vrfcParams['cpid'], $vrfcParams['vrfc_type'] . '0103', '1', 'add'); break; - case 'MOD': - $vrfcParams['req_type'] = '20'; - return $this->handleModification($articleNumber, $vrfcParams); + + case 'MOD': // 수정 + $vr_sq = $this->updateVrfcReq($articleNumber, $vrfcParams); + if ($vr_sq) $this->V2stdailyModel->set_v2_st_daily(null, $vrfcParams['cpid'], $vrfcParams['vrfc_type'] . '0102', '1', 'add'); break; - case 'CNC': - $vrfcParams['req_type'] = '30'; - return $this->handleStatusChange($articleNumber, $vrfcParams); + + case 'CNC': // 취소 + $vr_sq = $this->deleteVrfcReq($articleNumber, $vrfcParams); + if ($vr_sq) $this->V2stdailyModel->set_v2_st_daily(null, $vrfcParams['cpid'], 'A0101', '1', 'add'); break; - case 'FIN': - $vrfcParams['req_type'] = '40'; - return $this->handleStatusChange($articleNumber, $vrfcParams); + + case 'FIN': // 완료 + $vr_sq = $this->finVrfcReq($articleNumber, $vrfcParams); break; + default: - throw new \Exception("알 수 없는 requestType: " . $requestType); - } - - // 중복 체크 - $existing = $this->VrfcReqModel->where('atcl_no', $articleNumber) - - ->first(); - if ($existing) { - throw new \Exception("중복 요청: " . $articleNumber . " / " . $vrfcParams['req_type']); + throw new \Exception("알 수 없는 requestType: $requestType"); } - // 3. DB 저장 - if (!$this->VrfcReqModel->insert($vrfcParams)) { - $errorMessages = implode(', ', $this->VrfcReqModel->errors()); - throw new \Exception("V2 매물 삽입 오류: " . $errorMessages); + return ['vr_sq' => $vr_sq, 'articleNumber' => $articleNumber]; + } + + /** + * [REG] 신규 등록 + */ + private function insertVrfcReq($articleNumber, $params) + { + $existing = $this->VrfcReqModel->where('atcl_no', $articleNumber)->first(); + if ($existing) throw new \Exception("중복 등록 시도: $articleNumber"); + + $params['stat_cd'] = '10'; + $params['insert_user'] = '0'; + $params['req_type'] = 'C'; + + if (!$this->VrfcReqModel->insert($params)) { + $sql = (string)$this->VrfcReqModel->getLastQuery(); + write_custom_log("INSERT_FAILED | Atcl: $articleNumber | SQL: $sql", 'ERROR', 'failed'); + throw new \Exception("신규 등록 실패"); } - return $this->VrfcReqModel->getInsertID(); + $vr_sq = $this->VrfcReqModel->getInsertID(); + $this->recordStatusAndHistory($vr_sq, '10', 'C9', "신규접수 : 10"); + + return $vr_sq; + } + + /** + * [MOD] 수정 처리 + */ + private function updateVrfcReq($articleNumber, $params) + { + $existing = $this->findExisting($articleNumber); + if (!$existing) return $this->insertVrfcReq($articleNumber, $params); + + $params['stat_cd'] = '30'; + $params['req_type'] = 'U'; + $params['insert_tm'] = db_now(); + + return $this->updateProcess($existing, $params, 'MOD', "재접수 상태변경: {$existing['stat_cd']} => 30"); + } + + /** + * [CNC] 취소 처리 + */ + private function deleteVrfcReq($articleNumber, $params) + { + $existing = $this->findExisting($articleNumber); + $params['stat_cd'] = '19'; + $params['req_type'] = 'D'; + + return $this->updateProcess($existing, $params, 'CNC', "취소 처리: {$existing['stat_cd']} => 19"); + } + + /** + * [FIN] 완료 처리 + */ + private function finVrfcReq($articleNumber, $params) + { + $existing = $this->findExisting($articleNumber); + $params['stat_cd'] = '60'; + $params['req_type'] = 'F'; + + return $this->updateProcess($existing, $params, 'FIN', "완료 처리: {$existing['stat_cd']} => 60"); + } + + // --- 내부 공통 유틸리티 함수 --- + + private function findExisting($articleNumber) { + $existing = $this->VrfcReqModel->where('atcl_no', $articleNumber)->first(); + if (!$existing) throw new \Exception("해당 매물 없음: $articleNumber"); + return $existing; + } + + /** + * 공통 업데이트 및 이력 기록 로직 (Lock 최소화) + */ + private function updateProcess($existing, $params, $type, $memo) + { + $vr_sq = $existing['vr_sq']; + + if (!$this->VrfcReqModel->update($vr_sq, $params)) { + $sql = (string)$this->VrfcReqModel->getLastQuery(); + write_custom_log("UPDATE_FAILED | Type: $type | vr_sq: $vr_sq | SQL: $sql", 'ERROR', 'failed'); + throw new \Exception("[$type] 업데이트 실패"); + } + + $this->recordStatusAndHistory($vr_sq, $params['stat_cd'], 'C9', $memo); + return $vr_sq; + } + + /** + * 상태 및 이력 테이블 기록 (독립적 에러 처리) + */ + private function recordStatusAndHistory($vr_sq, $stat_cd, $chg_type, $memo) + { + // 1. 상태(stat) 저장 + try { + $this->V2chgstatModel->saveChgstat([ + 'vr_sq' => $vr_sq, 'stat_cd' => $stat_cd, 'insert_user' => '0', 'insert_tm' => db_now() + ], 'I'); + } catch (\Exception $e) { + write_custom_log("STAT_SAVE_ERR | vr_sq: $vr_sq | Msg: " . $e->getMessage(), 'ERROR', 'failed'); + } + + // 2. 이력(history) 저장 + try { + $this->V2chghistoryModel->v2_savehistory([ + 'vr_sq' => $vr_sq, 'stat_cd' => $stat_cd, 'chg_type' => $chg_type, + 'memo' => $memo, 'insert_id' => 'SYSTEM', 'insert_tm' => db_now() + ]); + } catch (\Exception $e) { + write_custom_log("HIST_SAVE_ERR | vr_sq: $vr_sq | Msg: " . $e->getMessage(), 'ERROR', 'failed'); + } } /** @@ -97,6 +188,7 @@ class NaverService $certRegister = []; $confirm_doc_img_url = []; $referenceFileUrl = []; + $requestDatetime = date('YmdHis', strtotime($payload['requestDatetime'] ?? 'now')); foreach ($files as $file) { $fileTypeCode = $file['fileTypeCode']; @@ -124,13 +216,13 @@ class NaverService 'req_type' => '', 'rdate' => $requestDatetime ?? db_now('Y-m-d H:i:s'), 'cpTelNo' => $articleInfo['seller']['sellerTelephoneNumber'], - 'stat_cd' => '10', + 'stat_cd' => '', 'try_cnt' => '0', - 'insert_user' => 'admin', + 'insert_user' => '', 'insert_tm' => db_now(), 'memo' => '', 'contact_fail_cnt' => '0', - 'sync_yn' => 'N', + 'sync_yn' => 'Y', 'reg_try_cnt' => '0', 'tel_fail_cause' => null, 'rgbk_confirm_owner_nm' => $articleInfo['seller']['ownerName'] ?? null, @@ -144,65 +236,11 @@ class NaverService 'referenceFileUrl' => empty($referenceFileUrl) ? null : json_encode($referenceFileUrl, JSON_UNESCAPED_UNICODE), ]; - return $vrfc_params; } +} - /** - * [REG] 신규 등록 처리 - */ - private function handleRegistration($articleNumber, $params) - { - $existing = $this->VrfcReqModel->where('atcl_no', $articleNumber)->first(); - if ($existing) { - // 이미 존재한다면 업데이트로 돌리거나 예외 처리 - return $this->handleModification($articleNumber, $params); - } - if (!$this->VrfcReqModel->insert($params)) { - throw new \Exception("등록 실패: " . implode(', ', $this->VrfcReqModel->errors())); - } - return $this->VrfcReqModel->getInsertID(); - } - /** - * [MOD] 수정 처리 - */ - private function handleModification($articleNumber, $params) - { - // 기존 기록이 있는지 확인 - $existing = $this->VrfcReqModel->where('atcl_no', $articleNumber)->first(); - - if (!$existing) { - // 수정 요청인데 데이터가 없으면 새로 등록 - return $this->handleRegistration($articleNumber, $params); - } - // 기존 데이터 업데이트 (PK인 reqSeq 기준으로 업데이트) - if (!$this->VrfcReqModel->update($existing['reqSeq'], $params)) { - throw new \Exception("수정 실패: " . implode(', ', $this->VrfcReqModel->errors())); - } - return $existing['reqSeq']; - } - /** - * [CNC / FIN] 상태값 변경 처리 - */ - private function handleStatusChange($articleNumber, $statusCode, $memo) - { - $existing = $this->VrfcReqModel->where('atcl_no', $articleNumber)->first(); - if (!$existing) { - throw new \Exception("상태 변경 실패: 해당 매물 없음 ($articleNumber)"); - } - - $updateData = [ - 'stat_cd' => $statusCode, - 'memo' => $existing['memo'] . " | " . $memo . "(" . date('Y-m-d H:i:s') . ")" - ]; - - if (!$this->VrfcReqModel->update($existing['reqSeq'], $updateData)) { - throw new \Exception("상태 업데이트 실패: " . $articleNumber); - } - return $existing['reqSeq']; - } -} \ No newline at end of file