289 lines
14 KiB
PHP
289 lines
14 KiB
PHP
<?php
|
|
$sub_menu = "800800";
|
|
include_once('./_common.php');
|
|
|
|
auth_check($auth[$sub_menu], 'r');
|
|
|
|
$g5['title'] = '상담 예약 관리';
|
|
|
|
// lib/notification_helper.php 포함 (설정값 가져오기 위해)
|
|
if (file_exists(G5_LIB_PATH . '/notification_helper.php')) {
|
|
include_once(G5_LIB_PATH . '/notification_helper.php');
|
|
}
|
|
|
|
function get_reservation_status_name($status_code) {
|
|
return get_order_config('reservation_status_' . $status_code, $status_code);
|
|
}
|
|
|
|
// 검색 조건
|
|
$sql_search = "";
|
|
$sfl = isset($_GET['sfl']) ? clean_xss_tags($_GET['sfl']) : '';
|
|
$stx = isset($_GET['stx']) ? clean_xss_tags($_GET['stx']) : '';
|
|
$sst = isset($_GET['sst']) ? clean_xss_tags($_GET['sst']) : 'id';
|
|
$sod = isset($_GET['sod']) ? clean_xss_tags($_GET['sod']) : 'desc';
|
|
$status_filter = isset($_GET['status_filter']) ? clean_xss_tags($_GET['status_filter']) : '';
|
|
|
|
if ($stx) {
|
|
$stx_escaped = sql_real_escape_string($stx);
|
|
if ($sfl === 'customer_name') {
|
|
$sql_search .= " AND customer_name LIKE '%{$stx_escaped}%' ";
|
|
} elseif ($sfl === 'customer_phone') {
|
|
$sql_search .= " AND customer_phone LIKE '%{$stx_escaped}%' ";
|
|
}
|
|
}
|
|
|
|
if ($status_filter) {
|
|
$sql_search .= " AND status = '" . sql_real_escape_string($status_filter) . "' ";
|
|
}
|
|
|
|
// 정렬
|
|
$sql_order = " ORDER BY {$sst} {$sod} ";
|
|
|
|
// 페이징
|
|
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
|
|
$page_rows = 15;
|
|
$from_record = ($page - 1) * $page_rows;
|
|
|
|
// 전체 개수
|
|
$sql_count = "SELECT COUNT(*) as cnt FROM consultant_reservations WHERE is_deleted = 0 {$sql_search}";
|
|
$count_row = sql_fetch($sql_count);
|
|
$total_count = $count_row['cnt'];
|
|
$total_page = ceil($total_count / $page_rows);
|
|
|
|
// 데이터 조회
|
|
$sql = "SELECT * FROM consultant_reservations WHERE is_deleted = 0 {$sql_search} {$sql_order} LIMIT {$from_record}, {$page_rows}";
|
|
$result = sql_query($sql);
|
|
$reservations = [];
|
|
while($row = sql_fetch_array($result)) {
|
|
$reservations[] = $row;
|
|
}
|
|
|
|
// 상담가 목록 조회 (예: 레벨 8)
|
|
$consultants_result = sql_query("SELECT mb_id, mb_name FROM {$g5['member_table']} WHERE mb_level = 8 AND mb_leave_date = '' ORDER BY mb_name ASC");
|
|
$consultants = [];
|
|
while($row = sql_fetch_array($consultants_result)) {
|
|
$consultants[] = $row;
|
|
}
|
|
|
|
include_once(G5_ADMIN_PATH . '/admin.head.php');
|
|
|
|
$qstr = http_build_query([
|
|
'sfl' => $sfl,
|
|
'stx' => $stx,
|
|
'sst' => $sst,
|
|
'sod' => $sod,
|
|
'status_filter' => $status_filter
|
|
]);
|
|
?>
|
|
|
|
<div class="local_ov01 local_ov">
|
|
<span class="btn_ov01">
|
|
<span class="ov_txt">전체 예약 </span>
|
|
<span class="ov_num"><?php echo number_format($total_count); ?>건</span>
|
|
<?php echo "DDDDD => ".$sql_count ?>
|
|
<?php echo "DDDDD=> ".$sql ?>
|
|
</span>
|
|
</div>
|
|
|
|
<form name="fsearch" id="fsearch" class="local_sch01 local_sch" method="get">
|
|
<label for="status_filter" class="sound_only">상태 필터</label>
|
|
<select name="status_filter" id="status_filter">
|
|
<option value="">상태 전체</option>
|
|
<option value="payment_pending" <?php echo get_selected($status_filter, 'payment_pending'); ?>><?php echo get_reservation_status_name('payment_pending'); ?></option>
|
|
<option value="reserved" <?php echo get_selected($status_filter, 'reserved'); ?>><?php echo get_reservation_status_name('reserved'); ?></option>
|
|
<option value="completed" <?php echo get_selected($status_filter, 'completed'); ?>><?php echo get_reservation_status_name('completed'); ?></option>
|
|
<option value="cancelled" <?php echo get_selected($status_filter, 'cancelled'); ?>><?php echo get_reservation_status_name('cancelled'); ?></option>
|
|
</select>
|
|
|
|
<label for="sfl" class="sound_only">검색대상</label>
|
|
<select name="sfl" id="sfl">
|
|
<option value="customer_name" <?php echo get_selected($sfl, 'customer_name'); ?>>고객명</option>
|
|
<option value="customer_phone" <?php echo get_selected($sfl, 'customer_phone'); ?>>연락처</option>
|
|
</select>
|
|
<label for="stx" class="sound_only">검색어<strong class="sound_only"> 필수</strong></label>
|
|
<input type="text" name="stx" value="<?php echo $stx ?>" id="stx" class="frm_input">
|
|
<input type="submit" class="btn_submit" value="검색">
|
|
</form>
|
|
|
|
<div class="tbl_head01 tbl_wrap">
|
|
<table>
|
|
<caption><?php echo $g5['title']; ?> 목록</caption>
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">예약번호</th>
|
|
<th scope="col">고객명</th>
|
|
<th scope="col">연락처</th>
|
|
<th scope="col">예약일시</th>
|
|
<th scope="col">상담종류</th>
|
|
<th scope="col">상태</th>
|
|
<th scope="col">담당상담가</th>
|
|
<th scope="col">신청일</th>
|
|
<th scope="col">관리</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($reservations)): ?>
|
|
<tr><td colspan="9" class="empty_table">자료가 없습니다.</td></tr>
|
|
<?php else: ?>
|
|
<?php foreach ($reservations as $res): ?>
|
|
<tr>
|
|
<td><?php echo $res['id']; ?></td>
|
|
<td><?php echo htmlspecialchars($res['customer_name']); ?></td>
|
|
<td><?php echo htmlspecialchars($res['customer_phone']); ?></td>
|
|
<td><?php echo $res['reservation_date'] . ' ' . substr($res['reservation_time'], 0, 5); ?></td>
|
|
<td><?php echo htmlspecialchars($res['temp_2']); ?></td>
|
|
<td><?php echo get_reservation_status_name($res['status']); ?></td>
|
|
<td><?php echo $res['consultant_id'] ? (get_member($res['consultant_id'])['mb_name'] ?? $res['consultant_id']) : '미배정'; ?></td>
|
|
<td><?php echo substr($res['created_at'], 0, 10); ?></td>
|
|
<td class="td_mng td_mng_s">
|
|
<button type="button" class="btn btn_03 manage-btn" data-id="<?php echo $res['id']; ?>">상세/관리</button>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<?php echo get_paging(G5_IS_MOBILE ? $config['cf_mobile_pages'] : $config['cf_write_pages'], $page, $total_page, $_SERVER['SCRIPT_NAME'].'?'.$qstr.'&page='); ?>
|
|
|
|
<!-- 상세/관리 모달 -->
|
|
<div id="reservationModal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); z-index:1000;">
|
|
<div style="position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); background:white; padding:20px; border-radius:5px; width:600px;">
|
|
<h3 id="modalTitle">상담 예약 상세/관리</h3>
|
|
<form name="fmodal" id="fmodal">
|
|
<input type="hidden" name="id" id="modal_id">
|
|
<div class="tbl_frm01 tbl_wrap">
|
|
<table>
|
|
<colgroup>
|
|
<col class="grid_4">
|
|
<col>
|
|
</colgroup>
|
|
<tbody>
|
|
<tr>
|
|
<th scope="row">고객 정보</th>
|
|
<td id="modal_customer_info"></td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">예약 정보</th>
|
|
<td id="modal_reservation_info"></td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">상담 정보</th>
|
|
<td id="modal_consult_info"></td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">고객 요청사항</th>
|
|
<td><textarea id="modal_request_memo" readonly style="width:100%;height:60px;"></textarea></td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row"><label for="modal_status">상태 변경</label></th>
|
|
<td>
|
|
<select name="status" id="modal_status">
|
|
<option value="payment_pending"><?php echo get_reservation_status_name('payment_pending'); ?></option>
|
|
<option value="reserved"><?php echo get_reservation_status_name('reserved'); ?></option>
|
|
<option value="completed"><?php echo get_reservation_status_name('completed'); ?></option>
|
|
<option value="cancelled"><?php echo get_reservation_status_name('cancelled'); ?></option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row"><label for="modal_consultant_id">상담가 배정</label></th>
|
|
<td>
|
|
<select name="consultant_id" id="modal_consultant_id">
|
|
<option value="">상담가 선택</option>
|
|
<?php foreach ($consultants as $c): ?>
|
|
<option value="<?php echo $c['mb_id']; ?>"><?php echo htmlspecialchars($c['mb_name']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row"><label for="modal_admin_memo">관리자 메모</label></th>
|
|
<td><textarea name="admin_memo" id="modal_admin_memo" style="width:100%;height:80px;"></textarea></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="btn_confirm01 btn_confirm" style="margin-top:20px;">
|
|
<button type="button" id="modalSaveBtn" class="btn_submit">저장</button>
|
|
<button type="button" id="modalCloseBtn" class="btn_cancel">닫기</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const modal = document.getElementById('reservationModal');
|
|
const manageButtons = document.querySelectorAll('.manage-btn');
|
|
const closeBtn = document.getElementById('modalCloseBtn');
|
|
const saveBtn = document.getElementById('modalSaveBtn');
|
|
|
|
function openModal(id) {
|
|
fetch('./consultant_reservations_ajax.php?action=get_details&id=' + id)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
const res = data.data;
|
|
document.getElementById('modal_id').value = res.id;
|
|
document.getElementById('modalTitle').innerText = `상담 예약 상세/관리 (예약번호: ${res.id})`;
|
|
document.getElementById('modal_customer_info').innerHTML = `${res.customer_name} (${res.customer_phone} / ${res.customer_email})`;
|
|
document.getElementById('modal_reservation_info').innerHTML = `${res.reservation_date} ${res.reservation_time.substring(0,5)} / <strong>상담비: ${Number(res.payment_amount).toLocaleString()}원</strong>`;
|
|
document.getElementById('modal_consult_info').innerHTML = `종류: ${res.temp_2} / 지역: ${res.temp_3} / 예상시간: ${res.temp_4}분`;
|
|
document.getElementById('modal_request_memo').value = res.request_memo;
|
|
document.getElementById('modal_status').value = res.status;
|
|
document.getElementById('modal_consultant_id').value = res.consultant_id || '';
|
|
document.getElementById('modal_admin_memo').value = res.admin_memo;
|
|
modal.style.display = 'block';
|
|
} else {
|
|
alert(data.message);
|
|
}
|
|
});
|
|
}
|
|
|
|
function closeModal() {
|
|
modal.style.display = 'none';
|
|
}
|
|
|
|
manageButtons.forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
openModal(this.dataset.id);
|
|
});
|
|
});
|
|
|
|
closeBtn.addEventListener('click', closeModal);
|
|
|
|
modal.addEventListener('click', function(e) {
|
|
if (e.target === modal) {
|
|
closeModal();
|
|
}
|
|
});
|
|
|
|
saveBtn.addEventListener('click', function() {
|
|
const form = document.getElementById('fmodal');
|
|
const formData = new FormData(form);
|
|
formData.append('action', 'update_reservation');
|
|
|
|
if (!confirm('변경 내용을 저장하시겠습니까?')) return;
|
|
|
|
fetch('./consultant_reservations_ajax.php', {
|
|
method: 'POST',
|
|
body: new URLSearchParams(formData)
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
alert(data.message);
|
|
location.reload();
|
|
} else {
|
|
alert('오류: ' + data.message);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<?php
|
|
include_once(G5_ADMIN_PATH . '/admin.tail.php');
|
|
?>
|