Compare commits

...

3 Commits

Author SHA1 Message Date
353df045d8 Merge branch 'master' of http://192.168.10.243:3000/owrainfo/confirms 2026-03-03 21:41:09 +09:00
f02f8c0457 현장 확인 업로드 2026-03-03 21:41:02 +09:00
243ca0c45e 현장 확인 업로드 수정 2026-03-03 21:39:51 +09:00
126 changed files with 2969 additions and 2089 deletions

View File

@@ -42,11 +42,13 @@ class NaverWorker extends BaseCommand
// 1. DB 연결 상태 체크 (더 견고하게) // 1. DB 연결 상태 체크 (더 견고하게)
try { try {
if ($this->db->connID === false || !@$this->db->connID->ping()) { // connID가 없거나, 가벼운 쿼리 실행 실패 시 재연결 시도
if ($this->db->connID === false || !$this->db->simpleQuery('SELECT 1')) {
$this->db->reconnect(); $this->db->reconnect();
CLI::write(CLI::color('🔄 Database reconnected.', 'yellow')); CLI::write(CLI::color('🔄 Database reconnected.', 'yellow'));
} }
} catch (\Throwable $e) { } catch (\Throwable $e) {
// 어떤 이유로든 에러 발생 시 재연결 시도
$this->db->reconnect(); $this->db->reconnect();
} }

View File

@@ -76,8 +76,10 @@ $routes->group('', ['namespace' => 'App\Controllers\Article'], static function (
$routes->post('chgStatus', 'Receipt::chgStatus'); // 상태변경 $routes->post('chgStatus', 'Receipt::chgStatus'); // 상태변경
$routes->post('sendSms', 'Receipt::sendSms'); // 문자발송 $routes->post('sendSms', 'Receipt::sendSms'); // 문자발송
$routes->post('saveRecInfo', 'Receipt::saveRecInfo'); // 거주인정보저장 $routes->post('saveRecInfo', 'Receipt::saveRecInfo'); // 거주인정보저장
$routes->get('getImages', 'Receipt::getImages'); // 이미지 목록 조회
$routes->post('uploadFile', 'Receipt::uploadFile'); // 파일업로드 $routes->post('uploadFile', 'Receipt::uploadFile'); // 파일업로드
$routes->post('removeUploadFile', 'Receipt::removeUploadFile'); // 파일삭제 $routes->post('removeUploadFile', 'Receipt::removeUploadFile'); // 파일삭제
$routes->post('updateImageOrder', 'Receipt::updateImageOrder'); // 이미지 순서 업데이트
$routes->get('downloadAllImages', 'Receipt::downloadAllImages'); // 이미지 일괄 다운로드 $routes->get('downloadAllImages', 'Receipt::downloadAllImages'); // 이미지 일괄 다운로드
$routes->post('saveImgLocation', 'Receipt::saveImgLocation'); // 촬영위치 저장 $routes->post('saveImgLocation', 'Receipt::saveImgLocation'); // 촬영위치 저장
}); });

View File

