2405 lines
78 KiB
JavaScript
2405 lines
78 KiB
JavaScript
// 거주인 녹취정보 상세 페이지 JavaScript
|
|
// 외부 의존성: jQuery, Bootstrap 5, SweetAlert2, Naver Maps, Dropzone 6.0, Sortable.js 1.15
|
|
|
|
var map;
|
|
var dz = null; // Dropzone 인스턴스
|
|
var sortable = null; // Sortable 인스턴스
|
|
|
|
$(function () {
|
|
|
|
// trade_type_onchange();
|
|
|
|
if (isDefined(window.rcpt_hscp_nm)) {
|
|
$(".spc").hide();
|
|
}
|
|
|
|
map = new naver.maps.Map('mapArea', {
|
|
center: new naver.maps.LatLng(window.lat, window.lng),
|
|
useStyleMap: true,
|
|
zoom: 17,
|
|
minZoom: 10,
|
|
mapTypeControl: true,
|
|
mapTypeControlOptions: {
|
|
style: naver.maps.MapTypeControlStyle.BUTTON,
|
|
position: naver.maps.Position.TOP_LEFT
|
|
},
|
|
zoomControl: true,
|
|
zoomControlOptions: {
|
|
position: naver.maps.Position.TOP_RIGHT
|
|
}
|
|
});
|
|
|
|
marker = new naver.maps.Marker({
|
|
position: new naver.maps.LatLng(window.lat, window.lng),
|
|
map: map
|
|
});
|
|
|
|
// Dropzone auto discover 비활성화
|
|
Dropzone.autoDiscover = false;
|
|
|
|
// 파일업로드 open
|
|
$("#btnUploadModal").on("click", function () {
|
|
$("#uploadModal").modal("show");
|
|
});
|
|
|
|
});
|
|
|
|
//공백 값 체크
|
|
function isDefined(str) {
|
|
var isResult = false;
|
|
str_temp = str + "";
|
|
str_temp = str_temp.replace(" ", "");
|
|
if (str_temp != "undefined" && str_temp != "" && str_temp != "null") {
|
|
isResult = true;
|
|
}
|
|
|
|
return isResult;
|
|
}
|
|
|
|
// 부모 창에서 삭제된 이미지 제거하는 함수
|
|
function removeImageFromParent(imgType, imgSq) {
|
|
console.log('[removeImageFromParent] 이미지 제거:', imgType, imgSq);
|
|
|
|
// 이미지 타입에 따라 다른 처리
|
|
switch(imgType) {
|
|
case 'I1': // 홍보확인서 - 단일 이미지를 photo.gif로 변경
|
|
$('#photo-display2_I1').attr('src', '/plugin/img/photo.gif')
|
|
.parent('a').replaceWith('<img id="photo-display2_I1" src="/plugin/img/photo.gif" alt="홍보확인서" class="w-100 object-fit-contain">');
|
|
break;
|
|
|
|
case 'I8': // 분양권 - 해당 div 제거
|
|
$('img[src*="' + imgSq + '"]').closest('div[style*="width: 150px"]').remove();
|
|
break;
|
|
|
|
case 'I4': // 매물사진 - 해당 thumb-card 제거
|
|
$('input[name="i4_seq[]"][value="' + imgSq + '"]').closest('.thumb-card').remove();
|
|
break;
|
|
|
|
case 'I9': // 360이미지 - 해당 thumb-card 제거
|
|
$('input[name^="img_location_' + imgSq + '"]').closest('.thumb-card').remove();
|
|
break;
|
|
|
|
case 'I10': // 촬영동의서 - 이미지를 photo.gif로 변경
|
|
$('img[alt="촬영동의서"]').attr('src', '/plugin/img/photo.gif')
|
|
.parent('a').replaceWith('<img src="/plugin/img/photo.gif" alt="촬영동의서" class="w-100 object-fit-contain">');
|
|
break;
|
|
|
|
case 'I2': // 현장확인내역서 - 이미지를 photo.gif로 변경
|
|
$('img[alt="현장확인내역서"]').attr('src', '/plugin/img/photo.gif')
|
|
.parent('a').replaceWith('<img src="/plugin/img/photo.gif" alt="현장확인내역서" class="w-100 object-fit-contain">');
|
|
break;
|
|
|
|
case 'V1': // 동영상 - 이미지를 photo.gif로 변경
|
|
$('img[alt="동영상"]').attr('src', '/plugin/img/photo.gif')
|
|
.parent('a').replaceWith('<img src="/plugin/img/photo.gif" alt="동영상" class="w-100 object-fit-contain">');
|
|
break;
|
|
|
|
case 'I5': // 평면도 - 이미지를 photo.gif로 변경
|
|
$('img[alt="평면도"]').attr('src', '/plugin/img/photo.gif')
|
|
.parent('a').replaceWith('<img src="/plugin/img/photo.gif" alt="평면도" class="w-100 object-fit-contain">');
|
|
break;
|
|
|
|
case 'I11': // 체크리스트 - 이미지를 photo.gif로 변경
|
|
$('img[alt="체크리스트"]').attr('src', '/plugin/img/photo.gif')
|
|
.parent('a').replaceWith('<img src="/plugin/img/photo.gif" alt="체크리스트" class="w-100 object-fit-contain">');
|
|
break;
|
|
|
|
default:
|
|
console.log('[removeImageFromParent] 알 수 없는 이미지 타입:', imgType);
|
|
}
|
|
}
|
|
|
|
// 부모 창에 업로드된 이미지 추가/업데이트하는 함수
|
|
function updateImageInParent(imgType, imageData) {
|
|
console.log('[updateImageInParent] 이미지 업데이트:', imgType, imageData);
|
|
|
|
if (!imageData || !imageData.img_path || !imageData.img_filenm) {
|
|
console.error('[updateImageInParent] 이미지 데이터 부족:', imageData);
|
|
return;
|
|
}
|
|
|
|
// 이미지 URL 생성
|
|
const imgPath = imageData.img_path + imageData.img_filenm;
|
|
const thumbPath = imageData.img_path + imageData.img_filenm.replace(/\.\w+$/, '_thumb.jpg');
|
|
|
|
// 클라우드 URL 처리
|
|
const NCLOUD_URL = 'https://kr.object.ncloudstorage.com/confirms-object/';
|
|
const fullImageUrl = imageData.cloud_upload_yn === 'Y' ? NCLOUD_URL + imgPath : imgPath;
|
|
const thumbImageUrl = imageData.cloud_upload_yn === 'Y' ? NCLOUD_URL + thumbPath : thumbPath;
|
|
|
|
// 이미지 타입에 따라 다른 처리
|
|
switch(imgType) {
|
|
case 'I1': // 홍보확인서 - 단일 이미지 업데이트
|
|
const $i1Container = $('#photo-display2_I1').closest('.ratio');
|
|
$i1Container.html(`
|
|
<a onclick="fn_preview('${fullImageUrl}')">
|
|
<img id="photo-display2_I1" src="${fullImageUrl}" alt="홍보확인서" class="w-100 object-fit-contain">
|
|
</a>
|
|
`);
|
|
break;
|
|
|
|
case 'I10': // 촬영동의서
|
|
const $i10Container = $('img[alt="촬영동의서"]').closest('.ratio');
|
|
$i10Container.html(`
|
|
<a onclick="fn_preview('${fullImageUrl}')">
|
|
<img src="${thumbImageUrl}" alt="촬영동의서" class="w-100 object-fit-contain">
|
|
</a>
|
|
`);
|
|
break;
|
|
|
|
case 'I2': // 현장확인내역서
|
|
const $i2Container = $('img[alt="현장확인내역서"]').closest('.ratio');
|
|
$i2Container.html(`
|
|
<a onclick="fn_preview('${fullImageUrl}')">
|
|
<img src="${thumbImageUrl}" alt="현장확인내역서" class="w-100 object-fit-contain">
|
|
</a>
|
|
`);
|
|
break;
|
|
|
|
case 'I8': // 분양권 - 새 이미지 추가
|
|
const $i8Container = $('img[alt="분양권"]').closest('.d-flex');
|
|
// photo.gif인 placeholder 제거
|
|
$i8Container.find('img[src="/plugin/img/photo.gif"]').closest('div[style*="width: 150px"]').remove();
|
|
|
|
// 새 이미지 추가
|
|
const i8Html = `
|
|
<div style="width: 150px;">
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<a onclick="fn_preview('${fullImageUrl}')" class="d-flex align-items-center justify-content-center">
|
|
<img src="${thumbImageUrl}" alt="분양권" class="w-100 h-100 object-fit-contain">
|
|
</a>
|
|
</div>
|
|
</div>
|
|
`;
|
|
$i8Container.append(i8Html);
|
|
break;
|
|
|
|
case 'I4': // 매물사진 - 새 thumb-card 추가
|
|
const $i4Container = $('input[name="i4_order[]"]').closest('.d-flex');
|
|
// photo.gif인 placeholder 제거
|
|
$i4Container.find('img[src="/plugin/img/photo.gif"]').closest('.thumb-card').remove();
|
|
|
|
// 새 thumb-card 추가
|
|
const i4Html = `
|
|
<div class="thumb-card">
|
|
<input type="text" class="form-control form-control-sm mb-1" name="i4_order[]" size="3" value="${imageData.view_odr || '1'}" />
|
|
<input type="hidden" name="i4_seq[]" value="${imageData.img_sq}" size="2" />
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<a onclick="fn_preview('${fullImageUrl}')">
|
|
<img src="${thumbImageUrl}" alt="매물사진" class="w-100 h-100 object-fit-contain">
|
|
</a>
|
|
</div>
|
|
</div>
|
|
`;
|
|
$i4Container.append(i4Html);
|
|
break;
|
|
|
|
case 'I9': // 360이미지 - 새 thumb-card 추가
|
|
console.log('[updateImageInParent] I9 처리 시작', imageData);
|
|
|
|
// 360이미지 컨테이너 찾기
|
|
let $i9Container = $('.fw-semibold:contains("360이미지")').closest('.border').find('.d-flex.flex-wrap');
|
|
console.log('[updateImageInParent] I9 컨테이너 찾음:', $i9Container.length);
|
|
|
|
if ($i9Container.length === 0) {
|
|
console.error('[updateImageInParent] I9 컨테이너를 찾을 수 없습니다!');
|
|
break;
|
|
}
|
|
|
|
// placeholder 제거 (photo.gif가 있으면)
|
|
const $placeholder = $i9Container.find('img[src="/plugin/img/photo.gif"]').closest('.thumb-card');
|
|
if ($placeholder.length > 0) {
|
|
console.log('[updateImageInParent] I9 placeholder 제거');
|
|
$placeholder.remove();
|
|
}
|
|
|
|
// 새 이미지 추가
|
|
const i9Html = `
|
|
<div class="thumb-card">
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden mb-1">
|
|
<a onclick="fn_preview('${fullImageUrl}')" class="d-flex align-items-center justify-content-center">
|
|
<img src="${thumbImageUrl}" alt="360이미지" class="w-100 h-100 object-fit-contain">
|
|
</a>
|
|
</div>
|
|
<input class="form-control form-control-sm" type="text" name="img_location_${imageData.img_sq}"
|
|
id="img_location_${imageData.img_sq}" value="${imageData.img_location || ''}" size="11" style="width: 160px;" placeholder="촬영위치">
|
|
</div>
|
|
`;
|
|
console.log('[updateImageInParent] I9 이미지 추가');
|
|
$i9Container.append(i9Html);
|
|
break;
|
|
|
|
case 'V1': // 동영상
|
|
const $v1Container = $('img[alt="동영상"]').closest('.ratio');
|
|
$v1Container.html(`
|
|
<a onclick="fn_preview('${fullImageUrl}', 'vdo')">
|
|
<img src="/plugin/img/video.png" alt="동영상" class="w-100 object-fit-contain">
|
|
</a>
|
|
`);
|
|
break;
|
|
|
|
case 'I5': // 평면도
|
|
const $i5Container = $('img[alt="평면도"]').closest('.ratio');
|
|
$i5Container.html(`
|
|
<a onclick="fn_preview('${fullImageUrl}')">
|
|
<img src="${thumbImageUrl}" alt="평면도" class="w-100 object-fit-contain">
|
|
</a>
|
|
`);
|
|
break;
|
|
|
|
case 'I11': // 체크리스트
|
|
const $i11Container = $('img[alt="체크리스트"]').closest('.ratio');
|
|
$i11Container.html(`
|
|
<a onclick="fn_preview('${fullImageUrl}')">
|
|
<img src="${thumbImageUrl}" alt="체크리스트" class="w-100 object-fit-contain">
|
|
</a>
|
|
`);
|
|
break;
|
|
|
|
default:
|
|
console.log('[updateImageInParent] 알 수 없는 이미지 타입:', imgType);
|
|
}
|
|
}
|
|
|
|
// AJAX로 이미지 리스트 전체 불러오기
|
|
var allImagesCache = []; // 이미지 데이터 캠시
|
|
|
|
function loadAllImages(rsrvSq) {
|
|
console.log('[loadAllImages] 시작, rsrv_sq:', rsrvSq);
|
|
|
|
if (!rsrvSq) {
|
|
console.warn('[loadAllImages] rsrv_sq가 없음');
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: '/article/receipt/getImages',
|
|
method: 'GET',
|
|
data: { rsrv_sq: rsrvSq },
|
|
success: function(response) {
|
|
console.log('[loadAllImages] 응답:', response);
|
|
|
|
if (response.success && response.images) {
|
|
const images = response.images;
|
|
allImagesCache = images; // 캠시에 저장
|
|
console.log('[loadAllImages] 이미지 개수:', images.length);
|
|
|
|
// 이미지 타입별로 렌더링
|
|
renderImagesByType('I1', images); // 홍보확인서
|
|
renderImagesByType('I10', images); // 촬영동의서
|
|
renderImagesByType('I2', images); // 현장확인내역서
|
|
renderImagesByType('I8', images); // 분양권
|
|
renderImagesByType('I4', images); // 매물사진
|
|
renderImagesByType('V1', images); // 동영상
|
|
renderImagesByType('I5', images); // 평면도
|
|
renderImagesByType('I11', images); // 체크리스트
|
|
renderImagesByType('I9', images); // 360이미지
|
|
|
|
console.log('[loadAllImages] 렌더링 완료');
|
|
} else {
|
|
console.error('[loadAllImages] 응답 오류:', response.msg || '알 수 없음');
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.error('[loadAllImages] AJAX 오류:', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 이미지 타입별로 렌더링
|
|
function renderImagesByType(imgType, allImages) {
|
|
const images = allImages.filter(img => img.img_type === imgType);
|
|
console.log('[renderImagesByType]', imgType, ':', images.length, '개');
|
|
|
|
switch(imgType) {
|
|
case 'I1': // 홍보확인서 (단일)
|
|
renderSingleImage(images[0], 'photo-display2_I1', '홍보확인서');
|
|
break;
|
|
|
|
case 'I10': // 촬영동의서 (단일)
|
|
renderSingleImage(images[0], null, '촬영동의서');
|
|
break;
|
|
|
|
case 'I2': // 현장확인내역서 (단일)
|
|
renderSingleImage(images[0], null, '현장확인내역서');
|
|
break;
|
|
|
|
case 'V1': // 동영상 (단일)
|
|
renderSingleImage(images[0], null, '동영상');
|
|
break;
|
|
|
|
case 'I5': // 평면도 (단일)
|
|
renderSingleImage(images[0], null, '평면도');
|
|
break;
|
|
|
|
case 'I11': // 체크리스트 (단일)
|
|
renderSingleImage(images[0], null, '체크리스트');
|
|
break;
|
|
|
|
case 'I8': // 분양권 (다중)
|
|
renderMultipleImages(images, 'I8', '분양권');
|
|
break;
|
|
|
|
case 'I4': // 매물사진 (다중, 순서O)
|
|
renderPropertyImages(images);
|
|
break;
|
|
|
|
case 'I9': // 360이미지 (다중, 위치O)
|
|
render360Images(images);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 단일 이미지 렌더링
|
|
function renderSingleImage(img, imgId, altText) {
|
|
// 이미지가 없으면 기본 이미지 표시
|
|
if (!img) {
|
|
const defaultHtml = `<img ${imgId ? 'id="'+imgId+'"' : ''} src="/plugin/img/photo.gif" alt="${altText}" class="w-100 object-fit-contain">`;
|
|
|
|
if (imgId) {
|
|
const existing = $(`#${imgId}`);
|
|
if (existing.length > 0) {
|
|
if (existing.parent('a').length > 0) {
|
|
existing.parent('a').replaceWith(defaultHtml);
|
|
} else {
|
|
existing.replaceWith(defaultHtml);
|
|
}
|
|
}
|
|
} else {
|
|
const existing = $(`img[alt="${altText}"]`);
|
|
if (existing.length > 0) {
|
|
if (existing.parent('a').length > 0) {
|
|
existing.parent('a').replaceWith(defaultHtml);
|
|
} else {
|
|
existing.replaceWith(defaultHtml);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
const originalUrl = img.original_url || img.thumbnail_url;
|
|
const thumbnailUrl = img.thumbnail_url || img.original_url;
|
|
|
|
const html = `<a onclick="fn_preview('${originalUrl}')">
|
|
<img ${imgId ? 'id="'+imgId+'"' : ''} src="${thumbnailUrl}" alt="${altText}" class="w-100 object-fit-contain">
|
|
</a>`;
|
|
|
|
if (imgId) {
|
|
$(`#${imgId}`).parent().replaceWith(html);
|
|
} else {
|
|
$(`img[alt="${altText}"]`).parent().replaceWith(html);
|
|
}
|
|
}
|
|
|
|
// 다중 이미지 렌더링 (분양권용)
|
|
function renderMultipleImages(images, imgType, altText) {
|
|
const container = $(`img[alt="${altText}"]`).closest('.d-flex.flex-wrap');
|
|
if (container.length === 0) return;
|
|
|
|
container.empty();
|
|
|
|
// 이미지가 없으면 기본 이미지 표시
|
|
if (images.length === 0) {
|
|
const defaultHtml = `
|
|
<div style="width: 150px;">
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<img src="/plugin/img/photo.gif" alt="${altText}" class="w-100 h-100 object-fit-contain">
|
|
</div>
|
|
</div>
|
|
`;
|
|
container.append(defaultHtml);
|
|
return;
|
|
}
|
|
|
|
images.forEach(img => {
|
|
const originalUrl = img.original_url || img.thumbnail_url;
|
|
const thumbnailUrl = img.thumbnail_url || img.original_url;
|
|
|
|
const html = `
|
|
<div style="width: 150px;">
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<a onclick="fn_preview('${originalUrl}')" class="d-flex align-items-center justify-content-center">
|
|
<img src="${thumbnailUrl}" alt="${altText}" class="w-100 h-100 object-fit-contain">
|
|
</a>
|
|
</div>
|
|
</div>
|
|
`;
|
|
container.append(html);
|
|
});
|
|
}
|
|
|
|
// 매물사진 렌더링 (분양권과 동일한 형태)
|
|
function renderPropertyImages(images) {
|
|
const container = $('#property-images-container');
|
|
if (container.length === 0) return;
|
|
|
|
container.empty();
|
|
|
|
// 이미지가 없으면 기본 이미지 표시
|
|
if (images.length === 0) {
|
|
const defaultHtml = `
|
|
<div class="property-image-item" style="width: 150px; position: relative;">
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<img src="/plugin/img/photo.gif" alt="매물사진" class="w-100 h-100 object-fit-contain">
|
|
</div>
|
|
</div>
|
|
`;
|
|
container.append(defaultHtml);
|
|
return;
|
|
}
|
|
|
|
// view_odr 기준으로 정렬
|
|
images.sort((a, b) => (a.view_odr || 0) - (b.view_odr || 0));
|
|
|
|
images.forEach((img, index) => {
|
|
const originalUrl = img.original_url || img.thumbnail_url;
|
|
const thumbnailUrl = img.thumbnail_url || img.original_url;
|
|
const orderNum = index + 1;
|
|
|
|
const html = `
|
|
<div class="property-image-item" style="width: 150px; position: relative; cursor: move;" data-img-sq="${img.img_sq}" data-view-order="${img.view_odr || orderNum}">
|
|
<div class="image-order-badge" style="position: absolute; top: 1px; left: 1px; background: #6c9ee8; color: white; min-width: 24px; height: 24px; padding: 0 6px; border-radius: 12px; display: inline-flex; align-items-center; justify-content: center; font-size: 13px; font-weight: 500; z-index: 10; box-shadow: 0 2px 4px rgba(0,0,0,0.2);">${orderNum}</div>
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<a onclick="fn_preview('${originalUrl}')" class="d-flex align-items-center justify-content-center">
|
|
<img src="${thumbnailUrl}" alt="매물사진" class="w-100 h-100 object-fit-contain">
|
|
</a>
|
|
</div>
|
|
</div>
|
|
`;
|
|
container.append(html);
|
|
});
|
|
|
|
// Sortable 초기화
|
|
initPropertyImagesSortable();
|
|
}
|
|
|
|
// 360이미지 렌더링 (위치 input 포함)
|
|
function render360Images(images) {
|
|
const container = $('img[alt="360이미지"]').closest('.d-flex.flex-wrap');
|
|
if (container.length === 0) return;
|
|
|
|
container.empty();
|
|
|
|
// 이미지가 없으면 기본 이미지 표시
|
|
if (images.length === 0) {
|
|
const defaultHtml = `
|
|
<div class="thumb-card">
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden mb-1">
|
|
<img src="/plugin/img/photo.gif" alt="360이미지" class="w-100 h-100 object-fit-contain">
|
|
</div>
|
|
<input class="form-control form-control-sm" type="text" placeholder="촬영위치" style="width: 160px;">
|
|
</div>
|
|
`;
|
|
container.append(defaultHtml);
|
|
return;
|
|
}
|
|
|
|
images.forEach(img => {
|
|
const originalUrl = img.original_url || img.thumbnail_url;
|
|
const thumbnailUrl = img.thumbnail_url || img.original_url;
|
|
const imgLocation = img.img_location || '';
|
|
const imgSq = img.img_sq || '';
|
|
|
|
const html = `
|
|
<div class="thumb-card">
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden mb-1">
|
|
<a onclick="fn_preview('${originalUrl}')" class="d-flex align-items-center justify-content-center">
|
|
<img src="${thumbnailUrl}" alt="360이미지" class="w-100 h-100 object-fit-contain">
|
|
</a>
|
|
</div>
|
|
<input class="form-control form-control-sm" type="text" name="img_location_${imgSq}" id="img_location_${imgSq}" value="${imgLocation}" size="11" style="width: 160px;" placeholder="촬영위치">
|
|
</div>
|
|
`;
|
|
container.append(html);
|
|
});
|
|
}
|
|
|
|
// 특정 타입의 모든 이미지 일괄삭제
|
|
function deleteAllImagesByType(imgType, imgTypeName) {
|
|
console.log('[deleteAllImagesByType] 시작:', imgType, imgTypeName);
|
|
|
|
const rsrvSq = $("#frm_file_info [name=rsrv_sq]").val();
|
|
const rcptSq = $("#frm_file_info [name=rcpt_sq]").val();
|
|
|
|
if (!rsrvSq || !rcptSq) {
|
|
alert('필수 정보가 없습니다.');
|
|
return;
|
|
}
|
|
|
|
// 먼저 사용자 확인
|
|
if (!confirm(`${imgTypeName} 이미지를 모두 삭제하시겠습니까?`)) {
|
|
return;
|
|
}
|
|
|
|
// 로딩 화면 표시
|
|
blockUI.blockPage({
|
|
message: '<div class="spinner-border text-primary" role="status"><span class="visually-hidden">Loading...</span></div><p class="mt-2">삭제 중...</p>'
|
|
});
|
|
|
|
// 해당 타입의 이미지 목록 조회 후 삭제
|
|
$.ajax({
|
|
url: '/article/receipt/getImages',
|
|
method: 'GET',
|
|
data: {
|
|
rsrv_sq: rsrvSq,
|
|
img_type: imgType
|
|
},
|
|
success: function(response) {
|
|
console.log('[deleteAllImagesByType] 조회 응답:', response);
|
|
|
|
if (response.success && response.images && response.images.length > 0) {
|
|
const images = response.images;
|
|
const imageCount = images.length;
|
|
|
|
// 삭제 Promise 배열
|
|
const deletePromises = images.map(img => {
|
|
return $.ajax({
|
|
url: '/article/receipt/removeUploadFile',
|
|
method: 'POST',
|
|
data: {
|
|
rcpt_sq: rcptSq,
|
|
img_sq: img.img_sq
|
|
}
|
|
});
|
|
});
|
|
|
|
// 모든 삭제 완료 대기
|
|
Promise.all(deletePromises)
|
|
.then(function(results) {
|
|
console.log('[deleteAllImagesByType] 모든 삭제 완료:', results);
|
|
|
|
// 성공/실패 카운트
|
|
const successCount = results.filter(r => r.code === '0').length;
|
|
const failCount = imageCount - successCount;
|
|
|
|
// 로딩 화면 제거
|
|
blockUI.unblockPage();
|
|
|
|
if (failCount > 0) {
|
|
alert(`${successCount}개 삭제 성공, ${failCount}개 실패`);
|
|
} else {
|
|
alert(`${imgTypeName} 이미지 ${successCount}개가 삭제되었습니다.`);
|
|
}
|
|
|
|
// AJAX로 이미지 재로딩
|
|
loadAllImages(rsrvSq);
|
|
})
|
|
.catch(function(error) {
|
|
console.error('[deleteAllImagesByType] 삭제 오류:', error);
|
|
|
|
// 로딩 화면 제거
|
|
blockUI.unblockPage();
|
|
|
|
alert('이미지 삭제 중 오류가 발생했습니다.');
|
|
loadAllImages(rsrvSq); // 오류 발생해도 재로딩
|
|
});
|
|
} else {
|
|
// 로딩 화면 제거
|
|
blockUI.unblockPage();
|
|
|
|
alert(`삭제할 ${imgTypeName} 이미지가 없습니다.`);
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.error('[deleteAllImagesByType] 조회 오류:', error);
|
|
|
|
// 로딩 화면 제거
|
|
blockUI.unblockPage();
|
|
|
|
alert('이미지 조회 중 오류가 발생했습니다.');
|
|
}
|
|
});
|
|
}
|
|
|
|
// 매물사진 Sortable 초기화
|
|
var propertyImagesSortable = null;
|
|
|
|
function initPropertyImagesSortable() {
|
|
const container = document.getElementById('property-images-container');
|
|
if (!container) {
|
|
console.warn('[initPropertyImagesSortable] 컨테이너를 찾을 수 없음');
|
|
return;
|
|
}
|
|
|
|
// 기존 Sortable 제거
|
|
if (propertyImagesSortable) {
|
|
propertyImagesSortable.destroy();
|
|
propertyImagesSortable = null;
|
|
}
|
|
|
|
// 이미지가 없으면 초기화하지 않음
|
|
const items = container.querySelectorAll('.property-image-item[data-img-sq]');
|
|
if (items.length === 0) {
|
|
console.log('[initPropertyImagesSortable] 이미지가 없어서 Sortable 초기화 안 함');
|
|
return;
|
|
}
|
|
|
|
propertyImagesSortable = new Sortable(container, {
|
|
animation: 150,
|
|
ghostClass: 'sortable-ghost',
|
|
dragClass: 'sortable-drag',
|
|
draggable: '.property-image-item',
|
|
onStart: function(evt) {
|
|
// 드래그 시작시 클릭 이벤트 막기
|
|
const links = container.querySelectorAll('a');
|
|
links.forEach(link => {
|
|
link.style.pointerEvents = 'none';
|
|
});
|
|
},
|
|
onEnd: function(evt) {
|
|
console.log('[PropertyImagesSortable] 순서 변경:', evt.oldIndex, '->', evt.newIndex);
|
|
updatePropertyImageOrderBadges();
|
|
|
|
// 드래그 종료 후 클릭 이벤트 복구 (약간의 딜레이 후)
|
|
setTimeout(function() {
|
|
const links = container.querySelectorAll('a');
|
|
links.forEach(link => {
|
|
link.style.pointerEvents = '';
|
|
});
|
|
}, 100);
|
|
}
|
|
});
|
|
|
|
console.log('[initPropertyImagesSortable] Sortable 초기화 완료, 이미지 수:', items.length);
|
|
}
|
|
|
|
// 매물사진 순서 배지 업데이트
|
|
function updatePropertyImageOrderBadges() {
|
|
const items = document.querySelectorAll('#property-images-container .property-image-item');
|
|
items.forEach((item, index) => {
|
|
const badge = item.querySelector('.image-order-badge');
|
|
if (badge) {
|
|
badge.textContent = index + 1;
|
|
}
|
|
});
|
|
console.log('[updatePropertyImageOrderBadges] 배지 업데이트 완료');
|
|
}
|
|
|
|
// 360이미지 촬영위치 저장
|
|
function save360ImageLocations() {
|
|
console.log('[save360ImageLocations] 촬영위치 저장 시작');
|
|
|
|
const rsrvSq = $("#frm_file_info [name=rsrv_sq]").val();
|
|
if (!rsrvSq) {
|
|
alert('예약번호가 없습니다.');
|
|
return;
|
|
}
|
|
|
|
// img_location으로 시작하는 모든 input 수집
|
|
const locationInputs = $('input[id^="img_location_"]');
|
|
|
|
if (locationInputs.length === 0) {
|
|
alert('저장할 360이미지가 없습니다.');
|
|
return;
|
|
}
|
|
|
|
// 각 input의 값을 수집하고 저장
|
|
const savePromises = [];
|
|
let savedCount = 0;
|
|
|
|
locationInputs.each(function() {
|
|
const imgSq = $(this).attr('id').replace('img_location_', '');
|
|
const location = $(this).val();
|
|
|
|
console.log('[save360ImageLocations] img_sq:', imgSq, 'location:', location);
|
|
|
|
const promise = $.ajax({
|
|
url: '/article/receipt/saveImgLocation',
|
|
method: 'POST',
|
|
data: {
|
|
img_sq: imgSq,
|
|
rsrv_sq: rsrvSq,
|
|
location: location
|
|
}
|
|
}).done(function(response) {
|
|
if (response.code === '0') {
|
|
savedCount++;
|
|
console.log('[save360ImageLocations] 저장 완료:', imgSq);
|
|
} else {
|
|
console.error('[save360ImageLocations] 저장 실패:', response.msg);
|
|
}
|
|
}).fail(function(xhr, status, error) {
|
|
console.error('[save360ImageLocations] AJAX 오류:', error);
|
|
});
|
|
|
|
savePromises.push(promise);
|
|
});
|
|
|
|
// 모든 저장 완료 대기
|
|
Promise.all(savePromises).then(function() {
|
|
console.log('[save360ImageLocations] 모든 촬영위치 저장 완료:', savedCount);
|
|
alert(`촬영위치가 저장되었습니다. (${savedCount}개)`);
|
|
}).catch(function(error) {
|
|
console.error('[save360ImageLocations] 저장 중 오류:', error);
|
|
alert('촬영위치 저장 중 오류가 발생했습니다.');
|
|
});
|
|
}
|
|
|
|
// 이미지 타입별 일괄 다운로드
|
|
function downloadImagesByType(imgType, imgTypeName) {
|
|
const rsrvSq = $("#frm_file_info [name=rsrv_sq]").val();
|
|
|
|
if (!rsrvSq) {
|
|
alert('예약번호가 없습니다.');
|
|
return;
|
|
}
|
|
|
|
// 해당 타입의 이미지 개수 확인
|
|
let imageCount = 0;
|
|
if (allImagesCache && allImagesCache.length > 0) {
|
|
imageCount = allImagesCache.filter(img => img.img_type === imgType).length;
|
|
}
|
|
|
|
if (imageCount === 0) {
|
|
alert('다운로드할 ' + imgTypeName + ' 이미지가 없습니다.');
|
|
return;
|
|
}
|
|
|
|
if (!confirm(`${imgTypeName} ${imageCount}장을 다운로드하시겠습니까?`)) {
|
|
return;
|
|
}
|
|
|
|
// 로딩 화면 표시
|
|
blockUI.blockPage({
|
|
message: '<div class="spinner-border text-primary" role="status"><span class="visually-hidden">Loading...</span></div><p class="mt-2">다운로드 준비 중...</p>'
|
|
});
|
|
|
|
// 다운로드 URL 생성 및 실행
|
|
const downloadUrl = `/article/receipt/downloadAllImages?rsrv_sq=${rsrvSq}&img_type=${imgType}`;
|
|
|
|
// iframe을 사용한 다운로드 (페이지 리로드 방지)
|
|
const iframe = document.createElement('iframe');
|
|
iframe.style.display = 'none';
|
|
iframe.src = downloadUrl;
|
|
document.body.appendChild(iframe);
|
|
|
|
// 다운로드 완료 후 정리 (3초 후)
|
|
setTimeout(function() {
|
|
blockUI.unblockPage();
|
|
document.body.removeChild(iframe);
|
|
console.log(`[downloadImagesByType] ${imgTypeName} 다운로드 완료`);
|
|
}, 3000);
|
|
}
|
|
|
|
// 매물사진 순서 저장
|
|
function savePropertyImageOrder() {
|
|
const items = document.querySelectorAll('#property-images-container .property-image-item[data-img-sq]');
|
|
|
|
if (items.length === 0) {
|
|
alert('저장할 이미지가 없습니다.');
|
|
return;
|
|
}
|
|
|
|
// 순서 데이터 수집
|
|
const orderData = [];
|
|
items.forEach((item, index) => {
|
|
const imgSq = item.getAttribute('data-img-sq');
|
|
if (imgSq) {
|
|
orderData.push({
|
|
img_sq: imgSq,
|
|
view_odr: index + 1
|
|
});
|
|
}
|
|
});
|
|
|
|
console.log('[savePropertyImageOrder] 저장할 순서:', orderData);
|
|
|
|
if (!confirm(`매물사진 순서를 저장하시겠습니까? (총 ${orderData.length}장)`)) {
|
|
return;
|
|
}
|
|
|
|
// 로딩 화면 표시
|
|
blockUI.blockPage({
|
|
message: '<div class="spinner-border text-primary" role="status"><span class="visually-hidden">Loading...</span></div><p class="mt-2">저장 중...</p>'
|
|
});
|
|
|
|
// 서버에 저장 요청
|
|
$.ajax({
|
|
url: '/article/receipt/updateImageOrder',
|
|
method: 'POST',
|
|
data: {
|
|
rcpt_sq: $("#frm_file_info [name=rcpt_sq]").val(),
|
|
img_type: 'I4',
|
|
orders: JSON.stringify(orderData)
|
|
},
|
|
success: function(response) {
|
|
blockUI.unblockPage();
|
|
|
|
if (response.code === '0' || response.success) {
|
|
alert('매물사진 순서가 저장되었습니다.');
|
|
|
|
// 재로딩하여 최신 상태 반영
|
|
const rsrvSq = $("#frm_file_info [name=rsrv_sq]").val();
|
|
if (rsrvSq) {
|
|
loadAllImages(rsrvSq);
|
|
}
|
|
} else {
|
|
alert('순서 저장 중 오류가 발생했습니다: ' + (response.msg || response.message || '알 수 없음'));
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
blockUI.unblockPage();
|
|
console.error('[savePropertyImageOrder] 오류:', error);
|
|
alert('순서 저장 중 오류가 발생했습니다.');
|
|
}
|
|
});
|
|
}
|
|
|
|
function editPriceInfo() {
|
|
// 1. 이미 내가 풀어서 '도장'이 찍힌 요소가 있는지 확인 (이미 수정 모드인지 체크)
|
|
const $manuallyOpened = $('#rcptFrm').find('[data-was-disabled="true"]');
|
|
|
|
if ($manuallyOpened.length > 0) {
|
|
// --- [다시 잠그기 모드] ---
|
|
$manuallyOpened.prop("disabled", true).removeAttr("data-was-disabled");
|
|
console.log("임시로 풀었던 필드들을 다시 잠갔습니다.");
|
|
} else {
|
|
// --- [잠금 풀기 모드] ---
|
|
// 2. 풀 대상들을 모읍니다. (기존 로직 포함)
|
|
let targets = [
|
|
"#trade_type",
|
|
"#rcpt_product_info2",
|
|
"#rcpt_product_info3",
|
|
".display-price-input" // 클래스 대상 추가
|
|
];
|
|
|
|
var rcpt_product = $('#rcpt_product').val();
|
|
var trade_type = $('#trade_type').val();
|
|
|
|
if (trade_type == "A1") {
|
|
if (['A01', 'A02', 'A03', 'B01', 'B02', 'B03'].includes(rcpt_product)) {
|
|
targets.push("#rcpt_product_info4", "#rcpt_product_info5", "#rcpt_product_info6");
|
|
}
|
|
}
|
|
|
|
// 3. 대상들 중에서 '현재 잠겨있는 것만' 골라서 도장 찍고 풀기
|
|
const $targetElements = $(targets.join(', '));
|
|
const $toOpen = $targetElements.filter(':disabled');
|
|
|
|
$toOpen.attr('data-was-disabled', 'true').prop('disabled', false);
|
|
|
|
console.log($toOpen.length + "개의 필드를 수정 가능하게 풀었습니다.");
|
|
if($toOpen.length > 0) $toOpen.first().focus();
|
|
}
|
|
}
|
|
|
|
// 수정 버튼 클릭 시 정보 수정 가능하도록
|
|
function editInfo() {
|
|
const $form = $('#rcptFrm');
|
|
|
|
// 1. 이미 내가 풀어서 '도장(data-was-disabled)'이 찍힌 요소가 있는지 확인
|
|
const $manuallyOpened = $form.find('[data-was-disabled="true"]');
|
|
|
|
if ($manuallyOpened.length > 0) {
|
|
// [다시 잠그기]
|
|
// 도장이 찍힌 놈들만 다시 잠그고 도장을 지웁니다.
|
|
$manuallyOpened.prop('disabled', true).removeAttr('data-was-disabled');
|
|
console.log("임시로 풀었던 요소들을 다시 잠갔습니다.");
|
|
} else {
|
|
// [잠금 풀기]
|
|
// 현재 disabled 상태인 요소들만 찾아서 도장을 찍고 풀어줍니다.
|
|
const $toOpen = $form.find('input:disabled, select:disabled');
|
|
|
|
if ($toOpen.length > 0) {
|
|
$toOpen.attr('data-was-disabled', 'true').prop('disabled', false);
|
|
$toOpen.first().focus();
|
|
console.log("잠겨있던 요소들을 수정 가능하게 풀었습니다.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// 가격수정 저장
|
|
function modifyPriceInfo(btn) {
|
|
// 거래구분 값 검증
|
|
var tradeType = $("#trade_type").val();
|
|
if (!tradeType || tradeType.trim() === "") {
|
|
Swal.fire({
|
|
text: "거래구분을 선택해주세요.",
|
|
icon: "warning",
|
|
confirmButtonText: "확인"
|
|
});
|
|
return;
|
|
}
|
|
|
|
Swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
// Display input에서 수정된 값 읽기
|
|
var dealAmount = $("#displayDealAmount").val() || 0;
|
|
var warrantyAmount = $("#displayWarrantyAmount").val() || 0;
|
|
var leaseAmount = $("#displayLeaseAmount").val() || 0;
|
|
var preSaleAmount = $("#displayPresaleAmount").val() || 0;
|
|
var premiumAmount = $("#displayPremiumAmount").val() || 0;
|
|
var preSaleOptionAmount = $("#displayOptionAmount").val() || 0;
|
|
|
|
// Hidden input에 값 동기화
|
|
$("#dealAmount").val(dealAmount);
|
|
$("#warrantyAmount").val(warrantyAmount);
|
|
$("#leaseAmount").val(leaseAmount);
|
|
$("#preSaleAmount").val(preSaleAmount);
|
|
$("#premiumAmount").val(premiumAmount);
|
|
$("#preSaleOptionAmount").val(preSaleOptionAmount);
|
|
|
|
var params = {
|
|
'rcpt_sq': $("#rcptFrm [name=rcpt_sq]").val() || $("input[name=rcpt_sq]").val(),
|
|
'rcpt_key': $("#rcptFrm [name=rcpt_key]").val(),
|
|
'rcpt_atclno': $("#rcptFrm [name=rcpt_atclno]").val(),
|
|
'trade_type': tradeType,
|
|
'rcpt_product_info2': $("#rcpt_product_info2").val(),
|
|
'rcpt_product_info3': $("#rcpt_product_info3").val(),
|
|
'rcpt_product_info4': $("#rcpt_product_info4").val(),
|
|
'rcpt_product_info5': $("#rcpt_product_info5").val(),
|
|
'rcpt_product_info6': $("#rcpt_product_info6").val(),
|
|
'dealAmount': dealAmount,
|
|
'warrantyAmount': warrantyAmount,
|
|
'leaseAmount': leaseAmount,
|
|
'preSaleAmount': preSaleAmount,
|
|
'premiumAmount': premiumAmount,
|
|
'preSaleOptionAmount': preSaleOptionAmount,
|
|
'rcpt_ptp_no': $("#rcpt_ptp_no").val(),
|
|
'agent_tel': $("#agent_tel").val(),
|
|
'rcpt_hscp_no': $(btn).data('hscp_no'),
|
|
'rcpt_ptp_no': $(btn).data('ptp_no'),
|
|
};
|
|
|
|
callAjax("/article/receipt/modifyPriceInfo", params, fn_result);
|
|
|
|
// 저장 완료 후 display input 다시 비활성화
|
|
$(".display-price-input").prop("disabled", true);
|
|
$(".btn-edit").show();
|
|
$(".btn-save").hide();
|
|
}
|
|
});
|
|
}
|
|
|
|
// 연락가능전화 저장
|
|
function fn_save_tel() {
|
|
Swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
var params = {
|
|
'rcpt_sq': $("#rcptFrm [name=rcpt_sq]").val() || $("input[name=rcpt_sq]").val(),
|
|
'agent_tel': $("#agent_tel").val(),
|
|
};
|
|
|
|
callAjax("/article/receipt/saveAptMemo", params, fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 평면도요청 저장
|
|
function res_ground() {
|
|
Swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
callAjax("/article/receipt/resGround", $("#rcptFrm").serialize(), fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 거주여부 변경 이벤트
|
|
function dbYn_change(value) {
|
|
// 거주여부가 Y이면 DB활용동의여부 활성화, N이면 비활성화
|
|
if (value === 'Y') {
|
|
$('#dbUsageAgrYn').prop('disabled', false);
|
|
} else {
|
|
$('#dbUsageAgrYn').prop('disabled', true);
|
|
$('#dbUsageAgrYn').val('N');
|
|
}
|
|
}
|
|
|
|
// 거주여부 저장
|
|
function saveResDbYn() {
|
|
Swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
callAjax("/article/receipt/resDbYn", $("#rcptFrm").serialize(), fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
//등록일로부터 3개월 체크
|
|
function assign(mon, menuid) {
|
|
var frm = document.getElementById('rcptFrm');
|
|
var to = frm.rsrv_date.value;
|
|
var mon_chk = mon.split("-");
|
|
var to_chk = to.split("-");
|
|
var date1 = new Date(mon_chk[0], mon_chk[1], mon_chk[2]).valueOf();
|
|
var date2 = new Date(to_chk[0], to_chk[1], to_chk[2]).valueOf();
|
|
if (date2 - date1 < 0) {
|
|
assignRegist(menuid);
|
|
} else {
|
|
Swal.fire({
|
|
title: "등록일로부터 3개월 이전만 가능합니다.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 배정자 등록
|
|
*/
|
|
function assignRegist(menuid) {
|
|
var frm = document.rcptFrm;
|
|
|
|
if (frm.rsrv_date.value == "") {
|
|
Swal.fire({
|
|
title: "방문희망일시를 선택해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
|
|
var date = new Date();
|
|
var yy = date.getFullYear();
|
|
var mm = date.getMonth() + 1;
|
|
var dd = date.getDate();
|
|
if (mm < 10) mm = "0" + mm;
|
|
if (dd < 10) dd = "0" + dd;
|
|
var today = yy + mm + dd;
|
|
var rsrv = frm.rsrv_date.value.replace(/-/gi, "");
|
|
|
|
if (parseInt(today) > parseInt(rsrv)) {
|
|
Swal.fire({
|
|
title: "방문희망일시는 금일 이전날짜는 불가능합니다.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
if (frm.rsrv_tm_ap.value == "") {
|
|
Swal.fire({
|
|
title: "오전/오후를 선택해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
if (frm.rsrv_tm_hour.value == "") {
|
|
Swal.fire({
|
|
title: "시간을 선택해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
if (frm.bonbu.value == "") {
|
|
Swal.fire({
|
|
title: "본부를 선택해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
if (frm.dept_sq.value == "") {
|
|
Swal.fire({
|
|
title: "팀을 선택해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
if (frm.usr_sq.value == "") {
|
|
Swal.fire({
|
|
title: "담당자를 선택해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
|
|
|
|
swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
callAjax("/article/receipt/assignRegist", $("#rcptFrm").serialize(), fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 동영상 촬영여부저장
|
|
function requestMovie() {
|
|
Swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
callAjax("/article/receipt/requestMovie", $("#rcptFrm").serialize(), fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 중개사메모 저장
|
|
function requestMessage() {
|
|
Swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
callAjax("/article/receipt/requestMessage", $("#rcptFrm").serialize(), fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 예약취소
|
|
function rsrvcancel() {
|
|
var stat = frm.rcpt_stat1.value;
|
|
var cd2 = frm.result_cd2.value;
|
|
|
|
if (stat == '70' && cd2 == '9030') {
|
|
Swal.fire({
|
|
title: "방문 전 취소가 불가능합니다.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
|
|
if (frm.result_cd2.value == "") {
|
|
Swal.fire({
|
|
title: "분류1을 선택해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
if (frm.result_cd3.value == "") {
|
|
Swal.fire({
|
|
title: "분류2를 선택해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
|
|
if (frm.result_msg.value == "") {
|
|
Swal.fire({
|
|
title: "취소사유를 입력해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
|
|
Swal.fire({
|
|
text: "취소 하시겠습니까?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
callAjax("/article/receipt/rsrvcancel", $("#rcptFrm").serialize(), fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 상태변경
|
|
function chgStatus(cd, rcpt_product, chg_floor_yn) {
|
|
if (cd == "") return;
|
|
|
|
var frm = document.rcptFrm;
|
|
var i1 = frm.I1.value; // 홍보확인서
|
|
var i4 = frm.I4.value; // 매물사진
|
|
var rr_yn = frm.req_rec_yn.value; //녹취필요여부
|
|
var chk_record = frm.chk_record.value; //녹취파일 확인 체크
|
|
var r_yn = frm.rec_yn.value; //녹취 완료여부
|
|
var req_rec_yn = "N";
|
|
|
|
var rcpt_product = frm.rcpt_product.value;
|
|
var r = '';
|
|
|
|
}
|
|
|
|
// 문자발송 modal
|
|
function viewSmsPop(cd) {
|
|
|
|
if (window.smsArr.length > 0) {
|
|
var tel = "";
|
|
if (cd == "S7" || cd == "S14") {
|
|
tel = window.rec_tel;
|
|
} else if (cd == "S10") {
|
|
tel = window.agent_contact_tel;
|
|
} else if (cd == "15") {
|
|
tel = window.agent_contact_tel;
|
|
} else {
|
|
tel = window.agent_head_tel;
|
|
}
|
|
|
|
|
|
for (const sms of window.smsArr) {
|
|
if (sms.cd == cd) {
|
|
$("#smsForm [name=cd]").val(cd);
|
|
$("#smsForm [name=phone]").val(tel);
|
|
$("#smsForm [name=content]").val(sms.cd_nm);
|
|
}
|
|
}
|
|
}
|
|
|
|
$("#smsModal").modal("show");
|
|
}
|
|
|
|
// 문자발송
|
|
function sendSms() {
|
|
if ($("#smsForm [name=phone]").val() == "") {
|
|
Swal.fire({
|
|
title: "수신번호를 입력해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
|
|
if ($("#smsForm [name=content]").val() == "") {
|
|
Swal.fire({
|
|
title: "내용을 입력해 주세요.",
|
|
icon: "warning"
|
|
})
|
|
return;
|
|
}
|
|
|
|
Swal.fire({
|
|
text: "SMS를 발송하시겠습니까?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
callAjax("/article/receipt/sendSms", $("#smsForm").serialize(), fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
function showFileName(input) {
|
|
if (input.files && input.files.length > 0) {
|
|
document.getElementById('file_name').textContent = input.files[0].name;
|
|
}
|
|
}
|
|
|
|
// 거주인 녹취정보 저장
|
|
function saveRecInfo() {
|
|
const rec_tel1 = $("#rec_tel1").val();
|
|
const rec_tel2 = $("#rec_tel2").val();
|
|
const rec_tel3 = $("#rec_tel3").val();
|
|
|
|
if (rec_tel1 == "" || rec_tel2 == "" || rec_tel3 == "") {
|
|
Swal.fire({
|
|
title: "거주자 전화번호를 입력해 주세요.",
|
|
icon: "warning"
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
Swal.fire({
|
|
text: "거주인정보를 저장하시겠습니까?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
var form = $('#rcptFrm')[0];
|
|
var formData = new FormData(form);
|
|
|
|
$.ajax({
|
|
url: "/article/receipt/saveRecInfo",
|
|
method: 'POST',
|
|
data: formData,
|
|
processData: false,
|
|
contentType: false,
|
|
cache: false,
|
|
beforeSend: function () {
|
|
blockUI.blockPage({
|
|
message: tpl
|
|
})
|
|
},
|
|
complete: function () {
|
|
blockUI.unblockPage()
|
|
},
|
|
success: function (result) {
|
|
if (result.code == '0') {
|
|
Swal.fire({
|
|
title: "정상 처리되었습니다.",
|
|
icon: "success",
|
|
draggable: true
|
|
}).then(() => {
|
|
// 서버에서 반환된 데이터로 화면 갱신
|
|
if (result.data) {
|
|
updateRecInfoUI(result.data);
|
|
}
|
|
});
|
|
} else {
|
|
Swal.fire({
|
|
title: result.msg,
|
|
icon: "error",
|
|
draggable: true
|
|
})
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
}
|
|
|
|
// 거주인 정보 UI 업데이트
|
|
function updateRecInfoUI(data) {
|
|
// 전화번호 업데이트
|
|
if (data.rec_tel) {
|
|
const telParts = data.rec_tel.split('-');
|
|
$('input[name="rec_tel1"]').val(telParts[0] || '');
|
|
$('input[name="rec_tel2"]').val(telParts[1] || '');
|
|
$('input[name="rec_tel3"]').val(telParts[2] || '');
|
|
}
|
|
|
|
// 거주인 이름 업데이트
|
|
$('input[name="rec_nm"]').val(data.rec_nm || '');
|
|
|
|
// 거주인 요청사항 업데이트
|
|
$('textarea[name="rec_remark"]').val(data.remark || '');
|
|
|
|
// 음성파일 정보 업데이트
|
|
const fileInfoHtml = data.record ? `
|
|
<div class="d-flex align-items-center gap-2 flex-wrap">
|
|
<a class="fw-semibold text-decoration-none"
|
|
href="/article/receipt/download_file?record_sq=${data.record.record_sq}">
|
|
${data.record.record_orignm}
|
|
</a>
|
|
<span class="badge bg-light text-dark border">${data.record.record_size} KB</span>
|
|
<span class="badge bg-light text-dark border">${data.record.insert_tm}</span>
|
|
</div>
|
|
` : '<span class="text-muted small">등록된 파일 없음</span>';
|
|
|
|
// 음성파일 영역 업데이트 (파일 업로드 버튼 앞까지)
|
|
const fileContainer = $('input[name="rec_file"]').closest('td').find('.d-flex').first();
|
|
fileContainer.find('.d-flex.align-items-center.gap-2.flex-wrap, .text-muted.small').first().replaceWith(fileInfoHtml);
|
|
|
|
// 녹취파일 체크박스 활성화 및 체크
|
|
if (data.record) {
|
|
$('#chk_record').prop('disabled', false).prop('checked', true);
|
|
} else {
|
|
$('#chk_record').prop('disabled', true).prop('checked', false);
|
|
}
|
|
|
|
// 파일명 표시 초기화
|
|
$('#file_name').text('');
|
|
$('input[name="rec_file"]').val('');
|
|
}
|
|
|
|
// 거주인 정보 다시 불러오기
|
|
function loadRecInfo() {
|
|
const rcpt_sq = $('input[name="rcpt_sq"]').val();
|
|
|
|
$.ajax({
|
|
url: "/article/receipt/getRecInfo",
|
|
method: 'GET',
|
|
data: { rcpt_sq: rcpt_sq },
|
|
dataType: 'json',
|
|
success: function (result) {
|
|
if (result.code == '0' && result.data) {
|
|
updateRecInfoUI(result.data);
|
|
}
|
|
},
|
|
error: function() {
|
|
console.error('거주인 정보를 불러오는데 실패했습니다.');
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
|
|
function fn_preview(src, type = 'img') {
|
|
|
|
const $img = $('#imgPreview');
|
|
const $video = $('#vdoPreview');
|
|
const video = document.getElementById('vdoPreview');
|
|
const source = document.getElementById('videoSource');
|
|
|
|
if (type === 'vdo') {
|
|
// 이미지 숨김
|
|
$img.hide().attr('src', '');
|
|
|
|
// video source 세팅
|
|
source.src = src;
|
|
|
|
// video 표시 + 로드
|
|
$video.show();
|
|
video.load();
|
|
|
|
$('#previewTitle').text('동영상 미리보기');
|
|
} else {
|
|
// video 정지 및 초기화
|
|
video.pause();
|
|
source.src = '';
|
|
video.load();
|
|
$video.hide();
|
|
|
|
// 이미지 표시
|
|
$img.attr('src', src).show();
|
|
|
|
$('#previewTitle').text('이미지 미리보기');
|
|
}
|
|
|
|
const modal = new bootstrap.Modal(document.getElementById('previewModal'));
|
|
modal.show();
|
|
}
|
|
|
|
function callAjax(target, params, callback) {
|
|
$.ajax({
|
|
url: target,
|
|
contentType: 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
method: "POST",
|
|
data: params,
|
|
beforeSend: function () {
|
|
blockUI.blockPage({
|
|
message: tpl
|
|
})
|
|
},
|
|
complete: function () {
|
|
blockUI.unblockPage()
|
|
},
|
|
success: function (result) {
|
|
callback(result);
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
function fn_result(result) {
|
|
if (result.code == '0') {
|
|
Swal.fire({
|
|
title: "정상 처리되었습니다.",
|
|
icon: "success",
|
|
draggable: true
|
|
});
|
|
|
|
// 정보변경 이력 갱신
|
|
loadHistory();
|
|
} else {
|
|
Swal.fire({
|
|
title: result.msg,
|
|
icon: "error",
|
|
draggable: true
|
|
})
|
|
}
|
|
}
|
|
|
|
// 정보변경 이력 AJAX 로드
|
|
function loadHistory() {
|
|
const rcptSq = $("#rcptFrm input[name='rcpt_sq']").val();
|
|
console.log('[loadHistory] rcpt_sq:', rcptSq);
|
|
|
|
if (!rcptSq) {
|
|
console.warn('[loadHistory] rcpt_sq가 없습니다.');
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: "/article/receipt/getHistory",
|
|
type: "GET",
|
|
data: { rcpt_sq: rcptSq },
|
|
success: function(result) {
|
|
console.log('[loadHistory] 응답:', result);
|
|
if (result.code === '0' && result.data) {
|
|
console.log('[loadHistory] 이력 데이터:', result.data);
|
|
updateHistoryUI(result.data);
|
|
} else {
|
|
console.warn('[loadHistory] 올바르지 않은 응답:', result);
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.error('[History] 로드 실패:', error);
|
|
console.error('[History] 응답:', xhr.responseText);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 정보변경 이력 UI 업데이트
|
|
function updateHistoryUI(historyData) {
|
|
const $historyTable = $('#history-table');
|
|
if (!$historyTable.length) {
|
|
console.error('[updateHistoryUI] 정보변경 이력 테이블을 찾을 수 없습니다.');
|
|
return;
|
|
}
|
|
|
|
let $tbody = $historyTable.find('tbody');
|
|
if (!$tbody.length) {
|
|
// tbody가 없으면 생성
|
|
const $thead = $historyTable.find('thead');
|
|
if ($thead.length) {
|
|
$tbody = $('<tbody></tbody>').insertAfter($thead);
|
|
}
|
|
}
|
|
|
|
$tbody.empty();
|
|
|
|
if (historyData && historyData.length > 0) {
|
|
historyData.forEach(h => {
|
|
const row = `
|
|
<tr>
|
|
<td style="text-align: center;">${h.rcpt_stat_nm || ''}</td>
|
|
<td style="text-align: center;">${h.changed_type_nm || ''}</td>
|
|
<td style="text-align: center;">${h.changed_id || ''}</td>
|
|
<td style="text-align: center;">${h.changed_tm || ''}</td>
|
|
<td>${h.remark || ''}</td>
|
|
</tr>
|
|
`;
|
|
$tbody.append(row);
|
|
});
|
|
} else {
|
|
$tbody.append('<tr><td colspan="5" style="text-align: center;">이력이 없습니다.</td></tr>');
|
|
}
|
|
}
|
|
|
|
// Dropzone 초기화 함수
|
|
function initDropzone(imgType) {
|
|
console.log('[Dropzone] initDropzone 호출, imgType:', imgType);
|
|
|
|
// 기존 Dropzone 인스턴스가 있으면 제거
|
|
if (dz) {
|
|
console.log('[Dropzone] 기존 인스턴스 제거');
|
|
dz.destroy();
|
|
dz = null;
|
|
}
|
|
|
|
// 파일 타입별 최대 개수 설정
|
|
const isV2 = document.getElementById('myDropzone')?.getAttribute('data-is-v2') === 'true';
|
|
console.log('[Dropzone] isV2:', isV2);
|
|
|
|
const maxFilesConfig = {
|
|
'I4': isV2 ? 1 : 15, // 매물사진 (V2는 1장, 일반은 15장)
|
|
'I8': 5, // 평면도
|
|
'I9': 5, // 녹취파일
|
|
'V1': 5 // 동영상
|
|
};
|
|
|
|
const maxFiles = maxFilesConfig[imgType] || 10; // 기본 10개
|
|
console.log('[Dropzone] maxFiles:', maxFiles);
|
|
|
|
let uploadStarted = false;
|
|
let uploadedCount = 0;
|
|
let totalFiles = 0;
|
|
|
|
dz = new Dropzone("#myDropzone", {
|
|
url: "/article/receipt/uploadFile",
|
|
method: "post",
|
|
paramName: "files",
|
|
autoProcessQueue: false, // 자동 업로드 끄기
|
|
uploadMultiple: false, // 파일을 개별적으로 업로드
|
|
parallelUploads: 1, // 한 번에 한 개씩 업로드
|
|
maxFiles: maxFiles, // 최대 파일 수
|
|
maxFilesize: 100,
|
|
addRemoveLinks: true,
|
|
clickable: "#uploadPick", // 파일선택 버튼만 클릭 가능
|
|
dictRemoveFile: "삭제",
|
|
dictDefaultMessage: "최대 " + maxFiles + "개",
|
|
dictFallbackMessage: "브라우저가 드래그앤드롭을 지원하지 않습니다.",
|
|
dictFileTooBig: "파일이 너무 큽니다 (최대 {{maxFilesize}}MB)",
|
|
dictInvalidFileType: "허용되지 않은 파일 형식입니다.",
|
|
dictResponseError: "서버 오류가 발생했습니다.",
|
|
dictCancelUpload: "업로드 취소",
|
|
dictMaxFilesExceeded: "최대 " + maxFiles + "개까지만 업로드할 수 있습니다.",
|
|
});
|
|
|
|
dz.on("addedfile", function (file) {
|
|
console.log('[Dropzone] addedfile 후처리:', file.name, 'isExisting:', file.isExisting);
|
|
|
|
// 교체 버튼 추가
|
|
const filePreview = file.previewElement;
|
|
const removeButton = filePreview.querySelector('.dz-remove');
|
|
|
|
if (removeButton && !filePreview.querySelector('.dz-replace')) {
|
|
// 버튼 영역 div 생성
|
|
const buttonsDiv = document.createElement('div');
|
|
buttonsDiv.className = 'file-buttons';
|
|
|
|
// 교체 버튼 생성
|
|
const replaceButton = document.createElement('a');
|
|
replaceButton.href = 'javascript:void(0);';
|
|
replaceButton.className = 'dz-replace';
|
|
replaceButton.textContent = '교체';
|
|
replaceButton.onclick = function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
replaceFile(file);
|
|
};
|
|
|
|
// 기존 삭제 버튼을 buttonsDiv로 감싸기
|
|
removeButton.parentNode.insertBefore(buttonsDiv, removeButton);
|
|
buttonsDiv.appendChild(removeButton);
|
|
buttonsDiv.appendChild(replaceButton);
|
|
|
|
// 기존 파일인 경우 삭제 확인 메시지 추가
|
|
if (file.isExisting) {
|
|
removeButton.textContent = 'DB삭제';
|
|
removeButton.style.color = '#dc3545';
|
|
|
|
// 삭제 버튼 클릭 시 확인 메시지
|
|
const originalHref = removeButton.getAttribute('data-dz-remove');
|
|
removeButton.removeAttribute('data-dz-remove');
|
|
removeButton.onclick = function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
if (confirm('이 파일을 DB와 클라우드에서 삭제하시겠습니까?\n\n파일명: ' + file.name)) {
|
|
dz.removeFile(file);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
// 파일 순서 배지 추가
|
|
updateFileOrderBadges();
|
|
|
|
// Sortable 초기화 (파일이 추가될 때마다)
|
|
initSortable();
|
|
});
|
|
|
|
dz.on("removedfile", function (file) {
|
|
console.log('[Dropzone] removedfile:', file.name, 'isExisting:', file.isExisting, 'isDeleting:', file.isDeleting, 'isModalClosing:', window.isModalClosing);
|
|
|
|
// 모달이 닫히는 중에는 서버 삭제 요청 하지 않음 (UI 정리만 수행)
|
|
if (window.isModalClosing) {
|
|
console.log('[Dropzone] 모달 닫힘 중이므로 서버 삭제 요청 안 함');
|
|
return;
|
|
}
|
|
|
|
// 기존 파일(DB에 있는 파일)인 경우 서버에서 삭제
|
|
if (file.isExisting && file.img_sq) {
|
|
// 이미 삭제 중인 경우 중복 요청 방지
|
|
if (file.isDeleting) {
|
|
console.log('[Dropzone] 이미 삭제 중인 파일:', file.img_sq);
|
|
return;
|
|
}
|
|
|
|
file.isDeleting = true; // 삭제 플래그 설정
|
|
console.log('[Dropzone] 기존 파일 삭제 요청, img_sq:', file.img_sq);
|
|
|
|
// 삭제 Promise 저장 (전체삭제 시 사용)
|
|
if (!window.deletePromises) {
|
|
window.deletePromises = [];
|
|
}
|
|
|
|
const deletePromise = $.ajax({
|
|
url: '/article/receipt/removeUploadFile',
|
|
method: 'POST',
|
|
data: {
|
|
rcpt_sq: $("#frm_file_info [name=rcpt_sq]").val(),
|
|
img_sq: file.img_sq
|
|
}
|
|
}).done(function(response) {
|
|
console.log('[Dropzone] 파일 삭제 완료:', response);
|
|
if (response.code === '0') {
|
|
// 개별 삭제인 경우 (전체삭제가 아닌 경우)
|
|
if (!window.isBulkDeleting) {
|
|
alert('파일이 삭제되었습니다.');
|
|
// AJAX로 이미지 재로딩
|
|
const rsrvSq = $("#frm_file_info [name=rsrv_sq]").val();
|
|
if (rsrvSq) {
|
|
loadAllImages(rsrvSq);
|
|
}
|
|
}
|
|
} else {
|
|
console.error('[Dropzone] 삭제 응답 에러:', response.msg);
|
|
file.isDeleting = false; // 실패 시 플래그 해제
|
|
if (!window.isBulkDeleting) {
|
|
alert('파일 삭제 중 오류가 발생했습니다: ' + (response.msg || '알 수 없는 오류'));
|
|
}
|
|
}
|
|
}).fail(function(xhr, status, error) {
|
|
console.error('[Dropzone] 파일 삭제 실패:', error);
|
|
file.isDeleting = false; // 실패 시 플래그 해제
|
|
if (!window.isBulkDeleting) {
|
|
alert('파일 삭제 중 오류가 발생했습니다.');
|
|
}
|
|
});
|
|
|
|
window.deletePromises.push(deletePromise);
|
|
}
|
|
|
|
// 파일 삭제 후 순서 배지 업데이트
|
|
setTimeout(updateFileOrderBadges, 100);
|
|
});
|
|
|
|
dz.on("sending", function (file, xhr, formData) {
|
|
console.log('[Dropzone] sending 이벤트:', file.name, 'isExisting:', file.isExisting);
|
|
|
|
// 기존 파일은 업로드하지 않음
|
|
if (file.isExisting) {
|
|
console.log('[Dropzone] 기존 파일이므로 업로드 스킵:', file.name);
|
|
return false;
|
|
}
|
|
|
|
// 현재 순서 찾기
|
|
const fileIndex = dz.files.indexOf(file);
|
|
|
|
formData.append("rcpt_key", $("#frm_file_info [name=rcpt_key]").val());
|
|
formData.append("rsrv_sq", $("#frm_file_info [name=rsrv_sq]").val());
|
|
formData.append("rcpt_sq", $("#frm_file_info [name=rcpt_sq]").val());
|
|
formData.append("img_type", $("#frm_file_info [name=img_type]").val());
|
|
formData.append("img_sub_type", $("#frm_file_info [name=img_sub_type]").val());
|
|
formData.append("vr_sq", $("#frm_file_info [name=vr_sq]").val());
|
|
formData.append("file_order", fileIndex + 1); // 파일 순서 추가
|
|
|
|
uploadStarted = true;
|
|
});
|
|
|
|
dz.on("processing", function (file) {
|
|
console.log('[Dropzone] processing 이벤트:', file.name);
|
|
});
|
|
|
|
dz.on("success", function (file, response) {
|
|
console.log('[Dropzone] success 이벤트:', file.name, response);
|
|
uploadedCount++;
|
|
console.log('[Dropzone] 업로드 진행:', uploadedCount + '/' + totalFiles);
|
|
|
|
// 업로드된 파일 정보 저장
|
|
if (!window.uploadedFiles) {
|
|
window.uploadedFiles = [];
|
|
}
|
|
|
|
// 서버 응답에서 이미지 정보 추출
|
|
if (response && response.code === '0' && response.data) {
|
|
window.uploadedFiles.push({
|
|
imgType: $("#frm_file_info [name=img_type]").val(),
|
|
imageData: response.data
|
|
});
|
|
console.log('[Dropzone] 업로드된 파일 정보 저장:', response.data);
|
|
}
|
|
|
|
// 다음 파일이 있으면 처리
|
|
if (dz.getQueuedFiles().length > 0) {
|
|
console.log('[Dropzone] 다음 파일 처리 시작');
|
|
dz.processQueue();
|
|
}
|
|
});
|
|
|
|
dz.on("error", function (file, errorMessage, xhr) {
|
|
console.log('[Dropzone] error 이벤트:', file.name, errorMessage, 'status:', file.status);
|
|
uploadedCount++;
|
|
|
|
// 모달이 닫히는 중이거나 파일이 취소된 경우 에러 메시지 표시 안 함
|
|
if (window.isModalClosing || file.status === 'canceled' || errorMessage === 'Upload canceled.') {
|
|
console.log('[Dropzone] 모달 닫힘 중이거나 취소된 파일이므로 에러 무시');
|
|
return;
|
|
}
|
|
|
|
// 에러 메시지 파싱
|
|
let displayMessage = '업로드 실패: ' + file.name;
|
|
if (typeof errorMessage === 'object' && errorMessage.msg) {
|
|
displayMessage = errorMessage.msg;
|
|
} else if (typeof errorMessage === 'string') {
|
|
displayMessage = errorMessage;
|
|
}
|
|
|
|
// 사용자에게 에러 알림
|
|
alert('⚠️ 파일 업로드 실패\n\n' + displayMessage);
|
|
|
|
// 파일에 에러 표시
|
|
if (file.previewElement) {
|
|
file.previewElement.classList.add('dz-error');
|
|
}
|
|
|
|
// 업로드 중단 (다음 파일 처리 안 함)
|
|
uploadStarted = false;
|
|
console.log('[Dropzone] 에러로 인해 업로드 중단');
|
|
});
|
|
|
|
dz.on("queuecomplete", function () {
|
|
console.log('[Dropzone] queuecomplete 이벤트, uploadStarted:', uploadStarted, 'uploadedCount:', uploadedCount, 'totalFiles:', totalFiles);
|
|
if (uploadStarted && uploadedCount >= totalFiles && totalFiles > 0) {
|
|
console.log('[Dropzone] 모든 파일 업로드 완료');
|
|
|
|
// 업로드된 파일 목록 초기화
|
|
window.uploadedFiles = [];
|
|
|
|
// AJAX로 최신 상태 불러오기
|
|
const rsrvSq = $("#frm_file_info [name=rsrv_sq]").val();
|
|
if (rsrvSq) {
|
|
console.log('[Dropzone] AJAX로 이미지 재로딩 시작');
|
|
loadAllImages(rsrvSq);
|
|
} else {
|
|
console.warn('[Dropzone] rsrv_sq가 없어서 재로딩 불가');
|
|
}
|
|
|
|
alert('파일이 업로드되었습니다.');
|
|
|
|
// 모달 닫기
|
|
$("#uploadModal").modal("hide");
|
|
}
|
|
});
|
|
|
|
// 버튼 이벤트 재등록 (파일선택 버튼은 Dropzone이 자동 처리)
|
|
|
|
$("#btnUpload").off("click").on("click", function () {
|
|
console.log('[Dropzone] btnUpload 클릭');
|
|
|
|
// 새로 추가된 파일만 필터링 (기존 파일 제외)
|
|
const newFiles = dz.files.filter(file => !file.isExisting && file.status === Dropzone.QUEUED);
|
|
const existingFiles = dz.files.filter(file => file.isExisting);
|
|
|
|
console.log('[Dropzone] 전체 파일:', dz.files.length, '기존 파일:', existingFiles.length, '새 파일:', newFiles.length);
|
|
|
|
if (newFiles.length === 0) {
|
|
if (existingFiles.length > 0) {
|
|
alert("변경사항이 저장되었습니다.");
|
|
} else {
|
|
alert("업로드할 파일을 먼저 선택해주세요.");
|
|
}
|
|
return;
|
|
}
|
|
|
|
totalFiles = newFiles.length;
|
|
uploadedCount = 0;
|
|
|
|
console.log('[Dropzone] 업로드 시작, totalFiles:', totalFiles);
|
|
uploadStarted = true;
|
|
dz.processQueue(); // 업로드 실행
|
|
});
|
|
|
|
$("#btnRemove").off("click").on("click", function () {
|
|
console.log('[Dropzone] btnRemove 클릭');
|
|
const files = dz.files.slice(); // 배열 복사
|
|
|
|
if (files.length === 0) {
|
|
alert("삭제할 파일이 없습니다.");
|
|
return;
|
|
}
|
|
|
|
const existingFilesCount = files.filter(f => f.isExisting).length;
|
|
const newFilesCount = files.length - existingFilesCount;
|
|
|
|
let confirmMsg = `총 ${files.length}개의 파일을 삭제하시겠습니까?`;
|
|
if (existingFilesCount > 0) {
|
|
confirmMsg += `\n- 기존 파일 ${existingFilesCount}개 (DB 및 클라우드에서 삭제)`;
|
|
}
|
|
if (newFilesCount > 0) {
|
|
confirmMsg += `\n- 신규 파일 ${newFilesCount}개 (목록에서만 제거)`;
|
|
}
|
|
|
|
if (!confirm(confirmMsg)) {
|
|
return;
|
|
}
|
|
|
|
// 전체삭제 플래그 설정
|
|
window.isBulkDeleting = true;
|
|
window.deletePromises = [];
|
|
window.deletedFiles = []; // 삭제된 파일 정보 저장
|
|
|
|
// 모든 파일 삭제 (removedfile 이벤트에서 AJAX 호출)
|
|
files.forEach(function (file) {
|
|
if (file.isExisting && file.img_sq) {
|
|
window.deletedFiles.push({
|
|
imgSq: file.img_sq,
|
|
imgType: $("#frm_file_info [name=img_type]").val()
|
|
});
|
|
}
|
|
dz.removeFile(file);
|
|
});
|
|
|
|
// 기존 파일이 있었으면 삭제 완료 대기
|
|
if (existingFilesCount > 0) {
|
|
console.log('[Dropzone] 삭제 대기 중... Promise 개수:', window.deletePromises.length);
|
|
|
|
Promise.all(window.deletePromises)
|
|
.then(function() {
|
|
console.log('[Dropzone] 모든 파일 삭제 완료');
|
|
window.isBulkDeleting = false;
|
|
window.isModalClosing = true; // 모달 닫힘 플래그 설정
|
|
|
|
// AJAX로 이미지 재로딩
|
|
const rsrvSq = $("#frm_file_info [name=rsrv_sq]").val();
|
|
if (rsrvSq) {
|
|
loadAllImages(rsrvSq);
|
|
}
|
|
|
|
alert('파일이 삭제되었습니다.');
|
|
|
|
// 모달 닫기
|
|
$("#uploadModal").modal("hide");
|
|
})
|
|
.catch(function(error) {
|
|
console.error('[Dropzone] 삭제 중 오류:', error);
|
|
window.isBulkDeleting = false;
|
|
alert('일부 파일 삭제 중 오류가 발생했습니다.');
|
|
location.reload();
|
|
});
|
|
} else {
|
|
// 신규 파일만 있었으면 즉시 완료
|
|
window.isBulkDeleting = false;
|
|
window.isModalClosing = true; // 모달 닫힘 플래그 설정
|
|
alert('파일이 목록에서 제거되었습니다.');
|
|
|
|
// 모달 닫기
|
|
$("#uploadModal").modal("hide");
|
|
}
|
|
});
|
|
|
|
// Sortable 초기화 함수
|
|
function initSortable() {
|
|
// 기존 Sortable 제거
|
|
if (sortable) {
|
|
sortable.destroy();
|
|
}
|
|
|
|
const dropzoneElement = document.querySelector("#myDropzone .dz-preview");
|
|
if (!dropzoneElement || !dropzoneElement.parentElement) {
|
|
return;
|
|
}
|
|
|
|
sortable = new Sortable(dropzoneElement.parentElement, {
|
|
animation: 150,
|
|
ghostClass: 'sortable-ghost',
|
|
handle: '.dz-image',
|
|
draggable: '.dz-preview',
|
|
onEnd: function(evt) {
|
|
console.log('[Sortable] 순서 변경:', evt.oldIndex, '->', evt.newIndex);
|
|
|
|
// Dropzone 파일 배열 순서 업데이트
|
|
const movedFile = dz.files[evt.oldIndex];
|
|
dz.files.splice(evt.oldIndex, 1);
|
|
dz.files.splice(evt.newIndex, 0, movedFile);
|
|
|
|
// 순서 배지 업데이트
|
|
updateFileOrderBadges();
|
|
}
|
|
});
|
|
}
|
|
|
|
// 파일 교체 함수
|
|
function replaceFile(oldFile) {
|
|
console.log('[Dropzone] 파일 교체 시작:', oldFile.name);
|
|
|
|
// 숨겨진 파일 input 생성
|
|
const input = document.createElement('input');
|
|
input.type = 'file';
|
|
input.accept = 'image/*';
|
|
input.style.display = 'none';
|
|
|
|
input.onchange = function(e) {
|
|
const newFile = e.target.files[0];
|
|
if (!newFile) return;
|
|
|
|
console.log('[Dropzone] 새 파일 선택됨:', newFile.name);
|
|
|
|
// 기존 파일의 인덱스 찾기
|
|
const oldIndex = dz.files.indexOf(oldFile);
|
|
|
|
// 기존 파일 제거 (UI에서만)
|
|
dz.removeFile(oldFile);
|
|
|
|
// 새 파일 추가
|
|
dz.addFile(newFile);
|
|
|
|
// 파일 순서 재정렬 (새 파일을 원래 위치로)
|
|
setTimeout(() => {
|
|
const newIndex = dz.files.length - 1;
|
|
if (oldIndex !== newIndex && oldIndex < dz.files.length) {
|
|
const movedFile = dz.files[newIndex];
|
|
dz.files.splice(newIndex, 1);
|
|
dz.files.splice(oldIndex, 0, movedFile);
|
|
|
|
// DOM 순서도 변경
|
|
const previews = document.querySelectorAll('#myDropzone .dz-preview');
|
|
const newPreview = previews[previews.length - 1];
|
|
const parent = newPreview.parentNode;
|
|
const targetPreview = previews[oldIndex];
|
|
parent.insertBefore(newPreview, targetPreview);
|
|
}
|
|
|
|
updateFileOrderBadges();
|
|
}, 100);
|
|
};
|
|
|
|
document.body.appendChild(input);
|
|
input.click();
|
|
document.body.removeChild(input);
|
|
}
|
|
|
|
// 파일 순서 배지 업데이트 함수
|
|
function updateFileOrderBadges() {
|
|
const previews = document.querySelectorAll('#myDropzone .dz-preview');
|
|
previews.forEach((preview, index) => {
|
|
// 기존 배지 제거
|
|
const existingBadge = preview.querySelector('.file-order-badge');
|
|
if (existingBadge) {
|
|
existingBadge.remove();
|
|
}
|
|
|
|
// 새 배지 추가 - 이미지 위에 표시
|
|
const badge = document.createElement('div');
|
|
badge.className = 'file-order-badge';
|
|
badge.textContent = index + 1;
|
|
|
|
const imageDiv = preview.querySelector('.dz-image');
|
|
if (imageDiv) {
|
|
imageDiv.style.position = 'relative';
|
|
imageDiv.appendChild(badge);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// 부모 페이지의 이미지 업데이트
|
|
function updateParentImage(imgType) {
|
|
if (!imgType) {
|
|
console.log('[updateParentImage] imgType이 없음');
|
|
return;
|
|
}
|
|
|
|
// I8 등 여러 이미지를 갤러리로 표시하는 타입은 업데이트 복잡하므로 스킵
|
|
const multiImageTypes = ['I8', 'I4', 'I5', 'I9'];
|
|
if (multiImageTypes.includes(imgType)) {
|
|
console.log('[updateParentImage] 복수 이미지 타입, 업데이트 스킵:', imgType);
|
|
return;
|
|
}
|
|
|
|
const rsrv_sq = $("#frm_file_info [name=rsrv_sq]").val();
|
|
if (!rsrv_sq) {
|
|
console.log('[updateParentImage] rsrv_sq가 없음');
|
|
return;
|
|
}
|
|
|
|
console.log('[updateParentImage] 부모 페이지 이미지 업데이트 시작:', imgType);
|
|
|
|
// 해당 img_type의 남은 이미지 조회
|
|
$.ajax({
|
|
url: '/article/receipt/getImages',
|
|
method: 'GET',
|
|
data: {
|
|
rsrv_sq: rsrv_sq,
|
|
img_type: imgType
|
|
},
|
|
success: function(response) {
|
|
console.log('[updateParentImage] 응답:', response);
|
|
|
|
const imgElement = $('#photo-display2_' + imgType);
|
|
if (imgElement.length === 0) {
|
|
console.log('[updateParentImage] 이미지 엘리먼트를 찾을 수 없음, 업데이트 스킵:', '#photo-display2_' + imgType);
|
|
return;
|
|
}
|
|
|
|
const parentAnchor = imgElement.parent('a');
|
|
|
|
if (response.success && response.images && response.images.length > 0) {
|
|
// 첫 번째 이미지로 업데이트
|
|
const firstImage = response.images[0];
|
|
imgElement.attr('src', firstImage.original_url);
|
|
|
|
// a 태그가 있으면 onclick도 업데이트
|
|
if (parentAnchor.length > 0) {
|
|
parentAnchor.attr('onclick', "fn_preview('" + firstImage.original_url + "')");
|
|
}
|
|
|
|
console.log('[updateParentImage] 이미지 업데이트 완료:', firstImage.original_url);
|
|
} else {
|
|
// 이미지가 없으면 기본 이미지로
|
|
imgElement.attr('src', '/plugin/img/photo.gif');
|
|
|
|
// a 태그가 있으면 제거 (기본 이미지는 클릭 불가)
|
|
if (parentAnchor.length > 0) {
|
|
parentAnchor.removeAttr('onclick');
|
|
}
|
|
|
|
console.log('[updateParentImage] 기본 이미지로 변경');
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.error('[updateParentImage] AJAX 실패, 업데이트 스킵:', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 기존 이미지를 Dropzone에 로드
|
|
function loadExistingImages(imgType, imgSubType) {
|
|
console.log('[loadExistingImages] 호출:', imgType, imgSubType);
|
|
|
|
const rsrv_sq = $("#frm_file_info [name=rsrv_sq]").val();
|
|
if (!rsrv_sq) {
|
|
console.log('[loadExistingImages] rsrv_sq가 없음');
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: '/article/receipt/getImages',
|
|
method: 'GET',
|
|
data: {
|
|
rsrv_sq: rsrv_sq,
|
|
img_type: imgType
|
|
},
|
|
success: function(response) {
|
|
console.log('[loadExistingImages] 응답:', response);
|
|
|
|
if (response.success && response.images && response.images.length > 0) {
|
|
response.images.forEach(function(img) {
|
|
// 가짜 File 객체 생성
|
|
const mockFile = {
|
|
name: img.img_filenm,
|
|
size: img.file_size || 0,
|
|
img_sq: img.img_sq,
|
|
img_type: img.img_type,
|
|
isExisting: true, // 기존 파일 표시
|
|
accepted: true,
|
|
status: Dropzone.ADDED,
|
|
original_url: img.original_url
|
|
};
|
|
|
|
// Dropzone에 파일 추가
|
|
dz.emit("addedfile", mockFile);
|
|
dz.emit("thumbnail", mockFile, img.thumbnail_url);
|
|
dz.emit("complete", mockFile);
|
|
|
|
// 썸네일 이미지 로드 실패 시 원본으로 대체
|
|
setTimeout(function() {
|
|
const preview = mockFile.previewElement;
|
|
if (preview) {
|
|
const thumbnailImg = preview.querySelector('[data-dz-thumbnail]');
|
|
if (thumbnailImg) {
|
|
thumbnailImg.onerror = function() {
|
|
console.log('[loadExistingImages] 썸네일 로드 실패, 원본 사용:', mockFile.name);
|
|
this.src = img.original_url;
|
|
this.onerror = null; // 무한 루프 방지
|
|
};
|
|
}
|
|
}
|
|
}, 100);
|
|
|
|
// files 배열에 추가 (Dropzone 내부 상태 관리)
|
|
dz.files.push(mockFile);
|
|
|
|
console.log('[loadExistingImages] 파일 추가됨:', mockFile.name);
|
|
});
|
|
} else {
|
|
console.log('[loadExistingImages] 이미지 없음');
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.error('[loadExistingImages] 실패:', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 단지 목록 가져오기
|
|
function loadComplexList() {
|
|
console.log('[loadComplexList] 단지 목록 로드 시작');
|
|
|
|
var legalDivisionNumber = $('input[name="rcpt_dong"]').val() ?? '';
|
|
console.log('[loadComplexList] legalDivisionNumber:', legalDivisionNumber);
|
|
var realEstateType = $('input[name="rcpt_product"]').val() ?? '';
|
|
|
|
// 값이 없을때
|
|
if ( legalDivisionNumber == '' ) return;
|
|
|
|
let sendData = {
|
|
legalDivisionNumber: legalDivisionNumber,
|
|
};
|
|
|
|
if (realEstateType) {
|
|
sendData.realEstateType = realEstateType;
|
|
}
|
|
|
|
console.log('[loadComplexList] 요청 데이터:', sendData);
|
|
|
|
$.ajax({
|
|
url: '/common/getComplexList',
|
|
method: 'GET',
|
|
data : sendData,
|
|
success: function(result) {
|
|
console.log('[loadComplexList] 응답:', result);
|
|
|
|
if (result.code === 'success' && result.data) {
|
|
var options = '<option value="">단지 선택</option>';
|
|
|
|
result.data.forEach(function(complex) {
|
|
options += '<option value="' + complex.complexNumber + '">' + complex.name + '</option>';
|
|
});
|
|
|
|
$('#rcpt_hscp_nm').html(options);
|
|
|
|
// 현재 선택된 단지가 있으면 선택
|
|
var currentHscpNo = $('input[name="rcpt_hscp_no"]').val();
|
|
if (currentHscpNo) {
|
|
$('#rcpt_hscp_nm').val(currentHscpNo);
|
|
// 평형 정보도 로드
|
|
// loadPyeongInfo(currentHscpNo);
|
|
}
|
|
|
|
console.log('[loadComplexList] 단지 목록 로드 완료, 개수:', result.data.length);
|
|
} else {
|
|
console.warn('[loadComplexList] 단지 목록 응답이 올바르지 않습니다:', result);
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.error('[loadComplexList] 단지 목록 요청 실패:', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
function loadPyeongInfo() {
|
|
|
|
var currentHscpNo = $('input[name="rcpt_hscp_no"]').val();
|
|
var currentPtpNo = $('input[name="rcpt_ptp_no"]').val();
|
|
var realEstateType = $('input[name="rcpt_product"]').val() ?? '';
|
|
console.log('[loadPyeongInfo] 평형 정보 로드 시작, hscpNo:', currentHscpNo);
|
|
$.ajax({
|
|
url: '/common/getPyeongInfo',
|
|
method: 'GET',
|
|
data: { complexNumber: currentHscpNo, realEstateType: realEstateType },
|
|
success: function(result) {
|
|
console.log('[loadPyeongInfo] 응답:', result);
|
|
if (result.code === 'success' && result.data) {
|
|
var options = '<option value="">평형 선택</option>';
|
|
result.data.forEach(function(pyeong) {
|
|
|
|
options += '<option value="' + pyeong.pyeongTypeNumber + '">' + pyeong.pyeongTypeName + '</option>';
|
|
});
|
|
|
|
$('#rcpt_ptp_nm').html(options);
|
|
if (currentPtpNo) {
|
|
$('#rcpt_ptp_nm').val(currentPtpNo);
|
|
}
|
|
console.log('[loadPyeongInfo] 평형 정보 로드 완료, 개수:', result.data.length);
|
|
} else {
|
|
console.warn('[loadPyeongInfo] 평형 정보 응답이 올바르지 않습니다:', result);
|
|
}
|
|
},
|
|
|
|
error: function(xhr, status, error) {
|
|
console.error('[loadPyeongInfo] 평형 정보 요청 실패:', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 파일업로드 모달 오픈
|
|
function viewFilePop(imgType, imgSubType) {
|
|
console.log('[viewFilePop] 호출:', imgType, imgSubType);
|
|
$("#frm_file_info [name=img_type]").val(imgType || "");
|
|
$("#frm_file_info [name=img_sub_type]").val(imgSubType || "");
|
|
|
|
// Dropzone 초기화 (imgType 전달)
|
|
initDropzone(imgType);
|
|
|
|
// 기존 이미지 로드
|
|
setTimeout(function() {
|
|
loadExistingImages(imgType, imgSubType);
|
|
}, 300);
|
|
|
|
$("#uploadModal").modal("show");
|
|
}
|
|
|
|
|
|
|
|
// 모달 닫힘 이벤트 처리
|
|
$(document).ready(function() {
|
|
// 중복 등록 방지를 위해 기존 핸들러 제거 후 재등록
|
|
$('#uploadModal').off('hide.bs.modal').on('hide.bs.modal', function () {
|
|
console.log('[Modal] ========== hide.bs.modal 시작 ==========');
|
|
console.log('[Modal] isModalClosing 설정 전:', window.isModalClosing);
|
|
window.isModalClosing = true;
|
|
console.log('[Modal] isModalClosing 설정 후:', window.isModalClosing);
|
|
|
|
// 중요: Dropzone removeFile() 호출하지 않음!
|
|
// removeFile()을 호출하면 removedfile 이벤트가 발생하여 의도치 않은 삭제가 발생할 수 있음
|
|
// 대신 모달이 완전히 닫힌 후 Dropzone을 destroy하여 정리함
|
|
if (dz) {
|
|
console.log('[Modal] 현재 Dropzone 파일 목록:');
|
|
dz.files.forEach(function(f, idx) {
|
|
console.log('[Modal] ' + (idx+1) + '. ' + f.name + ', isExisting:', f.isExisting + ', status:', f.status + ', img_sq:', f.img_sq);
|
|
});
|
|
console.log('[Modal] 주의: 파일 제거 하지 않음 (destroy로 정리 예정)');
|
|
}
|
|
});
|
|
|
|
$('#uploadModal').off('hidden.bs.modal').on('hidden.bs.modal', function () {
|
|
console.log('[Modal] ========== hidden.bs.modal 시작 ==========');
|
|
|
|
// 삭제 플래그 초기화
|
|
window.isBulkDeleting = false;
|
|
window.deletePromises = [];
|
|
window.uploadedFiles = [];
|
|
|
|
if (sortable) {
|
|
console.log('[Modal] Sortable 정리');
|
|
sortable.destroy();
|
|
sortable = null;
|
|
}
|
|
if (dz) {
|
|
console.log('[Modal] Dropzone 정리 (destroy)');
|
|
dz.destroy();
|
|
dz = null;
|
|
}
|
|
|
|
// 모든 정리 완료 후 플래그 초기화
|
|
window.isModalClosing = false;
|
|
console.log('[Modal] 모든 정리 완료, isModalClosing:', window.isModalClosing);
|
|
});
|
|
|
|
// ========== AJAX로 이미지 불러오기 ==========
|
|
// 페이지 로드 시 한 번에 모든 이미지를 불러와서 렌더링
|
|
const rsrvSq = $("#frm_file_info [name=rsrv_sq]").val();
|
|
if (rsrvSq) {
|
|
console.log('[PageLoad] AJAX로 이미지 로딩 시작, rsrv_sq:', rsrvSq);
|
|
loadAllImages(rsrvSq);
|
|
} else {
|
|
console.warn('[PageLoad] rsrv_sq가 없어서 이미지를 불러올 수 없습니다.');
|
|
}
|
|
|
|
// ========== 단지 목록 불러오기 ==========
|
|
// 페이지 로드 시 단지 목록을 가져와서 select 박스 채우기
|
|
loadComplexList();
|
|
// 평형 목록 불러 오기
|
|
loadPyeongInfo();
|
|
|
|
$(document).on('change', '#rcpt_hscp_nm', function() {
|
|
const selectedHscpNo = $(this).val();
|
|
console.log('[ComplexSelect] 단지 선택 변경, hscp_no:', selectedHscpNo);
|
|
$('input[name="rcpt_hscp_no"]').val(selectedHscpNo);
|
|
loadPyeongInfo();
|
|
});
|
|
|
|
});
|