Files
sam-kd/carrecord/write_form.php
hskwon aca1767eb9 초기 커밋: 5130 레거시 시스템
- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경
- DB 연결 하드코딩 → .env 기반으로 변경
- MySQL strict mode DATE 오류 수정
2025-12-10 20:14:31 +09:00

1358 lines
47 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/load_GoogleDrive.php'; // 세션 등 여러가지 포함됨 파일 포함
if(!isset($_SESSION["level"]) || $_SESSION["level"]>5) {
sleep(1);
header("Location:" . $WebSite . "login/login_form.php");
exit;
}
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
$title_message = '차량일지 및 월간 사진기록';
?>
<title> <?=$title_message?> </title>
</head>
<body>
<?php require_once($_SERVER['DOCUMENT_ROOT'] . '/common/modal.php'); ?>
<?php
$id = $_REQUEST["id"] ?? '';
$item = $_REQUEST["item"] ?? '';
$upfilename = $_REQUEST["upfilename"] ?? '';
$tablename = $_REQUEST["tablename"] ?? '';
$savetitle = $_REQUEST["savetitle"] ?? ''; // log기록 저장 타이틀
$mode = $_REQUEST["mode"] ?? '';
$num = $_REQUEST["num"] ?? '';
$timekey = $_REQUEST["timekey"] ?? '';
$item_id = '';
$content = '';
if ($mode=="modify"){
try{
$sql = "select * from ".$DB."." . $tablename . " where num = ? ";
$stmh = $pdo->prepare($sql);
$stmh->bindValue(1,$num,PDO::PARAM_STR);
$stmh->execute();
$count = $stmh->rowCount();
if($count<1){
print "검색결과가 없습니다.<br>";
}else{
$row = $stmh->fetch(PDO::FETCH_ASSOC);
include '_row.php';
}
}catch (PDOException $Exception) {
print "오류: ".$Exception->getMessage();
}
}
else if ($mode=="view"){
try{
$sql = "select * from ".$DB."." . $tablename . " where num = ? ";
$stmh = $pdo->prepare($sql);
$stmh->bindValue(1,$num,PDO::PARAM_STR);
$stmh->execute();
$count = $stmh->rowCount();
if($count<1){
print "검색결과가 없습니다.<br>";
}else{
$row = $stmh->fetch(PDO::FETCH_ASSOC);
include '_row.php';
}
}catch (PDOException $Exception) {
print "오류: ".$Exception->getMessage();
}
}
else
{
$item_subject = '월별 차량사진 대지';
$is_html = 0 ;
$content = '';
$regist_day = date('Y-m-d') ;
$nick = $user_name ;
}
// 초기 프로그램은 $num사용 이후 $id로 수정중임
$id=$num;
include $_SERVER['DOCUMENT_ROOT'] . '/load_GoogleDriveSecond.php'; // attached, image에 대한 정보 불러오기
// 차량 종류 및 차량 번호 가져오기
$vehicle_list = [];
try {
$sql = "SELECT DISTINCT vehicle_type, vehicle_number FROM " . $DB . ".car WHERE is_deleted IS NULL ORDER BY vehicle_type ASC, vehicle_number ASC";
$stmh = $pdo->query($sql);
while ($row = $stmh->fetch(PDO::FETCH_ASSOC)) {
if (!empty($row['vehicle_type']) && !empty($row['vehicle_number'])) {
// 차량종류 - 차량번호 형식으로 조합
$vehicle_list[] = [
'display' => htmlspecialchars($row['vehicle_type'], ENT_QUOTES, 'UTF-8') . ' - ' . htmlspecialchars($row['vehicle_number'], ENT_QUOTES, 'UTF-8'),
'type' => htmlspecialchars($row['vehicle_type'], ENT_QUOTES, 'UTF-8'),
'number' => htmlspecialchars($row['vehicle_number'], ENT_QUOTES, 'UTF-8')
];
}
}
} catch (PDOException $Exception) {
print "오류: " . $Exception->getMessage();
}
?>
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data">
<!-- 전달함수 설정 input hidden -->
<input type="hidden" id="tablename" name="tablename" value="<?=$tablename?>" >
<input type="hidden" id="id" name="id" value="<?=$id?>" >
<input type="hidden" id="num" name="num" value="<?=$num?>" >
<input type="hidden" id="item" name="item" value="<?=$item?>" >
<input type="hidden" id="mode" name="mode" value="<?=$mode?>" >
<input type="hidden" id="user_name" name="user_name" value="<?=$user_name?>" >
<input type="hidden" id="timekey" name="timekey" value="<?=$timekey?>" > <!-- 신규데이터 작성시 parentid key값으로 사용 -->
<input type="hidden" id="searchtext" name="searchtext" value="<?=$searchtext?>" >
<div class="container">
<div class="d-flex mt-3 mb-1 justify-content-center align-items-center">
<h5> <?=$title_message?> </h5>
</div>
<div class="d-flex mt-3 mb-3 justify-content-center align-items-center">
<button type="button" class="btn btn-dark btn-sm mx-1" id="saveBtn" > <i class="bi bi-floppy-fill"></i> 저장 </button>
<?php
// 삭제 수정은 관리자와 글쓴이만 가능토록 함
$currentUser = $nick; // 현재 로그인한 사용자
$postAuthor = $nick; // 게시물 작성자
$isAdmin = ($_SESSION["level"] == 1 || $_SESSION["userid"] == "admin" || $user_name == '이세희');
$canEdit = ($currentUser === $postAuthor || $isAdmin);
if($canEdit)
{
?>
<?php if($mode =='view') { ?>
<button type="button" class="btn btn-dark btn-sm mx-1" onclick="location.href='write_form.php?tablename=<?=$tablename?>&mode=modify&num=<?=$num?>'" > <i class="bi bi-pencil-square"></i> 수정 </button>
<button type="button" class="btn btn-dark btn-sm mx-1" onclick="location.href='write_form.php?tablename=<?=$tablename?>'" > <i class="bi bi-pencil"></i> 신규 </button>
<button type="button" class="btn btn-danger btn-sm mx-1" onclick="javascript:del('delete.php?tablename=<?=$tablename?>&num=<?=$num?>')" > <i class="bi bi-trash"></i> 삭제 </button>
<button type="button" class="btn btn-primary btn-sm mx-1" onclick="openImageSlider()"> <i class="bi bi-images"></i> 이미지 슬라이드 </button>
<?php } ?>
<!-- <button type="button" id="copylink" class="btn btn-primary btn-sm" > 외부로 보낼 링크복사 Copy Link</button> &nbsp; -->
<?php } ?>
<button class="btn btn-dark btn-sm mx-3" onclick="self.close();" > &times; 닫기 </button>
</div>
<div class="d-flex mt-2 mb-1 justify-content-center align-items-center">
<div class="card mt-2 mb-5 w-75" >
<div class="card-body">
<div class="d-flex mt-2 mb-1 justify-content-center align-items-center">
<table class="table table-bordered text-center align-middle">
<tbody>
<tr>
<th class="table-secondary" style="width: 15%;">작성일</th>
<th class="table-secondary" style="width: 30%;">차량정보</th>
<th class="table-secondary" style="width: 15%;">작성자</th>
<th class="table-secondary" style="width: 40%;">제목</th>
</tr>
<tr>
<td><input id="regist_day" name="regist_day" type="date" required class="form-control" value="<?=$regist_day?>"></td>
<td>
<select id="car_name" name="car_name" class="form-select mx-1" style="font-size: 0.8rem; height: 32px;">
<option value=""> (차량 정보 선택) </option>
<?php foreach ($vehicle_list as $vehicle) { ?>
<option value="<?= $vehicle['display'] ?>"
data-type="<?= $vehicle['type'] ?>"
data-number="<?= $vehicle['number'] ?>"
<?= ($car_name == $vehicle['display']) ? 'selected' : '' ?>>
<?= $vehicle['display'] ?>
</option>
<?php } ?>
</select>
</td>
<td><input id="nick" name="nick" type="text" required class="form-control" value="<?=$nick?>"></td>
<td><input id="subject" name="subject" type="text" class="form-control text-start" value="<?=$item_subject?>"></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="d-flex mt-1 mb-5 justify-content-center">
<label for="upfileimage" class="input-group-text btn btn-outline-primary btn-sm "> <i class="bi bi-images"></i> 사진 첨부 </label>
<input id="upfileimage" name="upfileimage[]" type="file" onchange="this.value" multiple accept=".gif, .jpg, .png" style="display:none">
</div>
<div id ="displayImage" style="display:none;"> </div>
</div>
</div>
</div>
</form>
<!-- 이미지 슬라이더 모달 -->
<div class="modal fade" id="imageSliderModal" tabindex="-1" aria-labelledby="imageSliderModalLabel" aria-hidden="true">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="imageSliderModalLabel">이미지 슬라이드쇼</h5>
<div class="ms-auto">
<button type="button" class="btn btn-primary me-2" onclick="downloadAllImages()">
<i class="bi bi-download"></i> 이미지 다운로드
</button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
</div>
<div class="modal-body p-0">
<div class="slider-container">
<div class="slider">
<!-- 이미지가 여기에 동적으로 로드됩니다 -->
</div>
<button class="slider-button prev"></button>
<button class="slider-button next"></button>
<div class="slider-dots">
<!-- 도트가 여기에 동적으로 생성됩니다 -->
</div>
</div>
</div>
</div>
</div>
</div>
<style>
.modal-fullscreen {
width: 100vw;
max-width: none;
height: 100vh;
margin: 0;
}
.modal-content {
height: 100vh;
border-radius: 0;
background-color: #000;
}
.modal-header {
background-color: rgba(0, 0, 0, 0.8);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
padding: 1rem;
}
.modal-title {
color: white;
}
.btn-close {
filter: invert(1) grayscale(100%) brightness(200%);
}
.modal-body {
padding: 0 !important;
height: calc(100vh - 60px); /* 헤더 높이 제외 */
}
.slider-container {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
background-color: #000;
}
.slider {
display: flex;
transition: transform 0.5s ease-in-out;
height: 100%;
}
.slide {
min-width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.slide-content {
position: relative;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.slide img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.slide-caption {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 15px;
text-align: center;
font-size: 16px;
}
.slider-button {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: rgba(0, 0, 0, 0.5);
color: white;
padding: 20px 25px;
border: none;
cursor: pointer;
font-size: 28px;
z-index: 10;
transition: background-color 0.3s;
}
.slider-button:hover {
background: rgba(0, 0, 0, 0.8);
}
.prev {
left: 20px;
}
.next {
right: 20px;
}
.slider-dots {
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 12px;
z-index: 10;
}
.dot {
width: 14px;
height: 14px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
cursor: pointer;
transition: background-color 0.3s;
}
.dot:hover {
background: rgba(255, 255, 255, 0.8);
}
.dot.active {
background: white;
}
.modal-header .btn-primary {
background-color: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.2);
color: white;
}
.modal-header .btn-primary:hover {
background-color: rgba(0, 0, 0, 0.8);
border-color: rgba(255, 255, 255, 0.4);
}
#downloadProgress {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 20px;
border-radius: 10px;
z-index: 9999;
display: none;
}
</style>
<script>
// 페이지 로딩
$(document).ready(function(){
var loader = document.getElementById('loadingOverlay');
if(loader)
loader.style.display = 'none';
// 이미지 슬라이더 모달 초기화
const imageSliderModal = new bootstrap.Modal(document.getElementById('imageSliderModal'), {
backdrop: 'static',
keyboard: false
});
// 이미지 슬라이더 버튼 클릭 이벤트
$('.btn-primary').on('click', function() {
if($(this).text().trim() === '이미지 슬라이드') {
imageSliderModal.show();
loadSliderImages();
}
});
// 모달이 닫힐 때 이벤트
$('#imageSliderModal').on('hidden.bs.modal', function () {
// 슬라이더 초기화
const slider = document.querySelector('#imageSliderModal .slider');
const dotsContainer = document.querySelector('#imageSliderModal .slider-dots');
slider.innerHTML = '';
dotsContainer.innerHTML = '';
// 모달 관련 요소들 제거
$('.modal-backdrop').remove();
$('body').removeClass('modal-open');
$('body').css({
'padding-right': '',
'overflow': '',
'position': ''
});
// 모달 자체 제거 후 다시 추가
const modalElement = $('#imageSliderModal');
modalElement.remove();
$('body').append(modalElement);
});
// 모달이 열릴 때 이벤트
$('#imageSliderModal').on('show.bs.modal', function () {
$('body').css('overflow', 'hidden');
});
});
// 이미지 슬라이더 모달 열기
function openImageSlider() {
const modal = new bootstrap.Modal(document.getElementById('imageSliderModal'));
modal.show();
loadSliderImages();
}
// 슬라이더 이미지 로드
function loadSliderImages() {
const slider = document.querySelector('#imageSliderModal .slider');
const dotsContainer = document.querySelector('#imageSliderModal .slider-dots');
let currentSlide = 0;
let slides = [];
let dots = [];
// num 값 사용
const num = $("#num").val();
const tablename = $("#tablename").val();
console.log("요청 파라미터:", {
num: num,
tablename: tablename,
item: 'image',
folderPath: '경동기업/uploads'
});
if (!num) {
console.error("ID 값이 없습니다.");
slider.innerHTML = '<div class="text-center text-muted">이미지를 불러올 수 없습니다.</div>';
return;
}
// saveimagename_arr 데이터 사용
const saveimagename_arr = <?php echo json_encode($saveimagename_arr); ?>;
console.log("saveimagename_arr 데이터:", saveimagename_arr);
slider.innerHTML = ''; // 기존 내용 초기화
dotsContainer.innerHTML = ''; // 도트 초기화
if (Array.isArray(saveimagename_arr) && saveimagename_arr.length > 0) {
saveimagename_arr.forEach((fileData, index) => {
const realName = fileData.realname || '다운로드 파일';
const fileId = fileData.fileId || null;
const rotation = fileData.rotation || 0;
if (!fileId) {
console.error("fileId가 누락되었습니다. index: " + index, fileData);
return;
}
// 구글 드라이브 이미지 URL 생성 (여러 형식 시도)
const imageUrls = [
`https://drive.google.com/thumbnail?id=${fileId}&sz=w1920-h1080`,
`https://drive.google.com/uc?export=view&id=${fileId}`,
`https://drive.google.com/file/d/${fileId}/preview`
];
// 슬라이드 추가
const slide = document.createElement('div');
slide.className = 'slide';
slide.innerHTML = `
<div class="slide-content" style="position:relative;">
<img src="${imageUrls[0]}"
alt="${realName}"
style="width:100%; height:100%; object-fit:contain; transform: rotate(${rotation}deg) scale(1);"
data-rotation="${rotation}"
data-scale="1"
data-fileid="${fileId}"
onerror="this.onerror=null; this.src='${imageUrls[1]}';"
onerror="this.onerror=null; this.src='${imageUrls[2]}';">
<div class="slide-caption">${realName}</div>
<div class="slider-btn-group" style="position:absolute; top:18px; right:18px; z-index:1001; display:flex; gap:8px; background:rgba(0,0,0,0.4); border-radius:8px; padding:4px 8px;">
<button type="button" class="btn btn-light btn-sm rotate-btn-slider" title="회전"
onclick="rotateSliderImage('${fileId}', this.closest('.slide-content').querySelector('img'))"
style="font-weight:bold; border:1px solid #888;">⟳</button>
<button type="button" class="btn btn-light btn-sm zoom-in-btn" title="확대"
onclick="zoomSliderImage(this.closest('.slide-content').querySelector('img'), 0.2)"
style="font-weight:bold; border:1px solid #888;"></button>
<button type="button" class="btn btn-light btn-sm zoom-out-btn" title="축소"
onclick="zoomSliderImage(this.closest('.slide-content').querySelector('img'), -0.2)"
style="font-weight:bold; border:1px solid #888;"></button>
</div>
</div>
`;
slider.appendChild(slide);
// 도트 추가
const dot = document.createElement('div');
dot.className = 'dot' + (index === 0 ? ' active' : '');
dotsContainer.appendChild(dot);
});
// 슬라이드와 도트 요소 업데이트
slides = document.querySelectorAll('#imageSliderModal .slide');
dots = document.querySelectorAll('#imageSliderModal .dot');
if (slides.length > 0) {
setupSliderControls();
} else {
slider.innerHTML = '<div class="text-center text-muted">유효한 이미지가 없습니다.</div>';
}
} else {
console.log("이미지 데이터가 없습니다.");
slider.innerHTML = '<div class="text-center text-muted">No images available</div>';
}
}
// 슬라이더 컨트롤 설정
function setupSliderControls() {
const slider = document.querySelector('#imageSliderModal .slider');
const slides = document.querySelectorAll('#imageSliderModal .slide');
const dots = document.querySelectorAll('#imageSliderModal .dot');
const prevButton = document.querySelector('#imageSliderModal .prev');
const nextButton = document.querySelector('#imageSliderModal .next');
let currentSlide = 0;
function updateSlider() {
slider.style.transform = `translateX(-${currentSlide * 100}%)`;
dots.forEach((dot, index) => {
dot.classList.toggle('active', index === currentSlide);
});
// 슬라이드 이동 시 scale 초기화
slides.forEach((slide, idx) => {
const img = slide.querySelector('img');
if (img) {
img.setAttribute('data-scale', 1);
const rotation = img.getAttribute('data-rotation') || '0';
img.style.transform = `rotate(${rotation}deg) scale(1)`;
}
});
}
function nextSlide() {
currentSlide = (currentSlide + 1) % slides.length;
updateSlider();
}
function prevSlide() {
currentSlide = (currentSlide - 1 + slides.length) % slides.length;
updateSlider();
}
// 버튼 클릭 이벤트
prevButton.onclick = prevSlide;
nextButton.onclick = nextSlide;
// 도트 클릭 이벤트
dots.forEach((dot, index) => {
dot.onclick = () => {
currentSlide = index;
updateSlider();
};
});
}
</script>
<script>
var ajaxRequest = null;
$(document).ready(function(){
$("#closeModalBtn").click(function(){
$('#myModal').modal('hide');
});
// 하단복사 버튼
$("#closeBtn1").click(function(){
$("#closeBtn").click();
})
$("#closeBtn").click(function(){ // 저장하고 창닫기
opener.location.reload();
self.close();
});
$("#saveBtn").click(function(){
Fninsert();
});
// 자료의 삽입/수정하는 모듈
function Fninsert() {
console.log($("#mode").val());
var form = $('#board_form')[0];
var data = new FormData(form);
// 폼 데이터를 콘솔에 출력하여 확인합니다.
// for (var pair of data.entries()) {
// console.log(pair[0] + ', ' + pair[1]);
// }
// console.log(data);
showMsgModal(2); // 파일저장중
ajaxRequest = $.ajax({
enctype: 'multipart/form-data', // file을 서버에 전송하려면 이렇게 해야 함 주의
processData: false,
contentType: false,
cache: false,
timeout: 600000,
url: "insert.php",
type: "post",
data: data,
dataType:"json",
success : function(data){
console.log(data);
setTimeout(function() {
Toastify({
text: "파일 저장완료 ",
duration: 2000,
close:true,
gravity:"top",
position: "center",
style: {
background: "linear-gradient(to right, #00b09b, #96c93d)"
},
}).showToast();
// 저장 완료 후 이미지 데이터를 다시 로드하여 회전 상태 반영
setTimeout(function() {
displayImage();
}, 500);
setTimeout(function(){
if (window.opener && !window.opener.closed) {
opener.location.reload();
}
}, 1000);
var num = data["num"];
var tablename = data["tablename"];
setTimeout(function(){
hideMsgModal();
// location.href='view.php?num=' + num + "&tablename=" + tablename ;
window.location.reload();
}, 1000);
}, 1000);
},
error : function( jqxhr , status , error ){
console.log( jqxhr , status , error );
}
});
}
}); // end of ready document
$(document).ready(function () {
displayImageLoad(); // 기졸이미지 업로드 보이기
// 첨부 이미지 업로드 처리
$("#upfileimage").change(function (e) {
if (this.files.length === 0) {
// 파일이 선택되지 않았을 때
console.warn("파일이 선택되지 않았습니다.");
return;
}
const form = $('#board_form')[0];
const data = new FormData(form);
// 추가 데이터 설정
data.append("tablename", $("#tablename").val() );
data.append("item", "image");
data.append("upfilename", "upfileimage"); // upfile 파일 name
data.append("folderPath", "경동기업/uploads");
data.append("DBtable", "picuploads");
showMsgModal(1); // 이미지저장중
// 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("응답 데이터:", response);
let successCount = 0;
let errorCount = 0;
let errorMessages = [];
response.forEach((item) => {
if (item.status === "success") {
successCount++;
} else if (item.status === "error") {
errorCount++;
errorMessages.push(`파일: ${item.file}, 메시지: ${item.message}`);
}
});
if (successCount > 0) {
Toastify({
text: `${successCount}개의 파일이 성공적으로 업로드되었습니다.`,
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();
}
setTimeout(function () {
displayImage();
hideMsgModal();
}, 1000);
},
error: function (jqxhr, status, error) {
console.error("업로드 실패:", jqxhr, status, error);
},
});
});
});
// 첨부된 이미지 불러오기
function displayImage() {
$('#displayImage').show();
const params = $("#timekey").val() ? $("#timekey").val() : $("#num").val();
if (!params) {
console.error("ID 값이 없습니다. 파일을 불러올 수 없습니다.");
alert("ID 값이 유효하지 않습니다. 다시 시도해주세요.");
return;
}
console.log("요청 ID:", params); // 요청 전 ID 확인
$.ajax({
url: '/filedrive/fileprocess.php',
type: 'GET',
data: {
num: params,
tablename: $("#tablename").val(),
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;
const rotation = fileData.rotation || 0;
if (!fileId) {
console.error("fileId가 누락되었습니다. index: " + index, fileData);
$("#displayImage").append(
"<div class='text-danger'>파일 ID가 누락되었습니다.</div>"
);
return;
}
// 삭제 버튼 표시 여부 확인
var currentUser = $("#nick").val(); // 현재 로그인한 사용자
var postAuthor = "<?php echo $nick; ?>"; // 게시물 작성자
var isAdmin = <?php echo ($_SESSION["level"] == 1 || $_SESSION["userid"] == "admin" || $user_name == '이세희') ? 'true' : 'false'; ?>;
var canDelete = (currentUser === postAuthor || isAdmin);
var deleteButton = canDelete ?
"<button type='button' class='btn btn-danger btn-sm' id='delImage" + index + "' onclick=\"delImageFn('" + index + "', '" + fileId + "')\">" +
"<i class='bi bi-trash'></i>" +
"</button>" : "";
// 회전 버튼 (작성자 또는 관리자일 때만 표시)
var currentUser = $("#nick").val(); // 현재 로그인한 사용자
var postAuthor = "<?php echo $nick; ?>"; // 게시물 작성자
var isAdmin = <?php echo ($_SESSION["level"] == 1 || $_SESSION["userid"] == "admin" || $user_name == '이세희') ? 'true' : 'false'; ?>;
var canRotate = (currentUser === postAuthor || isAdmin);
var rotateButton = canRotate ?
"<button type='button' class='btn btn-primary btn-sm' onclick=\"rotateImage('" + fileId + "', 'image" + index + "')\">" +
"<i class='bi bi-arrow-clockwise'></i>" +
"</button>" : "";
$("#displayImage").append(
"<div class='row mb-3'>" +
"<div class='col d-flex align-items-center justify-content-center'>" +
"<div class='position-relative'>" +
"<a href='#' onclick=\"openTmpImagePopup('" + link + "', 'image" + index + "'); return false;\">" +
"<img id='image" + index + "' src='" + thumbnail + "' style='width:150px; height:auto; transform: rotate(" + rotation + "deg);' data-rotation='" + rotation + "'>" +
"</a>" +
(canRotate ?
"<div class='position-absolute top-0 end-0 mt-1 me-1'>" +
"<button type='button' class='btn btn-primary btn-sm rotate-btn' onclick=\"rotateImage('" + fileId + "', 'image" + index + "')\">" +
"<i class='bi bi-arrow-clockwise'></i>" +
"</button>" +
"</div>" : "") +
"</div>" +
deleteButton +
"</div>" +
"</div>"
);
});
} else {
$("#displayImage").append(
"<div class='text-center text-muted'>No files</div>"
);
}
}).fail(function (error) {
console.error("파일 불러오기 오류:", error);
Swal.fire({
title: "파일 불러오기 실패",
text: "파일을 불러오는 중 문제가 발생했습니다.",
icon: "error",
confirmButtonText: "확인",
});
});
}
// 기존 이미지 불러오기 (Google Drive에서 가져오기)
function displayImageLoad() {
$('#displayImage').show();
var data = <?php echo json_encode($saveimagename_arr); ?>;
$("#displayImage").html(''); // 기존 내용 초기화
if (Array.isArray(data) && data.length > 0) {
data.forEach(function (fileData, i) {
const realName = fileData.realname || '다운로드 파일';
const thumbnail = fileData.thumbnail || '/assets/default-thumbnail.png';
const link = fileData.link || '#';
const fileId = fileData.fileId || null;
const rotation = fileData.rotation || 0;
if (!fileId) {
console.error("fileId가 누락되었습니다. index: " + i, fileData);
return;
}
// 삭제 버튼 표시 여부 확인
var currentUser = $("#nick").val(); // 현재 로그인한 사용자
var postAuthor = "<?php echo $nick; ?>"; // 게시물 작성자
var isAdmin = <?php echo ($_SESSION["level"] == 1 || $_SESSION["userid"] == "admin" || $user_name == '이세희') ? 'true' : 'false'; ?>;
var canDelete = (currentUser === postAuthor || isAdmin);
var deleteButton = canDelete ?
"<button type='button' class='btn btn-danger btn-sm' id='delImage" + i + "' onclick=\"delImageFn('" + i + "', '" + fileId + "')\">" +
"<i class='bi bi-trash'></i>" +
"</button>" : "";
// 회전 버튼 (작성자 또는 관리자일 때만 표시)
var currentUser = $("#nick").val(); // 현재 로그인한 사용자
var postAuthor = "<?php echo $nick; ?>"; // 게시물 작성자
var isAdmin = <?php echo ($_SESSION["level"] == 1 || $_SESSION["userid"] == "admin" || $user_name == '이세희') ? 'true' : 'false'; ?>;
var canRotate = (currentUser === postAuthor || isAdmin);
var rotateButton = canRotate ?
"<button type='button' class='btn btn-primary btn-sm' onclick=\"rotateImage('" + fileId + "', 'image" + i + "')\">" +
"<i class='bi bi-arrow-clockwise'></i>" +
"</button>" : "";
$("#displayImage").append(
"<div class='row mb-3'>" +
"<div class='col d-flex align-items-center justify-content-center'>" +
"<div class='position-relative'>" +
"<a href='#' onclick=\"openTmpImagePopup('" + link + "', 'image" + i + "'); return false;\">" +
"<img id='image" + i + "' src='" + thumbnail + "' style='width:150px; height:auto; transform: rotate(" + rotation + "deg);' data-rotation='" + rotation + "'>" +
"</a>" +
(canRotate ?
"<div class='position-absolute top-0 end-0 mt-1 me-1'>" +
"<button type='button' class='btn btn-primary btn-sm rotate-btn' onclick=\"rotateImage('" + fileId + "', 'image" + i + "')\">" +
"<i class='bi bi-arrow-clockwise'></i>" +
"</button>" +
"</div>" : "") +
"</div>" +
deleteButton +
"</div>" +
"</div>"
);
});
} else {
$("#displayImage").append(
"<div class='text-center text-muted'>No files</div>"
);
}
}
// 이미지 삭제 이미지삭제 처리 함수
function delImageFn(divID, fileId) {
// 작성자 확인
var currentUser = $("#nick").val(); // 현재 로그인한 사용자
var postAuthor = "<?php echo $nick; ?>"; // 게시물 작성자
// 관리자 권한 확인
var isAdmin = <?php echo ($_SESSION["level"] == 1 || $_SESSION["userid"] == "admin" || $user_name == '이세희') ? 'true' : 'false'; ?>;
// 작성자와 현재 사용자가 다르고, 관리자가 아닌 경우 삭제 불가
if (currentUser !== postAuthor && !isAdmin) {
Swal.fire({
title: "삭제 권한 없음",
text: "작성자와 관리자만 삭제할 수 있습니다.",
icon: "error",
confirmButtonText: "확인",
});
return;
}
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: $("#tablename").val(),
item: "image",
folderPath: "경동기업/uploads",
DBtable: "picuploads",
}),
contentType: "application/json",
dataType: 'json',
}).done(function (response) {
if (response.status === 'success') {
console.log("삭제 완료:", response);
// 이미지 컨테이너 전체를 제거 (이미지, 회전 버튼, 삭제 버튼이 모두 포함된 div)
$("#image" + divID).closest('.row').remove();
Swal.fire({
title: "삭제 완료",
text: "파일이 성공적으로 삭제되었습니다.",
icon: "success",
confirmButtonText: "확인",
});
} else {
console.log(response.message);
}
}).fail(function (error) {
console.error("삭제 중 오류:", error);
Swal.fire({
title: "삭제 실패",
text: "파일 삭제 중 문제가 발생했습니다.",
icon: "error",
confirmButtonText: "확인",
});
});
}
});
}
// 이미지 회전 함수
function rotateImage(fileId, imageId) {
const img = document.getElementById(imageId);
if (!img) {
console.error('이미지를 찾을 수 없습니다:', imageId);
return;
}
// 현재 회전 각도 가져오기 (data-rotation 속성 우선, 없으면 style에서 추출)
let currentRotation = parseInt(img.getAttribute('data-rotation') || '0');
if (!img.getAttribute('data-rotation')) {
currentRotation = parseInt(img.style.transform.replace('rotate(', '').replace('deg)', '')) || 0;
}
// 90도씩 회전
const newRotation = (currentRotation + 90) % 360;
// 이미지 회전 적용
img.style.transform = `rotate(${newRotation}deg)`;
img.setAttribute('data-rotation', newRotation);
// 회전 각도를 서버에 저장
saveRotationAngle(fileId, newRotation);
}
// 회전 각도를 서버에 저장하는 함수
function saveRotationAngle(fileId, angle) {
// 로딩 표시
Toastify({
text: "회전 상태 저장 중...",
duration: 2000,
close: true,
gravity: "top",
position: "center",
style: {
background: "linear-gradient(to right, #4a90e2, #67b26f)"
}
}).showToast();
// AJAX 요청 전 데이터 확인
const requestData = {
action: 'saveRotation',
fileId: fileId,
rotation: angle,
tablename: $("#tablename").val()
};
console.log('전송 데이터:', JSON.stringify(requestData)); // 디버깅용
$.ajax({
url: '/filedrive/fileprocess.php',
type: 'POST',
data: JSON.stringify(requestData),
contentType: "application/json",
dataType: 'json',
success: function(response) {
console.log('서버 응답:', response); // 디버깅용
if (response && response.status === 'success') {
Toastify({
text: response.message || "회전 상태가 저장되었습니다",
duration: 2000,
close: true,
gravity: "top",
position: "center",
style: {
background: "linear-gradient(to right, #00b09b, #96c93d)"
}
}).showToast();
// 회전 상태가 저장된 후 이미지 데이터를 다시 로드하여 화면 업데이트
setTimeout(function() {
displayImage();
}, 500);
} else {
const errorMessage = response ? response.message : '알 수 없는 오류가 발생했습니다.';
console.error('회전 각도 저장 실패:', errorMessage);
Toastify({
text: errorMessage,
duration: 2000,
close: true,
gravity: "top",
position: "center",
style: {
background: "linear-gradient(to right, #ff5f6d, #ffc371)"
}
}).showToast();
}
},
error: function(xhr, status, error) {
console.error('회전 각도 저장 중 오류:', {
status: status,
error: error,
response: xhr.responseText
});
let errorMessage = "회전 상태 저장 중 오류가 발생했습니다.";
try {
if (xhr.responseText) {
const response = JSON.parse(xhr.responseText);
if (response && response.message) {
errorMessage = response.message;
}
}
} catch (e) {
console.error('응답 파싱 오류:', e);
}
Toastify({
text: errorMessage,
duration: 2000,
close: true,
gravity: "top",
position: "center",
style: {
background: "linear-gradient(to right, #ff5f6d, #ffc371)"
}
}).showToast();
}
});
}
function getGoogleDriveFileId(link) {
// 구글드라이브 파일ID 추출
var match = link.match(/\/d\/([a-zA-Z0-9_-]+)/);
return match ? match[1] : '';
}
// 이미지 팝업을 여는 함수
function openTmpImagePopup(link, imageId) {
console.log('link : ',link);
console.log('imageId : ',imageId);
var fileId = getGoogleDriveFileId(link);
if (!fileId) {
alert('구글드라이브 파일ID 추출 실패');
return;
}
const imgElement = document.getElementById(imageId);
if (!imgElement) {
console.error('이미지 요소를 찾을 수 없습니다:', imageId);
return;
}
// data-rotation 속성 우선, 없으면 style에서 추출
let currentRotation = parseInt(imgElement.getAttribute('data-rotation') || '0');
if (!imgElement.getAttribute('data-rotation')) {
const transformStyle = imgElement.style.transform;
currentRotation = transformStyle ? parseInt(transformStyle.replace('rotate(', '').replace('deg)', '')) : 0;
}
// 팝업 창 열기 전에 모달 표시
showMsgModal(3); // "데이터를 처리 중입니다. 잠시만 기다려 주세요!"
$.post('/filedrive/download_and_rotate.php', { fileId: fileId, rotation: currentRotation }, function(res) {
// 모달 숨기기
hideMsgModal();
if (res.success) {
// 팝업 창 열기
var popupWindow = popupCenter('/filedrive/view_tmpimg.php?img=' + encodeURIComponent(res.imgUrl) + '&rotation=' + res.rotation, 'imagePopup', 800, 600);
if (!popupWindow) {
// alert('팝업 창을 여는 데 실패했습니다. 브라우저의 팝업 차단 설정을 확인해주세요.');
return;
}
} else {
alert(res.msg || '이미지 처리 실패');
}
}, 'json').fail(function() {
// 모달 숨기기
hideMsgModal();
alert('서버와 통신 중 오류가 발생했습니다.');
});
}
function del(href) {
var user_id = '<?php echo $user_id ; ?>' ;
var admin = '<?php echo $admin ; ?>' ;
var user_name = $("#user_name").val();
var currentUser = $("#nick").val(); // 현재 로그인한 사용자
var postAuthor = "<?php echo $nick; ?>"; // 게시물 작성자
// 관리자 권한 확인
var isAdmin = <?php echo ($_SESSION["level"] == 1 || $_SESSION["userid"] == "admin" || $user_name == '이세희') ? 'true' : 'false'; ?>;
// 작성자와 현재 사용자가 다르고, 관리자가 아닌 경우 삭제 불가
if (currentUser !== postAuthor && !isAdmin) {
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) {
$.ajax({
url: "delete.php",
type: "post",
data: $("#board_form").serialize(),
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();
setTimeout(function(){
if (window.opener && !window.opener.closed) {
window.opener.restorePageNumber(); // 부모 창에서 페이지 번호 복원
window.opener.location.reload(); // 부모 창 새로고침
window.close();
}
}, 1000);
},
error : function( jqxhr , status , error ){
console.log( jqxhr , status , error );
}
});
}
});
}
}
// view 모드일때 비활성화
$(document).ready(function() {
var mode = $("#mode").val();
// view 모드일 때, 버튼 및 입력 요소 비활성화
if (mode === 'view') {
$('input, textarea, select').prop('readonly', true); // input, textarea, select 비활성화
$('input[type=hidden]').prop('readonly', false);
$('button.add-row, button.remove-row, button.copy-row').prop('disabled', true); // 버튼 비활성화
$('select').prop('disabled', true); // select 요소 비활성화
}
});
// 모든 이미지 다운로드 함수
function downloadAllImages() {
const saveimagename_arr = <?php echo json_encode($saveimagename_arr); ?>;
if (!Array.isArray(saveimagename_arr) || saveimagename_arr.length === 0) {
Swal.fire({
title: '알림',
text: '다운로드할 이미지가 없습니다.',
icon: 'info'
});
return;
}
// 다운로드 링크를 포함한 HTML 생성
let downloadLinks = '<div class="download-links" style="max-height: 400px; overflow-y: auto; padding: 20px;">';
downloadLinks += '<h5>다운로드할 이미지 목록</h5>';
downloadLinks += '<ul class="list-group">';
saveimagename_arr.forEach((fileData, index) => {
const fileName = fileData.realname || `image_${index + 1}.jpg`;
const webViewLink = fileData.link;
if (webViewLink) {
downloadLinks += `
<li class="list-group-item d-flex justify-content-between align-items-center">
<span>${fileName}</span>
<a href="${webViewLink}" target="_blank" class="btn btn-primary btn-sm">
<i class="bi bi-download"></i> 다운로드
</a>
</li>
`;
}
});
downloadLinks += '</ul></div>';
// SweetAlert2로 다운로드 링크 표시
Swal.fire({
title: '이미지 다운로드',
html: downloadLinks,
width: '600px',
showCloseButton: true,
showConfirmButton: false,
customClass: {
container: 'download-modal'
}
});
}
// 슬라이드에서 이미지 회전 함수
function rotateSliderImage(fileId, imgElement) {
if (!imgElement) {
console.error('이미지 요소를 찾을 수 없습니다.');
return;
}
// 현재 회전 각도 가져오기
let currentRotation = parseInt(imgElement.getAttribute('data-rotation') || '0');
// 90도씩 회전
const newRotation = (currentRotation + 90) % 360;
// 이미지 회전 적용
imgElement.style.transform = `rotate(${newRotation}deg)`;
imgElement.setAttribute('data-rotation', newRotation);
// 서버에 회전 각도 저장
saveRotationAngle(fileId, newRotation);
// 메인 화면의 이미지도 업데이트
setTimeout(function() {
displayImage();
}, 1000);
}
// JS에 zoomSliderImage 함수 추가
function zoomSliderImage(imgElement, delta) {
if (!imgElement) return;
let scale = parseFloat(imgElement.getAttribute('data-scale') || '1');
scale += delta;
if (scale < 0.5) scale = 0.5;
if (scale > 3) scale = 3;
imgElement.setAttribute('data-scale', scale);
// 기존 회전값 유지
const rotation = imgElement.getAttribute('data-rotation') || '0';
imgElement.style.transform = `rotate(${rotation}deg) scale(${scale})`;
}
</script>
<!-- JSZip 라이브러리 추가 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
</body>
</html>