@@ -23,6 +23,8 @@ class Receipt extends BaseController
public function lists(): string public function lists(): string
{ {
error_log('========== Receipt::lists() CALLED ==========');
$usr_id = $this->request->getGet('usr_id') ?: ''; $usr_id = $this->request->getGet('usr_id') ?: '';
$sBonbu = $this->request->getGet('bonbu') ?: ''; $sBonbu = $this->request->getGet('bonbu') ?: '';
$sTeanm = $this->request->getGet('dept_sq') ?: ''; $sTeanm = $this->request->getGet('dept_sq') ?: '';
@@ -54,6 +56,8 @@ class Receipt extends BaseController
public function getResultList() public function getResultList()
{ {
error_log('========== Receipt::getResultList() CALLED ==========');
$start = (int) $this->request->getGet('start') ?: 0; $start = (int) $this->request->getGet('start') ?: 0;
$end = (int) $this->request->getGet('length') ?: 10; $end = (int) $this->request->getGet('length') ?: 10;
@@ -92,9 +96,13 @@ class Receipt extends BaseController
'srchTxt' => $this->request->getGet('srchTxt'), // 검색어 'srchTxt' => $this->request->getGet('srchTxt'), // 검색어
]; ];
error_log('[Receipt::getResultList] START - start=' . $start . ' length=' . $end);
$totalCount = $this->model->getTotalCount($data); $totalCount = $this->model->getTotalCount($data);
error_log('[Receipt::getResultList] TotalCount = ' . $totalCount);
$datas = $this->model->getResultList($start, $end, $data); $datas = $this->model->getResultList($start, $end, $data);
error_log('[Receipt::getResultList] END - returned ' . count($datas) . ' rows');
return $this->response->setJSON(body: [ return $this->response->setJSON(body: [
'recordsTotal' => $totalCount, 'recordsTotal' => $totalCount,
@@ -717,6 +725,26 @@ class Receipt extends BaseController
$rsrv_sq = $this->request->getPost('rsrv_sq'); $rsrv_sq = $this->request->getPost('rsrv_sq');
$rcpt_sq = $this->request->getPost('rcpt_sq'); $rcpt_sq = $this->request->getPost('rcpt_sq');
$img_type = $this->request->getPost('img_type'); $img_type = $this->request->getPost('img_type');
$img_sub_type = $this->request->getPost('img_sub_type');
$file_order = $this->request->getPost('file_order');
log_message('info', '[Receipt::uploadFile] Request received - rcpt_key:{rcpt_key}, rsrv_sq:{rsrv_sq}, rcpt_sq:{rcpt_sq}, img_type:{img_type}, img_sub_type:{img_sub_type}, file_order:{file_order}', [
'rcpt_key' => $rcpt_key,
'rsrv_sq' => $rsrv_sq,
'rcpt_sq' => $rcpt_sq,
'img_type' => $img_type,
'img_sub_type' => $img_sub_type,
'file_order' => $file_order,
]);
// 필수 파라미터 검증
if (empty($rsrv_sq)) {
log_message('error', '[Receipt::uploadFile] rsrv_sq is empty');
return $this->response->setJSON([
'code' => '9',
'msg' => 'rsrv_sq(예약일련번호)가 필요합니다.'
]);
}
$files = $this->request->getFiles(); $files = $this->request->getFiles();
$uploadPath = "/upload/result/" . $rsrv_sq . "/"; $uploadPath = "/upload/result/" . $rsrv_sq . "/";
@@ -738,7 +766,7 @@ class Receipt extends BaseController
// 워터마크 이미지 조회 // 워터마크 이미지 조회
$watermark_info = []; $watermark_info = [];
if (!empty($receipt) && ($receipt['comp_sq'] ?? '') == '2') { if (!empty($receipt) && !empty($receipt['rcpt_cpid'])) {
$watermark_info = $this->model->getWatermarkList($receipt['rcpt_cpid']); $watermark_info = $this->model->getWatermarkList($receipt['rcpt_cpid']);
} }
@@ -758,15 +786,20 @@ class Receipt extends BaseController
if ($uploadData !== false) { if ($uploadData !== false) {
$arrUploadfile[] = $uploadData; $arrUploadfile[] = $uploadData;
log_message('info', '[Receipt::uploadFile] upload success name={name} stored={stored}', [ log_message('info', '[Receipt::uploadFile] upload success name={name} stored={stored} cloud_url={url}', [
'name' => $file->getName(), 'name' => $file->getName(),
'stored' => $uploadData['file_name'] ?? '(unknown)', 'stored' => $uploadData['file_name'] ?? '(unknown)',
'url' => $uploadData['object_storage_url'] ?? '(none)',
]); ]);
} else { } else {
log_message('error', '[Receipt::uploadFile] do_upload2 failed name={name} error={error}:{errorString}', [ log_message('error', '[Receipt::uploadFile] Cloud upload failed name={name}', [
'name' => $file->getName(), 'name' => $file->getName(),
'error' => $file->getError(), ]);
'errorString' => $file->getErrorString(),
// 클라우드 업로드 실패 시 즉시 에러 반환
return $this->response->setJSON([
'code' => '9',
'msg' => '클라우드 스토리지 업로드 실패: ' . $file->getName() . '\n네트워크 연결 또는 권한을 확인해주세요.'
]); ]);
} }
@@ -786,26 +819,80 @@ class Receipt extends BaseController
$dir = rtrim(dirname($uploadFile['object_key']), '/'); // upload/result/* $dir = rtrim(dirname($uploadFile['object_key']), '/'); // upload/result/*
$thumbKey = $dir . '/' . $base . '_thumb.jpg'; $thumbKey = $dir . '/' . $base . '_thumb.jpg';
try {
// 원본 이미지 다운로드 (클라우드에서)
$imageDataBlob = file_get_contents($object_storage_url); $imageDataBlob = file_get_contents($object_storage_url);
if (!$imageDataBlob) {
throw new \Exception('Failed to download original image from cloud storage');
}
if (class_exists('\Imagick')) {
// Imagick 사용
$im = new \Imagick(); $im = new \Imagick();
$im->readImageBlob($imageDataBlob); $im->readImageBlob($imageDataBlob);
$imgWidth = $im->getImageWidth(); $imgWidth = $im->getImageWidth();
$imgHeight = $im->getImageHeight(); $imgHeight = $im->getImageHeight();
$im->thumbnailImage(105, 80, false); $im->thumbnailImage(105, 80, false);
$thumb_im = $im->getImageBlob(); $thumb_im = $im->getImageBlob();
// 썸네일 s3 전송
$lib->upload_object_storage_imagick2($thumbKey, $thumb_im);
$im->destroy(); $im->destroy();
// 썸네일 클라우드 업로드
$thumbUploaded = $lib->upload_object_storage_imagick2($thumbKey, $thumb_im);
if (!$thumbUploaded) {
log_message('warning', '[Receipt::uploadFile] Thumbnail cloud upload failed: {key}', ['key' => $thumbKey]);
}
} elseif (extension_loaded('gd')) {
// GD 라이브러리 사용
$source = imagecreatefromstring($imageDataBlob);
if ($source !== false) {
$imgWidth = imagesx($source);
$imgHeight = imagesy($source);
// 썸네일 크기 계산 (105x80 비율 유지)
$thumb_width = 105;
$thumb_height = 80;
// 썸네일 이미지 생성
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $thumb_width, $thumb_height, $imgWidth, $imgHeight);
// JPEG로 변환
ob_start();
imagejpeg($thumb, null, 85);
$thumb_im = ob_get_clean();
// 메모리 해제
imagedestroy($source);
imagedestroy($thumb);
// 썸네일 클라우드 업로드
$thumbUploaded = $lib->upload_object_storage_imagick2($thumbKey, $thumb_im);
if (!$thumbUploaded) {
log_message('warning', '[Receipt::uploadFile] Thumbnail cloud upload failed: {key}', ['key' => $thumbKey]);
}
log_message('info', '[Receipt::uploadFile] Thumbnail created with GD: {key}', ['key' => $thumbKey]);
} else {
log_message('warning', '[Receipt::uploadFile] GD failed to create image from string');
}
} else {
log_message('warning', '[Receipt::uploadFile] No image library available (Imagick or GD), skipping thumbnail generation');
}
} catch (\Exception $e) {
log_message('error', '[Receipt::uploadFile] Thumbnail generation failed: {message}', [
'message' => $e->getMessage(),
]);
}
} }
// 워터마크 삽입 // 워터마크 삽입
$watermark_imgs = ['I3', 'I4']; $watermark_imgs = ['I3', 'I4'];
if (in_array($img_type, $watermark_imgs)) { if (in_array($img_type, $watermark_imgs) && !empty($watermark_info)) {
if (!empty($watermark_info)) {
$common->watermarking($object_storage_url, $watermark_info, '', $receipt['rcpt_cpid'], $uploadFile['object_key']); $common->watermarking($object_storage_url, $watermark_info, '', $receipt['rcpt_cpid'], $uploadFile['object_key']);
} }
}
// 촬영정보 가져오기 // 촬영정보 가져오기
$arrExifData = @exif_read_data($object_storage_url); $arrExifData = @exif_read_data($object_storage_url);
@@ -880,19 +967,34 @@ class Receipt extends BaseController
'meta_data' => $metaData, // 이미지메타데이터 'meta_data' => $metaData, // 이미지메타데이터
'receipt' => $receipt, 'receipt' => $receipt,
'img_type' => $img_type, 'img_type' => $img_type,
'cloud_upload_yn' => 'Y', // 클라우드 업로드 성공 (여기까지 왔으면 성공)
]; ];
$this->model->saveImg($uploadParam); $img_sq = $this->model->saveImg($uploadParam);
} }
} }
// 성공 응답 - JavaScript에서 사용할 이미지 정보 포함
$lastUploadedFile = end($arrUploadfile);
return $this->response->setJSON([ return $this->response->setJSON([
'code' => '0', 'code' => '0',
'msg' => 'success' 'msg' => 'success',
'img_sq' => $img_sq ?? null,
'img_path' => $uploadPath,
'img_filenm' => $lastUploadedFile['file_name'] ?? '',
'cloud_upload_yn' => 'Y',
'img_location' => ''
]); ]);
} catch (\Exception $e) { } catch (\Exception $e) {
log_message('error', '[Receipt::uploadFile] Exception occurred: {message} at {file}:{line}', [
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString(),
]);
return $this->response->setJSON([ return $this->response->setJSON([
'code' => '9', 'code' => '9',
'msg' => $e->getMessage(), 'msg' => $e->getMessage(),
@@ -988,6 +1090,69 @@ class Receipt extends BaseController
} }
} }
// 업로드파일 목록 조회 (AJAX용)
public function getImages()
{
try {
$rsrv_sq = $this->request->getGet('rsrv_sq') ?? $this->request->getPost('rsrv_sq');
$img_type = $this->request->getGet('img_type') ?? $this->request->getPost('img_type');
if (empty($rsrv_sq)) {
return $this->response->setJSON([
'success' => false,
'msg' => 'rsrv_sq가 필요합니다.'
]);
}
// 전체 이미지 리스트 조회
$images = $this->model->getImageList2($rsrv_sq);
// img_type이 지정된 경우 필터링
if (!empty($img_type)) {
$images = array_filter($images, function($img) use ($img_type) {
return $img['img_type'] === $img_type;
});
$images = array_values($images); // 인덱스 재정렬
}
// 이미지 URL 생성
foreach ($images as &$img) {
$temp = explode(".", $img['img_filenm']);
$thumbName = $temp[0] . "_thumb.jpg";
$localOriginalPath = $img['img_path'] . $img['img_filenm'];
$localThumbPath = $img['img_path'] . $thumbName;
// 모든 파일은 클라우드에 저장됨
if (($img['cloud_upload_yn'] ?? 'Y') === 'Y') {
$img['original_url'] = NCLOUD_OBJECT_STORAGE_URL . $localOriginalPath;
$img['thumbnail_url'] = NCLOUD_OBJECT_STORAGE_URL . $localThumbPath;
} else {
// 혹시 모를 레거시 로컬 파일 (로컬 파일 시스템 체크)
$localThumbFullPath = FCPATH . $localThumbPath;
if (file_exists($localThumbFullPath)) {
$img['thumbnail_url'] = $localThumbPath;
} else {
$img['thumbnail_url'] = $localOriginalPath;
}
$img['original_url'] = $localOriginalPath;
}
}
return $this->response->setJSON([
'success' => true,
'images' => $images
]);
} catch (\Exception $e) {
log_message('error', '[Receipt::getImages] Error: ' . $e->getMessage());
return $this->response->setJSON([
'success' => false,
'msg' => $e->getMessage()
]);
}
}
// 업로드파일 삭제 // 업로드파일 삭제
public function removeUploadFile() public function removeUploadFile()
{ {
@@ -1016,17 +1181,76 @@ class Receipt extends BaseController
$lib->deleteFile($thumbPath); $lib->deleteFile($thumbPath);
} }
$this->model->removeUploadFile($rcpt_sq, $img_sq); $result = $this->model->removeUploadFile($rcpt_sq, $img_sq);
if (!$result['success']) {
return $this->response->setJSON([
'code' => '1',
'msg' => $result['msg'] ?? '삭제 실패'
]);
}
return $this->response->setJSON([ return $this->response->setJSON([
'code' => '0', 'code' => '0',
'msg' => 'success' 'msg' => 'success'
]); ]);
} catch (\Exception $e) { } catch (\Exception $e) {
log_message('error', 'removeUploadFile error: ' . $e->getMessage());
return $this->response->setJSON([
'code' => '1',
'msg' => '삭제 중 에러가 발생했습니다: ' . $e->getMessage()
]);
}
}
// 이미지 순서 업데이트
public function updateImageOrder()
{
try {
$rcpt_sq = $this->request->getPost('rcpt_sq');
$img_type = $this->request->getPost('img_type');
$orders = $this->request->getPost('orders');
log_message('info', '[updateImageOrder] 요청 데이터 - rcpt_sq: ' . $rcpt_sq . ', img_type: ' . $img_type . ', orders: ' . $orders);
if (!$rcpt_sq || !$img_type || !$orders) {
log_message('error', '[updateImageOrder] 필수 파라미터 누락');
return $this->response->setJSON([
'code' => '1',
'msg' => '필수 파라미터가 누락되었습니다.'
]);
}
// JSON 파싱
$orderData = json_decode($orders, true);
if (!is_array($orderData)) {
return $this->response->setJSON([
'code' => '1',
'msg' => '순서 데이터 형식이 올바르지 않습니다.'
]);
}
// 순서 업데이트
$result = $this->model->updateImageOrder($rcpt_sq, $img_type, $orderData);
if (!$result['success']) {
return $this->response->setJSON([
'code' => '1',
'msg' => $result['msg'] ?? '순서 업데이트 실패'
]);
}
return $this->response->setJSON([ return $this->response->setJSON([
'code' => '0', 'code' => '0',
'msg' => 'success' 'success' => true,
'msg' => '순서가 저장되었습니다.'
]);
} catch (\Exception $e) {
log_message('error', 'updateImageOrder error: ' . $e->getMessage());
return $this->response->setJSON([
'code' => '1',
'msg' => '순서 업데이트 중 에러가 발생했습니다: ' . $e->getMessage()
]); ]);
} }
} }

