4443 lines
171 KiB
PHP
4443 lines
171 KiB
PHP
<?php
|
|
$usr_level = session('usr_level');
|
|
|
|
?>
|
|
<?= $this->extend('layouts/main') ?>
|
|
<?= $this->section('content') ?>
|
|
|
|
<style>
|
|
.tbl_basic2 th {
|
|
padding: 0 10px;
|
|
height: 27px;
|
|
border: solid 1px #d8d9de;
|
|
background-color: #eff0f4;
|
|
letter-spacing: -1px;
|
|
font-weight: normal;
|
|
color: #5a5f69;
|
|
text-align: left;
|
|
}
|
|
|
|
.num {
|
|
font-family: Tahoma;
|
|
color: #b68556;
|
|
font-size: 17px;
|
|
}
|
|
|
|
.table-scroll {
|
|
max-height: 300px;
|
|
overflow-y: scroll;
|
|
}
|
|
</style>
|
|
|
|
<form id="rcptFrm" enctype="multipart/form-data" onsubmit="return false;">
|
|
<div class="main-card mb-2 card">
|
|
<div class="card-header bg-white border-bottom shadow-sm">
|
|
<div class="d-flex flex-wrap align-items-center w-100 justify-content-between card-header-tab">
|
|
<h4 class="mb-0 fw-bold text-dark">확인매물 상세 내용</h4>
|
|
<div class="d-flex align-items-center flex-nowrap gap-4 ms-auto" style="white-space:nowrap;">
|
|
<span class="text-muted me-2">매물ID:</span>
|
|
<span class="fw-bold text-primary fs-6 me-4"><?= esc($data['rcpt_atclno'] ?? '') ?></span>
|
|
<span class="text-muted me-2">CP ID:</span>
|
|
<span class="fw-bold text-primary fs-6 me-4"><?= esc($data['rcpt_cpid'] ?? '') ?></span>
|
|
<!-- 필요시 상태 등 추가 가능 -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<h5 class="card-title">공인 중개사 정보</h5>
|
|
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<colgroup>
|
|
<col width="15%" />
|
|
<col width="35%" />
|
|
<col width="15%" />
|
|
<col width="35%" />
|
|
</colgroup>
|
|
<tbody>
|
|
<tr>
|
|
<th>중개사ID</th>
|
|
<td><?= esc($data['agent_id'] ?? '') ?></td>
|
|
<th>중개사명</th>
|
|
<td><?= esc($data['agent_nm'] ?? '') ?></td>
|
|
</tr>
|
|
<tr>
|
|
<th>대표전화</th>
|
|
<td><?= esc($data['agent_head_tel'] ?? '') ?></td>
|
|
<th>담당자전화</th>
|
|
<td><?= esc($data['agent_contact_tel'] ?? '') ?></td>
|
|
</tr>
|
|
<tr>
|
|
<th>검증방식</th>
|
|
<td>
|
|
<?= (($data['isSiteVRVerification'] ?? '') === 'Y')
|
|
? "<span style='color:red;'>현장V2</span>"
|
|
: "현장"; ?>
|
|
</td>
|
|
<th>연락가능전화</th>
|
|
<td>
|
|
<?php $agent_tel = str_replace("-", "", $data['agent_tel'] ?? ''); ?>
|
|
<div class="d-flex align-items-center gap-2">
|
|
<input type="text" id="agent_tel" name="agent_tel" class="form-control form-control-sm" maxlength="16"
|
|
value="<?= esc($agent_tel) ?>" style="max-width: 220px;" />
|
|
<button type="button" class="btn btn-sm btn-outline-light" onclick="fn_save_tel();">저장</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 매물정보 -->
|
|
<form id="rcptFrm" enctype="multipart/form-data" onsubmit="return false;">
|
|
<input type="hidden" name="rcpt_sq" value="<?= $data['rcpt_sq'] ?>" />
|
|
<input type="hidden" name="rsrv_sq" value="<?= $data['rsrv_sq'] ?>" />
|
|
<input type="hidden" name="rcpt_atclno" value="<?= $data['rcpt_atclno'] ?>" />
|
|
<input type="hidden" name="rcpt_key" value="<?= $data['rcpt_key'] ?>" />
|
|
<input type="hidden" name="rcpt_product" id="rcpt_product" value="<?= $data['rcpt_product'] ?>" />
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">매물 정보</h5>
|
|
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<colgroup>
|
|
<col width="15%" />
|
|
<col width="35%" />
|
|
<col width="15%" />
|
|
<col width="35%" />
|
|
</colgroup>
|
|
<tbody>
|
|
<tr>
|
|
<th>등록일</th>
|
|
<td>
|
|
<?= $data['insert_tm'] ?>
|
|
</td>
|
|
<th>예약(촬영)요청일</th>
|
|
<td>
|
|
<?= $data['rsrv_date'] ?>
|
|
<?= $data['rsrv_tm_ap'] ?>
|
|
<?= $data['rsrv_tm_hour'] ?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>현장확인(촬영)일자</th>
|
|
<td>
|
|
<?= $data['photo_save_dt'] ?>
|
|
</td>
|
|
<th>가주소 여부</th>
|
|
<td>
|
|
<?php if ($data['virAddr_yn'] == 'Y') { ?><span style="font-weight: bold;color: red;">가주소</span>
|
|
<?php } else {
|
|
echo $data['virAddr_yn'];
|
|
} ?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>매물구분</th>
|
|
<td><?= $data['rcpt_product_nm'] ?></td>
|
|
<th>거래구분</th>
|
|
<td>
|
|
<select class="form-select" id="trade_type" onchange="trade_type_onchange();" disabled>
|
|
<option value="">거래구분</option>
|
|
<?php foreach ($codes as $c): ?>
|
|
<?php if ($c['category'] === "TRADE_TYPE"): ?>
|
|
<option value="<?= $c['cd'] ?>" <?php if ($c['cd'] === $data['trade_type']) {
|
|
echo "selected";
|
|
} ?>>
|
|
<?= $c['cd_nm'] ?>
|
|
</option>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th rowspan="3">지역구분</th>
|
|
<td rowspan="3">
|
|
<?= $data['addr'] ?>
|
|
</td>
|
|
<th>리 주소</th>
|
|
<td>
|
|
<input type="hidden" class="form-control" name="rcpt_dtl_addr" id="rcpt_dtl_addr"
|
|
value="<?= $data['rcpt_dtl_addr'] ?>" size="50" disabled="disabled" />
|
|
<input type="text" class="form-control" name="rcpt_dtl_addr1" id="rcpt_dtl_addr1"
|
|
value="<?= $data['rcpt_li_addr'] ?>" size="50" disabled="disabled" /><br />
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>상세주소</th>
|
|
<td class="d-flex gap-1">
|
|
<?php if (empty($data['rcpt_jibun_addr'])) { ?>
|
|
<input type="hidden" class="form-control" name="rcpt_dtl_addr2a" id="rcpt_dtl_addr2a"
|
|
value="<?= $data['rcpt_jibun_addr'] ?>" size="50" disabled="disabled" />
|
|
<input type="hidden" class="form-control" name="rcpt_dtl_addr2b" id="rcpt_dtl_addr2b"
|
|
value="<?= $data['rcpt_etc_addr'] ?>" size="50" disabled="disabled" />
|
|
<input type="text" class="form-control" name="rcpt_dtl_addr2" id="rcpt_dtl_addr2"
|
|
value="<?= $data['rcpt_dtl_addr'] ?>" size="50" disabled="disabled" /><br />
|
|
<input type="text" class="form-control" name="rcpt_dtl_addr3" id="rcpt_dtl_addr3"
|
|
value="<?= $data['rcpt_ho'] ?>" size="50" disabled="disabled" />
|
|
<input type="hidden" class="form-control" name="rcpt_ho" id="rcpt_ho" value="<?= $data['rcpt_ho'] ?>"
|
|
size="50" disabled="disabled" />
|
|
<?php } else { ?>
|
|
<input type="hidden" class="form-control" name="rcpt_dtl_addr2" id="rcpt_dtl_addr2"
|
|
value="<?= $data['rcpt_dtl_addr'] ?>" size="50" disabled="disabled" />
|
|
<input type="hidden" class="form-control" name="rcpt_dtl_addr3" id="rcpt_dtl_addr3"
|
|
value="<?= $data['rcpt_ho'] ?>" size="50" disabled="disabled" />
|
|
<input type="text" class="form-control" name="rcpt_dtl_addr2a" id="rcpt_dtl_addr2a"
|
|
value="<?= $data['rcpt_jibun_addr'] ?>" size="50" disabled="disabled" /><br />
|
|
<input type="text" class="form-control" name="rcpt_dtl_addr2b" id="rcpt_dtl_addr2b"
|
|
value="<?= $data['rcpt_etc_addr'] ?>" size="50" disabled="disabled" />
|
|
<input type="hidden" class="form-control" name="rcpt_ho" id="rcpt_ho" value="<?= $data['rcpt_ho'] ?>"
|
|
size="50" disabled="disabled" />
|
|
<?php } ?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>기타주소</th>
|
|
<td>
|
|
<input type="text" class="form-control" name="rcpt_ref_addr" id="rcpt_ref_addr"
|
|
value="<?= $data['rcpt_ref_addr'] ?>" size="50" disabled="disabled" />
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>단지명</th>
|
|
<td></td>
|
|
<th>가격</th>
|
|
<td>
|
|
<?php
|
|
// 숫자 콤마 제거(표시용)
|
|
$v2 = str_replace(',', '', $data['rcpt_product_info2'] ?? '');
|
|
$v3 = str_replace(',', '', $data['rcpt_product_info3'] ?? '');
|
|
$v4 = str_replace(',', '', $data['rcpt_product_info4'] ?? '');
|
|
$v5 = str_replace(',', '', $data['rcpt_product_info5'] ?? '');
|
|
|
|
// 분양가/프리미엄 노출 조건
|
|
$chk_array = ['B01', 'B02', 'B03'];
|
|
$show_sale_premium = (in_array(($data['rcpt_product'] ?? ''), $chk_array) || ($data['trade_type'] ?? '') === 'A1');
|
|
|
|
?>
|
|
|
|
<!-- 보증금/금액 -->
|
|
<div class="d-flex flex-column gap-1">
|
|
<div class="d-flex align-items-center gap-1 flex-wrap">
|
|
<input type="text" class="form-control form-control-sm" name="rcpt_product_info2"
|
|
id="rcpt_product_info2" value="<?= esc($v2) ?>" style="width: 110px;" disabled />
|
|
<span class="small text-nowrap">만원</span>
|
|
</div>
|
|
|
|
<!-- 월세(월) -->
|
|
<div id="div_trade_type_price_monthly">
|
|
<div class="d-flex align-items-center gap-1 flex-wrap">
|
|
<input type="text" class="form-control form-control-sm" name="rcpt_product_info3"
|
|
id="rcpt_product_info3" value="<?= esc($v3) ?>" style="width: 110px;" disabled />
|
|
<span class="small text-nowrap">만원 (월)</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 분양가 / 프리미엄 -->
|
|
<?php if ($show_sale_premium): ?>
|
|
<div class="d-flex align-items-center gap-2 flex-wrap mt-1">
|
|
<span class="small text-nowrap">분양가</span>
|
|
<input type="text" class="form-control form-control-sm" name="rcpt_product_info4"
|
|
id="rcpt_product_info4" value="<?= esc($v4) ?>" style="width: 110px;" disabled />
|
|
<span class="small text-nowrap">만원</span>
|
|
|
|
<span class="small text-muted">/</span>
|
|
|
|
<span class="small text-nowrap">프리미엄</span>
|
|
<input type="text" class="form-control form-control-sm" name="rcpt_product_info5"
|
|
id="rcpt_product_info5" value="<?= esc($v5) ?>" style="width: 110px;" disabled />
|
|
<span class="small text-nowrap">만원</span>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- 버튼 -->
|
|
<div class="d-flex align-items-center justify-content-end gap-1 mt-2">
|
|
<button type="button" class="btn btn-sm btn-outline-light btn-edit"
|
|
onclick="editPriceInfo();">수정</button>
|
|
<button type="button" class="btn btn-sm btn-outline-success btn-save"
|
|
onclick="modifyPriceInfo();">가격수정</button>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th>평형</th>
|
|
<td></td>
|
|
<?php
|
|
$chk_product_nm = [
|
|
'C04', // 전원주택
|
|
'D03', // 빌딩,건물
|
|
'D04', // 상가,건물
|
|
'E01', // 숙박,콘도
|
|
'E02', // 공장,창고
|
|
'Z00' // 기타
|
|
];
|
|
|
|
if (in_array($data['rcpt_product'], array('C03', 'C05', 'C06')) && $data['rcpt_product_info1'] == '매매') {
|
|
echo ("<th>지하층 / 지상층</th>");
|
|
} else if (in_array($data['rcpt_product'], $chk_product_nm)) {
|
|
echo ("<th>지하층 / 지상층</th>");
|
|
} else {
|
|
echo ("<th>층 / 총층</th>");
|
|
}
|
|
?>
|
|
<td class="d-flex gap-1">
|
|
<input type="text" class="form-control" name="rcpt_floor" id="rcpt_floor"
|
|
value="<?= $data['rcpt_floor'] ?>" size="8" maxlength="3" disabled="disabled"
|
|
style="width: 100px;" />
|
|
<input type="text" class="form-control" name="rcpt_floor2" id="rcpt_floor2"
|
|
value="<?= $data['rcpt_floor2'] ?>" size="8" maxlength="3" disabled="disabled"
|
|
style="width: 100px;" />
|
|
</td>
|
|
</tr>
|
|
<tr class="spc">
|
|
<th></th>
|
|
<td></td>
|
|
<th>면적확인파일1</th>
|
|
<td>
|
|
<?php
|
|
$arrI6 = [];
|
|
$arrI7 = [];
|
|
foreach ($images as $key => $img) {
|
|
switch ($img['img_type']) {
|
|
case "I6":
|
|
$arrI6[] = $img;
|
|
unset($images[$key]);
|
|
break;
|
|
|
|
case "I7":
|
|
$arrI7[] = $img;
|
|
unset($images[$key]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!empty($arrI6)) { ?>
|
|
<?php foreach ($arrI6 as $img) {
|
|
$sq = $img['img_sq'];
|
|
|
|
$link = $img['img_path'] . $img['img_filenm'];
|
|
$temp2 = explode(".", $img['img_filenm']);
|
|
//$name = $temp2[0]."_thumb.".$temp2[1];
|
|
$name = $temp2[0] . "_thumb.jpg";
|
|
$thumblink = $img['img_path'] . $name;
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$thumblink = NCLOUD_OBJECT_STORAGE_URL . $thumblink;
|
|
$link = NCLOUD_OBJECT_STORAGE_URL . $link;
|
|
}
|
|
|
|
?>
|
|
<div id="img_file_dis_I6" style="padding: 6px 0;">
|
|
<a onclick="fn_preview('<?= $link ?>')">
|
|
<img id="photo-display2_I6" src="<?= $thumblink ?>" alt="Image" class="lazy" />
|
|
</a>
|
|
</div>
|
|
<?php } ?>
|
|
<?php } else { ?>
|
|
<div id="img_file_dis_I6" style="padding: 10px 0;">
|
|
<img id="photo-display2_I6" src="/plugin/img/photo.gif" alt="No Image" />
|
|
</div>
|
|
<?php } ?>
|
|
</td>
|
|
</tr>
|
|
<tr class="spc">
|
|
<th>방</th>
|
|
<td></td>
|
|
<th>면적확인파일2</th>
|
|
<td>
|
|
<?php if (!empty($arrI7)) { ?>
|
|
<?php foreach ($arrI7 as $img) {
|
|
$sq = $img['img_sq'];
|
|
|
|
$link = $img['img_path'] . $img['img_filenm'];
|
|
$temp2 = explode(".", $img['img_filenm']);
|
|
//$name = $temp2[0]."_thumb.".$temp2[1];
|
|
$name = $temp2[0] . "_thumb.jpg";
|
|
$thumblink = $img['img_path'] . $name;
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$thumblink = NCLOUD_OBJECT_STORAGE_URL . $thumblink;
|
|
$link = NCLOUD_OBJECT_STORAGE_URL . $link;
|
|
}
|
|
|
|
?>
|
|
<div id="img_file_dis_I6" style="padding: 6px 0;">
|
|
<a onclick="fn_preview('<?= $link ?>')">
|
|
<img id="photo-display2_I6" src="<?= $thumblink ?>" alt="Image" class="lazy" />
|
|
</a>
|
|
</div>
|
|
<?php } ?>
|
|
<?php } else { ?>
|
|
<div id="img_file_dis_I6" style="padding: 10px 0;">
|
|
<img id="photo-display2_I6" src="/plugin/img/photo.gif" alt="No Image" />
|
|
</div>
|
|
<?php } ?>
|
|
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>지도좌표</th>
|
|
<td class="d-flex text-nowrap gap-1">
|
|
<div class="d-flex flex-nowrap gap-1">
|
|
|
|
<!-- 좌표 입력 -->
|
|
<div class="d-flex align-items-center gap-2 flex-wrap">
|
|
<div class="d-flex align-items-center gap-1">
|
|
<span class="small text-nowrap">경도</span>
|
|
<input type="text" class="form-control form-control-sm" name="rcpt_x" id="rcpt_x"
|
|
value="<?= esc($data['rcpt_x'] ?? '') ?>" style="width: 140px;" disabled />
|
|
</div>
|
|
|
|
<div class="d-flex align-items-center gap-1">
|
|
<span class="small text-nowrap">위도</span>
|
|
<input type="text" class="form-control form-control-sm" name="rcpt_y" id="rcpt_y"
|
|
value="<?= esc($data['rcpt_y'] ?? '') ?>" style="width: 140px;" disabled />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 버튼 -->
|
|
<div class="d-flex align-items-center gap-1 flex-wrap">
|
|
<button type="button" class="btn btn-sm btn-outline-light" id="btnSilverReadLatLng"
|
|
onclick="ajax_get_geocode();" disabled>
|
|
주소좌표
|
|
</button>
|
|
|
|
<button type="button" class="btn btn-sm btn-outline-light" id="btnSilverModifyMap"
|
|
onclick="modifyMap();" disabled>
|
|
지도좌표
|
|
</button>
|
|
</div>
|
|
|
|
</div>
|
|
</td>
|
|
<th></th>
|
|
<td colspan="2" class="d-flex gap-1 justify-content-end">
|
|
<button type="button" class="btn btn-sm btn-outline-light" id="btnSilverReadLatLng" onclick="">
|
|
수정
|
|
</button>
|
|
|
|
<button type="button" class="btn btn-sm btn-outline-light" id="btnSilverModifyMap" onclick="">
|
|
저장
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 거주여부 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">거주여부</h5>
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<tbody>
|
|
<tr>
|
|
<th>거주여부</th>
|
|
<td id="db_yn0">
|
|
<select class="form-select" name="resYn" id="resYn" onchange="dbYn_change(this.value);">
|
|
<option value="Y">Y</option>
|
|
<option value="N" selected="">N</option>
|
|
</select>
|
|
</td>
|
|
<th>
|
|
<div id="db_yn1">DB활용동의여부</div>
|
|
</th>
|
|
<td>
|
|
<div id="db_yn2">
|
|
<select class="form-select" name="dbUsageAgrYn" id="dbUsageAgrYn">
|
|
<option value="N" selected="">N</option>
|
|
<option value="Y">Y</option>
|
|
</select>
|
|
</div>
|
|
</td>
|
|
<td style="text-align: center;">
|
|
<button type="button" class="btn btn-sm btn-outline-light">저장</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 평면도요청 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">평면도요청</h5>
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<tbody>
|
|
<tr>
|
|
<th style="width: 100px;">
|
|
<div id="ground_plan">평면도요청</div>
|
|
</th>
|
|
<td>
|
|
<select class="form-select" name="ground_plan" id="ground_plan" style="width: 100px;">
|
|
<option value="N">N</option>
|
|
<option value="Y" selected="">Y</option>
|
|
</select>
|
|
</td>
|
|
<th style="width: 200px;">평면도 등록 여부</th>
|
|
<td>
|
|
<?php
|
|
$intAptChk = 0;
|
|
$typeArray = ['아파트', '주상복합', '오피스텔'];
|
|
if (empty($apt_ground))
|
|
$apt_ground = [];
|
|
foreach ($apt_ground as $gval) {
|
|
|
|
|
|
$addr = $gval['addr2'];
|
|
$hscp_no = $gval['hscp_no'];
|
|
|
|
if (in_array($data['rcpt_product_nm'], $typeArray)) {
|
|
if (strpos($data['rcpt_atclno'], $hscp_no) !== false) {
|
|
$intAptChk++;
|
|
}
|
|
} else {
|
|
|
|
$strAddrArray = explode(" ", $data['rcpt_dtl_addr']);
|
|
|
|
if ($addr == $strAddrArray['0']) {
|
|
$intAptChk++;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($intAptChk > 0) {
|
|
echo "Y";
|
|
} else {
|
|
echo "N";
|
|
}
|
|
?>
|
|
</td>
|
|
<td style="text-align: center;">
|
|
<button type="button" class="btn btn-sm btn-outline-light" onclick="res_ground();">저장</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 예약확정 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">예약확정</h5>
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<colgroup>
|
|
<col width="15%" />
|
|
<col width="35%" />
|
|
<col width="15%" />
|
|
<col width="35%" />
|
|
</colgroup>
|
|
<tbody>
|
|
<tr>
|
|
<th>방문희망일시</th>
|
|
<td class="d-flex gap-1" colspan="3">
|
|
<input type="text" name="rsrv_date" id="rsrv_date" class="form-control"
|
|
value="<?= $data['rsrv_date'] ?>" size="13" readonly />
|
|
<select class="form-select" name="rsrv_tm_ap" onchange="rsrv_tm_ap_onchange(this.value)">
|
|
<option value="">오전/오후</option>
|
|
<option value="00" <?php if (empty($data['rsrv_tm_ap']))
|
|
echo "selected"; ?>>무관</option>
|
|
<option value="AM" <?php if ($data['rsrv_tm_ap'] == 'AM')
|
|
echo "selected"; ?>>오전</option>
|
|
<option value="PM" <?php if ($data['rsrv_tm_ap'] == 'PM')
|
|
echo "selected"; ?>>오후</option>
|
|
</select>
|
|
<select class="form-select" name="rsrv_tm_hour" id="rsrv_tm_hour">
|
|
<option value="">-시-</option>
|
|
<option value="00" <? if ('00' == $data['rsrv_tm_hour'])
|
|
echo "selected"; ?>>무관</option>
|
|
<?php for ($i = 1; $i <= 24; $i++) {
|
|
$hh = sprintf("%02s", $i);
|
|
?>
|
|
<option value="<?= $hh ?>" <? if ($hh == $data['rsrv_tm_hour'])
|
|
echo "selected"; ?>>
|
|
<?= $hh ?>시
|
|
</option>
|
|
<?php } ?>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>방문날짜</th>
|
|
<td>
|
|
<?= $data['rsrv_date'] ?>
|
|
<?= $data['rsrv_tm_ap'] ?>
|
|
<?php if (!empty($data['rsrv_tm_hour']))
|
|
echo $data['rsrv_tm_hour'] . "시"; ?>
|
|
</td>
|
|
<th>담당자</th>
|
|
<td class="d-flex gap-1">
|
|
<select class="form-select" id="bonbu">
|
|
<option value="">본부선택</option>
|
|
<?php
|
|
|
|
foreach ($bonbu as $b): ?>
|
|
<option value="<?= $b['dept_sq'] ?>">
|
|
<?= $b['dept_nm'] ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<select class="form-select" id="team">
|
|
<option value="">팀선택</option>
|
|
<?php
|
|
$team_dept = $data['dept_sq'];
|
|
if (empty($data['dept_sq'])) {
|
|
$team_dept = $data['region_dept_sq'];
|
|
}
|
|
foreach ($team as $t): ?>
|
|
<option value="<?= $t['dept_sq'] ?>" <?php if ($t['dept_sq'] === $team_dept) {
|
|
echo "selected";
|
|
} ?>>
|
|
<?= $t['dept_nm'] ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<select class="form-select" id="user">
|
|
<option value="">담당자선택</option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="card-footer justify-content-end">
|
|
<button type="button" class="btn btn-sm btn-outline-success">저장</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 동영상촬영여부 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">동영상촬영여부</h5>
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<tbody>
|
|
<tr>
|
|
<th style="width: 200px;">
|
|
동영상촬영여부
|
|
</th>
|
|
<td>
|
|
<select class="form-select" name="exp_movie_yn" id="exp_movie_yn" style="width: 150px;">\
|
|
<option value="">-선택-</option>
|
|
<option value="N" <?php if ($data['exp_movie_yn'] == 'N')
|
|
echo "selected"; ?>>N</option>
|
|
<option value="Y" <?php if ($data['exp_movie_yn'] == 'N')
|
|
echo "selected"; ?>>Y</option>
|
|
</select>
|
|
</td>
|
|
<td style="text-align: center;">
|
|
<button type="button" class="btn btn-sm btn-outline-light" onclick="requestMovie();">저장</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 중개인 요청사항 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">중개인 요청사항</h5>
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<tbody>
|
|
<tr>
|
|
<th style="width: 200px;">
|
|
중개인 요청사항
|
|
</th>
|
|
<td>
|
|
<textarea class="form-control" id="request_msg" style="height:100px;resize: none;">
|
|
<?= $data['request_msg'] ?>
|
|
</textarea>
|
|
</td>
|
|
<td style="text-align: center;">
|
|
<button type="button" class="btn btn-sm btn-outline-light" onclick="requestMessage();">저장</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 시간대별 통계 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">
|
|
담당자 예약현황 (<?= $data['rsrv_date'] ?>)
|
|
</h5>
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<tbody>
|
|
<tr>
|
|
<?php if ($tmCount): ?>
|
|
<?php foreach ($tmCount as $tm): ?>
|
|
<th>
|
|
<?= $tm['rsrv_tm_ap'] ?>
|
|
<?= $tm['rsrv_tm_hour'] ?> 시
|
|
</th>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tr>
|
|
<tr>
|
|
<?php if ($tmCount): ?>
|
|
<?php foreach ($tmCount as $tm): ?>
|
|
<td><?= $tm['cnt'] ?> 건</td>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 취소 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">취소</h5>
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<tbody>
|
|
<tr>
|
|
<th style="width: 100px;">
|
|
<div id="ground_plan">취소</div>
|
|
</th>
|
|
<td class="d-flex gap-1">
|
|
<select class="form-select" name="result_cd2" id="result_cd2" style="width: 100px;">
|
|
<option value="">분류1</option>
|
|
<?php foreach ($codes as $c): ?>
|
|
<?php if ($c['category'] === "RECEIPT_STATUS2"): ?>
|
|
<?php if (substr($c['cd'], 0, 2) == "90"): ?>
|
|
<option value="<?= $c['cd'] ?>" <?php if ($c['cd'] === $data['result_cd2']) {
|
|
echo "selected";
|
|
} ?>>
|
|
<?= $c['cd_nm'] ?>
|
|
</option>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<select class="form-select" name="result_cd3" id="result_cd3" style="width: 100px;">
|
|
<option value="">분류2</option>
|
|
</select>
|
|
</td>
|
|
<th style="width: 150px;">취소사유</th>
|
|
<td>
|
|
<input type="text" class="form-control" id="result_msg" value="<?= $data['result_msg'] ?>" />
|
|
</td>
|
|
<td style="text-align: center;">
|
|
<button type="button" class="btn btn-sm btn-outline-light" onclick="rsrvcancel();">저장</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 매물 상태 정보 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">매물 상태 정보
|
|
<div class="d-flex justify-content-end">
|
|
<?php
|
|
if (in_array($usr_level, ['1'])): ?>
|
|
<button type="button" class="btn btn-outline-warning">검수지연으로 상태변경</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
</h5>
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<?php
|
|
$stat1 = $data['rsrv_delay_dt_dt'] . "<br/>" . $data['rsrv_delay_dt_tm']; //예약지연
|
|
$stat2 = $data['rsrv_cplt_dt_dt'] . "<br/>" . $data['rsrv_cplt_dt_tm']; //에약확인
|
|
if ($data['req_rec_yn'] == "Y") { //촬영
|
|
$stat3 = $data['photo_save_dt_dt'] . "<br/>" . $data['photo_save_dt_tm'] . "<br/>녹취필요";
|
|
} else {
|
|
$stat3 = $data['photo_save_dt_dt'] . "<br/>" . $data['photo_save_dt_tm'];
|
|
}
|
|
$stat4 = $data['check_delay_dt_dt'] . "<br/>" . $data['check_delay_dt_tm']; //검수지연
|
|
$stat5 = $data['check_fail_dt_dt'] . "<br/>" . $data['check_fail_dt_tm']; //검수실패
|
|
$stat6 = $data['check_dt_dt'] . "<br/>" . $data['check_dt_tm']; //검수
|
|
$stat7 = $data['check_cplt_dt_dt'] . "<br/>" . $data['check_cplt_dt_tm']; //검수완료
|
|
$stat8 = $data['cancel_dt_dt'] . "<br/>" . $data['cancel_dt_tm']; //취소
|
|
|
|
$currStat = substr($data['rcpt_stat'], 0, 2);
|
|
$currStat2 = substr($data['rcpt_stat'], 2, 2);
|
|
|
|
if ($currStat == 15) { //예약지연
|
|
$stat1 = "<b><font color='red'>" . $stat1 . "</font></b>";
|
|
} else if ($currStat == 20) { //예약확인
|
|
$stat2 = "<b><font color='red'>" . $stat2 . "</font></b>";
|
|
} else if ($currStat == 40) { //촬영
|
|
$stat3 = "<b><font color='red'>" . $stat3 . "</font></b>";
|
|
} else if ($currStat == 50) { //검수
|
|
$stat6 = "<b><font color='red'>" . $stat6 . "</font></b>";
|
|
} else if ($currStat == 60) { //검수완료
|
|
$stat7 = "<b><font color='red'>" . $stat7 . "</font></b>";
|
|
} else if ($currStat == 70) { //검수지연
|
|
$stat4 = "<b><font color='red'>" . $stat4 . "<br/>" . $data['rcpt_stat_nm'] . "</font></b>";
|
|
}
|
|
if ($currStat == 90 && $currStat2 != 50) { //취소
|
|
$stat8 = "<b><font color='red'>" . $stat8 . "<br/>" . $data['result_cd2_nm'] . "</font></b>";
|
|
} else if ($currStat == 90 && $currStat2 == 50) { //검수실패
|
|
$stat5 = "<b><font color='red'>" . $stat5 . "<br/>" . $data['rcpt_stat_nm'] . "</font></b>";
|
|
}
|
|
?>
|
|
<tr>
|
|
<th rowspan="2" width="100" style="text-align:center">현장확인<br />진행상황</th>
|
|
<th style="text-align:center">예약지연</th>
|
|
<th style="text-align:center">예약확인</th>
|
|
<th style="text-align:center">촬영</th>
|
|
<th style="text-align:center">검수지연</th>
|
|
<th style="text-align:center">검수실패</th>
|
|
<th style="text-align:center">검수</th>
|
|
<th style="text-align:center">검수완료</th>
|
|
<th style="text-align:center">취소</th>
|
|
</tr>
|
|
<tr>
|
|
<td style="text-align:center; height: 50px;">
|
|
<?= $stat1 ?>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<?= $stat2 ?>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<?= $stat3 ?>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<?= $stat4 ?>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<?= $stat5 ?>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<?= $stat6 ?>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<?= $stat7 ?>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<?= $stat8 ?>
|
|
</td>
|
|
</tr>
|
|
<?php if (!in_array($usr_level, [])): ?>
|
|
<tr>
|
|
<th>상태변경</th>
|
|
<?php if ($currStat == 10) { ?>
|
|
<td height="33" style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" onclick="chgStatus(150000);">예약지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" onclick="chgStatus(200000);">예약확인</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>촬영</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수</button>
|
|
</td>
|
|
<td style="text-align:center"></td>
|
|
<td style="text-align:center"></td>
|
|
<?php } else if ($currStat == 15) { ?>
|
|
<td height="33" style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" onclick="chgStatus(200000);">예약확인</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>촬영</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수</button>
|
|
</td>
|
|
<td style="text-align:center"></td>
|
|
<td style="text-align:center"></td>
|
|
<?php } else if ($currStat == 20) { ?>
|
|
<td height="33" style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약확인</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" onclick="chgStatus(400000);">촬영</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수</button>
|
|
</td>
|
|
<td style="text-align:center"></td>
|
|
<td style="text-align:center"></td>
|
|
<?php } else if ($currStat == 40) { ?>
|
|
<td height="33" style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약확인</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>촬영</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" onclick="chgStatus(700000);">검수지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success"
|
|
onclick="chgStatus(500000, '<?= $data['rcpt_product'] ?>', '<?= $data['chg_floor_yn'] ?>');">검수</button>
|
|
</td>
|
|
<td style="text-align:center"></td>
|
|
<td style="text-align:center"></td>
|
|
<?php } else if ($currStat == 70) { ?>
|
|
<td height="33" style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약확인</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>촬영</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success"
|
|
onclick="chgStatus(500000, '<?= $data['rcpt_product'] ?>', '<?= $data['chg_floor_yn'] ?>');">검수</button>
|
|
</td>
|
|
<td style="text-align:center;"> </td>
|
|
<td style="text-align:center"></td>
|
|
<?php } else if ($currStat == 50) { ?>
|
|
<td height="33" style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약확인</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" onclick="chgStatus(400000);">촬영</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" onclick="chgStatus(700000);">검수지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수</button>
|
|
</td>
|
|
<td style="text-align:center"></td>
|
|
<td style="text-align:center"></td>
|
|
<?php } else if ($currStat == 60) { //검수완료 ?>
|
|
<td height="33" style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약확인</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>촬영</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수</button>
|
|
</td>
|
|
<td style="text-align:center"></td>
|
|
<td style="text-align:center"></td>
|
|
<?php }
|
|
if ($currStat == 90 && $currStat2 != 50) { //취소 ?>
|
|
<td height="33" style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약확인</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>촬영</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수</button>
|
|
</td>
|
|
<td style="text-align:center"></td>
|
|
<td style="text-align:center"></td>
|
|
<?php } else if ($currStat == 90 && $currStat2 == 50) { //검수실패 ?>
|
|
<td height="33" style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>예약확인</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>촬영</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success" disabled>검수지연</button>
|
|
</td>
|
|
<td style="text-align:center">
|
|
</td>
|
|
<td style="text-align:center">
|
|
<button type="button" class="btn btn-sm btn-success"
|
|
onclick="chgStatus(500000, '<?= $data['rcpt_product'] ?>', '<?= $data['chg_floor_yn'] ?>');">검수</button>
|
|
</td>
|
|
<td style="text-align:center"></td>
|
|
<td style="text-align:center"></td>
|
|
<?php } ?>
|
|
</tr>
|
|
<?php endif; ?>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- SMS 보내기 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">SMS 보내기</h5>
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<?php
|
|
$smsList = [];
|
|
foreach ($codes as $c) {
|
|
if ($c['category'] === "SMS_MSG_TYPE") {
|
|
array_push($smsList, $c);
|
|
}
|
|
}
|
|
|
|
$smsTot = sizeof($smsList);
|
|
$rowspan = ceil($smsTot / 6);
|
|
?>
|
|
<tr>
|
|
<th rowspan="<?= $rowspan ?>" style="text-align:center">
|
|
상황별<br />SMS선택
|
|
</th>
|
|
<?php
|
|
$smsCnt = 1;
|
|
foreach ($smsList as $sms1):
|
|
if (!in_array($sms1['cd'], ["S10", "S3", "S7", "S15"])) {
|
|
continue;
|
|
}
|
|
?>
|
|
<td style="text-align:center">
|
|
<a href="javascript:viewSmsPop('<?= $sms1['cd'] ?>');">
|
|
<?= $sms1['category_nm'] ?>
|
|
</a>
|
|
</td>
|
|
<?php
|
|
if ($smsCnt % 6 == 0) {
|
|
echo "</tr><tr>";
|
|
}
|
|
$smsCnt++;
|
|
endforeach; ?>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 매물 위치 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">매물 위치</h5>
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<colgroup>
|
|
<col width="25%">
|
|
</colgroup>
|
|
|
|
<tr>
|
|
<td colspan="2" style="padding:5px;">
|
|
<div id="mapArea" style="width:100%;height:300px;"></div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 확인 정보 및 사진 정보 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">확인 정보 및 사진 정보</h5>
|
|
<div class="row g-3">
|
|
|
|
<!-- 홍보확인서 -->
|
|
<div class="col-12 col-lg-10p">
|
|
<div class="border rounded-3 p-2 ">
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<div class="fw-semibold">홍보확인서</div>
|
|
|
|
<!-- 업로드 버튼 -->
|
|
<button type="button" class="btn btn-sm btn-outline-secondary"
|
|
onclick="viewFilePop('I1', '')">파일</button>
|
|
</div>
|
|
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<?php
|
|
$arrI1 = array();
|
|
reset($images);
|
|
foreach ($images as $key => $img) {
|
|
if ($img['img_type'] == 'I1') {
|
|
$arrI1[] = $img;
|
|
unset($images[$key]);
|
|
}
|
|
}
|
|
if (!empty($arrI1)) {
|
|
foreach ($arrI1 as $img) {
|
|
list($filename, $ext) = explode(".", $img['img_filenm']);
|
|
$thumbname = $filename . "_thumb.jpg";
|
|
|
|
$imgPath = $img['img_path'] . $thumbname;
|
|
$link = $img['img_path'] . $img['img_filenm'];
|
|
|
|
$link = realFilePath($link);
|
|
$imgPath = realFilePath($imgPath);
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$imgPath = NCLOUD_OBJECT_STORAGE_URL . $img['img_path'] . $thumbname;
|
|
$link = NCLOUD_OBJECT_STORAGE_URL . $img['img_path'] . $img['img_filenm'];
|
|
}
|
|
|
|
$sq = $img['img_sq'];
|
|
}
|
|
?>
|
|
<a onclick="fn_preview('<?= $link ?>')">
|
|
<img id="photo-display2_I1" src="<?= $link ?>" alt="홍보확인서" class="w-100 object-fit-contain">
|
|
</a>
|
|
<?php } else { ?>
|
|
<img id="photo-display2_I1" src="/plugin/img/photo.gif" alt="홍보확인서" class="w-100 object-fit-contain">
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 촬영동의서 -->
|
|
<div class="col-12 col-lg-10p">
|
|
<div class="border rounded-3 p-2 ">
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<div class="fw-semibold">촬영동의서</div>
|
|
<button type="button" class="btn btn-sm btn-outline-secondary"
|
|
onclick="viewFilePop('I10', '')">파일</button>
|
|
</div>
|
|
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<?php
|
|
if (isset($imgs_count['I10']) && $imgs_count['I10'] != 0) {
|
|
foreach ($images as $img) {
|
|
if ($img['img_type'] == 'I10') {
|
|
$temp2 = explode(".", $img['img_filenm']);
|
|
//$name = $temp2[0]."_thumb.".$temp2[1];
|
|
$name = $temp2[0] . "_thumb.jpg";
|
|
|
|
$image_name = $img['img_path'] . $img['img_filenm'];
|
|
$thumbnail_image_name = $img['img_path'] . $name;
|
|
$agreement_image = realFilePath($image_name);
|
|
$agreement_image_thumbnail = realFilePath($thumbnail_image_name);
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$agreement_image_thumbnail = NCLOUD_OBJECT_STORAGE_URL . $thumbnail_image_name;
|
|
$agreement_image = NCLOUD_OBJECT_STORAGE_URL . $img['img_path'] . $img['img_filenm'];
|
|
}
|
|
?>
|
|
|
|
<a onclick="fn_preview('<?= $agreement_image ?>')">
|
|
<img src="<?= $agreement_image_thumbnail ?>" alt="촬영동의서" class="w-100 object-fit-contain">
|
|
</a>
|
|
<?php
|
|
}
|
|
}
|
|
} else {
|
|
?>
|
|
<img src="/plugin/img/photo.gif" alt="촬영동의서" class="w-100 object-fit-contain">
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 현장확인내역서 -->
|
|
<div class="col-12 col-lg-10p">
|
|
<div class="border rounded-3 p-2 ">
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<div class="fw-semibold">현장확인내역서</div>
|
|
<button type="button" class="btn btn-sm btn-outline-secondary"
|
|
onclick="viewFilePop('I2', '')">파일</button>
|
|
</div>
|
|
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<?php
|
|
if (isset($imgs_count['I2']) && $imgs_count['I2'] != 0) {
|
|
foreach ($images as $img) {
|
|
if ($img['img_type'] == 'I2') {
|
|
$temp2 = explode(".", $img['img_filenm']);
|
|
//$name = $temp2[0]."_thumb.".$temp2[1];
|
|
$name = $temp2[0] . "_thumb.jpg";
|
|
$image_name = $img['img_path'] . $img['img_filenm'];
|
|
$thumbnail_image_name = $img['img_path'] . $name;
|
|
$agreement_image = realFilePath($image_name);
|
|
$agreement_image_thumbnail = realFilePath($thumbnail_image_name);
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$agreement_image_thumbnail = NCLOUD_OBJECT_STORAGE_URL . $thumbnail_image_name;
|
|
$agreement_image = NCLOUD_OBJECT_STORAGE_URL . $img['img_path'] . $img['img_filenm'];
|
|
}
|
|
?>
|
|
<a onclick="fn_preview('<?= $agreement_image ?>')">
|
|
<img src="<?= $agreement_image_thumbnail ?>" alt="현장확인내역서" class="w-100 object-fit-contain">
|
|
</a>
|
|
<?php
|
|
}
|
|
}
|
|
} else {
|
|
?>
|
|
<img src="/plugin/img/photo.gif" alt="현장확인내역서" class="w-100 object-fit-contain">
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 분양권(썸네일 여러개 + 파일 버튼) -->
|
|
<div class="my-3">
|
|
<div class="border rounded-3 p-2">
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<div class="fw-semibold">분양권 (최대 5장)</div>
|
|
|
|
<!-- 버튼 그룹 -->
|
|
<div class="d-flex gap-1">
|
|
<button type="button" class="btn btn-sm btn-outline-secondary"
|
|
onclick="viewFilePop('I8', '0')">파일</button>
|
|
<button type="button" class="btn btn-sm btn-outline-success"
|
|
onclick="downloadImagesByType('I8', '분양권')">일괄다운로드</button>
|
|
<button type="button" class="btn btn-sm btn-outline-danger"
|
|
onclick="deleteAllImagesByType('I8', '분양권')">일괄삭제</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex flex-wrap gap-2">
|
|
<!-- NOTE: 기존 코드가 id 중복(photo-display2_I8)이라 반드시 고쳐야 함 -->
|
|
<?php
|
|
$arrI8 = array();
|
|
reset($images);
|
|
foreach ($images as $key => $img) {
|
|
if ($img['img_type'] == 'I8') {
|
|
$arrI8[] = $img;
|
|
unset($images[$key]);
|
|
}
|
|
}
|
|
if (!empty($arrI8)) {
|
|
|
|
foreach ($arrI8 as $img) {
|
|
list($filename, $ext) = explode(".", $img['img_filenm']);
|
|
$thumbname = $filename . "_thumb.jpg";
|
|
|
|
$imgPath = $img['img_path'] . $thumbname;
|
|
$link = $img['img_path'] . $img['img_filenm'];
|
|
|
|
$agreement_image = realFilePath($link);
|
|
$agreement_image_thumbnail = realFilePath($imgPath);
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$agreement_image_thumbnail = NCLOUD_OBJECT_STORAGE_URL . $imgPath;
|
|
$agreement_image = NCLOUD_OBJECT_STORAGE_URL . $link;
|
|
}
|
|
?>
|
|
<div style="width: 150px;">
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<a onclick="fn_preview('<?= $agreement_image ?>')" class="d-flex align-items-center justify-content-center">
|
|
<img src="<?= $agreement_image_thumbnail ?>" alt="분양권" class="w-100 h-100 object-fit-contain">
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<?php } ?>
|
|
<?php } else { ?>
|
|
<div style="width: 150px;">
|
|
<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>
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 매물사진 -->
|
|
<div class="my-3">
|
|
<div class="border rounded-3 p-2">
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<div class="fw-semibold">매물사진 (최대 15장)</div>
|
|
|
|
<div class="d-flex gap-1 flex-wrap">
|
|
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="viewFilePop('I4', '')">파일</button>
|
|
<button type="button" class="btn btn-sm btn-outline-primary"
|
|
onclick="savePropertyImageOrder()">순서저장</button>
|
|
<button type="button" class="btn btn-sm btn-outline-success"
|
|
onclick="downloadImagesByType('I4', '매물사진')">일괄다운로드</button>
|
|
<button type="button" class="btn btn-sm btn-outline-danger"
|
|
onclick="deleteAllImagesByType('I4', '매물사진')">일괄삭제</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="property-images-container" class="d-flex flex-wrap gap-2">
|
|
<!-- 기존 li+table 구조 대신 썸네일 카드로 -->
|
|
<!-- 필요 개수만큼 반복 -->
|
|
<?php
|
|
if (isset($imgs_count['I4']) && $imgs_count['I4'] != 0) {
|
|
$cnt = 0;
|
|
foreach ($images as $img) {
|
|
if ($img['img_type'] == 'I4') {
|
|
|
|
$link = $img['img_path'] . $img['img_filenm'];
|
|
$temp2 = explode(".", $img['img_filenm']);
|
|
//$name = $temp2[0]."_thumb.".$temp2[1];
|
|
$thumbname = $temp2[0] . "_thumb.jpg";
|
|
$thumblink = $img['img_path'] . $thumbname;
|
|
|
|
$agreement_image = realFilePath($link);
|
|
$agreement_image_thumbnail = realFilePath($thumblink);
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$agreement_image_thumbnail = NCLOUD_OBJECT_STORAGE_URL . $thumblink;
|
|
$agreement_image = NCLOUD_OBJECT_STORAGE_URL . $link;
|
|
}
|
|
|
|
$cnt++;
|
|
?>
|
|
<div class="property-image-item" style="width: 150px; position: relative; cursor: move;" data-img-sq="<?= $img['img_sq'] ?>" data-view-order="<?= $img['view_odr'] ?>">
|
|
<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);"><?= $cnt ?></div>
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<a onclick="fn_preview('<?= $agreement_image ?>')" class="d-flex align-items-center justify-content-center">
|
|
<img src="<?= $agreement_image_thumbnail ?>" alt="매물사진" class="w-100 h-100 object-fit-contain">
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<?php }
|
|
} ?>
|
|
<?php } else { ?>
|
|
<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>
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 동영상 / 평면도 / 체크리스트 -->
|
|
<div class="row g-3">
|
|
<!-- 동영상 -->
|
|
<div class="col-12 col-lg-10p">
|
|
<div class="border rounded-3 p-2 ">
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<div class="fw-semibold">동영상</div>
|
|
<button type="button" class="btn btn-sm btn-outline-secondary"
|
|
onclick="viewFilePop('V1', '')">파일</button>
|
|
</div>
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<?php
|
|
if (isset($imgs_count['V1']) && $imgs_count['V1'] != 0) {
|
|
foreach ($images as $img) {
|
|
if ($img['img_type'] == 'V1') {
|
|
|
|
$link = $img['img_path'] . $img['img_filenm'];
|
|
$temp2 = explode(".", $img['img_filenm']);
|
|
//$name = $temp2[0]."_thumb.".$temp2[1];
|
|
$name = $temp2[0] . "_thumb.jpg";
|
|
$thumblink = $img['img_path'] . $name;
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$thumblink = NCLOUD_OBJECT_STORAGE_URL . $thumblink;
|
|
$link = NCLOUD_OBJECT_STORAGE_URL . $link;
|
|
}
|
|
?>
|
|
|
|
<a onclick="fn_preview('<?= $link ?>', 'vdo')">
|
|
<img src="/plugin/img/video.png" alt="동영상" class="w-100 object-fit-contain">
|
|
</a>
|
|
|
|
<?php
|
|
}
|
|
}
|
|
} else {
|
|
?>
|
|
<img src="/plugin/img/photo.gif" alt="동영상" class="w-100 object-fit-contain">
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 평면도 -->
|
|
<div class="col-12 col-lg-10p">
|
|
<div class="border rounded-3 p-2 ">
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<div class="fw-semibold">평면도</div>
|
|
<button type="button" class="btn btn-sm btn-outline-secondary"
|
|
onclick="viewFilePop('I5', '')">파일</button>
|
|
</div>
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<?php
|
|
if (isset($imgs_count['I5']) && $imgs_count['I5'] != 0) {
|
|
foreach ($images as $img) {
|
|
if ($img['img_type'] == 'I5') {
|
|
$link = $img['img_path'] . $img['img_filenm'];
|
|
$temp2 = explode(".", $img['img_filenm']);
|
|
$name = $temp2[0] . "_thumb.jpg";
|
|
$thumblink = $img['img_path'] . $name;
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$thumblink = NCLOUD_OBJECT_STORAGE_URL . $thumblink;
|
|
$link = NCLOUD_OBJECT_STORAGE_URL . $link;
|
|
}
|
|
?>
|
|
<a onclick="fn_preview('<?= $link ?>')">
|
|
<img id="photo-display2_I1" src="<?= $thumblink ?>" alt="평면도" class="w-100 object-fit-contain">
|
|
</a>
|
|
<?php }
|
|
}
|
|
} else { ?>
|
|
|
|
<img src="/plugin/img/photo.gif" alt="평면도" class="w-100 object-fit-contain">
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 체크리스트 -->
|
|
<div class="col-12 col-lg-10p">
|
|
<div class="border rounded-3 p-2 ">
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<div class="fw-semibold">체크리스트</div>
|
|
<button type="button" class="btn btn-sm btn-outline-secondary"
|
|
onclick="viewFilePop('I11', '')">파일</button>
|
|
</div>
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden">
|
|
<?php
|
|
if (isset($imgs_count['I11']) && $imgs_count['I11'] != 0) {
|
|
foreach ($images as $img) {
|
|
if ($img['img_type'] == 'I11') {
|
|
$link = $img['img_path'] . $img['img_filenm'];
|
|
$temp2 = explode(".", $img['img_filenm']);
|
|
$name = $temp2[0] . "_thumb.jpg";
|
|
$thumblink = $img['img_path'] . $name;
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$thumblink = NCLOUD_OBJECT_STORAGE_URL . $thumblink;
|
|
$link = NCLOUD_OBJECT_STORAGE_URL . $link;
|
|
}
|
|
?>
|
|
<a onclick="fn_preview('<?= $link ?>')">
|
|
<img id="photo-display2_I1" src="<?= $thumblink ?>" alt="체크리스트" class="w-100 object-fit-contain">
|
|
</a>
|
|
<?php }
|
|
}
|
|
} else { ?>
|
|
|
|
<img src="/plugin/img/photo.gif" alt="체크리스트" class="w-100 object-fit-contain">
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 평면도중복 -->
|
|
<?php if (!empty($dupleGroundPlan)): ?>
|
|
<div class="border rounded-3 p-3 mb-3 bg-white">
|
|
<div class="d-flex align-items-center justify-content-between mb-2">
|
|
<div class="fw-semibold">평면도 중복</div>
|
|
<span class="badge bg-secondary"><?= count($dupleGroundPlan ?? []) ?>건</span>
|
|
</div>
|
|
|
|
<div class="text-muted small py-2">중복된 평면도가 없습니다.</div>
|
|
|
|
<div class="vstack gap-2">
|
|
<?php $numbering = 1;
|
|
foreach ($dupleGroundPlan as $row): ?>
|
|
<div class="border rounded-3 p-2 bg-light">
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<div class="fw-semibold">
|
|
<span class="badge bg-dark me-2">중복 <?= $numbering ?></span>
|
|
<span class="text-muted small">평면도 중복</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-2 mt-1 small">
|
|
<div class="col-12 col-md-6">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<span class="text-muted">매물번호</span>
|
|
<span class="fw-semibold"><?= esc($row['rcpt_key'] ?? '') ?></span>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-md-6">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<span class="text-muted">촬영일자</span>
|
|
<span class="fw-semibold"><?= esc($row['photo_save_dt'] ?? '') ?></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php $numbering++; endforeach; ?>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- 매물현장확인 체크리스트 -->
|
|
<?php if ($data['exp_photo_yn'] == 'N'): ?>
|
|
<div class="border rounded-3 p-3 mb-3 bg-white">
|
|
<div class="d-flex align-items-center justify-content-between mb-2">
|
|
<div class="fw-semibold">매물현장확인 체크리스트</div>
|
|
</div>
|
|
|
|
<div class="row g-2 align-items-center">
|
|
<div class="col-1 col-md-1">
|
|
<label class="form-label mb-0">엘리베이터</label>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9">
|
|
<div class="d-flex gap-3">
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="elevator_yn" id="elevator_y" value="Y" <?php if ($result_check['elevator_yn'] == 'Y') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="elevator_y">있음</label>
|
|
</div>
|
|
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="elevator_yn" id="elevator_n" value="N" <?php if ($result_check['elevator_yn'] == 'N') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="elevator_n">없음</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-2 align-items-center">
|
|
<div class="col-1 col-md-1">
|
|
<label class="form-label mb-0">관리비/월</label>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9">
|
|
<div class="d-flex gap-3">
|
|
<input type="text" class="form-control" name="maintenance_fee" id="maintenance_fee"
|
|
value="<?= $result_check['maintenance_fee'] ?>" size="10" maxlength="10" style="width: 150px;" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-2 align-items-center">
|
|
<div class="col-1 col-md-1">
|
|
<label class="form-label mb-0">엘리베이터CCTV</label>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9">
|
|
<div class="d-flex gap-3">
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="elevator_cctv_yn" id="elevator_cctv_y" value="Y"
|
|
<?php if ($result_check['elevator_cctv_yn'] == 'Y') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="elevator_cctv_y">있음</label>
|
|
</div>
|
|
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="elevator_cctv_yn" id="elevator_cctv_n" value="N"
|
|
<?php if ($result_check['elevator_cctv_yn'] == 'N') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="elevator_cctv_n">없음</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-2 align-items-center">
|
|
<div class="col-1 col-md-1">
|
|
<label class="form-label mb-0">건물내부CCTV</label>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9">
|
|
<div class="d-flex gap-3">
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="building_in_cctv_yn" id="building_in_cctv_y"
|
|
value="Y" <?php if ($result_check['building_in_cctv_yn'] == 'Y') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="building_in_cctv_y">있음</label>
|
|
</div>
|
|
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="building_in_cctv_yn" id="building_in_cctv_n"
|
|
value="N" <?php if ($result_check['building_in_cctv_yn'] == 'N') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="building_in_cctv_n">없음</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-2 align-items-center">
|
|
<div class="col-1 col-md-1">
|
|
<label class="form-label mb-0">건물외부CCTV</label>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9">
|
|
<div class="d-flex gap-3">
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="building_ou_cctv_yn" id="building_ou_cctv_y"
|
|
value="Y" <?php if ($result_check['building_ou_cctv_yn'] == 'Y') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="building_ou_cctv_y">있음</label>
|
|
</div>
|
|
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="building_ou_cctv_yn" id="building_ou_cctv_n"
|
|
value="N" <?php if ($result_check['building_ou_cctv_yn'] == 'N') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="building_ou_cctv_n">없음</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-2 align-items-center">
|
|
<div class="col-1 col-md-1">
|
|
<label class="form-label mb-0">난방방식</label>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9">
|
|
<div class="d-flex gap-3">
|
|
<input type="text" class="form-control" name="heating_type" id="heating_type"
|
|
value="<?= $result_check['heating_type'] ?>" size="10" maxlength="10" style="width: 150px;" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-2 align-items-center">
|
|
<div class="col-1 col-md-1">
|
|
<label class="form-label mb-0">경비실</label>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9">
|
|
<div class="d-flex gap-3">
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="security_dept_yn" id="security_dept_y" value="Y"
|
|
<?php if ($result_check['security_dept_yn'] == 'Y') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="security_dept_y">있음</label>
|
|
</div>
|
|
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="security_dept_yn" id="security_dept_n" value="N"
|
|
<?php if ($result_check['security_dept_yn'] == 'N') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="security_dept_n">없음</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="row g-2 align-items-center">
|
|
<div class="col-1 col-md-1">
|
|
<label class="form-label mb-0">주차장</label>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9">
|
|
<div class="d-flex gap-3">
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="parking_lot_yn" id="parking_lot_y" value="Y"
|
|
<?php if ($result_check['parking_lot_yn'] == 'Y') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="parking_lot_y">있음</label>
|
|
</div>
|
|
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="parking_lot_yn" id="parking_lot_n" value="N"
|
|
<?php if ($result_check['parking_lot_yn'] == 'N') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="parking_lot_n">없음</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-2 align-items-center">
|
|
<div class="col-1 col-md-1">
|
|
<label class="form-label mb-0">인터폰</label>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9">
|
|
<div class="d-flex gap-3">
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="interphone_yn" id="interphone_y" value="Y" <?php if ($result_check['interphone_yn'] == 'Y') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="interphone_y">있음</label>
|
|
</div>
|
|
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="interphone_yn" id="interphone_n" value="N" <?php if ($result_check['interphone_yn'] == 'N') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="interphone_n">없음</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-2 align-items-center">
|
|
<div class="col-1 col-md-1">
|
|
<label class="form-label mb-0">출입카드키</label>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9">
|
|
<div class="d-flex gap-3">
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="building_security_yn" id="building_security_y"
|
|
value="Y" <?php if ($result_check['building_security_yn'] == 'Y') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="building_security_y">있음</label>
|
|
</div>
|
|
|
|
<div class="form-check form-check-inline mb-0">
|
|
<input class="form-check-input" type="radio" name="building_security_yn" id="building_security_n"
|
|
value="N" <?php if ($result_check['building_security_yn'] == 'N') {
|
|
echo 'checked="checked"';
|
|
} ?>>
|
|
<label class="form-check-label" for="building_security_n">없음</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- 검수사항 -->
|
|
<div class="my-3">
|
|
<div class="border rounded-3 p-2">
|
|
<div class="fw-semibold mb-2">검수사항</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="chkPromote" id="chkPromote" value="Y">
|
|
<label class="form-check-label" for="chkPromote">홍보확인서 확인</label>
|
|
</div>
|
|
<?php if ($data['rcpt_product'] == 'B01' || $data['rcpt_product'] == 'B02' || $data['rcpt_product'] == 'B03'): ?>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="chkBunyang" id="chkBunyang" value="Y">
|
|
<label class="form-check-label" for="chkBunyang">분양권 확인</label>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 360이미지 / 촬영위치 -->
|
|
<div class="my-3">
|
|
<div class="border rounded-3 p-2">
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<div class="fw-semibold">360이미지 (최대 5장) / 촬영위치</div>
|
|
<div class="d-flex gap-1">
|
|
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="viewFilePop('I9', '')">파일</button>
|
|
<button type="button" class="btn btn-sm btn-outline-primary" onclick="save360ImageLocations()">촬영위치 저장</button>
|
|
<button type="button" class="btn btn-sm btn-outline-success"
|
|
onclick="downloadImagesByType('I9', '360이미지')">일괄다운로드</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex flex-wrap gap-2">
|
|
<?php
|
|
if (isset($imgs_count['I9']) && $imgs_count['I9'] != 0) {
|
|
$cnt = 0;
|
|
foreach ($images as $img) {
|
|
if ($img['img_type'] == 'I9') {
|
|
$link = $img['img_path'] . $img['img_filenm'];
|
|
$temp2 = explode(".", $img['img_filenm']);
|
|
$name = $temp2[0] . "_thumb.jpg";
|
|
$thumblink = $img['img_path'] . $name;
|
|
|
|
if ($img['cloud_upload_yn'] == 'Y') {
|
|
$thumblink = NCLOUD_OBJECT_STORAGE_URL . $thumblink;
|
|
$link = NCLOUD_OBJECT_STORAGE_URL . $link;
|
|
}
|
|
$cnt++;
|
|
?>
|
|
<div class="thumb-card">
|
|
<div class="ratio ratio-4x3 bg-light rounded-2 overflow-hidden mb-1">
|
|
<a onclick="fn_preview('<?= $link ?>')" class="d-flex align-items-center justify-content-center">
|
|
<img src="<?= $thumblink ?>" alt="360이미지" class="w-100 h-100 object-fit-contain"
|
|
onerror="console.error('360이미지 로드 실패:', this.src); this.style.border='2px solid red';"
|
|
onload="console.log('360이미지 로드 성공:', this.src);">
|
|
</a>
|
|
</div>
|
|
<input class="form-control form-control-sm" type="text" name="img_location_<?= $img['img_sq'] ?>"
|
|
id="img_location_<?= $img['img_sq'] ?>" value="<?= $img['img_location'] ?>" size="11"
|
|
style="width: 160px;">
|
|
</div>
|
|
<?php }
|
|
}
|
|
} else { ?>
|
|
<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>
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- 거주인 정보 및 녹취 내용 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">중개인 요청사항</h5>
|
|
|
|
<?php
|
|
// 전화번호 분해
|
|
$arrRecTel = ["", "", ""];
|
|
if (!empty($data['rec_tel'])) {
|
|
$tmp = explode("-", $data['rec_tel']);
|
|
$arrRecTel[0] = $tmp[0] ?? "";
|
|
$arrRecTel[1] = $tmp[1] ?? "";
|
|
$arrRecTel[2] = $tmp[2] ?? "";
|
|
}
|
|
?>
|
|
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table mb-0">
|
|
<colgroup>
|
|
<col width="15%" />
|
|
<col width="35%" />
|
|
<col width="15%" />
|
|
<col width="35%" />
|
|
</colgroup>
|
|
|
|
<tbody>
|
|
<!-- 1) 거주자 정보 -->
|
|
<tr>
|
|
<th class="align-middle">거주자 전화번호</th>
|
|
<td class="align-middle">
|
|
<div class="input-group input-group-sm" style="max-width: 340px;">
|
|
<input type="text" class="form-control" name="rec_tel1" maxlength="4" placeholder="010"
|
|
value="<?= esc($arrRecTel[0]) ?>" />
|
|
<span class="input-group-text">-</span>
|
|
<input type="text" class="form-control" name="rec_tel2" maxlength="4" placeholder="1234"
|
|
value="<?= esc($arrRecTel[1]) ?>" />
|
|
<span class="input-group-text">-</span>
|
|
<input type="text" class="form-control" name="rec_tel3" maxlength="4" placeholder="5678"
|
|
value="<?= esc($arrRecTel[2]) ?>" />
|
|
</div>
|
|
</td>
|
|
|
|
<th class="align-middle">거주인 이름</th>
|
|
<td class="align-middle">
|
|
<input type="text" class="form-control form-control-sm" name="rec_nm" style="max-width: 220px;"
|
|
value="<?= esc($data['rec_nm'] ?? '') ?>" />
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- 2) 음성파일 -->
|
|
<tr>
|
|
<th class="align-middle">음성파일</th>
|
|
<td colspan="3" class="align-middle">
|
|
<div class="d-flex align-items-center flex-wrap gap-2">
|
|
|
|
<!-- 현재 파일 정보 -->
|
|
<?php if (!empty($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=<?= $record['record_sq'] ?>">
|
|
<?= esc($record['record_orignm']) ?>
|
|
</a>
|
|
<span class="badge bg-light text-dark border"><?= esc($record['record_size']) ?> KB</span>
|
|
<span class="badge bg-light text-dark border"><?= esc($record['insert_tm']) ?></span>
|
|
</div>
|
|
<?php else: ?>
|
|
<span class="text-muted small">등록된 파일 없음</span>
|
|
<?php endif; ?>
|
|
|
|
<div class="vr"></div>
|
|
|
|
<!-- 업로드 버튼 + 파일명 -->
|
|
<label class="btn btn-sm btn-outline-secondary mb-0">
|
|
파일 업로드
|
|
<input type="file" id="rec_file" name="rec_file" accept=".wav" class="d-none"
|
|
onchange="showFileName(this);">
|
|
</label>
|
|
<span id="file_name" class="text-muted small"></span>
|
|
|
|
<div class="vr"></div>
|
|
|
|
<!-- 체크박스 -->
|
|
<div class="form-check mb-0">
|
|
<input class="form-check-input" type="checkbox" name="chk_record" id="chk_record" value="Y"
|
|
<?= empty($record) ? 'disabled' : 'checked' ?>>
|
|
<label class="form-check-label" for="chk_record">
|
|
녹취파일 확인
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- 3) 거주인 요청사항 -->
|
|
<tr>
|
|
<th class="align-middle">거주인 요청사항</th>
|
|
<td colspan="3">
|
|
<textarea class="form-control form-control-sm" name="rec_remark" rows="2"
|
|
placeholder="요청사항을 입력하세요"><?= esc($data['remark'] ?? '') ?></textarea>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="card-footer d-flex justify-content-end gap-1">
|
|
<?php if (!in_array($usr_level, [])): ?>
|
|
<button type="button" class="btn btn-sm btn-outline-primary" onclick="saveRecInfo();">저장</button>
|
|
<?php endif; ?>
|
|
<button type="button" class="btn btn-sm btn-outline-focus" onclick="viewSmsPop('S14');">완료안내</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- 정보변경 이력 -->
|
|
<div class="main-card mb-3 card">
|
|
<div class="card-body ">
|
|
<h5 class="card-title">정보변경 이력</h5>
|
|
<div class="table-scroll">
|
|
<table class="table table-bordered table-sm tbl_basic2 apt-info-table">
|
|
<tr>
|
|
<th style="text-align: center;">진행상태</th>
|
|
<th style="text-align: center;">변경내용</th>
|
|
<th style="text-align: center;">처리자(ID)</th>
|
|
<th style="text-align: center;">처리일시</th>
|
|
<th style="text-align: center;">세부내용</th>
|
|
</tr>
|
|
<?php if (!empty($history)) { ?>
|
|
<?php foreach ($history as $h) { ?>
|
|
<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>
|
|
<?php } ?>
|
|
<?php } ?>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<?= $this->section('modals') ?>
|
|
<div class="modal" id="previewModal" tabindex="-1">
|
|
<div class="modal-dialog modal-xl">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">미리보기</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body p-0">
|
|
<img id="imgPreview" src="" alt="미리보기" width="100%" height="auto">
|
|
<video id="vdoPreview" controls playsinline preload="metadata" style="display: none;height: 500px;width: 100%;">
|
|
<source id="videoSource" src="" type="video/mp4">
|
|
브라우저가 video 태그를 지원하지 않습니다.
|
|
</video>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="uploadModal" tabindex="-1">
|
|
<div class="modal-dialog modal-xl">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">파일 업로드</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body p-0">
|
|
<form id="frm_file_info" method="post" enctype="multipart/form-data" onsubmit="return false;">
|
|
<input type="hidden" name="rcpt_key" value="<?= $data['rcpt_key'] ?? '' ?>">
|
|
<input type="hidden" name="rsrv_sq" value="<?= $data['rsrv_sq'] ?? '' ?>">
|
|
<input type="hidden" name="rcpt_sq" value="<?= $data['rcpt_sq'] ?? '' ?>">
|
|
<input type="hidden" name="img_type" value="">
|
|
<input type="hidden" name="img_sub_type" value="">
|
|
<input type="hidden" name="vr_sq" value="">
|
|
|
|
<!-- 버튼 툴바 -->
|
|
<div class="d-flex justify-content-end gap-2 mb-2" style="padding: 10px 10px 0 0;">
|
|
<button type="button" class="btn btn-sm btn-primary" id="uploadPick">
|
|
<i class="pe-7s-up-arrow"></i> 파일선택
|
|
</button>
|
|
|
|
<button type="button" class="btn btn-sm btn-success" id="btnUpload">
|
|
<i class="pe-7s-up-arrow"></i> 파일업로드
|
|
</button>
|
|
|
|
<button type="button" class="btn btn-sm btn-danger" id="btnRemove">
|
|
<i class="pe-7s-less"></i> 업로드취소
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Dropzone 영역 -->
|
|
<div id="myDropzone" class="dropzone border rounded-3 p-2" style="max-height: 520px;overflow-y: auto; overflow-x: hidden; min-height: 250px;">
|
|
<div class="dz-message dz-message-fixed needsclick text-center py-3">
|
|
<i class="pe-7s-upload" style="font-size:28px; color: #6c757d;"></i><br>
|
|
<span style="font-size: 13px; color: #6c757d;">파일을 드래그하거나 위 [파일선택] 버튼을 클릭하세요</span>
|
|
</div>
|
|
</div>
|
|
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="smsModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-md">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">SMS 보내기</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
|
|
<form id="smsForm" onsubmit="return false;">
|
|
<input type="hidden" name="rcpt_key" value="<?= $data['rcpt_key'] ?>" />
|
|
<input type="hidden" name="rcpt_sq" value="<?= $data['rcpt_sq'] ?>" />
|
|
<input type="hidden" name="rsrv_sq" value="<?= $data['rsrv_sq'] ?>" />
|
|
<input type="hidden" name="cd" />
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label for="smsPhone" class="form-label">수신번호</label>
|
|
<input type="tel" class="form-control" id="smsPhone" name="phone" placeholder="010-0000-0000" required>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="smsContent" class="form-label">내용</label>
|
|
<textarea class="form-control" id="smsContent" name="content" rows="5" placeholder="메시지 내용을 입력하세요"
|
|
style="resize: none;" required></textarea>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer justify-content-center gap-1">
|
|
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-dismiss="modal">
|
|
닫기
|
|
</button>
|
|
<button type="submit" class="btn btn-sm btn-outline-primary" id="btnSendSms">
|
|
보내기
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?= $this->endSection() ?>
|
|
|
|
<script type="text/javascript" src="https://oapi.map.naver.com/openapi/v3/maps.js?ncpKeyId=dtounkwjc5"></script>
|
|
<script src="https://unpkg.com/dropzone@6.0.0-beta.1/dist/dropzone-min.js"></script>
|
|
<link href="https://unpkg.com/dropzone@6.0.0-beta.1/dist/dropzone.css" rel="stylesheet" type="text/css" />
|
|
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
|
|
<style>
|
|
/* Dropzone 커스텀 스타일 */
|
|
.dropzone {
|
|
display: grid;
|
|
grid-template-columns: repeat(8, 1fr); /* 한 줄에 8개 고정 */
|
|
gap: 6px;
|
|
align-items: flex-start;
|
|
cursor: default !important; /* 클릭 커서 제거 */
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.dropzone .dz-preview {
|
|
margin: 0;
|
|
min-height: auto !important;
|
|
}
|
|
|
|
.dropzone .dz-preview.dz-image-preview {
|
|
background: #fff;
|
|
border: 2px solid #e1e4e8;
|
|
border-radius: 6px;
|
|
padding: 5px;
|
|
width: 100%;
|
|
cursor: move;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.dropzone .dz-preview.dz-image-preview:hover {
|
|
border-color: #007bff;
|
|
box-shadow: 0 2px 8px rgba(0,123,255,0.2);
|
|
}
|
|
|
|
.dropzone .dz-preview.sortable-ghost {
|
|
opacity: 0.4;
|
|
}
|
|
|
|
/* 이미지 영역 */
|
|
.dropzone .dz-preview .dz-image {
|
|
width: 100%;
|
|
aspect-ratio: 1;
|
|
border-radius: 4px;
|
|
overflow: visible; /* 배지가 보이도록 변경 */
|
|
margin-bottom: 5px;
|
|
position: relative;
|
|
}
|
|
|
|
.dropzone .dz-preview .dz-image img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* 파일 정보 영역 */
|
|
.dropzone .dz-preview .dz-details {
|
|
position: relative;
|
|
padding: 3px 0;
|
|
text-align: center;
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
.dropzone .dz-preview .dz-filename {
|
|
display: block !important;
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
.dropzone .dz-preview .dz-filename span {
|
|
display: block;
|
|
width: 100%;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
font-size: 10px;
|
|
color: #586069;
|
|
padding: 0 2px;
|
|
line-height: 1.3;
|
|
}
|
|
|
|
.dropzone .dz-preview .dz-size {
|
|
font-size: 9px;
|
|
color: #959da5;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
/* 프로그레스 바 */
|
|
.dropzone .dz-preview .dz-progress {
|
|
height: 3px;
|
|
border-radius: 2px;
|
|
margin: 5px 0 3px 0;
|
|
overflow: hidden;
|
|
background: #e1e4e8;
|
|
opacity: 1 !important;
|
|
display: none; /* 기본적으로 숨김 */
|
|
}
|
|
|
|
.dropzone .dz-preview.dz-processing .dz-progress {
|
|
display: block; /* 업로드 중일 때만 표시 */
|
|
}
|
|
|
|
.dropzone .dz-preview .dz-progress .dz-upload {
|
|
background: linear-gradient(90deg, #0366d6 0%, #0969da 100%);
|
|
height: 100%;
|
|
transition: width 0.3s ease;
|
|
}
|
|
|
|
/* 성공/에러 표시 */
|
|
.dropzone .dz-preview .dz-success-mark,
|
|
.dropzone .dz-preview .dz-error-mark {
|
|
display: none !important;
|
|
}
|
|
|
|
.dropzone .dz-preview.dz-success .dz-image::before {
|
|
content: "✓";
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
background: rgba(40, 167, 69, 0.9);
|
|
color: white;
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
z-index: 5;
|
|
}
|
|
|
|
.dropzone .dz-preview.dz-error .dz-image::before {
|
|
content: "✕";
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
background: rgba(220, 53, 69, 0.9);
|
|
color: white;
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
z-index: 5;
|
|
}
|
|
|
|
/* 버튼 영역 */
|
|
.dropzone .dz-preview .file-buttons {
|
|
display: flex;
|
|
gap: 3px;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
/* 삭제 버튼 */
|
|
.dropzone .dz-preview .dz-remove {
|
|
display: block !important;
|
|
flex: 1;
|
|
padding: 3px 6px;
|
|
font-size: 9px;
|
|
text-align: center;
|
|
border: 1px solid #dc3545;
|
|
border-radius: 3px;
|
|
background: white;
|
|
color: #dc3545;
|
|
text-decoration: none;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.dropzone .dz-preview .dz-remove:hover {
|
|
background: #dc3545;
|
|
color: white;
|
|
}
|
|
|
|
/* 교체 버튼 */
|
|
.dropzone .dz-preview .dz-replace {
|
|
display: block !important;
|
|
flex: 1;
|
|
padding: 3px 6px;
|
|
|
|
/* 매물사진 순서 배지 스타일 */
|
|
.property-image-item {
|
|
position: relative;
|
|
}
|
|
|
|
.image-order-badge {
|
|
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);
|
|
}
|
|
|
|
.property-image-item.sortable-ghost {
|
|
opacity: 0.4;
|
|
}
|
|
|
|
.property-image-item.sortable-drag {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.dropzone .dz-preview .dz-replace {
|
|
font-size: 9px;
|
|
text-align: center;
|
|
border: 1px solid #007bff;
|
|
border-radius: 3px;
|
|
background: white;
|
|
color: #007bff;
|
|
text-decoration: none;
|
|
transition: all 0.2s;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.dropzone .dz-preview .dz-replace:hover {
|
|
background: #007bff;
|
|
color: white;
|
|
}
|
|
|
|
/* 순서 번호 배지 */
|
|
.file-order-badge {
|
|
position: absolute;
|
|
top: -6px;
|
|
left: -6px;
|
|
background: #007bff;
|
|
color: white;
|
|
border-radius: 50%;
|
|
width: 24px;
|
|
height: 24px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 12px;
|
|
font-weight: bold;
|
|
z-index: 10;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
|
border: 2px solid white;
|
|
}
|
|
|
|
/* 에러 메시지 */
|
|
.dropzone .dz-preview .dz-error-message {
|
|
display: none !important;
|
|
}
|
|
|
|
/* 메시지 영역 간격 조정 */
|
|
.dropzone .dz-message {
|
|
margin: 1em 0 !important;
|
|
grid-column: 1 / -1; /* 전체 너비 차지 */
|
|
pointer-events: none; /* 클릭 이벤트 차단 */
|
|
}
|
|
|
|
/* 파일선택 버튼만 클릭 가능하도록 */
|
|
.dropzone.dz-clickable {
|
|
cursor: default !important;
|
|
}
|
|
|
|
.dropzone.dz-clickable * {
|
|
cursor: default !important;
|
|
}
|
|
|
|
.dropzone .dz-message * {
|
|
pointer-events: none;
|
|
}
|
|
</style>
|
|
<script type="text/javascript">
|
|
|
|
const rcpt_hscp_nm = '<?= $data['rcpt_hscp_nm'] ?>';
|
|
const spc_stat = '<?= $data['spc_stat'] ?>'
|
|
|
|
const lat = parseFloat("<?= esc($data['rcpt_y'] ?? '0') ?>");
|
|
const lng = parseFloat("<?= esc($data['rcpt_x'] ?? '0') ?>");
|
|
|
|
const smsArr = <?= json_encode($sms ?? [], JSON_UNESCAPED_UNICODE); ?>;
|
|
|
|
var map;
|
|
var dz = null; // Dropzone 인스턴스
|
|
var sortable = null; // Sortable 인스턴스
|
|
|
|
$(function () {
|
|
|
|
trade_type_onchange();
|
|
|
|
if (isDefined(rcpt_hscp_nm)) {
|
|
$(".spc").hide();
|
|
}
|
|
|
|
map = new naver.maps.Map('mapArea', {
|
|
center: new naver.maps.LatLng(lat, 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(lat, 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 trade_type_onchange() {
|
|
var trade_type = $('#trade_type').val();
|
|
if (trade_type == 'B2' || trade_type == 'B3') {
|
|
// 월세...
|
|
$('#div_trade_type_price_monthly').show();
|
|
} else {
|
|
$('#div_trade_type_price_monthly').hide();
|
|
}
|
|
}
|
|
|
|
// 가격수정 btn
|
|
function editPriceInfo() {
|
|
var rcpt_product = $('#rcpt_product').val();
|
|
var trade_type = $('#trade_type').val();
|
|
|
|
$("#trade_type").prop("disabled", false);
|
|
|
|
$("#rcpt_product_info2").prop("disabled", false);
|
|
$("#rcpt_product_info3").prop("disabled", false);
|
|
|
|
if (trade_type == "A1") {
|
|
if (rcpt_product == 'A01' || rcpt_product == 'A02' || rcpt_product == 'A03' || rcpt_product == 'B01' || rcpt_product == 'B02' || rcpt_product == 'B03') {
|
|
$("#rcpt_product_info4").prop("disabled", false);
|
|
$("#rcpt_product_info5").prop("disabled", false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 가격수정 저장
|
|
function modifyPriceInfo() {
|
|
swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
type: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
closeOnConfirm: false,
|
|
closeOnCancel: true,
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
var params = {
|
|
'rcpt_sq': '<?= $data['rcpt_sq'] ?>',
|
|
'agent_tel': $("#agent_tel").val(),
|
|
};
|
|
|
|
callAjax("/article/receipt/modifyPriceInfo", params, fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 연락가능전화 저장
|
|
function fn_save_tel() {
|
|
swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
type: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
closeOnConfirm: false,
|
|
closeOnCancel: true,
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
var params = {
|
|
'rcpt_sq': '<?= $data['rcpt_sq'] ?>',
|
|
'agent_tel': $("#agent_tel").val(),
|
|
};
|
|
|
|
callAjax("/article/receipt/saveAptMemo", params, fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 평면도요청 저장
|
|
function res_ground() {
|
|
swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
type: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
closeOnConfirm: false,
|
|
closeOnCancel: true,
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
callAjax("/article/receipt/resGround", $("#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: "저장 하시겠습니까?",
|
|
type: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
closeOnConfirm: false,
|
|
closeOnCancel: true,
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
callAjax("/article/receipt/assignRegist", $("#rcptFrm").serialize(), fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 동영상 촬영여부저장
|
|
function requestMovie() {
|
|
swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
type: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
closeOnConfirm: false,
|
|
closeOnCancel: true,
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
callAjax("/article/receipt/requestMovie", $("#rcptFrm").serialize(), fn_result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 중개사메모 저장
|
|
function requestMessage() {
|
|
swal.fire({
|
|
text: "저장 하시겠습니까?",
|
|
type: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
closeOnConfirm: false,
|
|
closeOnCancel: true,
|
|
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: "취소 하시겠습니까?",
|
|
type: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
closeOnConfirm: false,
|
|
closeOnCancel: true,
|
|
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 (smsArr.length > 0) {
|
|
var tel = "";
|
|
if (cd == "S7" || cd == "S14") {
|
|
tel = '<?= $data['rec_tel'] ?>';
|
|
} else if (cd == "S10") {
|
|
tel = '<?= $data['agent_contact_tel'] ?>';
|
|
} else if (cd == "15") {
|
|
tel = '<?= $data['agent_contact_tel'] ?>';
|
|
} else {
|
|
tel = '<?= $data['agent_head_tel'] ?>';
|
|
}
|
|
|
|
|
|
for (const sms of 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를 발송하시겠습니까?",
|
|
type: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
closeOnConfirm: false,
|
|
closeOnCancel: true,
|
|
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: "거주인정보를 저장하시겠습니까?",
|
|
type: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: "예",
|
|
cancelButtonText: "아니오",
|
|
closeOnConfirm: false,
|
|
closeOnCancel: true,
|
|
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
|
|
})
|
|
|
|
location.reload();
|
|
} else {
|
|
Swal.fire({
|
|
title: result.msg,
|
|
icon: "error",
|
|
draggable: true
|
|
})
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
})
|
|
|
|
|
|
setTimeout(() => {
|
|
location.reload();
|
|
}, 1000);
|
|
} else {
|
|
Swal.fire({
|
|
title: result.msg,
|
|
icon: "error",
|
|
draggable: true
|
|
})
|
|
}
|
|
}
|
|
|
|
// Dropzone 초기화 함수
|
|
function initDropzone(imgType) {
|
|
console.log('[Dropzone] initDropzone 호출, imgType:', imgType);
|
|
|
|
// 기존 Dropzone 인스턴스가 있으면 제거
|
|
if (dz) {
|
|
console.log('[Dropzone] 기존 인스턴스 제거');
|
|
dz.destroy();
|
|
dz = null;
|
|
}
|
|
|
|
// 파일 타입별 최대 개수 설정
|
|
const maxFilesConfig = {
|
|
'I4': 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 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가 없어서 이미지를 불러올 수 없습니다.');
|
|
}
|
|
})
|
|
|
|
</script>
|
|
|
|
<?= $this->endSection() ?>
|