Files
sam-kd/annualleave/index.php

2403 lines
95 KiB
PHP
Raw Normal View History

<?php require_once($_SERVER['DOCUMENT_ROOT'] . '/session.php');
if (!isset($_SESSION["name"])) {
$_SESSION["url"] = '/annualleave/index.php?user_name=' . $user_name;
sleep(1);
header("Location:/login/logout.php");
exit;
}
$title_message = '직원 연차';
?>
<?php include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php' ?>
<link href="css/style.css" rel="stylesheet">
<!-- CSS (style.css 혹은 <style> 태그) -->
<style>
/* style.css 혹은 <style> 태그에 추가 */
#monthlyLeaveModal .modal-body {
max-height: 750px; /* 최대 높이 750px */
overflow-y: auto; /* 넘칠 때만 세로 스크롤 */
padding: 1rem; /* 패딩은 필요에 따라 조정 */
}
/* 테이블 헤더 고정 */
#monthlyLeaveModal .modal-body table thead th {
position: sticky;
top: 0;
background: #6c757d; /* 다크 그레이 */
color: #fff; /* 텍스트를 흰색으로 */
z-index: 2;
}
/* 연차 모달 스크롤 스타일 */
#myModal .modal-content {
max-height: 90vh; /* 뷰포트 높이의 90% */
overflow: hidden; /* 기본 오버플로우 숨김 */
}
#myModal .modal-body {
max-height: calc(90vh - 120px); /* 헤더와 푸터 높이 제외 */
overflow-y: auto; /* 세로 스크롤 활성화 */
padding: 1rem; /* 패딩 추가 */
}
/* 스크롤바 스타일링 */
#myModal .modal-body::-webkit-scrollbar {
width: 8px;
}
#myModal .modal-body::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
#myModal .modal-body::-webkit-scrollbar-thumb {
background: #888;
border-radius: 4px;
}
#myModal .modal-body::-webkit-scrollbar-thumb:hover {
background: #555;
}
</style>
<title> <?=$title_message?> </title>
</head>
<body>
<?php if($mycompany ==='경동')
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader.php');
else
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader1.php');
?>
<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/common.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
$pdo = db_connect();
// 배열로 기본정보 불러옴
require_once($_SERVER['DOCUMENT_ROOT'] . "/almember/load_DB.php");
// echo '<pre>';
// print_r($employee_json);
// echo '</pre>';
if (intval($level) == 1 )
$admin = 1;
else
$admin = 2;
$tablename = "eworks";
// 변수 초기화
$mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : '';
$search = isset($_REQUEST['search']) ? $_REQUEST['search'] : '';
// 새로 추가: 소속 검색값 (corpSearch)
$corpSearch = isset($_REQUEST["corpSearch"]) ? $_REQUEST["corpSearch"] : $mycompany ;
$partSearch = isset($_REQUEST["partSearch"]) ? $_REQUEST["partSearch"] : "";
// corp.json 파일에서 소속 목록 불러오기
$corpFile = $_SERVER['DOCUMENT_ROOT'] . '/member/corp.json';
$corpData = [];
if (file_exists($corpFile)) {
$corpJson = file_get_contents($corpFile);
$corpData = json_decode($corpJson, true);
if (!is_array($corpData)) { $corpData = []; }
}
// part.json 파일에서 부서 목록 불러오기
$partFile = $_SERVER['DOCUMENT_ROOT'] . '/member/part.json';
$partData = [];
if (file_exists($partFile)) {
$partJson = file_get_contents($partFile);
$partData = json_decode($partJson, true);
if (!is_array($partData)) {
$partData = [];
}
}
// holiday 테이블에서 휴일 목록 불러오기
$holidayDates = [];
try {
$holidaySql = "SELECT startdate, enddate FROM " . $DB . ".holiday WHERE is_deleted IS NULL";
$holidayStmt = $pdo->query($holidaySql);
$holidayRows = $holidayStmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($holidayRows as $holidayRow) {
$startdate = $holidayRow['startdate'];
$enddate = $holidayRow['enddate'];
// enddate가 '0000-00-00'이거나 비어있으면 startdate만 휴일
if (empty($enddate) || $enddate === '0000-00-00' || $enddate === null) {
$holidayDates[] = $startdate;
} else {
// 기간 내의 모든 날짜를 배열에 추가
$start = new DateTime($startdate);
$end = new DateTime($enddate);
$end->modify('+1 day'); // 종료일 포함
$period = new DatePeriod($start, new DateInterval('P1D'), $end);
foreach ($period as $date) {
$holidayDates[] = $date->format('Y-m-d');
}
}
}
} catch (PDOException $e) {
// 오류 발생 시 빈 배열 유지
error_log("Holiday 데이터 로드 오류: " . $e->getMessage());
}
if(intval($level) !== 1) {
$AndisDeleted = " AND is_deleted IS NULL AND eworks_item='연차' ";
$WhereisDeleted = " where is_deleted IS NULL AND eworks_item='연차' ";
if ($search == "") {
if ($admin == 1) {
$sql = "SELECT * FROM " . $DB . "." . $tablename . $WhereisDeleted . " ORDER BY al_askdatefrom DESC, registdate DESC";
} else {
$sql = "SELECT * FROM " . $DB . "." . $tablename . " WHERE author LIKE '%$user_name%' " . $AndisDeleted . " ORDER BY al_askdatefrom DESC, registdate DESC";
}
} else {
if ($admin == 1) {
$sql = "SELECT * FROM " . $DB . "." . $tablename . " WHERE (author LIKE '%$search%') " . $AndisDeleted . " ORDER BY al_askdatefrom DESC, registdate DESC";
} else {
$sql = "SELECT * FROM " . $DB . "." . $tablename . " WHERE (author = '$user_name') AND (author LIKE '%$search%') " . $AndisDeleted . " ORDER BY al_askdatefrom DESC, registdate DESC";
}
}
$stmt = $pdo->prepare($sql);
}
else // 관리자인 경우
{
// 기본 SQL 쿼리 (검색조건 미포함)
$sql = "SELECT * FROM {$DB}.{$tablename} ORDER BY num DESC";
// print '관리자';
// 검색 조건 구성: 검색어와 소속 및 부서 검색 조건을 모두 고려
$conditions = [" eworks_item='연차' ", " is_deleted IS NULL "];
$bindParams = [];
if ($mode == "search" or !empty($corpSearch) ) {
if (!empty($search)) {
// member 테이블의 모든 컬럼에 대해 LIKE 검색 (예제)
$columns = [];
$stmt = $pdo->query("SHOW COLUMNS FROM " . $DB . "." . $tablename);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$columns[] = $row['Field'];
}
$searchConditions = [];
foreach ($columns as $index => $col) {
$paramName = ":search{$index}";
$searchConditions[] = "$col LIKE $paramName";
$bindParams[$paramName] = "%$search%";
}
$conditions[] = "(" . implode(" OR ", $searchConditions) . ")";
}
if (!empty($corpSearch)) {
// 소속(division) 검색 조건 추가
$conditions[] = "al_company LIKE :corpSearch";
$bindParams[":corpSearch"] = "%$corpSearch%";
}
if (!empty($partSearch)) {
// 부서(part) 검색 조건 추가
$conditions[] = "al_part LIKE :partSearch";
$bindParams[":partSearch"] = "%$partSearch%";
}
if (!empty($conditions)) {
$sql = "SELECT * FROM {$DB}.{$tablename} WHERE " . implode(" AND ", $conditions) . " ORDER BY num DESC";
}
}
$stmt = $pdo->prepare($sql);
if (!empty($bindParams)) {
foreach ($bindParams as $paramName => $paramValue) {
$stmt->bindValue($paramName, $paramValue, PDO::PARAM_STR);
}
}
}
// print $sql ;
// echo '<pre>';
// print_r($conditions);
// echo '</pre>';
// 여기서 execute()
$stmt->execute();
// 실행 후 결과를 fetchAll()하거나 rowCount() 확인
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$total_row = count($rows);
// print $total_row ;
// print $eworks_level;
?>
<form name="board_form" id="board_form" method="post" >
<input type="hidden" id="username" name="username" value="<?= isset($user_name) ? $user_name : '' ?>">
<?php if ($chkMobile == false) { ?>
<div class="container">
<?php } else { ?>
<div class="container-fluid">
<?php } ?>
<!-- 월별 연차사용 Modal -->
<div id="monthlyLeaveModal" class="modal" tabindex="-1">
<div class="modal-dialog modal-fullscreen"> <!-- modal-dialog-scrollable 제거 -->
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">월별 연차사용</h5>
<button type="button" class="btn-close monthlyClose" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="d-flex mb-3">
<select id="monthYearSelect" class="form-select w-auto me-2">
<?php
$curr = date('Y');
echo "<option value='{$curr}' selected>{$curr}</option>";
echo "<option value='".($curr-1)."'>".($curr-1)."</option>";
?>
</select>
<select id="corpSelect" class="form-select w-auto">
<option value="">전체</option>
<option value="경동">경동</option>
<option value="주일">주일</option>
</select>
</div>
<div id="monthlyLeaveContent"><!-- AJAX 로드된 테이블 --></div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-body">
<div class="d-flex justify-content-center align-items-center mt-3 mb-3">
<span class=" fs-5"> <?=$title_message?> </span>
<button type="button" class="btn btn-dark btn-sm mx-2" onclick='location.reload()'> <i class="bi bi-arrow-clockwise"></i> </button>
&nbsp;&nbsp;&nbsp;&nbsp;
<?php if ($admin == 1 || strval($eworks_level) == '2') { ?>
<!-- <button type="button" id="openAlmemberBtn" class="btn btn-success btn-sm me-2">
<i class="bi bi-pencil-square"></i> 직원 정보 -->
<button type="button" class="btn btn-primary btn-sm" onclick="location.href='./admin.php'">
<i class="bi bi-pencil-square"></i>
관리자모드
</button>
<? } ?>
</div>
<div class="d-flex justify-content-center align-items-center mt-3 mb-1">
<h6 class="text-center mb-1">
<div class="d-flex justify-content-center align-items-center mb-1">
<select id="yearSelect" class="form-select form-select-sm d-inline w-auto">
<?php
$currentYear = date("Y");
for ($year = $currentYear; $year >= $currentYear - 3; $year--) {
echo "<option value='{$year}'" . ($year == $currentYear ? " selected" : "") . ">{$year}</option>";
}
?>
</select>
년도 &nbsp; <?=$user_name?>
</div>
<div class="d-flex justify-content-center align-items-center mb-1">
<table class="table table-bordered text-center">
<tbody>
<tr>
<td class="table-success fs-6"><span class="badge bg-success">발생일</span></td>
<td class="table-success fs-6"><span class="badge bg-danger">전년도 선사용</span></td>
<td class="table-primary fs-6"><span class="badge bg-primary">사용일</span></td>
<td class="table-secondary fs-6"><span class="badge bg-secondary">잔여일</span></td>
</tr>
<tr>
<td class="text-success fs-6" id="totalDays"><?=$total?></td>
<td class="text-danger fs-6" id="previous_usageDays"><?=$previous_usage?></td>
<td class="text-primary fs-6" id="usedDays"><?=$thisyeartotalusedday?></td>
<td class="text-dark fs-6" id="remainingDays"><?=$thisyeartotalremainday?></td>
</tr>
</tbody>
</table>
</div>
</h6>
</div>
<div class="d-flex justify-content-center mt-1 mb-4">
<h6 style="background-color:#a5a5a5;"> 결재완료 삭제 불가 </h6>
</div>
<div class="d-flex justify-content-center align-items-center mt-2 mb-2">
<?php if (intval($level) === 1) : ?>
<i class="bi bi-caret-right"></i> <?= $total_row ?> &nbsp;&nbsp;&nbsp;
<!-- 소속 검색 select 추가 -->
<div class="inputWrap30 mx-1">
<select name="corpSearch" id="corpSearch" class="form-select w100px mx-1" style="font-size: 0.9rem; height: 32px;">
<option value=""><?= "(소속)" ?></option>
<?php foreach($corpData as $corp): ?>
<option value="<?= htmlspecialchars($corp, ENT_QUOTES, 'UTF-8') ?>" <?= ($corpSearch === $corp) ? 'selected' : '' ?>>
<?= htmlspecialchars($corp, ENT_QUOTES, 'UTF-8') ?>
</option>
<?php endforeach; ?>
</select>
</div>
<!-- 부서 검색 select 추가 -->
<div class="inputWrap30 mx-1">
<select name="partSearch" id="partSearch" class="form-select w120px mx-1" style="font-size: 0.9rem; height: 32px;">
<option value=""><?= "(부서)" ?></option>
<!-- 옵션은 JS에서 동적으로 채워짐 -->
</select>
</div>
<input type="text" name="search" id="search" class="form-control me-1" style="width:150px;height:32px;" value="<?=$search?>" onkeydown="JavaScript:SearchEnter();" placeholder="검색어">
<button type="button" id="searchBtn" class="btn btn-dark btn-sm me-1"> <i class="bi bi-search"></i> 검색 </button>
<?php endif ?>
<button type="button" id="writeBtn" class="btn btn-dark btn-sm mx-2"> <i class="bi bi-pencil-square"></i> 신청 </button>
<?php if ($admin == 1 || strval($eworks_level) == '2') { ?>
<button type="button" id="monthlyLeaveBtn" class="btn btn-secondary btn-sm mx-2"> <i class="bi bi-calendar-event"></i> 월별 연차사용 </button>
<?php } ?>
</div>
<div class="row d-flex justify-content-center">
<table class="table table-hover" id="myTable">
<thead class="table-primary">
<tr>
<th class="text-center">번호</th>
<th class="text-center">접수일</th>
<th class="text-center">회사</th>
<th class="text-center">부서</th>
<th class="text-center">성명</th>
<th class="text-center">시작일</th>
<th class="text-center">종료일</th>
<th class="text-center">사용일수</th>
<th class="text-center">사유</th>
<th class="text-center text-primary">결재권자</th>
<th class="text-center">결재상태</th>
</tr>
</thead>
<tbody>
<?php
$start_num = $total_row;
// 필요하다면 $rows를 순회
foreach ($rows as $row) {
include "rowDBask.php";
switch ($status) {
case 'send':
$statusstr = '결재요청';
break;
case 'ing':
$statusstr = '결재중';
break;
case 'end':
$statusstr = '결재완료';
break;
default:
$statusstr = '';
break;
}
?>
<tr onclick="loadForm('update','<?=$num?>');">
<td class="text-center"><?=$start_num?></td>
<td class="text-center"><?=iconv_substr($registdate, 5, 5, "utf-8")?></td>
<td class="text-center"><?=$al_company?></td>
<td class="text-center"><?=$al_part?></td>
<td class="text-center"><?=$author?></td>
<td class="text-center"><?=iconv_substr($al_askdatefrom, 5, 5, "utf-8")?></td>
<td class="text-center"><?=iconv_substr($al_askdateto, 5, 5, "utf-8")?></td>
<td class="text-center"><?=$al_usedday?></td>
<td class="text-center"><?=$al_content?></td>
<td class="text-center text-primary"><?=$e_line?></td>
<td class="text-center"><?=$statusstr?></td>
</tr>
<?php
$start_num--;
}
?>
</tbody>
</table>
</div>
<div class="d-flex justify-content-center mt-5 mb-5">
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div id="myModal" class="modal" >
<div class="modal-content" style="width:600px;">
<div class="modal-header">
<span class="modal-title">연차</span>
<span class="close closeBtn">&times;</span>
</div>
<div class="modal-body">
<div class="custom-card"></div>
</div>
</div>
</div>
</form>
<div class="container mt-3 mb-3">
<? include '../footer.php'; ?>
</div>
<script>
var ajaxRequest_write = null;
var ajaxRequest = null;
var dataTable; // DataTables 인스턴스 전역 변수
var annualleavepageNumber; // 현재 페이지 번호 저장을 위한 전역 변수
$(document).ready(function() {
// DataTables 초기 설정
dataTable = $('#myTable').DataTable({
"paging": true,
"ordering": true,
"searching": false, // 실시간 검색어
"pageLength": 50,
"lengthMenu": [50, 100, 200, 500, 1000],
"language": {
"lengthMenu": "Show _MENU_ entries",
"search": "Live Search:"
},
"order": [
[0, 'desc']
]
});
// 페이지 번호 복원 (초기 로드 시)
var savedPageNumber = getCookie('annualleavepageNumber');
if (savedPageNumber) {
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
}
// 페이지 변경 이벤트 리스너
dataTable.on('page.dt', function() {
var annualleavepageNumber = dataTable.page.info().page + 1;
setCookie('annualleavepageNumber', annualleavepageNumber, 10); // 쿠키에 페이지 번호 저장
});
// 페이지 길이 셀렉트 박스 변경 이벤트 처리
$('#myTable_length select').on('change', function() {
var selectedValue = $(this).val();
dataTable.page.len(selectedValue).draw(); // 페이지 길이 변경 (DataTable 파괴 및 재초기화 없이)
// 변경 후 현재 페이지 번호 복원
savedPageNumber = getCookie('annualleavepageNumber');
if (savedPageNumber) {
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
}
});
// 파일 업로드 이벤트를 전역적으로 한 번만 바인딩
bindFileUploadEvents();
});
function SearchEnter() {
if (event.keyCode == 13) {
document.getElementById('board_form').submit();
}
}
function loadForm(mode, num = null, al_company = null, al_part = null) {
if (num == null) {
$("#mode").val('insert');
} else {
$("#mode").val('update');
$("#num").val(num);
}
// alert( al_company + al_part);
$.ajax({
type: "POST",
url: "fetch_modal.php",
data: { mode: mode, num: num, al_company : al_company, al_part: al_part },
dataType: "html",
success: function(response) {
document.querySelector(".modal-body .custom-card").innerHTML = response;
$("#myModal").show();
// 모달이 로드된 후 holiday 데이터 다시 초기화 (fetch_modal.php의 스크립트 실행 대기)
setTimeout(function() {
// fetch_modal.php에서 전달된 holiday 데이터가 있는지 확인하고 업데이트
if (typeof window.holidaySet === 'undefined') {
// holidaySet이 없으면 기본값으로 초기화
window.holidaySet = new Set(holidayDates || []);
}
// holidaySet이 이미 있으면 그대로 사용 (fetch_modal.php에서 업데이트됨)
}, 100);
$("#closeBtn").off("click").on("click", function() {
$("#myModal").hide();
});
$(".closeBtn").off("click").on("click", function() {
$("#myModal").hide();
});
// PHP에서 생성된 JSON 데이터를 JavaScript 변수로 변환
var employeeData = <?= $employee_json ?>;
//console.log('employeeData', employeeData);
// 동적으로 추가된 select 요소에 이벤트 바인딩 (중복 방지)
$(document).off('change', '#author').on('change', '#author', function() {
var selectedName = $(this).val(); // 선택된 성명
$.ajax({
url: "get_employee_info.php",
type: "post",
data: { name: selectedName },
dataType: "json",
success: function(data){
//alert(data);
// console.log(data);
if (data) {
// 업데이트: 회사, 부서, 입사일
if ($("#al_company").length) $("#al_company").val(data.division);
if ($("#al_part").length) $("#al_part").val(data.part);
if ($("#dateofentry").length) $("#dateofentry").val(data.enterDate);
if ($("#referencedate").length) $("#referencedate").val(data.referencedate);
if ($("#initial_less_than_one_year").length) $("#initial_less_than_one_year").val(data.initial_less_than_one_year);
if ($("#continueYear").length) $("#continueYear").val(data.continueYear);
if ($("#service_based").length) $("#service_based").val(data.service_based);
if ($("#previous_year_usage").length) $("#previous_year_usage").val(data.previous_year_usage);
if ($("#totalremainday").length) $("#totalremainday").val(data.available);
}
},
error: function(xhr, status, error){
console.log("Error: " + error);
}
});
});
// 저장 버튼 (중복 방지)
$(document).off('click', '#saveBtn').on('click', '#saveBtn', function() {
var num = $("#num").val();
var part = $("#part").val();
var status = $("#status").val();
var user_name = $("#user_name").val();
var admin = '<?= $admin ?>';
if(status=='send' || admin === '1') {
if(Number(num)>0)
$("#mode").val('modify');
else
$("#mode").val('insert');
// savetext div의 HTML 내용을 가져옴
var htmlContent = document.getElementById('savetext').innerHTML;
$("#htmltext").val(encodeURIComponent(htmlContent));
// temp_key를 form에 추가
var tempKey = $("#temp_key").val();
if (tempKey) {
$('<input>').attr({
type: 'hidden',
name: 'temp_key',
value: tempKey
}).appendTo('#board_form');
}
$.ajax({
url: "insert_ask.php",
type: "post",
data: $("#board_form").serialize(),
dataType:"json",
success : function(data) {
console.log(data);
// 파일 업로드 처리 (Google Drive API 사용)
var upfileInput = document.getElementById('upfile');
var upfileimageInput = document.getElementById('upfileimage');
if (upfileInput && upfileInput.files.length > 0) {
uploadFilesToGoogleDrive(upfileInput.files, 'attached', data.num);
}
if (upfileimageInput && upfileimageInput.files.length > 0) {
uploadFilesToGoogleDrive(upfileimageInput.files, 'image', data.num);
}
Toastify({
text: "파일 저장완료",
duration: 2000,
close: true,
gravity: "top",
position: "center",
style: {
background: "linear-gradient(to right, #00b09b, #96c93d)"
},
}).showToast();
setTimeout(function() {
$("#myModal").modal('hide');
location.reload();
}, 1000);
},
error : function(jqxhr, status, error) {
console.log(jqxhr, status, error);
}
});
} else {
Toastify({
text: "본인과 관리자만 수정 가능",
duration: 2000,
close: true,
gravity: "top",
position: "center",
style: {
background: "linear-gradient(to right, #00b09b, #96c93d)"
},
}).showToast();
}
});
// 삭제 버튼 (중복 방지)
$(document).off('click', '#deleteBtn').on('click', '#deleteBtn', function() {
var level = '<?= $_SESSION["level"] ?>';
var user_id = '<?php echo $user_id; ?>';
var author_id = '<?php echo $author_id; ?>';
if (level !== '1' && user_id !== author_id) {
Swal.fire({
title: '삭제불가',
text: "작성자와 관리자만 삭제 가능합니다.",
icon: 'error',
confirmButtonText: '확인'
});
} else {
Swal.fire({
title: '자료 삭제',
text: "삭제는 신중! 정말 삭제하시겠습니까?",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: '삭제',
cancelButtonText: '취소'
}).then((result) => {
if (result.isConfirmed) {
$("#mode").val('delete');
var form = $('#board_form')[0];
var formData = new FormData(form);
formData.set('mode', $("#mode").val());
formData.set('num', $("#num").val());
$.ajax({
enctype: 'multipart/form-data',
processData: false,
contentType: false,
cache: false,
timeout: 1000000,
url: "insert_ask.php",
type: "post",
data: formData,
dataType: "json",
success: function(data) {
console.log(data);
Toastify({
text: "파일 삭제완료",
duration: 2000,
close: true,
gravity: "top",
position: "center",
style: {
background: "linear-gradient(to right, #00b09b, #96c93d)"
},
}).showToast();
$("#myModal").modal('hide');
location.reload();
},
error: function(jqxhr, status, error) {
console.log(jqxhr, status, error);
}
});
}
});
}
});
// 신청일 변경시 종료일도 변경함 (중복 방지)
$(document).off('change', '#al_askdatefrom').on('change', '#al_askdatefrom', function(){
var radioVal = $('input[name="al_item"]:checked').val();
// console.log(radioVal);
$('#al_askdateto').val($("#al_askdatefrom").val());
const result = getDateDiff($("#al_askdatefrom").val(), $("#al_askdateto").val());
switch(radioVal)
{
case '연차' :
$('#al_usedday').val(result);
break;
case '오전반차' :
case '오후반차' :
$('#al_usedday').val(result/2);
break;
case '오전반반차' :
case '오후반반차' :
$('#al_usedday').val(result/4);
break;
case '경조사' :
$('#al_usedday').val(0);
break;
}
});
$(document).off('change', 'input[name="al_item"]').on('change', 'input[name="al_item"]', function(){
var radioVal = $('input[name="al_item"]:checked').val();
console.log(radioVal);
// $('#al_askdateto').val($("#al_askdatefrom").val());
const result = getDateDiff($("#al_askdatefrom").val(), $("#al_askdateto").val());
switch(radioVal)
{
case '연차' :
$('#al_usedday').val(result);
break;
case '오전반차' :
case '오후반차' :
$('#al_usedday').val(result/2);
break;
case '오전반반차' :
case '오후반반차' :
$('#al_usedday').val(result/4);
break;
case '경조사' :
$('#al_usedday').val(0);
break;
}
});
// 종료일을 변경해도 자동계산해 주기 (중복 방지)
$(document).off('change', '#al_askdateto').on('change', '#al_askdateto', function(){
var radioVal = $('input[name="al_item"]:checked').val();
console.log(radioVal);
// $('#al_askdateto').val($("#al_askdatefrom").val());
const result = getDateDiff($("#al_askdatefrom").val(), $("#al_askdateto").val());
switch(radioVal)
{
case '연차' :
$('#al_usedday').val(result);
break;
case '오전반차' :
case '오후반차' :
$('#al_usedday').val(result/2);
break;
case '오전반반차' :
case '오후반반차' :
$('#al_usedday').val(result/4);
break;
case '경조사' :
$('#al_usedday').val(0);
break;
}
});
// setTimeout(function() {
// // 페이지 로드 후 #author 변경 이벤트 트리거
// $("#author").trigger('change');
// }, 1000);
// 파일 삭제 이벤트 (중복 방지)
$(document).off('click', '.remove-file').on('click', '.remove-file', function() {
var fileId = $(this).data('file-id');
var fileType = $(this).data('file-type');
removeFile(fileId, fileType);
});
// 기존 파일 불러오기 (수정 모드일 때)
if ($("#num").val() && $("#num").val() > 0) {
loadExistingFiles($("#num").val());
} else {
// 신규 입력 시 임시키로 파일 불러오기
var tempKey = $("#temp_key").val();
if (tempKey) {
loadExistingFiles(tempKey);
}
}
},
error: function(jqxhr, status, error) {
console.log("AJAX Error: ", status, error);
}
});
}
$(document).ready(function() {
$("#writeBtn").off("click").on("click", function() {
loadForm('insert', num = null, al_company = "<?=$mycompany?>" , al_part = "<?=$mypart?>");
});
$("#closeModalBtn").off("click").click(function() {
$('#myModal').modal('hide');
});
$(".close").off("click").click(function() {
$('#myModal').modal('hide');
});
$("#openAlmemberBtn").off("click").click(function() {
popupCenter('../almember/list.php', '직원 연차 등록', 900, 800);
});
$("#searchBtn").off("click").click(function() {
document.getElementById('board_form').submit();
});
function restorePageNumber() {
var savedPageNumber = getCookie('annualleavepageNumber');
location.reload(true);
}
});
$(document).ready(function(){
var loader = document.getElementById('loadingOverlay');
if(loader)
loader.style.display = 'none';
var modal = document.getElementById("myModal");
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
});
// PHP에서 전달된 휴일 목록을 JavaScript 변수로 변환
var holidayDates = <?= json_encode($holidayDates, JSON_UNESCAPED_UNICODE) ?>;
// 휴일 날짜를 Set으로 변환하여 빠른 검색 가능하도록 함
var holidaySet = new Set(holidayDates);
// 날짜를 YYYY-MM-DD 형식으로 변환하는 함수
function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return year + '-' + month + '-' + day;
}
// 두날짜 사이 일자 구하기 (주말과 휴일 제외)
const getDateDiff = (d1, d2) => {
if (!d1 || !d2) return 0;
const date1 = new Date(d1);
const date2 = new Date(d2);
// 날짜 유효성 검사
if (isNaN(date1.getTime()) || isNaN(date2.getTime())) {
console.warn('getDateDiff: 유효하지 않은 날짜', d1, d2);
return 0;
}
// holidaySet이 없으면 빈 Set 사용 (방어 코드)
const holidays = (typeof holidaySet !== 'undefined' && holidaySet instanceof Set)
? holidaySet
: (typeof window.holidaySet !== 'undefined' && window.holidaySet instanceof Set)
? window.holidaySet
: new Set();
let count = 0;
const oneDay = 24 * 60 * 60 * 1000; // 하루의 밀리세컨드 수
// 시작일과 종료일을 포함하여 계산하기 위해 date1의 복사본 생성
const startDate = new Date(date1);
const endDate = new Date(date2);
// 시작일이 종료일보다 큰 경우 교환
if (startDate > endDate) {
const temp = startDate;
startDate = endDate;
endDate = temp;
}
// 시작일부터 종료일까지 반복 (포함)
const currentDate = new Date(startDate);
while (currentDate <= endDate) {
const dayOfWeek = currentDate.getDay(); // 요일 (0:일, 1:월, ..., 6:토)
const dateString = formatDate(currentDate); // YYYY-MM-DD 형식으로 변환
// 주말이 아니고 휴일도 아닌 경우에만 count 증가
if (dayOfWeek !== 0 && dayOfWeek !== 6 && !holidays.has(dateString)) {
count++;
}
currentDate.setTime(currentDate.getTime() + oneDay); // 다음 날짜로 이동
}
return count;
}
$(document).ready(function () {
$('#yearSelect').change(function () {
const selectedYear = $(this).val();
$.ajax({
url: '/almember/load_al_info.php', // 데이터 업데이트를 처리할 PHP 파일
method: 'POST',
data: { year: selectedYear, user_name: "<?=$user_name?>" },
dataType: 'json',
success: function (response) {
if (response.success) {
$('#totalDays').text(response.total);
$('#usedDays').text(response.usedDays);
$('#remainingDays').text(response.remainingDays);
$('#previous_usageDays').text(response.previous_usageDays); // 이전사용일자 정보 가져오기
} else {
alert('데이터를 업데이트하는 동안 오류가 발생했습니다.');
}
},
error: function(jqxhr, status, error) {
console.log(jqxhr, status, error);
alert('서버 요청 중 오류가 발생했습니다.');
}
});
});
});
$(document).ready(function(){
$("input").attr("autocomplete", "off");
});
</script>
<script>
// 전역 업로드 상태 추적
var globalUploadState = {
upfile: false,
upfileimage: false,
pendingUploads: new Set()
};
// 파일 업로드 이벤트를 바인딩하는 함수
function bindFileUploadEvents() {
// 기존 이벤트 핸들러 제거
$(document).off('change', '#upfile');
$(document).off('change', '#upfileimage');
// 파일 업로드 이벤트 바인딩
$(document).on('change', '#upfile', function() {
console.log('[이벤트] 파일 선택됨:', this.files.length, '개');
// 전역 업로드 상태 확인
if (globalUploadState.upfile) {
console.warn('[이벤트] 이미 파일 업로드가 진행 중입니다. 중복 실행 차단.');
Toastify({
text: "파일 업로드가 진행 중입니다. 잠시 기다려주세요.",
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#ff9800",
}).showToast();
return;
}
// 중복 실행 방지를 위한 디바운싱 강화
if (this.uploadTimeout) {
clearTimeout(this.uploadTimeout);
}
// 고유 키 생성하여 중복 방지
var uploadKey = 'upfile_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
if (globalUploadState.pendingUploads.has('upfile')) {
console.warn('[이벤트] 이미 대기 중인 파일 업로드가 있습니다.');
return;
}
globalUploadState.pendingUploads.add('upfile');
console.log('[이벤트] 파일 업로드 대기열에 추가:', uploadKey);
this.uploadTimeout = setTimeout(() => {
globalUploadState.pendingUploads.delete('upfile');
handleFileUpload(this, 'upfile', 'attached');
}, 500); // 디바운싱 시간 증가
});
$(document).on('change', '#upfileimage', function() {
console.log('[이벤트] 이미지 선택됨:', this.files.length, '개');
// 전역 업로드 상태 확인
if (globalUploadState.upfileimage) {
console.warn('[이벤트] 이미 이미지 업로드가 진행 중입니다. 중복 실행 차단.');
Toastify({
text: "이미지 업로드가 진행 중입니다. 잠시 기다려주세요.",
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#ff9800",
}).showToast();
return;
}
// 중복 실행 방지를 위한 디바운싱 강화
if (this.uploadTimeout) {
clearTimeout(this.uploadTimeout);
}
// 고유 키 생성하여 중복 방지
var uploadKey = 'upfileimage_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
if (globalUploadState.pendingUploads.has('upfileimage')) {
console.warn('[이벤트] 이미 대기 중인 이미지 업로드가 있습니다.');
return;
}
globalUploadState.pendingUploads.add('upfileimage');
console.log('[이벤트] 이미지 업로드 대기열에 추가:', uploadKey);
this.uploadTimeout = setTimeout(() => {
globalUploadState.pendingUploads.delete('upfileimage');
handleFileUpload(this, 'upfileimage', 'image');
}, 500); // 디바운싱 시간 증가
});
}
// 통합된 파일 업로드 처리 함수
function handleFileUpload(input, inputType, itemType) {
if (input.files.length === 0) return;
console.log(`[파일업로드] ${itemType} 업로드 시작 - 파일 개수:`, input.files.length);
console.log(`[파일업로드] 현재 업로드 상태: ${input.isUploading ? '진행중' : '대기중'}`);
// 전역 업로드 상태로 중복 체크 강화
var stateKey = inputType === 'upfile' ? 'upfile' : 'upfileimage';
if (globalUploadState[stateKey]) {
console.warn(`[파일업로드] ${itemType} 전역 상태에서 이미 업로드 진행중 - 중복 실행 차단`);
Toastify({
text: "파일 업로드가 이미 진행중입니다. 잠시 기다려주세요.",
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#ff9800",
}).showToast();
return;
}
// 이미 업로드 중인지 한번 더 체크 (강화된 중복 방지)
if (input.isUploading) {
console.warn(`[파일업로드] ${itemType} 이미 업로드 진행중 - 중복 실행 차단`);
return;
}
// 업로드 상태 설정 (전역 및 로컬)
globalUploadState[stateKey] = true;
input.isUploading = true;
console.log(`[파일업로드] ${itemType} 업로드 상태를 true로 설정 (전역: ${stateKey})`);
// 중복 파일 체크
var existingFileNames = [];
var displayId = itemType === 'attached' ? 'displayFile' : 'displayImage';
$(`#${displayId} .row a`).each(function() {
existingFileNames.push($(this).text().trim());
});
console.log(`[파일업로드] 기존 파일 목록:`, existingFileNames);
var duplicateFound = false;
var duplicateFiles = [];
for (var i = 0; i < input.files.length; i++) {
if (existingFileNames.includes(input.files[i].name)) {
duplicateFiles.push(input.files[i].name);
duplicateFound = true;
}
}
if (duplicateFound) {
console.warn(`[파일업로드] 중복 파일 발견:`, duplicateFiles);
Toastify({
text: `이미 같은 이름의 파일이 있습니다: ${duplicateFiles.join(', ')}`,
duration: 3000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#ff9800",
}).showToast();
}
if (duplicateFound) {
// 상태 해제 (전역 및 로컬)
globalUploadState[stateKey] = false;
input.isUploading = false;
console.log(`[파일업로드] ${itemType} 중복 파일로 인해 업로드 중단 - 상태 해제 (전역: ${stateKey})`);
return;
}
console.log(`[파일업로드] ${itemType} Google Drive 업로드 시작...`);
const form = $('#board_form')[0] || document.getElementById('savetext');
// 기존 FormData 방식 대신 새로운 FormData 생성하여 필요한 데이터만 전송
const data = new FormData();
console.log(`[파일업로드] 새로운 FormData 생성 - 기존 form 데이터는 제외`);
// 업로드 중인 파일명 로깅
var uploadingFiles = [];
for (let i = 0; i < input.files.length; i++) {
uploadingFiles.push({
name: input.files[i].name,
size: input.files[i].size,
type: input.files[i].type,
lastModified: input.files[i].lastModified
});
}
console.log(`[파일업로드] 업로드할 파일 상세 정보:`, uploadingFiles);
// 추가 데이터 설정
data.append("tablename", "eworks");
data.append("item", itemType);
data.append("upfilename", inputType);
data.append("folderPath", "경동기업/uploads");
data.append("DBtable", "picuploads");
// num이 없으면 임시키 사용
var currentNum = $("#num").val();
if (!currentNum || currentNum === '') {
currentNum = $("#temp_key").val() || "temp_" + Date.now();
}
data.append("num", currentNum);
console.log(`[파일업로드] FormData 기본 정보:`, {
tablename: "eworks",
item: itemType,
upfilename: inputType,
folderPath: "경동기업/uploads",
DBtable: "picuploads",
num: currentNum
});
// 파일 데이터 추가 (중복 방지 강화)
console.log(`[파일업로드] FormData에 파일 추가 시작...`);
// 중복 파일 방지를 위한 Set
var addedFiles = new Set();
var actualAddedCount = 0;
for (let i = 0; i < input.files.length; i++) {
var file = input.files[i];
var fileKey = file.name + "_" + file.size + "_" + file.lastModified;
if (addedFiles.has(fileKey)) {
console.warn(`[파일업로드] 중복 파일 감지 및 제외:`, file.name);
continue;
}
addedFiles.add(fileKey);
actualAddedCount++;
console.log(`[파일업로드] 파일 ${actualAddedCount} 추가:`, {
name: file.name,
size: file.size,
type: file.type,
lastModified: file.lastModified,
index: i,
fieldName: `${inputType}[]`,
fileKey: fileKey
});
data.append(`${inputType}[]`, file);
}
console.log(`[파일업로드] FormData에 총 ${actualAddedCount}개 고유 파일 추가 완료 (원본: ${input.files.length}개)`);
// 최종 검증
var formDataFiles = data.getAll(`${inputType}[]`);
console.log(`[파일업로드] FormData 최종 검증 - 실제 추가된 파일: ${formDataFiles.length}개`);
if (formDataFiles.length === 0) {
console.warn(`[파일업로드] FormData에 파일이 없습니다. 업로드 중단.`);
globalUploadState[stateKey] = false;
input.isUploading = false;
return;
}
// AJAX 요청 (Google Drive API)
$.ajax({
enctype: 'multipart/form-data',
processData: false,
contentType: false,
cache: false,
timeout: 600000,
url: "/filedrive/fileprocess.php",
type: "POST",
data: data,
success: function(response) {
console.log(`[파일업로드] ${itemType} Google Drive 업로드 응답:`, response);
let successCount = 0;
let errorCount = 0;
let errorMessages = [];
let successFiles = [];
let errorFiles = [];
// 응답이 배열인지 객체인지 확인하여 처리
if (Array.isArray(response)) {
response.forEach((item) => {
if (item.status === "success") {
successCount++;
successFiles.push(item.file || '파일명불명');
} else if (item.status === "error") {
errorCount++;
errorFiles.push(item.file || '파일명불명');
errorMessages.push(`파일: ${item.file}, 메시지: ${item.message}`);
}
});
} else if (response && typeof response === 'object') {
// 단일 파일 응답인 경우
if (response.status === "success") {
successCount++;
successFiles.push(response.file || '파일명불명');
} else if (response.status === "error") {
errorCount++;
errorFiles.push(response.file || '파일명불명');
errorMessages.push(`파일: ${response.file || '알 수 없음'}, 메시지: ${response.message || '알 수 없음'}`);
}
}
console.log(`[파일업로드] ${itemType} 업로드 결과 - 성공: ${successCount}개`, successFiles);
if (errorCount > 0) {
console.error(`[파일업로드] ${itemType} 업로드 실패 - 실패: ${errorCount}개`, errorFiles);
}
if (successCount > 0) {
console.log(`[파일업로드] ${itemType} 성공 메시지 표시 및 화면 업데이트`);
Toastify({
text: `${successCount}개의 ${itemType === 'attached' ? '파일' : '이미지'}이 성공적으로 업로드되었습니다.`,
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#4fbe87",
}).showToast();
// 파일 표시 업데이트
if (itemType === 'attached') {
displayFile();
} else {
displayImage();
}
}
if (errorCount > 0) {
Toastify({
text: `오류 발생: ${errorCount}개의 ${itemType === 'attached' ? '파일' : '이미지'} 업로드 실패\n상세 오류: ${errorMessages.join("\n")}`,
duration: 5000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#f44336",
}).showToast();
}
// 업로드 상태 해제 (전역 및 로컬)
globalUploadState[stateKey] = false;
input.isUploading = false;
console.log(`[파일업로드] ${itemType} 업로드 완료. 상태 해제됨 (전역: ${stateKey}).`);
},
error: function(jqxhr, status, error) {
console.error(`[파일업로드] ${itemType} Google Drive 업로드 실패:`, jqxhr, status, error);
console.error(`[파일업로드] 실패한 파일 목록:`, uploadingFiles);
Toastify({
text: "Google Drive 업로드 중 오류가 발생했습니다.",
duration: 3000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#f44336",
}).showToast();
// 업로드 상태 해제 (전역 및 로컬)
globalUploadState[stateKey] = false;
input.isUploading = false;
console.log(`[파일업로드] ${itemType} 업로드 실패. 상태 해제됨 (전역: ${stateKey}).`);
}
});
// 파일 미리보기 표시
if (itemType === 'attached') {
handleFilePreview(input, 'displayFile', 'upfile');
} else {
handleImagePreview(input, 'displayImage', 'upfileimage');
}
}
// 파일 미리보기 처리 함수
function handleFilePreview(input, displayId, fileType) {
var files = input.files;
var displayDiv = document.getElementById(displayId);
if (files.length > 0) {
displayDiv.style.display = 'block';
displayDiv.innerHTML = '';
for (var i = 0; i < files.length; i++) {
var file = files[i];
var fileDiv = document.createElement('div');
fileDiv.className = 'd-flex align-items-center justify-content-between p-2 border rounded mb-2';
fileDiv.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-file-earmark me-2"></i>
<span class="small">${file.name} (${formatFileSize(file.size)})</span>
</div>
<button type="button" class="btn btn-sm btn-outline-danger remove-new-file" data-index="${i}">
<i class="bi bi-x"></i>
</button>
`;
displayDiv.appendChild(fileDiv);
}
// 새로 추가된 파일 삭제 이벤트 (개선된 버전)
$(document).off('click', '.remove-new-file').on('click', '.remove-new-file', function() {
console.log('[파일삭제] 새로 추가된 파일 삭제 시작');
var index = $(this).data('index');
var input = document.getElementById(fileType);
var fileName = input.files[index]?.name || '알 수 없음';
console.log(`[파일삭제] 삭제할 파일: ${fileName} (인덱스: ${index})`);
// 파일 목록에서 해당 인덱스 제거
var dt = new DataTransfer();
var { files } = input;
var removedFileName = '';
for (var i = 0; i < files.length; i++) {
if (i !== index) {
dt.items.add(files[i]);
} else {
removedFileName = files[i].name;
}
}
input.files = dt.files;
console.log(`[파일삭제] ${removedFileName} 파일 제거 완료. 남은 파일: ${dt.files.length}개`);
// 미리보기 업데이트
handleFilePreview(input, displayId, fileType);
// 성공 메시지
Toastify({
text: `${removedFileName} 파일이 삭제되었습니다.`,
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#28a745",
}).showToast();
});
} else {
displayDiv.style.display = 'none';
displayDiv.innerHTML = '';
}
}
// 이미지 미리보기 처리 함수
function handleImagePreview(input, displayId, fileType) {
var files = input.files;
var displayDiv = document.getElementById(displayId);
if (files.length > 0) {
displayDiv.style.display = 'block';
displayDiv.innerHTML = '';
for (var i = 0; i < files.length; i++) {
var file = files[i];
var fileDiv = document.createElement('div');
fileDiv.className = 'd-flex align-items-center justify-content-between p-2 border rounded mb-2';
// 이미지 미리보기
var reader = new FileReader();
reader.onload = function(e) {
fileDiv.innerHTML = `
<div class="d-flex align-items-center">
<img src="${e.target.result}" class="me-2" style="width: 40px; height: 40px; object-fit: cover;">
<span class="small">${file.name} (${formatFileSize(file.size)})</span>
</div>
<button type="button" class="btn btn-sm btn-outline-danger remove-new-file" data-index="${i}">
<i class="bi bi-x"></i>
</button>
`;
};
reader.readAsDataURL(file);
displayDiv.appendChild(fileDiv);
}
// 새로 추가된 이미지 삭제 이벤트 (개선된 버전)
$(document).off('click', '.remove-new-file').on('click', '.remove-new-file', function() {
console.log('[이미지삭제] 새로 추가된 이미지 삭제 시작');
var index = $(this).data('index');
var input = document.getElementById(fileType);
var fileName = input.files[index]?.name || '알 수 없음';
console.log(`[이미지삭제] 삭제할 이미지: ${fileName} (인덱스: ${index})`);
// 이미지 목록에서 해당 인덱스 제거
var dt = new DataTransfer();
var { files } = input;
var removedFileName = '';
for (var i = 0; i < files.length; i++) {
if (i !== index) {
dt.items.add(files[i]);
} else {
removedFileName = files[i].name;
}
}
input.files = dt.files;
console.log(`[이미지삭제] ${removedFileName} 이미지 제거 완료. 남은 이미지: ${dt.files.length}개`);
// 미리보기 업데이트
handleImagePreview(input, displayId, fileType);
// 성공 메시지
Toastify({
text: `${removedFileName} 이미지가 삭제되었습니다.`,
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#28a745",
}).showToast();
});
} else {
displayDiv.style.display = 'none';
displayDiv.innerHTML = '';
}
}
function handleImageUpload(input, displayId, fileType) {
var files = input.files;
var displayDiv = document.getElementById(displayId);
if (files.length > 0) {
displayDiv.style.display = 'block';
displayDiv.innerHTML = '';
for (var i = 0; i < files.length; i++) {
var file = files[i];
var fileDiv = document.createElement('div');
fileDiv.className = 'd-flex align-items-center justify-content-between p-2 border rounded mb-2';
// 이미지 미리보기
var reader = new FileReader();
reader.onload = function(e) {
fileDiv.innerHTML = `
<div class="d-flex align-items-center">
<img src="${e.target.result}" class="me-2" style="width: 40px; height: 40px; object-fit: cover;">
<span class="small">${file.name} (${formatFileSize(file.size)})</span>
</div>
<button type="button" class="btn btn-sm btn-outline-danger remove-new-file" data-index="${i}">
<i class="bi bi-x"></i>
</button>
`;
};
reader.readAsDataURL(file);
displayDiv.appendChild(fileDiv);
}
// 새로 추가된 이미지 삭제 이벤트 (통합)
$(document).off('click', '.remove-new-file').on('click', '.remove-new-file', function() {
console.log('[handleImageUpload] 이미지 삭제 시작');
var index = $(this).data('index');
var input = document.getElementById(fileType);
var fileName = input.files[index]?.name || '알 수 없음';
console.log(`[handleImageUpload] 삭제할 이미지: ${fileName} (인덱스: ${index})`);
var dt = new DataTransfer();
var { files } = input;
var removedFileName = '';
for (var i = 0; i < files.length; i++) {
if (i !== index) {
dt.items.add(files[i]);
} else {
removedFileName = files[i].name;
}
}
input.files = dt.files;
console.log(`[handleImageUpload] ${removedFileName} 제거 완료. 남은 이미지: ${dt.files.length}개`);
handleImageUpload(input, displayId, fileType);
// 성공 메시지
Toastify({
text: `${removedFileName} 이미지가 삭제되었습니다.`,
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#28a745",
}).showToast();
});
} else {
displayDiv.style.display = 'none';
displayDiv.innerHTML = '';
}
}
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
var k = 1024;
var sizes = ['Bytes', 'KB', 'MB', 'GB'];
var i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
// Google Drive에 파일 업로드하는 함수
function uploadFilesToGoogleDrive(files, itemType, num) {
if (files.length === 0) {
console.warn("[별도업로드] 업로드할 파일이 없습니다.");
return;
}
console.log(`[별도업로드] ${itemType} 저장 후 업로드 시작 - 파일 개수: ${files.length}`);
// 새로운 FormData 생성 (form 데이터 제외)
const data = new FormData();
// 추가 데이터 설정
data.append("tablename", "eworks");
data.append("item", itemType);
data.append("upfilename", itemType === 'attached' ? "upfile" : "upfileimage");
data.append("folderPath", "경동기업/uploads");
data.append("DBtable", "picuploads");
// num이 없으면 임시키 사용
var currentNum = num;
if (!currentNum || currentNum === '') {
currentNum = $("#temp_key").val() || "temp_" + Date.now();
}
data.append("num", currentNum);
console.log(`[별도업로드] 기본 데이터 설정:`, {
tablename: "eworks",
item: itemType,
upfilename: itemType === 'attached' ? "upfile" : "upfileimage",
folderPath: "경동기업/uploads",
DBtable: "picuploads",
num: currentNum
});
// 파일 데이터 추가 (중복 방지)
var addedFiles = new Set();
var actualAddedCount = 0;
for (let i = 0; i < files.length; i++) {
var file = files[i];
var fileKey = file.name + "_" + file.size + "_" + file.lastModified;
if (addedFiles.has(fileKey)) {
console.warn(`[별도업로드] 중복 파일 제외:`, file.name);
continue;
}
addedFiles.add(fileKey);
actualAddedCount++;
var fieldName = itemType === 'attached' ? 'upfile[]' : 'upfileimage[]';
data.append(fieldName, file);
console.log(`[별도업로드] 파일 ${actualAddedCount} 추가:`, {
name: file.name,
size: file.size,
fieldName: fieldName
});
}
console.log(`[별도업로드] 총 ${actualAddedCount}개 고유 파일 FormData에 추가 완료 (원본: ${files.length}개)`);
if (actualAddedCount === 0) {
console.warn(`[별도업로드] 추가할 고유 파일이 없습니다. 업로드 중단.`);
return;
}
// AJAX 요청 (Google Drive API)
$.ajax({
enctype: 'multipart/form-data',
processData: false,
contentType: false,
cache: false,
timeout: 600000,
url: "/filedrive/fileprocess.php",
type: "POST",
data: data,
success: function(response) {
console.log(`[별도업로드] ${itemType} Google Drive 업로드 응답:`, response);
let successCount = 0;
let errorCount = 0;
let errorMessages = [];
// 응답이 배열인지 객체인지 확인하여 처리
if (Array.isArray(response)) {
response.forEach((item) => {
if (item.status === "success") {
successCount++;
} else if (item.status === "error") {
errorCount++;
errorMessages.push(`파일: ${item.file}, 메시지: ${item.message}`);
}
});
} else if (response && typeof response === 'object') {
// 단일 파일 응답인 경우
if (response.status === "success") {
successCount++;
} else if (response.status === "error") {
errorCount++;
errorMessages.push(`파일: ${response.file || '알 수 없음'}, 메시지: ${response.message || '알 수 없음'}`);
}
}
if (successCount > 0) {
Toastify({
text: `${successCount}개의 파일이 Google Drive에 성공적으로 업로드되었습니다.`,
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#4fbe87",
}).showToast();
}
if (errorCount > 0) {
Toastify({
text: `오류 발생: ${errorCount}개의 파일 업로드 실패\n상세 오류: ${errorMessages.join("\n")}`,
duration: 5000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#f44336",
}).showToast();
}
},
error: function(jqxhr, status, error) {
console.error("Google Drive 업로드 실패:", jqxhr, status, error);
Toastify({
text: "Google Drive 업로드 중 오류가 발생했습니다.",
duration: 3000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#f44336",
}).showToast();
}
});
}
// 화면에서 저장한 첨부된 파일 불러오기
function displayFile() {
$('#displayFile').show();
const params = $("#timekey").val() ? $("#timekey").val() : ($("#num").val() || $("#temp_key").val());
if (!params) {
console.error("ID 값이 없습니다. 파일을 불러올 수 없습니다.");
return;
}
console.log("요청 ID:", params);
$.ajax({
url: '/filedrive/fileprocess.php',
type: 'GET',
data: {
num: params,
tablename: "eworks",
item: 'attached',
folderPath: '경동기업/uploads',
},
dataType: 'json',
}).done(function (data) {
console.log("파일 데이터:", data);
$("#displayFile").html(''); // 기존 내용 초기화
if (Array.isArray(data) && data.length > 0) {
data.forEach(function (fileData, index) {
const realName = fileData.realname || '다운로드 파일';
const link = fileData.link || '#';
const fileId = fileData.fileId || null;
if (!fileId) {
console.error("fileId가 누락되었습니다. index: " + index, fileData);
$("#displayFile").append(
"<div class='text-danger'>파일 ID가 누락되었습니다.</div>"
);
return;
}
$("#displayFile").append(
"<div class='row mt-1 mb-2'>" +
"<div class='d-flex align-items-center justify-content-center'>" +
"<span id='file" + index + "'>" +
"<a href='#' onclick=\"popupCenter('" + link + "', 'filePopup', 800, 600); return false;\">" + realName + "</a>" +
"</span> &nbsp;&nbsp;" +
"<button type='button' class='btn btn-danger btn-sm' id='delFile" + index + "' onclick=\"delFileFn('" + index + "', '" + fileId + "')\">" +
"<i class='bi bi-trash'></i>" +
"</button>" +
"</div>" +
"</div>"
);
});
} else {
$("#displayFile").append(
"<div class='text-center text-muted'>No files</div>"
);
}
}).fail(function (error) {
console.error("파일 불러오기 오류:", error);
});
}
// 첨부된 이미지 불러오기
function displayImage() {
$('#displayImage').show();
const params = $("#timekey").val() ? $("#timekey").val() : ($("#num").val() || $("#temp_key").val());
if (!params) {
console.error("ID 값이 없습니다. 파일을 불러올 수 없습니다.");
return;
}
console.log("요청 ID:", params);
$.ajax({
url: '/filedrive/fileprocess.php',
type: 'GET',
data: {
num: params,
tablename: "eworks",
item: 'image',
folderPath: '경동기업/uploads',
},
dataType: 'json',
}).done(function (data) {
console.log("파일 데이터:", data);
$("#displayImage").html(''); // 기존 내용 초기화
if (Array.isArray(data) && data.length > 0) {
data.forEach(function (fileData, index) {
const realName = fileData.realname || '다운로드 파일';
const thumbnail = fileData.thumbnail || '/assets/default-thumbnail.png';
const link = fileData.link || '#';
const fileId = fileData.fileId || null;
if (!fileId) {
console.error("fileId가 누락되었습니다. index: " + index, fileData);
$("#displayImage").append(
"<div class='text-danger'>파일 ID가 누락되었습니다.</div>"
);
return;
}
$("#displayImage").append(
"<div class='row mb-3'>" +
"<div class='col d-flex align-items-center justify-content-center'>" +
"<a href='#' onclick=\"popupCenter('" + link + "', 'imagePopup', 800, 600); return false;\">" +
"<img id='image" + index + "' src='" + thumbnail + "' style='width:150px; height:auto;'>" +
"</a> &nbsp;&nbsp;" +
"<button type='button' class='btn btn-danger btn-sm' id='delImage" + index + "' onclick=\"delImageFn('" + index + "', '" + fileId + "')\">" +
"<i class='bi bi-trash'></i>" +
"</button>" +
"</div>" +
"</div>"
);
});
} else {
$("#displayImage").append(
"<div class='text-center text-muted'>No files</div>"
);
}
}).fail(function (error) {
console.error("파일 불러오기 오류:", error);
});
}
// 파일 삭제 처리 함수
function delFileFn(divID, fileId) {
console.log(`[delFileFn] 파일 삭제 함수 호출 - divID: ${divID}, fileId: ${fileId}`);
// DOM 상태 미리 확인
var fileSpanCheck = $("#file" + divID);
var deleteButtonCheck = $("#delFile" + divID);
var allRows = $("#displayFile .row");
console.log(`[delFileFn] 현재 DOM 상태:`, {
fileSpan: fileSpanCheck.length,
deleteButton: deleteButtonCheck.length,
totalRows: allRows.length
});
Swal.fire({
title: "파일 삭제 확인",
text: "정말 삭제하시겠습니까?",
icon: "warning",
showCancelButton: true,
confirmButtonText: "삭제",
cancelButtonText: "취소",
reverseButtons: true,
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: '/filedrive/fileprocess.php',
type: 'DELETE',
data: JSON.stringify({
fileId: fileId,
tablename: "eworks",
item: "attached",
folderPath: "경동기업/uploads",
DBtable: "picuploads",
}),
contentType: "application/json",
dataType: 'json',
}).done(function (response) {
if (response.status === 'success') {
console.log(`[기존파일삭제] 파일 삭제 완료:`, response);
// 화면에서 파일 제거 (수정된 버전 - ID 기반)
var fileSpan = $("#file" + divID);
var deleteButton = $("#delFile" + divID);
var fileName = fileSpan.find('a').text().trim() || '파일';
console.log(`[기존파일삭제] 화면에서 제거할 파일: ${fileName} (ID: file${divID}, delFile${divID})`);
console.log(`[기존파일삭제] 찾은 요소 - fileSpan: ${fileSpan.length}개, deleteButton: ${deleteButton.length}개`);
if (fileSpan.length > 0 || deleteButton.length > 0) {
// 부모 row div를 찾아서 제거
var parentRow = fileSpan.closest('.row');
if (parentRow.length === 0) {
parentRow = deleteButton.closest('.row');
}
console.log(`[기존파일삭제] 부모 row 요소: ${parentRow.length}개`);
if (parentRow.length > 0) {
// 페이드아웃 애니메이션과 함께 전체 행 제거
parentRow.fadeOut(400, function() {
$(this).remove();
console.log(`[기존파일삭제] ${fileName} 화면에서 제거 완료`);
// 성공 메시지 표시
Toastify({
text: `${fileName} 파일이 성공적으로 삭제되었습니다.`,
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#28a745",
}).showToast();
// 파일이 모두 삭제되었는지 확인
setTimeout(function() {
var remainingFiles = $("#displayFile .row").length;
console.log(`[기존파일삭제] 남은 파일 개수: ${remainingFiles}`);
if (remainingFiles === 0) {
$("#displayFile").html('<div class="text-center text-muted">첨부된 파일이 없습니다.</div>');
console.log('[기존파일삭제] 모든 파일이 삭제됨 - 안내 메시지 표시');
}
}, 100);
});
} else {
// row를 찾지 못한 경우 개별 요소들을 제거
console.log(`[기존파일삭제] row를 찾지 못함. 개별 요소 제거 시도`);
fileSpan.fadeOut(400, function() { $(this).remove(); });
deleteButton.fadeOut(400, function() { $(this).remove(); });
// 성공 메시지 표시
Toastify({
text: `${fileName} 파일이 성공적으로 삭제되었습니다.`,
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#28a745",
}).showToast();
}
} else {
console.warn(`[기존파일삭제] 삭제할 파일 요소를 찾을 수 없음 (divID: ${divID})`);
console.log(`[기존파일삭제] 전체 파일 목록을 다시 불러와서 동기화`);
// 전체 파일 목록을 다시 불러와서 동기화
displayFile();
}
} else {
console.log(response.message);
Toastify({
text: "파일 삭제 중 문제가 발생했습니다.",
duration: 2000,
close: true,
gravity: "top",
position: "center",
style: {
background: "linear-gradient(to right, #ff6b6b, #ee5a24)"
},
}).showToast();
}
}).fail(function (error) {
console.error("삭제 중 오류:", error);
Toastify({
title: "삭제 실패",
text: "파일 삭제 중 문제가 발생했습니다.",
icon: "error",
confirmButtonText: "확인",
});
});
}
});
}
// 이미지 삭제 처리 함수
function delImageFn(divID, fileId) {
console.log(`[delImageFn] 이미지 삭제 함수 호출 - divID: ${divID}, fileId: ${fileId}`);
// DOM 상태 미리 확인
var imageCheck = $("#image" + divID);
var deleteButtonCheck = $("#delImage" + divID);
var allRows = $("#displayImage .row");
console.log(`[delImageFn] 현재 DOM 상태:`, {
imageElement: imageCheck.length,
deleteButton: deleteButtonCheck.length,
totalRows: allRows.length
});
Swal.fire({
title: "이미지 삭제 확인",
text: "정말 삭제하시겠습니까?",
icon: "warning",
showCancelButton: true,
confirmButtonText: "삭제",
cancelButtonText: "취소",
reverseButtons: true,
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: '/filedrive/fileprocess.php',
type: 'DELETE',
data: JSON.stringify({
fileId: fileId,
tablename: "eworks",
item: "image",
folderPath: "경동기업/uploads",
DBtable: "picuploads",
}),
contentType: "application/json",
dataType: 'json',
}).done(function (response) {
if (response.status === 'success') {
console.log(`[기존이미지삭제] 이미지 삭제 완료:`, response);
// 화면에서 이미지 제거 (수정된 버전 - ID 기반)
var imageElement = $("#image" + divID);
var deleteButton = $("#delImage" + divID);
var imageName = '이미지';
// 이미지 이름 찾기 시도
if (imageElement.length > 0) {
var altText = imageElement.attr('alt') || imageElement.attr('title');
if (altText) {
imageName = altText;
}
}
console.log(`[기존이미지삭제] 화면에서 제거할 이미지: ${imageName} (ID: image${divID}, delImage${divID})`);
console.log(`[기존이미지삭제] 찾은 요소 - imageElement: ${imageElement.length}개, deleteButton: ${deleteButton.length}개`);
if (imageElement.length > 0 || deleteButton.length > 0) {
// 부모 row div를 찾아서 제거
var parentRow = imageElement.closest('.row');
if (parentRow.length === 0) {
parentRow = deleteButton.closest('.row');
}
console.log(`[기존이미지삭제] 부모 row 요소: ${parentRow.length}개`);
if (parentRow.length > 0) {
// 페이드아웃 애니메이션과 함께 전체 행 제거
parentRow.fadeOut(400, function() {
$(this).remove();
console.log(`[기존이미지삭제] ${imageName} 화면에서 제거 완료`);
// 성공 메시지 표시
Toastify({
text: `${imageName}가 성공적으로 삭제되었습니다.`,
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#28a745",
}).showToast();
// 이미지가 모두 삭제되었는지 확인
setTimeout(function() {
var remainingImages = $("#displayImage .row").length;
console.log(`[기존이미지삭제] 남은 이미지 개수: ${remainingImages}`);
if (remainingImages === 0) {
$("#displayImage").html('<div class="text-center text-muted">첨부된 이미지가 없습니다.</div>');
console.log('[기존이미지삭제] 모든 이미지가 삭제됨 - 안내 메시지 표시');
}
}, 100);
});
} else {
// row를 찾지 못한 경우 개별 요소들을 제거
console.log(`[기존이미지삭제] row를 찾지 못함. 개별 요소 제거 시도`);
imageElement.fadeOut(400, function() { $(this).remove(); });
deleteButton.fadeOut(400, function() { $(this).remove(); });
// 성공 메시지 표시
Toastify({
text: `${imageName}가 성공적으로 삭제되었습니다.`,
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#28a745",
}).showToast();
}
} else {
console.warn(`[기존이미지삭제] 삭제할 이미지 요소를 찾을 수 없음 (divID: ${divID})`);
console.log(`[기존이미지삭제] 전체 이미지 목록을 다시 불러와서 동기화`);
// 전체 이미지 목록을 다시 불러와서 동기화
displayImage();
}
} else {
console.log(response.message);
Toastify({
text: "이미지 삭제 중 문제가 발생했습니다.",
duration: 2000,
close: true,
gravity: "top",
position: "center",
style: {
background: "linear-gradient(to right, #ff6b6b, #ee5a24)"
},
}).showToast();
}
}).fail(function (error) {
console.error("삭제 중 오류:", error);
Toastify({
title: "삭제 실패",
text: "이미지 삭제 중 문제가 발생했습니다.",
icon: "error",
confirmButtonText: "확인",
});
});
}
});
}
// 팝업 창을 중앙에 열기
function popupCenter(url, title, w, h) {
var left = (screen.width/2)-(w/2);
var top = (screen.height/2)-(h/2);
return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
}
function loadExistingFiles(num) {
// num이 없으면 임시키 사용
var currentNum = num;
if (!currentNum || currentNum === '') {
currentNum = $("#temp_key").val();
}
// 기존 첨부파일 불러오기 (Google Drive에서)
$.ajax({
url: '/filedrive/fileprocess.php',
type: 'GET',
data: {
num: currentNum,
tablename: 'eworks',
item: 'attached',
folderPath: '경동기업/uploads'
},
dataType: 'json',
success: function(data) {
if (data && data.length > 0) {
displayExistingFiles(data, 'displayFile');
}
},
error: function(xhr, status, error) {
console.log('기존 파일 불러오기 오류:', error);
}
});
// 기존 이미지 불러오기
$.ajax({
url: '/filedrive/fileprocess.php',
type: 'GET',
data: {
num: currentNum,
tablename: 'eworks',
item: 'image',
folderPath: '경동기업/uploads'
},
dataType: 'json',
success: function(data) {
if (data && data.length > 0) {
displayExistingImages(data, 'displayImage');
}
},
error: function(xhr, status, error) {
console.log('기존 이미지 불러오기 오류:', error);
}
});
}
function displayExistingFiles(files, displayId) {
var displayDiv = document.getElementById(displayId);
if (files.length > 0) {
displayDiv.style.display = 'block';
displayDiv.innerHTML = '<h6 class="mb-2">기존 첨부파일:</h6>';
files.forEach(function(file, index) {
var fileDiv = document.createElement('div');
fileDiv.className = 'd-flex align-items-center justify-content-between p-2 border rounded mb-2';
fileDiv.innerHTML = `
<div class="d-flex align-items-center" data-file-id="${file.fileId}" data-file-type="attached">
<i class="bi bi-file-earmark me-2"></i>
<a href="${file.link || '#'}" target="_blank" class="text-decoration-none">
${file.realname || '다운로드 파일'}
</a>
</div>
<button type="button" class="btn btn-sm btn-outline-danger remove-file" data-file-id="${file.fileId}" data-file-type="attached">
<i class="bi bi-trash"></i>
</button>
`;
displayDiv.appendChild(fileDiv);
});
}
}
function displayExistingImages(images, displayId) {
var displayDiv = document.getElementById(displayId);
if (images.length > 0) {
displayDiv.style.display = 'block';
displayDiv.innerHTML = '<h6 class="mb-2">기존 이미지:</h6>';
images.forEach(function(image, index) {
var imageDiv = document.createElement('div');
imageDiv.className = 'd-flex align-items-center justify-content-between p-2 border rounded mb-2';
imageDiv.innerHTML = `
<div class="d-flex align-items-center" data-file-id="${image.fileId}" data-file-type="image">
<img src="${image.thumbnail || image.link}" class="me-2" style="width: 40px; height: 40px; object-fit: cover;">
<a href="${image.link || '#'}" target="_blank" class="text-decoration-none">
${image.realname || '이미지 파일'}
</a>
</div>
<button type="button" class="btn btn-sm btn-outline-danger remove-file" data-file-id="${image.fileId}" data-file-type="image">
<i class="bi bi-trash"></i>
</button>
`;
displayDiv.appendChild(imageDiv);
});
}
}
function removeFile(fileId, fileType) {
Swal.fire({
title: '파일 삭제 확인',
text: '정말로 이 파일을 삭제하시겠습니까?',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: '삭제',
cancelButtonText: '취소'
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: '/filedrive/fileprocess.php',
type: 'DELETE',
data: JSON.stringify({
fileId: fileId,
tablename: 'eworks',
item: fileType,
folderPath: "경동기업/uploads",
DBtable: "picuploads"
}),
contentType: "application/json",
dataType: 'json',
success: function(response) {
if (response.status === 'success') {
console.log(`[모달파일삭제] ${fileType} 파일 삭제 완료:`, response);
// 해당 파일의 버튼 요소를 찾아서 제거
var removeButton = $(`button[data-file-id="${fileId}"]`);
var fileContainer = removeButton.closest('.d-flex, .row');
var fileName = 'Unknown File';
// 파일명 찾기
var fileNameElement = fileContainer.find('a').first();
if (fileNameElement.length > 0) {
fileName = fileNameElement.text().trim();
}
console.log(`[모달파일삭제] 화면에서 제거할 파일: ${fileName}`);
// 애니메이션과 함께 파일 컨테이너 제거
fileContainer.fadeOut(400, function() {
$(this).remove();
console.log(`[모달파일삭제] ${fileName} 화면에서 제거 완료`);
// 성공 메시지 표시
Toastify({
text: `${fileName}이 성공적으로 삭제되었습니다.`,
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#28a745",
}).showToast();
// 파일 목록이 비어있는지 확인
var displayContainer = fileType === 'attached' ? '#displayFile' : '#displayImage';
setTimeout(function() {
var remainingFiles = $(displayContainer + ' .d-flex, ' + displayContainer + ' .row').length;
console.log(`[모달파일삭제] 남은 ${fileType} 파일 개수: ${remainingFiles}`);
if (remainingFiles === 0) {
var emptyMessage = fileType === 'attached' ? '첨부된 파일이 없습니다.' : '첨부된 이미지가 없습니다.';
$(displayContainer).html(`<div class="text-center text-muted">${emptyMessage}</div>`);
console.log(`[모달파일삭제] 모든 ${fileType} 파일이 삭제됨 - 안내 메시지 표시`);
}
}, 100);
});
} else {
console.error(`[모달파일삭제] ${fileType} 파일 삭제 실패:`, response);
Toastify({
text: "파일 삭제 중 문제가 발생했습니다.",
duration: 2000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#dc3545",
}).showToast();
}
},
error: function(xhr, status, error) {
console.error(`[모달파일삭제] ${fileType} 파일 삭제 중 오류:`, {
status: status,
error: error,
response: xhr.responseText
});
Toastify({
text: "파일 삭제 중 오류가 발생했습니다.",
duration: 3000,
close: true,
gravity: "top",
position: "center",
backgroundColor: "#dc3545",
}).showToast();
}
});
}
});
}
$(document).ready(function(){
// PHP의 부서 JSON 데이터를 JS 변수로 저장 (각 항목은 ['corp'=> ..., 'part'=> ...] 형식)
var partData = <?= json_encode($partData) ?>;
// PHP에서 전달된 부서 검색 값 (기존에 선택된 값)
var initialPart = "<?= htmlspecialchars($partSearch, ENT_QUOTES, 'UTF-8') ?>";
// 부서 select 업데이트 함수
function updatePartSelect(selectedCorp) {
var $partSelect = $('#partSearch');
$partSelect.empty();
$partSelect.append('<option value=""><?= "(부서)" ?></option>');
// 선택된 소속과 일치하는 부서 옵션만 추가
$.each(partData, function(index, dept) {
if(dept.corp === selectedCorp) {
$partSelect.append('<option value="'+ dept.part +'">'+ dept.part +'</option>');
}
});
// 만약 초기 부서값이 있다면 선택
if(initialPart !== "") {
$partSelect.val(initialPart);
}
}
// 페이지 로드 시, 이미 소속이 선택되어 있다면 부서 옵션 업데이트
var initialCorp = $('#corpSearch').val();
updatePartSelect(initialCorp);
// 소속 select 변경 시 부서 select 업데이트
$('#corpSearch').on('change', function(){
var selectedCorp = $(this).val();
updatePartSelect(selectedCorp);
});
});
$(function(){
// 모달 열기
$('#monthlyLeaveBtn').on('click', function(){
$('#monthlyLeaveModal').show();
loadMonthlyLeave();
});
// 모달 닫기
$('.monthlyClose').on('click', function(){
$('#monthlyLeaveModal').hide();
});
// select 변경 시 다시 로드
$('#monthYearSelect, #corpSelect').on('change', loadMonthlyLeave);
function loadMonthlyLeave(){
var year = $('#monthYearSelect').val();
var corp = $('#corpSelect').val();
$.ajax({
url: 'monthly_leave_ajax.php',
type: 'POST',
data: { year: year, corp: corp },
success: function(html){
$('#monthlyLeaveContent').html(html);
},
error: function(xhr){
console.error(xhr.responseText);
}
});
}
});
</script>
</body>
</html>