View File

@@ -49,7 +49,6 @@ class Common
$wmTextAlpha = 0.5; // 워터마크 텍스트 투명도 $wmTextAlpha = 0.5; // 워터마크 텍스트 투명도
try { try {
$img = new \Imagick(); $img = new \Imagick();
if (is_string($imagePath) && is_file($imagePath)) { if (is_string($imagePath) && is_file($imagePath)) {
$img->readImage($imagePath); $img->readImage($imagePath);
@@ -96,19 +95,23 @@ class Common
} }
} }
if (empty($wmImagePath)) if (empty($wmImagePath)) {
return; return;
}
// 워터마크 이미지 경로 처리
if (substr($wmImagePath, 0, 1) == '/') { if (substr($wmImagePath, 0, 1) == '/') {
$wmImagePath = substr($wmImagePath, 1); $wmImagePath = substr($wmImagePath, 1);
} }
// ROOTPATH와 결합하여 절대 경로 생성 (img 폴더는 프로젝트 루트에 있음)
$fullWmPath = ROOTPATH . $wmImagePath;
// echo FCPATH.$wmImagePath; if (!is_file($fullWmPath)) {
return;
}
$wm = new \Imagick($fullWmPath);
$wm = new \Imagick($wmImagePath);
$hWm = $wm->getImageHeight(); $hWm = $wm->getImageHeight();
$wWm = $wm->getImageWidth(); $wWm = $wm->getImageWidth();
@@ -119,12 +122,16 @@ class Common
$img->compositeImage($wm, \Imagick::COMPOSITE_OVER, $wmImgLeft, $wmImgTop); $img->compositeImage($wm, \Imagick::COMPOSITE_OVER, $wmImgLeft, $wmImgTop);
$wm->destroy(); $wm->destroy();
// 워터마크 텍스트가 있는 경우에만 텍스트 그리기
if (!empty($wmText)) {
$draw = new \ImagickDraw(); $draw = new \ImagickDraw();
$basePath = defined('BASEPATH') ? BASEPATH : (defined('ROOTPATH') ? ROOTPATH . 'system/' : ''); // 폰트 경로: img/watermark/fonts/
$wmFont = $basePath . 'fonts/' . $wmFont; if (!empty($wmFont)) {
if (is_file($wmFont)) { $fontPath = ROOTPATH . 'img/watermark/fonts/' . $wmFont;
$draw->setFont($wmFont); if (is_file($fontPath)) {
$draw->setFont($fontPath);
}
} }
$draw->setFontSize($wmFontSize); $draw->setFontSize($wmFontSize);
@@ -141,6 +148,7 @@ class Common
$img->drawImage($draw); $img->drawImage($draw);
$draw->destroy(); $draw->destroy();
}
// $img->writeImage(); // $img->writeImage();
@@ -149,14 +157,9 @@ class Common
if (empty($key)) { if (empty($key)) {
throw new \RuntimeException('Empty upload key'); throw new \RuntimeException('Empty upload key');
} }
$ok = $uploader->upload_object_storage_imagick2($key, $watermark_img); $ok = $uploader->upload_object_storage_imagick2($key, $watermark_img);
if ($ok) { if (!$ok) {
log_message('info', '[watermarking] upload success key={key} size={size} cpid={cpid}', [
'key' => $key,
'size' => strlen($watermark_img),
'cpid' => $cpid,
]);
} else {
log_message('error', '[watermarking] upload failed key={key} cpid={cpid}', [ log_message('error', '[watermarking] upload failed key={key} cpid={cpid}', [
'key' => $key, 'key' => $key,
'cpid' => $cpid, 'cpid' => $cpid,
@@ -166,7 +169,11 @@ class Common
// $object_upload = $this->upload->upload_object_storage($imagePath , $imagePath , 'data'); // $object_upload = $this->upload->upload_object_storage($imagePath , $imagePath , 'data');
} catch (\Throwable $e) { } catch (\Throwable $e) {
log_message('error', '[watermarking] ' . $e->getMessage()); log_message('error', '[watermarking] Exception: {message} at {file}:{line}', [
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
]);
} }
} }

View File

@@ -54,7 +54,7 @@ class MyUpload
} }
/** /**
* 파일 업로드 요청 * 파일 업로드 요청 (Object Storage 전용)
* 추가일 2025.12.24 * 추가일 2025.12.24
* 작성자 - yangsh * 작성자 - yangsh
*/ */
@@ -73,39 +73,40 @@ class MyUpload
$newName = $file->getRandomName(); $newName = $file->getRandomName();
// ✅ PHP 임시 업로드 파일 경로 (writable로 move() 필요 없음) // ✅ PHP 임시 업로드 파일 경로
$tmpFile = $file->getTempName(); $tmpFile = $file->getTempName();
if (!is_file($tmpFile)) { if (!is_file($tmpFile)) {
$this->set_error('upload_temp_file_missing'); $this->set_error('upload_temp_file_missing');
log_message('error', 'do_upload2 temp file missing: ' . $tmpFile); log_message('error', '[MyUpload] Temp file missing: ' . $tmpFile);
return false; return false;
} }
// ✅ 클라우드에 올라갈 "Key"를 직접 만든다 (로컬 경로 절대 넣지 말기) // ✅ 클라우드에 올라갈 "Key"
// 예시: upload/tmp/랜덤파일명 또는 upload/apt_file/{rcpt_no}/...
$objectKey = $filePath . $newName; $objectKey = $filePath . $newName;
// 클라우드 업로드 (필수)
$up = $this->upload_object_storage($objectKey, $tmpFile, 'file'); $up = $this->upload_object_storage($objectKey, $tmpFile, 'file');
if ($up === false) { if ($up === false) {
$this->set_error('upload_destination_cloud_error'); $this->set_error('cloud_upload_failed');
log_message('error', '[MyUpload] Cloud upload failed: ' . $objectKey);
@unlink($tmpFile);
return false; return false;
} }
// (선택) tmp 파일 삭제 // tmp 파일 삭제
@unlink($tmpFile); @unlink($tmpFile);
$this->s3_data = [ $this->s3_data = [
'object_key' => $objectKey, 'object_key' => $objectKey,
'object_storage_url' => $up['object_storage_url'] ?? null, 'object_storage_url' => $up['object_storage_url'] ?? null,
'origin_name' => $file->getClientName(), 'origin_name' => $file->getClientName(),
'file_name' => basename($objectKey), // xxxx.jpg 'file_name' => basename($objectKey),
'base_name' => pathinfo($objectKey, PATHINFO_FILENAME), // xxxx 'base_name' => pathinfo($objectKey, PATHINFO_FILENAME),
'ext' => pathinfo($objectKey, PATHINFO_EXTENSION), // jpg 'ext' => pathinfo($objectKey, PATHINFO_EXTENSION),
]; ];
log_message('info', '[MyUpload] Cloud upload success: ' . $objectKey);
log_message('debug', 's3_data=' . json_encode($this->s3_data ?? null, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
return $this->s3_data; return $this->s3_data;
} }
@@ -386,6 +387,7 @@ class MyUpload
'Key' => ltrim($object_storage_upload_path, '/'), 'Key' => ltrim($object_storage_upload_path, '/'),
'Body' => $blobData, 'Body' => $blobData,
'ACL' => 'public-read', 'ACL' => 'public-read',
'ContentType' => 'image/jpeg',
]); ]);

