Feat: VIP 관리 시스템 개선 - 모달 구조 정리, 만료일 자동 상태 관리

- VIP 리스트 모달을 루프 내 숨겨진 TR에 통합 (Bootstrap 호환성 유지)
- X 아이콘 제거 및 액션 버튼 표시 조건 개선 (status='정상'인 경우만 표시)
- 행 높이 표준화 (60px, align-middle)
- 만료일이 오늘 이전일 경우 상태 자동 '만료' 처리 (AJAX 및 1회성 실행 모드)
- 만료일 설정 페이지 결과 테이블에 상태 변경 정보 추가
This commit is contained in:
2026-02-20 15:38:38 +09:00
parent bd1f111e8d
commit 3afec44da9
3 changed files with 81 additions and 80 deletions

View File

@ -191,37 +191,40 @@ $table = "{$fg['vip_list_table']} AS a LEFT JOIN {$fg['vip_category_table']} AS
$is_expired = ($expire_date != '9999-12-31' && strtotime($expire_date) < strtotime($today)) ? true : false;
$expired_class = $is_expired ? 'expired-vip' : '';
?>
<tr class="<?=($R['status'] != '정상') ? "unused" : "" ?> vip-row <?=$expired_class?>" style="cursor: pointer;" onclick="openVipModal(<?=$R['idx']?>)">
<td class="text-center"><?=$R['vip_card_no']?></td>
<td class="text-center"><?=$R['status']?></td>
<td class="text-center"><?=$R['vip_name']?></td>
<td class="text-center"><?=$R['vip_tel']?></td>
<td class="text-center"><?=$R['vip_birth']?></td>
<td class="text-center" style="<?=($is_expired) ? 'color: #999; opacity: 0.6;' : ''?>"><?=($R['vip_date'] == '9999-12-31')? '평생' : $R['vip_date']?></td>
<td class="text-center">
<tr class="<?=($R['status'] != '정상') ? "unused" : "" ?> vip-row <?=$expired_class?>" style="cursor: pointer; height: 60px;" data-bs-toggle="modal" data-bs-target="#modify_modal_<?=$R['idx']?>">
<td class="text-center align-middle"><?=$R['vip_card_no']?></td>
<td class="text-center align-middle"><?=$R['status']?></td>
<td class="text-center align-middle"><?=$R['vip_name']?></td>
<td class="text-center align-middle"><?=$R['vip_tel']?></td>
<td class="text-center align-middle"><?=$R['vip_birth']?></td>
<td class="text-center align-middle" style="<?=($is_expired) ? 'color: #999; opacity: 0.6;' : ''?>"><?=($R['vip_date'] == '9999-12-31')? '평생' : $R['vip_date']?></td>
<td class="text-center align-middle">
<?php
$edate = $R['last_ent_date'];
echo ($edate == '0000-00-00 00:00:00')? '미이용' : date('Y-m-d',strtotime($edate));
?></td>
<td class="text-center"><?=$R['ent_count']?></td>
<td class="text-center d-flex justify-content-center gap-1" onclick="event.stopPropagation();">
<td class="text-center align-middle"><?=$R['ent_count']?></td>
<td class="text-center align-middle d-flex justify-content-center gap-1" onclick="event.stopPropagation();" style="min-height: 60px;">
<?php if($_SESSION['user_lv'] > "1"){ ?>
<!-- 입장처리 버튼 -->
<?php if ($R['status'] == '정상') { ?>
<a class="btn btn-danger btn-xs" href="javascript:entMemWithConfirm('<?=$R['idx']?>', <?=$is_expired ? 'true' : 'false'?>)" role="button"><i class="fas fa-sign-in-alt"></i></a>
<?php } else { ?>
<i class="fas fa-times"></i>
<?php if($R['status'] == '정상') { ?>
<a class="btn btn-danger btn-xs" href="javascript:entMemWithConfirm('<?=$R['idx']?>', <?=$is_expired ? 'true' : 'false'?>)" role="button"><i class="fas fa-sign-in-alt"></i></a>
<button type="button" class="btn btn-success btn-xs" data-bs-toggle="modal" data-bs-target="#modify_modal_<?=$R['idx']?>" onclick="event.stopPropagation()"><i class="fa-solid fa-pen-to-square"></i></button>
<button type="button" class="btn btn-primary btn-xs" data-bs-toggle="modal" data-bs-target="#renew_modal_<?=$R['idx']?>" onclick="event.stopPropagation()"><i class="fa-solid fa-repeat"></i></button>
<?php } ?>
<!-- 입장처리 버튼 끝 -->
<!-- 수정 모달 -->
<?php if($_SESSION['user_lv'] === "4" && $R['status'] != "재발급"){ ?>
<a class="btn btn-danger btn-xs" href="javascript:deleteItem('<?=$R['idx']?>')" role="button"><?=($R['status'] == '정상')? '<i class="fa-solid fa-trash-can"></i>' : '<i class="fa-solid fa-trash-can-arrow-up"></i>'?></a>
<?php } ?>
<?php } ?>
</td>
</tr>
<div id="modify_modal_<?=$R['idx']?>" class="modal fade" tabindex="-1" aria-labelledby="modify_modal_<?=$R['idx']?>" aria-hidden="true">
<div class="modal-dialog modal modal-dialog-centered">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<form class="modify" id="modify_<?=$R['idx']?>">
<div class="modal-header">
<h5 class="modal-title">정보 보기/수정</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-start">
<input type="hidden" id="idx_<?=$R['idx']?>" name="idx" value="<?=$R['idx']?>" readonly>
@ -232,7 +235,10 @@ $table = "{$fg['vip_list_table']} AS a LEFT JOIN {$fg['vip_category_table']} AS
if($R['status'] != "정상") {
$ro = "disabled";
echo "<p>폐기된 카드는 수정할 수 없습니다.</p>";
;
}
$gender = '';
if($R['status'] == "정상") {
$gender = $R['vip_gender'];
}
?>
<div class="input-group mb-1">
@ -270,11 +276,7 @@ $table = "{$fg['vip_list_table']} AS a LEFT JOIN {$fg['vip_category_table']} AS
<div class="input-group mb-1">
<span class="input-group-text col-md-2" id="vip_name_<?=$R['idx']?>">고객명</span>
<input type="text" class="form-control" id="vip_name_<?=$R['idx']?>" name="vip_name" value="<?=$R['vip_name']?>" required <?=$ro?>>
<? // DB에서 성별값을 불러온다.
if($R['status'] == "정상") { // 정상 상태가 아니면 성별도 필요없음
$gender = $R['vip_gender']
?>
<!-- 불러온 성별에 따라 라디오버튼 선택하도록 -->
<?php if($R['status'] == "정상") { ?>
<input type="radio" class="btn-check" name="vip_gender" id="vip_gender_<?=$R['idx']?>_male" value="남" <?php if($gender == "남") echo "checked" ?> required>
<label class="btn btn-outline-primary" for="vip_gender_<?=$R['idx']?>_male">남</label>
<input type="radio" class="btn-check" name="vip_gender" id="vip_gender_<?=$R['idx']?>_female" value="여" <?php if($gender =="여") echo "checked" ?> required>
@ -302,52 +304,43 @@ $table = "{$fg['vip_list_table']} AS a LEFT JOIN {$fg['vip_category_table']} AS
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" <?=$ro?> >수정</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="Close" data-bs-target="#modify_modal_<?=$R['idx']?>">닫기</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
</div>
</div>
<!-- 수정 모달 끝 -->
<!-- 수정 버튼 -->
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#modify_modal_<?=$R['idx']?>"><i class="fa-solid fa-pen-to-square"></i></button>
<!-- 재발급 버튼 -->
<?php if ( $R['status'] === "정상" ) { ?>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#renew_modal_<?=$R['idx']?>"><i class="fa-solid fa-repeat"></i></button>
<div id="renew_modal_<?=$R['idx']?>" class="modal fade text-center ">
<div class="modal-dialog">
<div class="modal-content">
<form class="renew" id="renew_<?=$R['idx']?>">
<input type="hidden" id="idx_<?=$R['idx']?>" name="idx" value="<?=$R['idx']?>" readonly>
<input type="hidden" id="last_edit_name_<?=$R['idx']?>" name="last_edit_name" value="<?=$_SESSION['user_name']?>" readonly>
<div class="modal-header">
<h5 class="modal-title">재발급</h4>
<!-- 재발급 모달 -->
<?php if ( $R['status'] === "정상" ) { ?>
<div id="renew_modal_<?=$R['idx']?>" class="modal fade" tabindex="-1" aria-labelledby="renew_modal_<?=$R['idx']?>" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<form class="renew" id="renew_<?=$R['idx']?>">
<input type="hidden" id="idx_<?=$R['idx']?>" name="idx" value="<?=$R['idx']?>" readonly>
<input type="hidden" id="last_edit_name_<?=$R['idx']?>" name="last_edit_name" value="<?=$_SESSION['user_name']?>" readonly>
<div class="modal-header">
<h5 class="modal-title">재발급</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-start">
<div class="input-group">
<span class="input-group-text col-md-4" id="re_no_<?=$R['idx']?>">재발급 카드번호</span>
<input type="number" class="form-control" oninput="checkDupRc(this.value)" id="rc_no_<?=$R['idx']?>" name="rc_no" maxlength="6" value="" required>
</div>
<div class="modal-body text-start">
<div class="input-group">
<span class="input-group-text col-md-4" id="re_no_<?=$R['idx']?>">재발급 카드번호</span>
<input type="number" class="form-control" oninput="checkDupRc(this.value)" id="rc_no_<?=$R['idx']?>" name="rc_no" maxlength="6" value="" required>
</div>
<div class="input-group checkdup">
<span id="duplicate-rc-warning"></span>
</div>
<div class="input-group checkdup">
<span id="duplicate-rc-warning"></span>
</div>
<div class="modal-footer">
<button type="submit" id="renew_submit" class="btn btn-primary">확인</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="Close" data-bs-target="#renew_modal_<?=$R['idx']?>">닫기</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
<div class="modal-footer">
<button type="submit" id="renew_submit" class="btn btn-primary">확인</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
</div>
</form>
</div>
</div>
<?php } ?>
<!-- 폐기는 관리자만 -->
<?php if($_SESSION['user_lv'] === "4" && $R['status'] != "재발급"){ ?>
<a class="btn btn-danger" href="javascript:deleteItem('<?=$R['idx']?>')" role="button"><?=($R['status'] == '정상')? '<i class="fa-solid fa-trash-can"></i>' : '<i class="fa-solid fa-trash-can-arrow-up"></i>'?></a>
<?php }
} ?>
</td>
</tr>
</div>
<?php } ?>
<?php } ?>
</tbody>

View File

@ -16,14 +16,8 @@ if(isset($_POST['mode']) && trim($_POST['mode']) === "enter") {
$datetime = date("Y-m-d H:i:s");
// 만료일 설정 로직
// 방문횟수가 0이면 등록일 + 1년, 1 이상이면 최종이용일 + 1년
if ($ent_count == 1) {
// 첫 입장: 등록일 + 1년
$vip_date = date("Y-m-d", strtotime($list['join_datetime'] . " +1 year"));
} else {
// 재입장: 현재 최종이용일 + 1년
$vip_date = date("Y-m-d", strtotime($date . " +1 year"));
}
// 현재 최종이용일 + 1년
$vip_date = date("Y-m-d", strtotime($date . " +1 year"));
// 리스트 DB에 최종사용일자 및 만료일 업데이트
$listquery = "UPDATE {$fg['vip_list_table']} SET last_ent_date='{$date}', ent_count='{$ent_count}', vip_date='{$vip_date}' WHERE idx='{$idx}'";

View File

@ -14,7 +14,7 @@ if(!$_SESSION['user_id']) {
}
// 권한 체크 (관리자 이상만 가능)
if($_SESSION['user_lv'] < 2) {
if($_SESSION['user_lv'] < 3) {
die('권한이 없습니다.');
}
@ -56,8 +56,12 @@ if(isset($_POST['ajax_mode'])) {
$vip_date = date("Y-m-d", strtotime($list['last_ent_date'] . " +1 year"));
}
// 만료 여부 확인 (만료일이 오늘 이전이면 상태를 '만료'로 변경)
$today = date('Y-m-d');
$new_status = (strtotime($vip_date) < strtotime($today)) ? '만료' : '정상';
// DB 업데이트
$updateQuery = "UPDATE {$fg['vip_list_table']} SET vip_date='{$vip_date}' WHERE idx='{$list['idx']}'";
$updateQuery = "UPDATE {$fg['vip_list_table']} SET vip_date='{$vip_date}', status='{$new_status}' WHERE idx='{$list['idx']}'";
$update_result = sql_query($updateQuery);
if ($update_result) {
@ -68,7 +72,7 @@ if(isset($_POST['ajax_mode'])) {
// log 기록
$work = "VIP만료일일괄설정";
$work_detail = "카드번호 : ".$list['vip_card_no']." 만료일 : ".$vip_date." 처리자 : ".$_SESSION['user_name'];
$work_detail = "카드번호 : ".$list['vip_card_no']." 만료일 : ".$vip_date." 상태 : ".$new_status." 처리자 : ".$_SESSION['user_name'];
$logUpdate = log_update($work, $work_detail, $_SESSION['user_id'], $datetime);
}
@ -112,8 +116,12 @@ if(isset($_REQUEST['confirm']) && $_REQUEST['confirm'] == 'yes') {
$logic_type = "최종이용일 기준";
}
// 만료 여부 확인 (만료일이 오늘 이전이면 상태를 '만료'로 변경)
$today = date('Y-m-d');
$new_status = (strtotime($vip_date) < strtotime($today)) ? '만료' : '정상';
// DB 업데이트
$updateQuery = "UPDATE {$fg['vip_list_table']} SET vip_date='{$vip_date}' WHERE idx='{$list['idx']}'";
$updateQuery = "UPDATE {$fg['vip_list_table']} SET vip_date='{$vip_date}', status='{$new_status}' WHERE idx='{$list['idx']}'";
$update_result = sql_query($updateQuery);
if ($update_result) {
@ -124,7 +132,9 @@ if(isset($_REQUEST['confirm']) && $_REQUEST['confirm'] == 'yes') {
'old_date' => $list['vip_date'],
'new_date' => $vip_date,
'logic' => $logic_type,
'ent_count' => $ent_count
'ent_count' => $ent_count,
'new_status' => $new_status,
'status_changed' => ($new_status !== $list['status']) ? 'O' : 'X'
);
} else {
$error_count++;
@ -132,7 +142,7 @@ if(isset($_REQUEST['confirm']) && $_REQUEST['confirm'] == 'yes') {
// log 기록
$work = "VIP만료일일괄설정";
$work_detail = "카드번호 : ".$list['vip_card_no']." 만료일 : ".$vip_date." (" . $logic_type . ") 처리자 : ".$_SESSION['user_name'];
$work_detail = "카드번호 : ".$list['vip_card_no']." 만료일 : ".$vip_date." (" . $logic_type . ") 상태 : ".$new_status." 처리자 : ".$_SESSION['user_name'];
$logUpdate = log_update($work, $work_detail, $_SESSION['user_id'], $datetime);
}
@ -186,6 +196,8 @@ if(isset($_REQUEST['confirm']) && $_REQUEST['confirm'] == 'yes') {
<th>신규 만료일</th>
<th>설정 기준</th>
<th>방문횟수</th>
<th>신규 상태</th>
<th>상태변경</th>
</tr>
</thead>
<tbody>
@ -197,6 +209,8 @@ if(isset($_REQUEST['confirm']) && $_REQUEST['confirm'] == 'yes') {
<td><strong><?= $item['new_date'] ?></strong></td>
<td><?= $item['logic'] ?></td>
<td><?= $item['ent_count'] ?></td>
<td><?= $item['new_status'] ?></td>
<td><?= ($item['status_changed'] === 'O') ? '<span class="badge bg-warning">변경됨</span>' : '-' ?></td>
</tr>
<?php } ?>
</tbody>