Files
dnssash/adm/order_manage/estimate_management_page.php
2026-06-11 18:47:38 +09:00

339 lines
12 KiB
PHP

<?php
$sub_menu = "800200";
include_once('./_common.php');
auth_check_menu($auth, $sub_menu, 'r');
$g5['title'] = '견적 관리';
include_once('./admin.head.php');
// 검색 조건
$where = " WHERE 1=1 ";
$search_params = '';
if (isset($_GET['status']) && $_GET['status']) {
$status = sql_real_escape_string($_GET['status']);
$where .= " AND (e.status = '{$status}' OR w.wr_1 = '{$status}')";
$search_params .= "&status={$_GET['status']}";
}
if (isset($_GET['stx']) && $_GET['stx']) {
$stx = sql_real_escape_string($_GET['stx']);
$where .= " AND (w.wr_subject LIKE '%{$stx}%' OR w.wr_name LIKE '%{$stx}%')";
$search_params .= "&stx={$_GET['stx']}";
}
$write_table = $g5['write_prefix'] . 'order';
?>
<style>
.status-popup-overlay {
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0,0,0,0.5); z-index: 9999; display: none;
}
.status-popup {
position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
background: #fff; border: 1px solid #ddd; border-radius: 4px;
min-width: 400px; z-index: 10000; box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.status-popup-header {
padding: 15px 20px; border-bottom: 1px solid #eee; background: #f8f9fa;
border-radius: 4px 4px 0 0;
}
.status-popup-header h3 { margin: 0; font-size: 16px; color: #333; font-weight: 600; }
.status-popup-body { padding: 20px; }
.form-group { margin-bottom: 15px; }
.form-group label { display: block; margin-bottom: 5px; font-weight: 500; color: #333; }
.form-control {
width: 100%; padding: 8px 12px; border: 1px solid #ddd; border-radius: 3px;
font-size: 14px; box-sizing: border-box;
}
.status-popup-footer {
padding: 15px 20px; border-top: 1px solid #eee; text-align: right;
background: #f8f9fa; border-radius: 0 0 4px 4px;
}
.btn {
padding: 8px 16px; border: none; border-radius: 3px; cursor: pointer;
font-size: 14px; margin-left: 5px; transition: all 0.2s;
}
.btn-primary { background: #007bff; color: white; }
.btn-secondary { background: #6c757d; color: white; }
.close-btn {
float: right; background: none; border: none; font-size: 18px;
cursor: pointer; color: #999; padding: 0; width: 20px; height: 20px;
}
.status-견적신청중 { color: #6c757d; }
.status-작성완료 { color: #28a745; }
.status-견적제안 { color: #17a2b8; }
.status-견적채택 { color: #ffc107; }
.status-입금예정 { color: #fd7e14; }
.status-입금확인 { color: #20c997; }
.status-다운로드 { color: #6610f2; }
.status-견적취소 { color: #dc3545; }
.status-btn {
cursor: pointer; padding: 4px 8px; border-radius: 3px;
background: #f8f9fa; border: 1px solid #dee2e6; font-size: 12px;
}
.status-btn:hover { background: #e9ecef; }
.brand-info {
display: inline-block; background: #e9ecef; padding: 2px 6px;
border-radius: 3px; font-size: 11px; color: #495057; margin-right: 3px;
}
</style>
<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 ?? 0) ?>건 </span></span>
</div>
<form name="fsearch" method="get">
<input type="hidden" name="sca" value="<?php echo $sca ?>">
<div class="local_sch01 local_sch">
<label for="stx" class="sound_only">검색어<strong class="sound_only"> 필수</strong></label>
<select name="status">
<option value="">전체상태</option>
<option value="견적신청중" <?php echo ($_GET['status'] ?? '') === '견적신청중' ? 'selected' : ''; ?>>견적신청중</option>
<option value="작성완료" <?php echo ($_GET['status'] ?? '') === '작성완료' ? 'selected' : ''; ?>>작성완료</option>
<option value="견적제안" <?php echo ($_GET['status'] ?? '') === '견적제안' ? 'selected' : ''; ?>>견적제안</option>
<option value="견적채택" <?php echo ($_GET['status'] ?? '') === '견적채택' ? 'selected' : ''; ?>>견적채택</option>
<option value="입금예정" <?php echo ($_GET['status'] ?? '') === '입금예정' ? 'selected' : ''; ?>>입금예정</option>
<option value="입금확인" <?php echo ($_GET['status'] ?? '') === '입금확인' ? 'selected' : ''; ?>>입금확인</option>
</select>
<input type="text" name="stx" value="<?php echo $_GET['stx'] ?? '' ?>" placeholder="제목, 작성자 검색">
<input type="submit" class="btn_submit" value="검색">
</div>
</form>
<form name="flist" id="flist" method="post" onsubmit="return flist_submit(this);">
<div class="tbl_head01 tbl_wrap">
<table>
<thead>
<tr>
<th scope="col">
<label for="chkall" class="sound_only">전체</label>
<input type="checkbox" name="chkall" value="1" id="chkall" onclick="check_all(this.form)">
</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
// 목록 조회
$sql = "SELECT w.*, e.status as estimate_status,
(SELECT GROUP_CONCAT(DISTINCT brand)
FROM estimate_item ei
JOIN estimate est ON ei.estimate_id = est.id
WHERE est.wr_id = w.wr_id AND brand IS NOT NULL AND brand != '') as brands
FROM {$write_table} w
LEFT JOIN estimate e ON w.wr_id = e.wr_id
{$where}
ORDER BY w.wr_num, w.wr_reply
LIMIT 0, 30";
$result = sql_query($sql);
$listall = '<a href="'.$_SERVER['SCRIPT_NAME'].'" class="ov_listall">전체목록</a>';
for ($i=0; $row=sql_fetch_array($result); $i++) {
$status = $row['wr_1'] ?: $row['estimate_status'] ?: '견적신청중';
$brands = $row['brands'] ? explode(',', $row['brands']) : [];
// 사용자별 표시명
$display_status = $status;
if ($member['mb_level'] >= 8) {
// 관리자용 표시명
$display_status = $status;
}
?>
<tr class="<?php echo $row['wr_parent'] ? 'reply' : 'original' ?>">
<td>
<input type="checkbox" name="chk_wr_id[]" value="<?php echo $row['wr_id'] ?>" id="chk_wr_id_<?php echo $i ?>">
</td>
<td><?php echo $row['wr_id'] ?></td>
<td class="td_subject">
<?php echo $row['wr_parent'] ? '└ ' : '' ?>
<a href="<?php echo G5_BBS_URL ?>/board.php?bo_table=order&amp;wr_id=<?php echo $row['wr_id'] ?>">
<?php echo get_text($row['wr_subject']) ?>
</a>
</td>
<td><?php echo $row['wr_name'] ?></td>
<td class="text-center">
<span class="status-btn status-<?php echo $status ?>"
onclick="openStatusPopup(<?php echo $row['wr_id'] ?>, '<?php echo $status ?>', <?php echo $member['mb_level'] ?>, <?php echo !empty($row['wr_parent']) ? 'true' : 'false' ?>)">
<?php echo $display_status ?>
</span>
</td>
<td class="text-center">
<?php
if ($brands) {
foreach (array_slice($brands, 0, 2) as $brand) {
echo '<span class="brand-info">' . htmlspecialchars(trim($brand)) . '</span>';
}
if (count($brands) > 2) {
echo '<span class="brand-info">+' . (count($brands) - 2) . '</span>';
}
} else {
echo '<span style="color:#999;">-</span>';
}
?>
</td>
<td><?php echo substr($row['wr_datetime'], 0, 10) ?></td>
<td>
<a href="<?php echo G5_BBS_URL ?>/board.php?bo_table=order&amp;wr_id=<?php echo $row['wr_id'] ?>" class="btn btn_03">보기</a>
</td>
</tr>
<?php
}
if ($i == 0) {
echo '<tr><td colspan="8" class="empty_table">자료가 없습니다.</td></tr>';
}
?>
</tbody>
</table>
</div>
</form>
<!-- 상태 변경 팝업 -->
<div id="statusPopupOverlay" class="status-popup-overlay">
<div class="status-popup">
<div class="status-popup-header">
<h3>상태 변경</h3>
<button type="button" class="close-btn" onclick="closeStatusPopup()">&times;</button>
</div>
<div class="status-popup-body">
<form id="statusChangeForm">
<input type="hidden" id="popup_wr_id" name="wr_id">
<input type="hidden" name="action" value="change_status">
<div class="form-group">
<label>현재 상태:</label>
<div id="current_status_display" style="color:#666; font-weight:500;"></div>
</div>
<div class="form-group">
<label for="new_status">변경할 상태:</label>
<select id="new_status" name="new_status" class="form-control" required>
<!-- JavaScript로 동적 생성 -->
</select>
</div>
<div class="form-group">
<label for="memo">변경 사유 (선택):</label>
<textarea id="memo" name="memo" class="form-control" placeholder="상태 변경 사유를 입력하세요"></textarea>
</div>
</form>
</div>
<div class="status-popup-footer">
<button type="button" class="btn btn-secondary" onclick="closeStatusPopup()">취소</button>
<button type="button" class="btn btn-primary" onclick="submitStatusChange()">변경</button>
</div>
</div>
</div>
<script>
// 상태 전환 규칙
const statusTransitions = {
admin: {
original: {
'견적신청중': ['작성완료', '견적취소'],
'작성완료': ['견적신청중', '입금예정'],
'견적채택': ['입금예정'],
'입금예정': ['입금확인'],
'입금확인': ['다운로드'],
'다운로드': ['견적신청중']
},
reply: {
'견적제안': ['견적채택', '견적취소'],
'견적채택': ['견적제안'],
'견적취소': ['견적제안']
}
}
};
let currentWrId, currentStatus, currentUserLevel, isReply;
function openStatusPopup(wrId, status, userLevel, isReplyPost) {
currentWrId = wrId;
currentStatus = status;
currentUserLevel = userLevel;
isReply = isReplyPost;
document.getElementById('popup_wr_id').value = wrId;
document.getElementById('current_status_display').textContent = status;
const newStatusSelect = document.getElementById('new_status');
newStatusSelect.innerHTML = '';
const postType = isReplyPost ? 'reply' : 'original';
const availableStatuses = statusTransitions.admin[postType][status] || [];
if (availableStatuses.length === 0) {
newStatusSelect.innerHTML = '<option value="">변경 가능한 상태가 없습니다</option>';
} else {
availableStatuses.forEach(statusValue => {
const option = document.createElement('option');
option.value = statusValue;
option.textContent = statusValue;
newStatusSelect.appendChild(option);
});
}
document.getElementById('statusPopupOverlay').style.display = 'block';
}
function closeStatusPopup() {
document.getElementById('statusPopupOverlay').style.display = 'none';
}
function submitStatusChange() {
const form = document.getElementById('statusChangeForm');
const formData = new FormData(form);
const newStatus = document.getElementById('new_status').value;
if (!newStatus) {
alert('변경할 상태를 선택해주세요.');
return;
}
if (!confirm('상태를 "' + newStatus + '"로 변경하시겠습니까?')) {
return;
}
fetch('./list.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert(data.message);
closeStatusPopup();
location.reload();
} else {
alert('오류: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('서버 오류가 발생했습니다.');
});
}
document.getElementById('statusPopupOverlay').addEventListener('click', function(e) {
if (e.target === this) {
closeStatusPopup();
}
});
</script>
<?php
include_once('./admin.tail.php');
?>