View File

@@ -0,0 +1,154 @@
<?php
namespace App\Models\Entities;
use CodeIgniter\Model;
class WatermarkModel extends Model
{
protected $table = 'watermark';
protected $primaryKey = ['cpid', 'wm_type']; // 복합키
protected $useAutoIncrement = false;
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $allowedFields = [
'cpid',
'wm_type',
'wm_img_path',
'wm_img_height',
'wm_img_width',
'wm_position',
'wm_img_opacity',
'wm_space',
'text_font',
'text_color',
'text_opacity',
'text_size',
'text_pixel',
'img_width_min',
'img_width_max'
];
protected $useTimestamps = false;
protected $validationRules = [
'cpid' => 'required|max_length[20]',
'wm_type' => 'required|integer',
'wm_img_path' => 'required|max_length[300]',
'wm_img_height' => 'required|integer',
'wm_img_width' => 'required|integer',
'wm_position' => 'required|max_length[2]',
'wm_img_opacity' => 'required|integer',
'wm_space' => 'required|integer',
'img_width_min' => 'required|integer',
'img_width_max' => 'required|integer'
];
protected $validationMessages = [];
protected $skipValidation = false;
/**
* 워터마크 정보 조회 (복합키)
*
* @param string $cpid
* @param int $wm_type
* @return array|null
*/
public function getWatermark($cpid, $wm_type)
{
return $this->where('cpid', $cpid)
->where('wm_type', $wm_type)
->first();
}
/**
* cpid로 워터마크 목록 조회
*
* @param string $cpid
* @return array
*/
public function getWatermarksByCpid($cpid)
{
return $this->where('cpid', $cpid)->findAll();
}
/**
* 워터마크 타입별 조회
*
* @param int $wm_type
* @return array
*/
public function getWatermarksByType($wm_type)
{
return $this->where('wm_type', $wm_type)->findAll();
}
/**
* 워터마크 정보 저장/업데이트
*
* @param array $data
* @return bool
*/
public function saveWatermark($data)
{
if (!isset($data['cpid']) || !isset($data['wm_type'])) {
return false;
}
// 복합키로 기존 데이터 확인
$existing = $this->getWatermark($data['cpid'], $data['wm_type']);
if ($existing) {
// 업데이트
return $this->where('cpid', $data['cpid'])
->where('wm_type', $data['wm_type'])
->set($data)
->update();
} else {
// 삽입
return $this->insert($data);
}
}
/**
* 워터마크 삭제 (복합키)
*
* @param string $cpid
* @param int $wm_type
* @return bool
*/
public function deleteWatermark($cpid, $wm_type)
{
return $this->where('cpid', $cpid)
->where('wm_type', $wm_type)
->delete();
}
/**
* cpid로 모든 워터마크 삭제
*
* @param string $cpid
* @return bool
*/
public function deleteAllByCpid($cpid)
{
return $this->where('cpid', $cpid)->delete();
}
/**
* 이미지 크기 범위로 워터마크 조회
*
* @param string $cpid
* @param int $img_width
* @return array|null
*/
public function getWatermarkByImageSize($cpid, $img_width)
{
return $this->where('cpid', $cpid)
->where('img_width_min <=', $img_width)
->where('img_width_max >=', $img_width)
->findAll();
}
}

View File

@@ -409,10 +409,9 @@ class ReceiptModel extends Model
} }
// log_message('debug', '[getTotalCount] SQL = ' . $builder->getCompiledSelect());
$row = $builder->get()->getRowArray(); $row = $builder->get()->getRowArray();
error_log('[getTotalCount] SQL = ' . $this->db->getLastQuery());
return (int) ($row['cnt'] ?? 0); return (int) ($row['cnt'] ?? 0);
} }
@@ -538,10 +537,10 @@ class ReceiptModel extends Model
$builder->join('result b', 'b.rcpt_sq = a.rcpt_sq', 'inner'); $builder->join('result b', 'b.rcpt_sq = a.rcpt_sq', 'inner');
$builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'inner'); $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'inner');
$builder->join('departments d', 'b.dept_sq = d.dept_sq', 'left'); $builder->join('departments d', 'b.dept_sq = d.dept_sq', 'left outer');
$builder->join('users u', 'b.usr_sq = u.usr_sq', 'left'); $builder->join('users u', 'b.usr_sq = u.usr_sq', 'left outer');
$builder->join('result_imgs e', "e.rsrv_sq = b.rsrv_sq AND e.img_type = 'I1' AND e.use_yn = 'Y'", 'left'); $builder->join('result_imgs e', "e.rsrv_sq = b.rsrv_sq AND e.img_type = 'I1' AND e.use_yn = 'Y'", 'left outer');
$builder->join('receipt_transimage_log l', 'a.rcpt_key = l.rcpt_key', 'left'); $builder->join('receipt_transimage_log l', 'a.rcpt_key = l.rcpt_key', 'left outer');
$login_dept_info = $this->getDeptDetail($dept_sq); // 로그인 사용자 소속부서정보 $login_dept_info = $this->getDeptDetail($dept_sq); // 로그인 사용자 소속부서정보
@@ -573,8 +572,8 @@ class ReceiptModel extends Model
$builder->where('a.rcpt_tm >=', $data['sdate'] . ' 00:00:00'); $builder->where('a.rcpt_tm >=', $data['sdate'] . ' 00:00:00');
$builder->where('a.rcpt_tm <=', $data['edate'] . ' 23:59:59'); $builder->where('a.rcpt_tm <=', $data['edate'] . ' 23:59:59');
} else { } else {
$builder->where('b.rsrv_date >=', $data['sdate'] . ' 00:00:00'); $builder->where('b.rsrv_date >=', $data['sdate'] );
$builder->where('b.rsrv_date <=', $data['edate'] . ' 23:59:59'); $builder->where('b.rsrv_date <=', $data['edate'] );
} }
// 지역 // 지역
@@ -753,9 +752,12 @@ class ReceiptModel extends Model
$builder->limit($end, $start); $builder->limit($end, $start);
// log_message('debug', '[getResultList] SQL = ' . $builder->getCompiledSelect()); $result = $builder->get()->getResultArray();
return $builder->get()->getResultArray(); error_log('[getResultList] SQL = ' . $this->db->getLastQuery());
error_log('[getResultList] Result count = ' . count($result));
return $result;
} }
@@ -1837,7 +1839,8 @@ class ReceiptModel extends Model
$receipt = $param['receipt']; $receipt = $param['receipt'];
$cloud_upload_yn = 'Y'; // 실제 클라우드 업로드 성공 여부를 파라미터에서 받아옴 (기본값 'Y')
$cloud_upload_yn = $param['cloud_upload_yn'] ?? 'Y';
if ($param['img_type'] == 'I6' || $param['img_type'] == 'I7') { if ($param['img_type'] == 'I6' || $param['img_type'] == 'I7') {
$yn_sql = "update receipt " . $yn_sql = "update receipt " .
@@ -2011,7 +2014,15 @@ class ReceiptModel extends Model
// 이미지정보 조회 // 이미지정보 조회
$row = $this->getUploadFileInfo($img_sq); $row = $this->getUploadFileInfo($img_sq);
if (!empty($row)) { if (empty($row)) {
$this->db->transComplete();
// 파일이 이미 삭제된 경우 성공으로 처리 (중복 삭제 요청 방지)
log_message('info', "[removeUploadFile] 파일 정보 없음 (이미 삭제됨): img_sq={$img_sq}");
return [
'success' => true,
'msg' => '이미 삭제된 파일입니다',
];
}
if ($row['img_type'] == 'I6' || $row['img_type'] == 'I7') { if ($row['img_type'] == 'I6' || $row['img_type'] == 'I7') {
$yn_sql = "update receipt " . $yn_sql = "update receipt " .
@@ -2027,7 +2038,7 @@ class ReceiptModel extends Model
" AND use_yn = 'Y'" . " AND use_yn = 'Y'" .
" AND img_type = 'I8') WHEN 0 THEN 'N' ELSE 'Y' END" . " AND img_type = 'I8') WHEN 0 THEN 'N' ELSE 'Y' END" .
" WHERE rcpt_sq = ? "; " WHERE rcpt_sq = ? ";
$yn_data = [$rcpt_sq]; $yn_data = [$img_sq, $rcpt_sq];
$this->db->query($yn_sql, $yn_data); $this->db->query($yn_sql, $yn_data);
} else if ($row['img_type'] == 'I9') { } else if ($row['img_type'] == 'I9') {
$yn_sql = "UPDATE receipt" . $yn_sql = "UPDATE receipt" .
@@ -2041,7 +2052,7 @@ class ReceiptModel extends Model
" END" . " END" .
" )" . " )" .
" WHERE rcpt_sq = ?"; " WHERE rcpt_sq = ?";
$yn_data = [$rcpt_sq]; $yn_data = [$img_sq, $rcpt_sq];
$this->db->query($yn_sql, $yn_data); $this->db->query($yn_sql, $yn_data);
} else if ($row['img_type'] == 'I11') { } else if ($row['img_type'] == 'I11') {
$yn_sql = "update receipt " . $yn_sql = "update receipt " .
@@ -2049,28 +2060,19 @@ class ReceiptModel extends Model
" where rcpt_sq = ? "; " where rcpt_sq = ? ";
$yn_data = [$rcpt_sq]; $yn_data = [$rcpt_sq];
$this->db->query($yn_sql, $yn_data); $this->db->query($yn_sql, $yn_data);
} }
//삭제이미지보다 순번이 높은거는 순번 업데이트 //삭제이미지보다 순번이 높은거는 순번 업데이트
$sql = "UPDATE result_imgs SET view_odr = view_odr - 1 WHERE rsrv_sq = ? AND img_type = ? AND view_odr > ? AND use_yn = 'Y'"; $sql = "UPDATE result_imgs SET view_odr = view_odr - 1 WHERE rsrv_sq = ? AND img_type = ? AND view_odr > ? AND use_yn = 'Y'";
$data = [$row['rsrv_sq'], $row['img_type'], $row['view_odr']]; $data = [$row['rsrv_sq'], $row['img_type'], $row['view_odr']];
$this->db->query($sql, $data); $this->db->query($sql, $data);
//이미지 삭제 //이미지 삭제
$sql = "DELETE FROM result_imgs WHERE img_sq = ?"; $sql = "DELETE FROM result_imgs WHERE img_sq = ?";
$data = [$img_sq]; $data = [$img_sq];
if ($this->db->query($sql, $data) === false) { $deleteResult = $this->db->query($sql, $data);
return [
'success' => false,
'msg' => '삭제실패',
];
}
if (in_array($row['img_type'], ['I1', 'I2', 'I8', 'I10', 'I11'])) { if (in_array($row['img_type'], ['I1', 'I2', 'I8', 'I10', 'I11'])) {
$remark = ""; $remark = "";
@@ -2096,18 +2098,77 @@ class ReceiptModel extends Model
$sql = "SELECT rcpt_stat FROM receipt WHERE rcpt_sq = ?"; $sql = "SELECT rcpt_stat FROM receipt WHERE rcpt_sq = ?";
$data = [$rcpt_sq]; $data = [$rcpt_sq];
$query = $this->db->query($sql, $data); $query = $this->db->query($sql, $data);
$row = $query->getRowArray(); $rowStat = $query->getRowArray();
$this->saveChangedHistory($rcpt_sq, $row['rcpt_stat'], 'C31', $usr_id, $remark); $this->saveChangedHistory($rcpt_sq, $rowStat['rcpt_stat'], 'C31', $usr_id, $remark);
} }
$this->db->transComplete(); $this->db->transComplete();
if ($deleteResult === false || $this->db->transStatus() === false) {
return [
'success' => false,
'msg' => '삭제실패',
];
}
return [
'success' => true,
];
}
// 이미지 순서 업데이트
public function updateImageOrder($rcpt_sq, $img_type, $orderData)
{
log_message('info', '[ReceiptModel::updateImageOrder] 시작 - rcpt_sq: ' . $rcpt_sq . ', img_type: ' . $img_type . ', 개수: ' . count($orderData));
$this->db->transStart();
try {
$updateCount = 0;
foreach ($orderData as $item) {
$img_sq = $item['img_sq'] ?? null;
$view_odr = $item['view_odr'] ?? null;
if (!$img_sq || !$view_odr) {
log_message('warning', '[ReceiptModel::updateImageOrder] 스킵 - img_sq 또는 view_odr 없음');
continue;
}
$sql = "UPDATE result_imgs SET view_odr = ? WHERE img_sq = ? AND img_type = ?";
$data = [$view_odr, $img_sq, $img_type];
log_message('debug', '[ReceiptModel::updateImageOrder] 업데이트 - img_sq: ' . $img_sq . ', view_odr: ' . $view_odr);
$result = $this->db->query($sql, $data);
if ($result) {
$updateCount++;
}
}
$this->db->transComplete();
if ($this->db->transStatus() === false) {
log_message('error', '[ReceiptModel::updateImageOrder] 트랜잭션 실패');
return [
'success' => false,
'msg' => '순서 업데이트 실패',
];
}
log_message('info', '[ReceiptModel::updateImageOrder] 완료 - 업데이트 수: ' . $updateCount);
return [ return [
'success' => true, 'success' => true,
]; ];
} catch (\Exception $e) {
log_message('error', '[ReceiptModel::updateImageOrder] Exception: ' . $e->getMessage());
return [
'success' => false,
'msg' => '순서 업데이트 중 오류 발생: ' . $e->getMessage(),
];
} }
} }

View File

@@ -40,8 +40,8 @@ class TypeSParameterMapper extends BaseParameterMapper
'rcpt_product_info5' => $price['premiumAmount'] ?? '0', 'rcpt_product_info5' => $price['premiumAmount'] ?? '0',
'rcpt_living_yn' => ($rawData['site']['isRegistration'] ?? false) ? 'Y' : 'N', 'rcpt_living_yn' => ($rawData['site']['isRegistration'] ?? false) ? 'Y' : 'N',
'rcpt_agent' => $realtor['realtorName'] ?? null, 'rcpt_agent' => $realtor['realtorName'] ?? null,
'rcpt_sido' => mb_substr($address['legalDivision']['cityNumber'] ?? '', 0, 5), 'rcpt_sido' => $address['legalDivision']['cityNumber'] ?? null,
'rcpt_gugun' => mb_substr($address['legalDivision']['divisionNumber'] ?? '', 0, 10), 'rcpt_gugun' => $address['legalDivision']['divisionNumber'] ?? null,
'rcpt_dong' => $address['legalDivision']['sectorNumber'] ?? null, 'rcpt_dong' => $address['legalDivision']['sectorNumber'] ?? null,
'rcpt_hscp_nm' => $address['complexName'] ?? null, 'rcpt_hscp_nm' => $address['complexName'] ?? null,
'rcpt_hscp_no' => $address['complexNumber'] ?? null, 'rcpt_hscp_no' => $address['complexNumber'] ?? null,

File diff suppressed because it is too large Load Diff

View File

@@ -103,30 +103,35 @@ $usr_nm = session('usr_nm');
} }
</style> </style>
<h1>확인매물 현황</h1>
<div class="col-md-12 col-xl-12"> <div class="col-md-12 col-xl-12">
<div class="main-card mb-3 card"> <div class="main-card mb-3 card">
<div class="card-header bg-white border-bottom shadow-sm">
<div class="d-flex flex-wrap align-items-center gap-3 card-header-tab">
<div>
<h4 class="mb-0 fw-bold text-dark">확인매물 현황</h4>
</div>
</div>
</div>
<div class="card-body"> <div class="card-body">
<form id="frm_srch_info" method="get" onsubmit="return false;"> <form id="frm_srch_info" method="get" onsubmit="return false;">
<!-- 검색 폼 --> <!-- 검색 폼 -->
<div class="row g-3"> <div class="row g-3">
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">매물ID</label> <label class="form-label mb-1">매물ID</label>
<input type="text" class="form-control" name="rcpt_atclno" id="rcpt_atclno" <input type="text" class="form-control form-control-sm" name="rcpt_atclno" id="rcpt_atclno"
onkeypress="atcl_no_enter(event)"> onkeypress="atcl_no_enter(event)">
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<label class="form-label mb-1">일자별조회</label> <label class="form-label mb-1">일자별조회</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<select class="form-select" name="schDateGb"> <select class="form-select form-select-sm" name="schDateGb">
<option value="1" selected>예약일자</option> <option value="1" selected>예약일자</option>
<option value="2">등록일자</option> <option value="2">등록일자</option>
</select> </select>
<input type="date" class="form-control" name="sdate" id="sdate" placeholder="시작일"> <input type="date" class="form-control form-control-sm" name="sdate" id="sdate" placeholder="시작일">
<span class="input-group-text">~</span> <span class="input-group-text">~</span>
<input type="date" class="form-control" name="edate" id="edate" placeholder="종료일"> <input type="date" class="form-control form-control-sm" name="edate" id="edate" placeholder="종료일">
</div> </div>
</div> </div>
@@ -193,7 +198,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">거래구분</label> <label class="form-label mb-1">거래구분</label>
<select class="form-select" name="rcpt_product_info1"> <select class="form-select form-select-sm" name="rcpt_product_info1">
<option value="">전체</option> <option value="">전체</option>
<?php foreach ($codes as $c): ?> <?php foreach ($codes as $c): ?>
<?php if ($c['category'] === "NHN_DEAL_TYPE"): ?> <?php if ($c['category'] === "NHN_DEAL_TYPE"): ?>
@@ -205,7 +210,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">동영상촬영여부</label> <label class="form-label mb-1">동영상촬영여부</label>
<select class="form-select" name="exp_movie_yn"> <select class="form-select form-select-sm" name="exp_movie_yn">
<option value="">전체</option> <option value="">전체</option>
<option value="Y">촬영</option> <option value="Y">촬영</option>
<option value="N">미촬영</option> <option value="N">미촬영</option>
@@ -214,7 +219,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">홍보확인서여부</label> <label class="form-label mb-1">홍보확인서여부</label>
<select class="form-select" name="conf_img_yn"> <select class="form-select form-select-sm" name="conf_img_yn">
<option value="">전체</option> <option value="">전체</option>
<option value="Y">Y</option> <option value="Y">Y</option>
<option value="N">N</option> <option value="N">N</option>
@@ -223,7 +228,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">분양권</label> <label class="form-label mb-1">분양권</label>
<select class="form-select" name="parcel_out_yn"> <select class="form-select form-select-sm" name="parcel_out_yn">
<option value="">전체</option> <option value="">전체</option>
<option value="Y"> Y</option> <option value="Y"> Y</option>
<option value="N"> N</option> <option value="N"> N</option>
@@ -232,7 +237,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">CP ID</label> <label class="form-label mb-1">CP ID</label>
<select class="form-select" name="rcpt_cpid"> <select class="form-select form-select-sm" name="rcpt_cpid">
<option value="">전체</option> <option value="">전체</option>
<?php foreach ($codes as $c): ?> <?php foreach ($codes as $c): ?>
<?php if ($c['category'] === "CP_ID"): ?> <?php if ($c['category'] === "CP_ID"): ?>
@@ -244,7 +249,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">매물종류</label> <label class="form-label mb-1">매물종류</label>
<select class="form-select" name="rcpt_product"> <select class="form-select form-select-sm" name="rcpt_product">
<option value="">전체</option> <option value="">전체</option>
<?php foreach ($codes as $c): ?> <?php foreach ($codes as $c): ?>
<?php if ($c['category'] === "ARTICLE_TYPE"): ?> <?php if ($c['category'] === "ARTICLE_TYPE"): ?>
@@ -256,7 +261,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">면적확인</label> <label class="form-label mb-1">면적확인</label>
<select class="form-select" name="exp_spc_yn"> <select class="form-select form-select-sm" name="exp_spc_yn">
<option value="">전체</option> <option value="">전체</option>
<option value="Y"> Y</option> <option value="Y"> Y</option>
<option value="N"> N</option> <option value="N"> N</option>
@@ -265,7 +270,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">체크리스트</label> <label class="form-label mb-1">체크리스트</label>
<select class="form-select" name="check_list_img_yn"> <select class="form-select form-select-sm" name="check_list_img_yn">
<option value="">전체</option> <option value="">전체</option>
<option value="Y"> Y <option value="Y"> Y
</option> </option>
@@ -276,7 +281,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">평면도유무</label> <label class="form-label mb-1">평면도유무</label>
<select class="form-select" name="ground_plan_yn"> <select class="form-select form-select-sm" name="ground_plan_yn">
<option value="">전체</option> <option value="">전체</option>
<option value="Y">Y</option> <option value="Y">Y</option>
<option value="N">N</option> <option value="N">N</option>
@@ -285,7 +290,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">평면도요청</label> <label class="form-label mb-1">평면도요청</label>
<select class="form-select" name="ground_plan"> <select class="form-select form-select-sm" name="ground_plan">
<option value="">전체</option> <option value="">전체</option>
<option value="Y">Y</option> <option value="Y">Y</option>
<option value="N">N</option> <option value="N">N</option>
@@ -294,7 +299,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">직거래</label> <label class="form-label mb-1">직거래</label>
<select class="form-select" name="direct_trad_yn"> <select class="form-select form-select-sm" name="direct_trad_yn">
<option value="">전체</option> <option value="">전체</option>
<option value="Y">Y</option> <option value="Y">Y</option>
<option value="N">N</option> <option value="N">N</option>
@@ -303,7 +308,7 @@ $usr_nm = session('usr_nm');
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">360촬영여부</label> <label class="form-label mb-1">360촬영여부</label>
<select class="form-select" name="image_360_yn"> <select class="form-select form-select-sm" name="image_360_yn">
<option value="">전체</option> <option value="">전체</option>
<option value="Y">Y</option> <option value="Y">Y</option>
<option value="N">N</option> <option value="N">N</option>
@@ -313,7 +318,7 @@ $usr_nm = session('usr_nm');
<!-- 검색유형 --> <!-- 검색유형 -->
<div class="col-md-1"> <div class="col-md-1">
<label class="form-label mb-1">검색유형</label> <label class="form-label mb-1">검색유형</label>
<select class="form-select" name="srchType"> <select class="form-select form-select-sm" name="srchType">
<option value="">선택</option> <option value="">선택</option>
<option value="1">중개사명</option> <option value="1">중개사명</option>
<option value="2">주소</option> <option value="2">주소</option>
@@ -324,7 +329,7 @@ $usr_nm = session('usr_nm');
<!-- 검색어 --> <!-- 검색어 -->
<div class="col-md-2"> <div class="col-md-2">
<label class="form-label mb-1">검색어</label> <label class="form-label mb-1">검색어</label>
<input type="text" class="form-control" name="srchTxt" placeholder="검색어 입력"> <input type="text" class="form-control form-control-sm" name="srchTxt" placeholder="검색어 입력">
</div> </div>
<div class="col-md-1 d-grid"> <div class="col-md-1 d-grid">
@@ -341,18 +346,17 @@ $usr_nm = session('usr_nm');
</div> </div>
<div class="main-card mb-3 card"> <div class="main-card mb-3 card">
<div class="card-header d-flex align-items-center"> <div class="card-header bg-white border-bottom shadow-sm">
<div class="d-flex align-items-center flex-wrap" style="gap: 8px; flex: 1"> <div class="d-flex flex-wrap align-items-center w-100 justify-content-between card-header-tab">
<h5 class="mb-0 fw-bold text-dark">검색 결과</h5>
</div> <div class="d-flex align-items-center gap-2 ms-auto">
<div class="ml-auto">
<button class="btn btn-sm btn-outline-success" id="excel-download"> <button class="btn btn-sm btn-outline-success" id="excel-download">
<i class="fa fa-fw" aria-hidden="true" title="file-excel-o"></i> <i class="fa fa-fw" aria-hidden="true" title="file-excel-o"></i>
엑셀다운로드 엑셀다운로드
</button> </button>
</div> </div>
</div> </div>
</div>
<div class="card-body"> <div class="card-body">
<div class="table-responsive"> <div class="table-responsive">
<table id="resultList" class="table table-hover table-striped table-bordered"> <table id="resultList" class="table table-hover table-striped table-bordered">

8
check_watermark.sql Normal file
View File

@@ -0,0 +1,8 @@
-- watermark 테이블 데이터 확인
SELECT * FROM watermark;
-- 특정 cpid의 워터마크 확인 (cpid를 실제 값으로 변경)
SELECT * FROM watermark WHERE cpid = 'YOUR_CPID';
-- receipt 테이블에서 comp_sq 확인
SELECT rcpt_sq, rcpt_cpid, comp_sq FROM receipt LIMIT 10;

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
img/watermark/KAB_TYPE1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
img/watermark/KAB_TYPE2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
img/watermark/KAB_TYPE3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
img/watermark/LEE_TYPE1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
img/watermark/LEE_TYPE2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
img/watermark/LEE_TYPE3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
img/watermark/TEN_TYPE1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
img/watermark/TEN_TYPE2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
img/watermark/TEN_TYPE3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Some files were not shown because too many files have changed in this diff Show More