v1.2.11
- [CUSTOMER] Install 요청, 청소 전, 청소 후 사진도 보이도록 수정. multi image 보이도록 수정. - [MAP] Container 교체 요청 시 사진 multi upload & preview. - [INSTALL WAIT LIST] Install request 완료 사진 multi upload & preview. - [INSTALL ORDER] Install 완료 사진 multi upload & preview. 조회 조건 바뀌어도 View Mode 유지되도록 수정.
This commit is contained in:
parent
62342d3454
commit
c48c0a97da
|
|
@ -264,11 +264,10 @@ trait InstallAPI {
|
||||||
|
|
||||||
while ($img = mysqli_fetch_assoc($ri)) {
|
while ($img = mysqli_fetch_assoc($ri)) {
|
||||||
|
|
||||||
$imgPath = $img['i_filepath'] . $img['i_filename'];
|
|
||||||
|
|
||||||
$photos[] = [
|
$photos[] = [
|
||||||
'i_uid' => (int)$img['i_uid'],
|
'i_uid' => (int)$img['i_uid'],
|
||||||
'imgPath' => $imgPath
|
'i_filepath' => $img['i_filepath'],
|
||||||
|
'i_filename' => $img['i_filename']
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1708,20 +1707,19 @@ trait InstallAPI {
|
||||||
$fail('select_di', 'daily_install not found');
|
$fail('select_di', 'daily_install not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isset($_FILES['photo']) || $_FILES['photo']['error'] !== 0){
|
if(!isset($_FILES['photos'])){
|
||||||
$fail('file', 'no file');
|
$fail('file', 'no files');
|
||||||
}
|
}
|
||||||
|
|
||||||
$file = $_FILES['photo'];
|
|
||||||
$customer_uid = intval($di['di_customer_uid']);
|
$customer_uid = intval($di['di_customer_uid']);
|
||||||
|
|
||||||
$ok = $this->save_customer_image_single(
|
$ok = $this->save_customer_image_multi(
|
||||||
$customer_uid,
|
$customer_uid,
|
||||||
$member_uid,
|
$member_uid,
|
||||||
$i_type,
|
$i_type,
|
||||||
$di_uid, // i_sourceuid = di_uid
|
$di_uid,
|
||||||
$note,
|
$note,
|
||||||
$file
|
$_FILES['photos']
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!$ok){
|
if(!$ok){
|
||||||
|
|
@ -1732,7 +1730,7 @@ trait InstallAPI {
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function save_customer_image_single($i_customeruid, $i_memberuid, $i_type, $i_sourceuid, $i_note, $file){
|
private function save_customer_image_multi($i_customeruid, $i_memberuid, $i_type, $i_sourceuid, $i_note, $files){
|
||||||
|
|
||||||
$conn = $GLOBALS['conn'];
|
$conn = $GLOBALS['conn'];
|
||||||
|
|
||||||
|
|
@ -1744,14 +1742,9 @@ trait InstallAPI {
|
||||||
$i_noteEsc = mysqli_real_escape_string($conn, trim($i_note));
|
$i_noteEsc = mysqli_real_escape_string($conn, trim($i_note));
|
||||||
$i_createddate = date("YmdHis");
|
$i_createddate = date("YmdHis");
|
||||||
|
|
||||||
// 확장자 체크(최소 보안)
|
|
||||||
$allowed = ['jpg','jpeg','png','webp'];
|
$allowed = ['jpg','jpeg','png','webp'];
|
||||||
$ext = strtolower(pathinfo($file['name'] ?? '', PATHINFO_EXTENSION));
|
|
||||||
if(!$ext || !in_array($ext, $allowed)){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 작업 단위 1장 유지: (customeruid + type, sourceuid 는 제외)
|
// 기존 row 비활성화
|
||||||
$qry_update = "
|
$qry_update = "
|
||||||
UPDATE tbl_customer_image
|
UPDATE tbl_customer_image
|
||||||
SET i_status = 'I'
|
SET i_status = 'I'
|
||||||
|
|
@ -1761,19 +1754,36 @@ trait InstallAPI {
|
||||||
";
|
";
|
||||||
if(qry($qry_update) === false) return false;
|
if(qry($qry_update) === false) return false;
|
||||||
|
|
||||||
// 저장 폴더
|
// 폴더
|
||||||
$upload_folder = getenv("DOCUMENT_ROOT")."/upload/customer_image/".$i_customeruid;
|
$upload_folder = getenv("DOCUMENT_ROOT")."/upload/customer_image/".$i_customeruid;
|
||||||
if(!is_dir($upload_folder)){
|
if(!is_dir($upload_folder)){
|
||||||
mkdir($upload_folder, 0777, true);
|
mkdir($upload_folder, 0777, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$newFileName = "IMG_".$i_customeruid."_".time().rand(1000,9999)."_0.jpg";
|
$savedFiles = [];
|
||||||
|
|
||||||
|
foreach ($files['name'] as $i => $name) {
|
||||||
|
|
||||||
|
if ($files['error'][$i] !== 0) continue;
|
||||||
|
|
||||||
|
$ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
|
||||||
|
if(!$ext || !in_array($ext, $allowed)) continue;
|
||||||
|
|
||||||
|
$tmp = $files['tmp_name'][$i];
|
||||||
|
|
||||||
|
$newFileName = "IMG_".$i_customeruid."_".time().rand(1000,9999)."_".$i.".jpg";
|
||||||
$savePath = $upload_folder . "/" . $newFileName;
|
$savePath = $upload_folder . "/" . $newFileName;
|
||||||
|
|
||||||
if (!$this->compressAndResizeImage($file['tmp_name'], $savePath, $ext, 1200, 75)) {
|
if (!$this->compressAndResizeImage($tmp, $savePath, $ext, 1200, 75)) {
|
||||||
return false;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$savedFiles[] = $newFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($savedFiles)) return false;
|
||||||
|
|
||||||
|
$fileNameString = implode(',', $savedFiles);
|
||||||
$dbFilePath = "/upload/customer_image/".$i_customeruid."/";
|
$dbFilePath = "/upload/customer_image/".$i_customeruid."/";
|
||||||
|
|
||||||
$sqlIns = "
|
$sqlIns = "
|
||||||
|
|
@ -1794,7 +1804,7 @@ trait InstallAPI {
|
||||||
'{$i_memberuid}',
|
'{$i_memberuid}',
|
||||||
'{$i_createddate}',
|
'{$i_createddate}',
|
||||||
'{$i_type}',
|
'{$i_type}',
|
||||||
'{$newFileName}',
|
'{$fileNameString}',
|
||||||
'{$dbFilePath}',
|
'{$dbFilePath}',
|
||||||
'A',
|
'A',
|
||||||
'{$i_noteEsc}',
|
'{$i_noteEsc}',
|
||||||
|
|
|
||||||
|
|
@ -2059,125 +2059,104 @@ if( $total_count < 1 ) {
|
||||||
";
|
";
|
||||||
$rt_img = $jdb->nQuery($qry_img, "image list error");
|
$rt_img = $jdb->nQuery($qry_img, "image list error");
|
||||||
|
|
||||||
// 분류 배열
|
function getImageTypeLabel($type) {
|
||||||
$install = [];
|
switch ($type) {
|
||||||
$container = [];
|
case 'install':
|
||||||
|
return 'Install Image';
|
||||||
while ($img = mysqli_fetch_array($rt_img, MYSQLI_ASSOC)) {
|
case 'install_order':
|
||||||
if ($img['i_type'] == "install") $install[] = $img;
|
return 'Container Request Image';
|
||||||
else $container[] = $img;
|
case 'clean_before':
|
||||||
|
return 'Before Clean';
|
||||||
|
case 'clean_after':
|
||||||
|
return 'After Clean';
|
||||||
|
default:
|
||||||
|
return ucfirst(str_replace('_', ' ', $type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($install) + count($container) == 0) {
|
if (mysqli_num_rows($rt_img) == 0) {
|
||||||
echo "<p>No images found.</p>";
|
echo "<p>No images found.</p>";
|
||||||
} else {
|
} else {
|
||||||
|
echo '<div style="display:flex; flex-wrap:wrap; gap:16px;">';
|
||||||
|
|
||||||
// ===========================
|
while ($img = mysqli_fetch_array($rt_img, MYSQLI_ASSOC)) {
|
||||||
// INSTALL
|
|
||||||
// ===========================
|
|
||||||
if (count($install) > 0) {
|
|
||||||
echo "<h4 style='margin-top:20px;'>Install</h4>";
|
|
||||||
|
|
||||||
foreach ($install as $img) {
|
|
||||||
|
|
||||||
echo '<div style="
|
echo '<div style="
|
||||||
|
width:220px;
|
||||||
border:1px solid #ddd;
|
border:1px solid #ddd;
|
||||||
padding:15px;
|
|
||||||
border-radius:8px;
|
border-radius:8px;
|
||||||
margin-bottom:20px;
|
padding:10px;
|
||||||
background:#fafafa;
|
background:#fafafa;
|
||||||
|
position:relative;
|
||||||
">';
|
">';
|
||||||
|
|
||||||
echo '<div style="display:flex; gap:15px; flex-wrap:wrap;">';
|
echo '
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-danger btn-delete-image"
|
||||||
|
data-uid="'.htmlspecialchars($img['i_uid']).'"
|
||||||
|
style="
|
||||||
|
position:absolute;
|
||||||
|
top:6px;
|
||||||
|
right:6px;
|
||||||
|
padding:2px 6px;
|
||||||
|
font-size:11px;
|
||||||
|
"
|
||||||
|
title="Delete image"
|
||||||
|
>
|
||||||
|
<i class="bi bi-x"></i>
|
||||||
|
</button>
|
||||||
|
';
|
||||||
|
|
||||||
|
// 이미지 영역 (위)
|
||||||
|
echo '<div style="display:flex; gap:6px; flex-wrap:wrap; margin-bottom:8px;">';
|
||||||
|
|
||||||
$files = explode(",", $img['i_filename']);
|
$files = explode(",", $img['i_filename']);
|
||||||
foreach ($files as $f) {
|
foreach ($files as $f) {
|
||||||
$imgPath = $img['i_filepath'] . trim($f);
|
$f = trim($f);
|
||||||
echo '
|
if (!$f) continue;
|
||||||
<div style="width:150px; text-align:center;">
|
|
||||||
<img src="'.$imgPath.'"
|
$imgPath = $img['i_filepath'] . $f;
|
||||||
|
|
||||||
|
echo '<img
|
||||||
|
src="'.htmlspecialchars($imgPath).'"
|
||||||
class="preview-img"
|
class="preview-img"
|
||||||
data-img="'.$imgPath.'"
|
data-img="'.htmlspecialchars($imgPath).'"
|
||||||
data-filename="'.$f.'"
|
style="
|
||||||
data-uid="'.$img['i_uid'].'"
|
width:100px;
|
||||||
data-customeruid="'.$c_uid.'"
|
height:80px;
|
||||||
data-type="'.$img['i_type'].'"
|
object-fit:cover;
|
||||||
style="width:100%; height:120px;
|
border-radius:5px;
|
||||||
object-fit:cover; border-radius:5px;
|
cursor:pointer;
|
||||||
cursor:pointer; border:1px solid #ccc;">
|
border:1px solid #ccc;
|
||||||
</div>
|
"
|
||||||
';
|
>';
|
||||||
}
|
}
|
||||||
|
echo '</div>';
|
||||||
|
|
||||||
|
// 설명 영역 (아래)
|
||||||
|
echo '<div style="font-size:12px; line-height:1.4;">';
|
||||||
|
echo '
|
||||||
|
<div style="margin-bottom:5px;">
|
||||||
|
<span class="badge bg-secondary" style="font-size:11px;">
|
||||||
|
'.htmlspecialchars(getImageTypeLabel($img['i_type'])).'
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div><b>Note:</b> '.nl2br(htmlspecialchars($img['i_note'])).'</div>
|
||||||
|
<div><b>Created:</b> '.date("Y-m-d H:i", strtotime($img['i_createddate'])).'</div>
|
||||||
|
<div><b>By:</b> '
|
||||||
|
. htmlspecialchars($img['m_firstname'] ?? '')
|
||||||
|
. ' '
|
||||||
|
. htmlspecialchars($img['m_lastname'] ?? '')
|
||||||
|
.'</div>
|
||||||
|
';
|
||||||
|
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
|
|
||||||
echo '<div style="margin-top:10px; font-size:14px; line-height:20px;">
|
echo '</div>'; // card end
|
||||||
<b>Note:</b> '.nl2br($img['i_note']).'<br>';
|
|
||||||
echo "<b>Created:</b> " . date("Y-m-d H:i:s", strtotime($img['i_createddate'])).'<br>';
|
|
||||||
echo "<b>Created by:</b> " . $img['m_firstname']. ' ' . $img['m_lastname']. ' (' . $img['m_initial']. ')';
|
|
||||||
echo '</div></div>';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================
|
echo '</div>'; // wrapper end
|
||||||
// CONTAINER
|
|
||||||
// ===========================
|
|
||||||
// if (count($container) > 0) {
|
|
||||||
// echo "<h4 style='margin-top:30px;'>Container</h4>";
|
|
||||||
|
|
||||||
// foreach ($container as $img) {
|
|
||||||
|
|
||||||
// echo '<div style="
|
|
||||||
// border:1px solid #ddd;
|
|
||||||
// padding:15px;
|
|
||||||
// border-radius:8px;
|
|
||||||
// margin-bottom:20px;
|
|
||||||
// background:#fafafa;
|
|
||||||
// ">';
|
|
||||||
|
|
||||||
// echo '<div style="display:flex; gap:15px; flex-wrap:wrap;">';
|
|
||||||
|
|
||||||
// $files = explode(",", $img['i_filename']);
|
|
||||||
// foreach ($files as $f) {
|
|
||||||
// $imgPath = $img['i_filepath'] . trim($f);
|
|
||||||
// echo '
|
|
||||||
// <div style="width:150px; text-align:center;">
|
|
||||||
// <img src="'.$imgPath.'"
|
|
||||||
// class="preview-img"
|
|
||||||
// data-img="'.$imgPath.'"
|
|
||||||
// data-filename="'.$f.'"
|
|
||||||
// data-uid="'.$img['i_uid'].'"
|
|
||||||
// data-customeruid="'.$c_uid.'"
|
|
||||||
// data-type="'.$img['i_type'].'"
|
|
||||||
// style="width:100%; height:120px;
|
|
||||||
// object-fit:cover; border-radius:5px;
|
|
||||||
// cursor:pointer; border:1px solid #ccc;">
|
|
||||||
// </div>
|
|
||||||
// ';
|
|
||||||
// }
|
|
||||||
|
|
||||||
// echo '</div>';
|
|
||||||
|
|
||||||
// echo '<div style="margin-top:10px; font-size:14px; line-height:20px;">
|
|
||||||
// <b>Note:</b> '.nl2br($img['i_note']).'<br>';
|
|
||||||
// echo "<b>Created:</b> " . date("Y-m-d H:i:s", strtotime($img['i_createddate'])).'<br>';
|
|
||||||
// echo '
|
|
||||||
// </div>
|
|
||||||
// <button onclick="openEditModal(
|
|
||||||
// \''.$img['i_uid'].'\',
|
|
||||||
// \''.htmlspecialchars($img['i_note'], ENT_QUOTES).'\',
|
|
||||||
// \''.$c_uid.'\',
|
|
||||||
// \''.htmlspecialchars($img['i_filename'], ENT_QUOTES).'\',
|
|
||||||
// \''.$img['i_filepath'].'\',
|
|
||||||
// \''.$img['i_type'].'\'
|
|
||||||
// )"
|
|
||||||
// style="margin-top:10px; padding:4px 10px; background:#007bff; color:white; border:none; border-radius:4px;">
|
|
||||||
// Edit
|
|
||||||
// </button>';
|
|
||||||
|
|
||||||
// echo '</div>';
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
@ -2211,7 +2190,7 @@ if( $total_count < 1 ) {
|
||||||
<form id="deleteImageForm" method="POST" action="/lib/user_process.php">
|
<form id="deleteImageForm" method="POST" action="/lib/user_process.php">
|
||||||
<input type="hidden" name="actionStr" value="DELETEIMAGE">
|
<input type="hidden" name="actionStr" value="DELETEIMAGE">
|
||||||
<input type="hidden" name="i_uid" id="delete_i_uid">
|
<input type="hidden" name="i_uid" id="delete_i_uid">
|
||||||
<input type="hidden" name="i_customeruid" id="delete_i_customeruid">
|
<input type="hidden" name="i_customeruid" id="delete_i_customeruid" value="<?=$c_uid?>">
|
||||||
<input type="hidden" name="fileName" id="delete_fileName">
|
<input type="hidden" name="fileName" id="delete_fileName">
|
||||||
<input type="hidden" name="goStr" value="<?=$goStr?>">
|
<input type="hidden" name="goStr" value="<?=$goStr?>">
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -2414,22 +2393,48 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
// Delete image
|
// Delete image
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
|
||||||
const deleteBtn = document.getElementById("btnDeleteImage");
|
const modalEl = document.getElementById("deleteConfirmModal");
|
||||||
const confirmModalObj = new bootstrap.Modal(document.getElementById("deleteConfirmModal"));
|
if (!modalEl) return;
|
||||||
|
|
||||||
|
const confirmModalObj = new bootstrap.Modal(modalEl);
|
||||||
|
|
||||||
|
// 삭제 버튼 클릭
|
||||||
|
document.addEventListener("click", function (e) {
|
||||||
|
const btn = e.target.closest(".btn-delete-image");
|
||||||
|
if (!btn) return;
|
||||||
|
|
||||||
|
const uid = btn.dataset.uid;
|
||||||
|
if (!uid) return;
|
||||||
|
|
||||||
|
// 현재 선택된 이미지 UID 저장
|
||||||
|
const uidInput = document.getElementById("currentImageUid");
|
||||||
|
if (uidInput) {
|
||||||
|
uidInput.value = uid;
|
||||||
|
}
|
||||||
|
|
||||||
if (deleteBtn) {
|
|
||||||
deleteBtn.addEventListener("click", function () {
|
|
||||||
confirmModalObj.show();
|
confirmModalObj.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// confirm 버튼 클릭
|
||||||
|
const confirmBtn = document.getElementById("confirmDeleteBtn");
|
||||||
|
if (confirmBtn) {
|
||||||
|
confirmBtn.addEventListener("click", function () {
|
||||||
|
|
||||||
|
const uid = document.getElementById("currentImageUid")?.value;
|
||||||
|
if (!uid) return;
|
||||||
|
|
||||||
|
const formInput = document.getElementById("delete_i_uid");
|
||||||
|
if (formInput) {
|
||||||
|
formInput.value = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
const form = document.getElementById("deleteImageForm");
|
||||||
|
if (form) {
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("confirmDeleteBtn").addEventListener("click", function () {
|
|
||||||
const uid = document.getElementById("currentImageUid").value;
|
|
||||||
if (!uid) return;
|
|
||||||
|
|
||||||
document.getElementById("delete_i_uid").value = uid;
|
|
||||||
document.getElementById("deleteImageForm").submit();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function openEditModal(uid, note, customeruid, filesString, filepath, type) {
|
function openEditModal(uid, note, customeruid, filesString, filepath, type) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
$selectedDate = $_GET['date'] ?? date('Y-m-d');
|
$selectedDate = $_GET['date'] ?? date('Y-m-d');
|
||||||
$canViewAllDrivers = ($_SESSION['ss_LEVEL'] <= 5 || $_SESSION['ss_GROUP'] == 1);
|
$canViewAllDrivers = ($_SESSION['ss_LEVEL'] <= 5 || $_SESSION['ss_GROUP'] == 1);
|
||||||
$selectedDriver = $_GET['driver_uid'] ?? ($canViewAllDrivers ? 0 : $_SESSION['ss_DRUID']);
|
$selectedDriver = $_GET['driver_uid'] ?? ($canViewAllDrivers ? 0 : $_SESSION['ss_DRUID']);
|
||||||
|
$view_mode = strtolower($_GET['view_mode'] ?? 'list');
|
||||||
|
|
||||||
$isAdmin = $canViewAllDrivers;
|
$isAdmin = $canViewAllDrivers;
|
||||||
|
|
||||||
|
|
@ -40,6 +41,7 @@ $sql_order = "
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM tbl_customer_image ci
|
FROM tbl_customer_image ci
|
||||||
WHERE ci.i_sourceuid = di.di_uid
|
WHERE ci.i_sourceuid = di.di_uid
|
||||||
|
and ci.i_type in ('install','clean_before','clean_after')
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
) AS has_image
|
) AS has_image
|
||||||
FROM tbl_daily_install di
|
FROM tbl_daily_install di
|
||||||
|
|
@ -105,11 +107,10 @@ if (isset($_GET['ajax']) && $_GET['ajax'] === 'work_images') {
|
||||||
|
|
||||||
// filepath + filename split
|
// filepath + filename split
|
||||||
$files = array_filter(array_map('trim', explode(',', $img['i_filename'] ?? '')));
|
$files = array_filter(array_map('trim', explode(',', $img['i_filename'] ?? '')));
|
||||||
$first = $files ? $files[0] : '';
|
|
||||||
|
|
||||||
$imgPath = '';
|
$images = [];
|
||||||
if ($first !== '') {
|
foreach ($files as $f) {
|
||||||
$imgPath = ($img['i_filepath'] ?? '') . $first;
|
$images[] = ($img['i_filepath'] ?? '') . $f;
|
||||||
}
|
}
|
||||||
|
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
|
|
@ -120,8 +121,7 @@ if (isset($_GET['ajax']) && $_GET['ajax'] === 'work_images') {
|
||||||
'i_sourceuid' => $img['i_sourceuid'],
|
'i_sourceuid' => $img['i_sourceuid'],
|
||||||
'i_note' => $img['i_note'],
|
'i_note' => $img['i_note'],
|
||||||
'i_createddate' => $img['i_createddate'],
|
'i_createddate' => $img['i_createddate'],
|
||||||
'imgPath' => $imgPath,
|
'images' => $images // ⭐ 핵심
|
||||||
'filename' => $first
|
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
exit;
|
exit;
|
||||||
|
|
@ -204,11 +204,11 @@ if (isset($_GET['ajax']) && $_GET['ajax'] === 'work_images') {
|
||||||
<!-- TOGGLE -->
|
<!-- TOGGLE -->
|
||||||
<div class="radio-segment d-flex" style="width:100%;">
|
<div class="radio-segment d-flex" style="width:100%;">
|
||||||
<label class="w-50 text-center">
|
<label class="w-50 text-center">
|
||||||
<input type="radio" name="view_mode" value="list" checked>
|
<input type="radio" name="view_mode" value="list" <?= $view_mode === 'list' ? 'checked' : '' ?>>
|
||||||
<span>LIST</span>
|
<span>LIST</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="w-50 text-center">
|
<label class="w-50 text-center">
|
||||||
<input type="radio" name="view_mode" value="map">
|
<input type="radio" name="view_mode" value="map" <?= $view_mode === 'map' ? 'checked' : '' ?>>
|
||||||
<span>MAP</span>
|
<span>MAP</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -348,7 +348,7 @@ if (isset($_GET['ajax']) && $_GET['ajax'] === 'work_images') {
|
||||||
|
|
||||||
<div id="wm_before_photo_list" class="photo-body"></div>
|
<div id="wm_before_photo_list" class="photo-body"></div>
|
||||||
|
|
||||||
<input type="file" class="form-control form-control-sm mt-2" id="wm_photos_before" accept="image/*">
|
<input type="file" class="form-control form-control-sm mt-2" id="wm_photos_before" accept="image/*" multiple>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -359,7 +359,7 @@ if (isset($_GET['ajax']) && $_GET['ajax'] === 'work_images') {
|
||||||
|
|
||||||
<div id="wm_after_photo_list" class="photo-body"></div>
|
<div id="wm_after_photo_list" class="photo-body"></div>
|
||||||
|
|
||||||
<input type="file" class="form-control form-control-sm mt-2" id="wm_photos_after" accept="image/*">
|
<input type="file" class="form-control form-control-sm mt-2" id="wm_photos_after" accept="image/*" multiple>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -380,6 +380,7 @@ if (isset($_GET['ajax']) && $_GET['ajax'] === 'work_images') {
|
||||||
<!-- =============================== -->
|
<!-- =============================== -->
|
||||||
<!-- IMAGE MODAL -->
|
<!-- IMAGE MODAL -->
|
||||||
<!-- =============================== -->
|
<!-- =============================== -->
|
||||||
|
<script src="/js/customer_image.js?v=<?=time()?>"></script>
|
||||||
<div class="modal fade" id="customerImageModal" tabindex="-1">
|
<div class="modal fade" id="customerImageModal" tabindex="-1">
|
||||||
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
|
@ -669,20 +670,19 @@ function initWorkModal(){
|
||||||
const workType = selectedRow.di_work_type;
|
const workType = selectedRow.di_work_type;
|
||||||
const afterFileInput = document.getElementById('wm_photos_after');
|
const afterFileInput = document.getElementById('wm_photos_after');
|
||||||
const beforeFileInput = document.getElementById('wm_photos_before');
|
const beforeFileInput = document.getElementById('wm_photos_before');
|
||||||
const afterFile = afterFileInput?.files?.[0] || null;
|
const afterFiles = Array.from(afterFileInput?.files || []);
|
||||||
const beforeFile = beforeFileInput?.files?.[0] || null;
|
const beforeFiles = Array.from(beforeFileInput?.files || []);
|
||||||
|
|
||||||
let uploads = [];
|
let uploads = [];
|
||||||
|
|
||||||
// AFTER
|
// AFTER
|
||||||
if(afterFile){
|
if(afterFiles.length){
|
||||||
const type = (workType === 'CLEAN') ? 'clean_after' : 'install';
|
const type = (workType === 'CLEAN') ? 'clean_after' : 'install';
|
||||||
uploads.push(uploadPhotoPromise(selectedRow, afterFile, type));
|
uploads.push(uploadPhotoPromise(selectedRow, afterFiles, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
// BEFORE (CLEAN만)
|
if(workType === 'CLEAN' && beforeFiles.length){
|
||||||
if(workType === 'CLEAN' && beforeFile){
|
uploads.push(uploadPhotoPromise(selectedRow, beforeFiles, 'clean_before'));
|
||||||
uploads.push(uploadPhotoPromise(selectedRow, beforeFile, 'clean_before'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uploads.length > 0){
|
if(uploads.length > 0){
|
||||||
|
|
@ -1053,26 +1053,24 @@ function renderAfterPhoto(photo){
|
||||||
const wrap = document.getElementById('wm_after_photo_list');
|
const wrap = document.getElementById('wm_after_photo_list');
|
||||||
if(!wrap) return;
|
if(!wrap) return;
|
||||||
|
|
||||||
if(!photo || !photo.imgPath){
|
if(!photo || !photo.images || !photo.images.length){
|
||||||
wrap.innerHTML = `<div class="small text-muted">No after photo.</div>`;
|
wrap.innerHTML = `<div class="small text-muted">No after photo.</div>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = photo.imgPath;
|
|
||||||
|
|
||||||
wrap.innerHTML = `
|
wrap.innerHTML = `
|
||||||
<div style="width:100%;">
|
<div style="display:flex; gap:8px; flex-wrap:wrap;">
|
||||||
|
${photo.images.map(url => `
|
||||||
<img src="${escapeHtml(url)}"
|
<img src="${escapeHtml(url)}"
|
||||||
style="width:100%; height:160px; object-fit:cover; border-radius:8px; border:1px solid #ddd; cursor:pointer;"
|
style="width:100px; height:80px; object-fit:cover; border-radius:6px; border:1px solid #ddd; cursor:pointer;"
|
||||||
class="after-photo-thumb"
|
class="after-photo-thumb"
|
||||||
data-img-url="${escapeHtml(url)}">
|
data-img-url="${escapeHtml(url)}">
|
||||||
|
`).join('')}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// 클릭 이벤트 연결
|
wrap.querySelectorAll('.after-photo-thumb').forEach(img => {
|
||||||
const imgEl = wrap.querySelector('.after-photo-thumb');
|
img.addEventListener('click', function(){
|
||||||
if(imgEl){
|
|
||||||
imgEl.addEventListener('click', function(){
|
|
||||||
|
|
||||||
const modalEl = document.getElementById('customerImageModal');
|
const modalEl = document.getElementById('customerImageModal');
|
||||||
const body = document.getElementById('customerImageModalBody');
|
const body = document.getElementById('customerImageModalBody');
|
||||||
|
|
@ -1081,15 +1079,14 @@ function renderAfterPhoto(photo){
|
||||||
|
|
||||||
body.innerHTML = `
|
body.innerHTML = `
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<img src="${escapeHtml(url)}"
|
<img src="${this.dataset.imgUrl}"
|
||||||
style="max-width:100%; max-height:75vh; border-radius:10px;">
|
style="max-width:100%; max-height:75vh; border-radius:10px;">
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const modal = new bootstrap.Modal(modalEl);
|
new bootstrap.Modal(modalEl).show();
|
||||||
modal.show();
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderBeforePhoto(photo){
|
function renderBeforePhoto(photo){
|
||||||
|
|
@ -1097,19 +1094,40 @@ function renderBeforePhoto(photo){
|
||||||
const wrap = document.getElementById('wm_before_photo_list');
|
const wrap = document.getElementById('wm_before_photo_list');
|
||||||
if(!wrap) return;
|
if(!wrap) return;
|
||||||
|
|
||||||
if(!photo || !photo.imgPath){
|
if(!photo || !photo.images || !photo.images.length){
|
||||||
wrap.innerHTML = `<div class="small text-muted">No before photo.</div>`;
|
wrap.innerHTML = `<div class="small text-muted">No before photo.</div>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = photo.imgPath;
|
|
||||||
|
|
||||||
wrap.innerHTML = `
|
wrap.innerHTML = `
|
||||||
<div style="width:100%;">
|
<div style="display:flex; gap:8px; flex-wrap:wrap;">
|
||||||
|
${photo.images.map(url => `
|
||||||
<img src="${escapeHtml(url)}"
|
<img src="${escapeHtml(url)}"
|
||||||
style="width:100%; height:160px; object-fit:cover; border-radius:8px; border:1px solid #ddd; cursor:pointer;">
|
style="width:100px; height:80px; object-fit:cover; border-radius:6px; border:1px solid #ddd; cursor:pointer;"
|
||||||
|
class="before-photo-thumb"
|
||||||
|
data-img-url="${escapeHtml(url)}">
|
||||||
|
`).join('')}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
wrap.querySelectorAll('.before-photo-thumb').forEach(img => {
|
||||||
|
img.addEventListener('click', function(){
|
||||||
|
|
||||||
|
const modalEl = document.getElementById('customerImageModal');
|
||||||
|
const body = document.getElementById('customerImageModalBody');
|
||||||
|
|
||||||
|
if(!modalEl || !body) return;
|
||||||
|
|
||||||
|
body.innerHTML = `
|
||||||
|
<div class="text-center">
|
||||||
|
<img src="${this.dataset.imgUrl}"
|
||||||
|
style="max-width:100%; max-height:75vh; border-radius:10px;">
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
new bootstrap.Modal(modalEl).show();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetPhotoBlocks(){
|
function resetPhotoBlocks(){
|
||||||
|
|
@ -1159,6 +1177,7 @@ function openCustomerImages(customerUid, iType = 'install_order') {
|
||||||
.then(res => res.text())
|
.then(res => res.text())
|
||||||
.then(html => {
|
.then(html => {
|
||||||
body.innerHTML = html;
|
body.innerHTML = html;
|
||||||
|
initCustomerImageSlider(body);
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
@ -1238,7 +1257,7 @@ function togglePhotoSection(workType){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadPhotoPromise(row, file, type){
|
function uploadPhotoPromise(row, files, type){
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
|
|
||||||
|
|
@ -1250,7 +1269,9 @@ function uploadPhotoPromise(row, file, type){
|
||||||
fd.append('member_uid', memberUid);
|
fd.append('member_uid', memberUid);
|
||||||
fd.append('note', (document.getElementById('wm_comment').value || '').trim());
|
fd.append('note', (document.getElementById('wm_comment').value || '').trim());
|
||||||
fd.append('i_type', type);
|
fd.append('i_type', type);
|
||||||
fd.append('photo', file);
|
files.forEach(file => {
|
||||||
|
fd.append('photos[]', file);
|
||||||
|
});
|
||||||
|
|
||||||
fetch('/assets/internal_api.php?func=upload_after_photo', {
|
fetch('/assets/internal_api.php?func=upload_after_photo', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -1855,12 +1876,14 @@ function reloadPage(){
|
||||||
|
|
||||||
const date = document.getElementById('installDate').value;
|
const date = document.getElementById('installDate').value;
|
||||||
const driver = document.getElementById('driverSelect').value;
|
const driver = document.getElementById('driverSelect').value;
|
||||||
|
const viewMode = document.querySelector('input[name="view_mode"]:checked')?.value || 'list';
|
||||||
|
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
|
|
||||||
url.searchParams.set('view', 'install_order');
|
url.searchParams.set('view', 'install_order');
|
||||||
url.searchParams.set('date', date);
|
url.searchParams.set('date', date);
|
||||||
url.searchParams.set('driver_uid', driver);
|
url.searchParams.set('driver_uid', driver);
|
||||||
|
url.searchParams.set('view_mode', viewMode);
|
||||||
|
|
||||||
window.location.href = url.toString();
|
window.location.href = url.toString();
|
||||||
}
|
}
|
||||||
|
|
@ -2115,6 +2138,22 @@ function showPopupMessage(message, type = 'success', duration = 1200) {
|
||||||
/* ===============================
|
/* ===============================
|
||||||
TOGGLE
|
TOGGLE
|
||||||
=================================*/
|
=================================*/
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
const viewMode = params.get('view_mode') || 'list';
|
||||||
|
|
||||||
|
const targetRadio = document.querySelector(`input[name="view_mode"][value="${viewMode}"]`);
|
||||||
|
|
||||||
|
if (targetRadio) {
|
||||||
|
targetRadio.checked = true;
|
||||||
|
|
||||||
|
// change 강제 실행
|
||||||
|
targetRadio.dispatchEvent(new Event('change'));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
document.querySelectorAll('input[name="view_mode"]').forEach(radio => {
|
document.querySelectorAll('input[name="view_mode"]').forEach(radio => {
|
||||||
radio.addEventListener('change', function () {
|
radio.addEventListener('change', function () {
|
||||||
document.getElementById('mapSection')
|
document.getElementById('mapSection')
|
||||||
|
|
|
||||||
|
|
@ -1562,6 +1562,7 @@ function formatPhone($phone) {
|
||||||
di_customer_name: w.iw_customer_name,
|
di_customer_name: w.iw_customer_name,
|
||||||
di_address: w.iw_address,
|
di_address: w.iw_address,
|
||||||
di_city: w.iw_city,
|
di_city: w.iw_city,
|
||||||
|
di_postal: w.iw_postal,
|
||||||
di_lat: w.iw_lat,
|
di_lat: w.iw_lat,
|
||||||
di_lng: w.iw_lng,
|
di_lng: w.iw_lng,
|
||||||
di_work_type: w.iw_work_type,
|
di_work_type: w.iw_work_type,
|
||||||
|
|
@ -1576,7 +1577,7 @@ function formatPhone($phone) {
|
||||||
|
|
||||||
// lat/lng 없으면 여기서 geocode
|
// lat/lng 없으면 여기서 geocode
|
||||||
if (!row.di_lat || !row.di_lng) {
|
if (!row.di_lat || !row.di_lng) {
|
||||||
const fullAddress = [w.iw_address, w.iw_city].filter(Boolean).join(', ');
|
const fullAddress = [w.iw_address, w.iw_city, w.iw_postal].filter(Boolean).join(', ');
|
||||||
|
|
||||||
if (fullAddress) {
|
if (fullAddress) {
|
||||||
geocoder.geocode({ address: fullAddress }, (results, status) => {
|
geocoder.geocode({ address: fullAddress }, (results, status) => {
|
||||||
|
|
|
||||||
|
|
@ -107,9 +107,7 @@
|
||||||
<!-- New -->
|
<!-- New -->
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>
|
||||||
<script src="/js/customer_image.js?v=20260213"></script>
|
|
||||||
|
|
||||||
<div class="loading-overlay">Loading...</div>
|
<div class="loading-overlay">Loading...</div>
|
||||||
|
|
||||||
|
|
@ -799,6 +797,7 @@ function popup(){
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- image modal -->
|
<!-- image modal -->
|
||||||
|
<script src="/js/customer_image.js?v=<?=time()?>"></script>
|
||||||
<div class="modal fade top map" id="customerImageModal" tabindex="-1" role="dialog">
|
<div class="modal fade top map" id="customerImageModal" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
|
@ -2514,6 +2513,7 @@ function popup(){
|
||||||
const outer = document.getElementById('simpleInstallPhotoWrap');
|
const outer = document.getElementById('simpleInstallPhotoWrap');
|
||||||
|
|
||||||
if (!wrap || !outer) return;
|
if (!wrap || !outer) return;
|
||||||
|
|
||||||
wrap.innerHTML = '';
|
wrap.innerHTML = '';
|
||||||
|
|
||||||
if (!photos || photos.length === 0) {
|
if (!photos || photos.length === 0) {
|
||||||
|
|
@ -2522,21 +2522,36 @@ function popup(){
|
||||||
}
|
}
|
||||||
|
|
||||||
outer.style.display = 'block';
|
outer.style.display = 'block';
|
||||||
|
|
||||||
photos.forEach(photo => {
|
photos.forEach(photo => {
|
||||||
|
|
||||||
if (!photo.imgPath) return;
|
if (!photo.i_filename) return;
|
||||||
|
|
||||||
|
const basePath = (photo.i_filepath || '').trim();
|
||||||
|
|
||||||
|
const filenames = photo.i_filename
|
||||||
|
.split(',')
|
||||||
|
.map(f => f.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
filenames.forEach(name => {
|
||||||
|
|
||||||
|
const fullUrl = basePath.endsWith('/')
|
||||||
|
? basePath + name
|
||||||
|
: basePath + '/' + name;
|
||||||
|
|
||||||
const url = photo.imgPath;
|
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.style.width = '120px';
|
div.style.width = '120px';
|
||||||
|
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<img src="${url}"
|
<img src="${fullUrl}"
|
||||||
style="width:100%; height:100px; object-fit:cover; border-radius:8px; border:1px solid #ddd;">
|
style="width:100%; height:100px; object-fit:cover; border-radius:8px; border:1px solid #ddd;">
|
||||||
`;
|
`;
|
||||||
|
|
||||||
wrap.appendChild(div);
|
wrap.appendChild(div);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeHtml(str) {
|
function escapeHtml(str) {
|
||||||
|
|
@ -2784,6 +2799,7 @@ function popup(){
|
||||||
.then(res => res.text())
|
.then(res => res.text())
|
||||||
.then(html => {
|
.then(html => {
|
||||||
body.innerHTML = html;
|
body.innerHTML = html;
|
||||||
|
initCustomerImageSlider(body);
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ $sqDriver = qry("SELECT
|
||||||
FROM
|
FROM
|
||||||
tbl_member
|
tbl_member
|
||||||
WHERE
|
WHERE
|
||||||
m_level = 9 AND m_status = 'A' ".$qrySTR."
|
m_level in (8,9) AND m_status = 'A' ".$qrySTR." AND m_gid = 0
|
||||||
ORDER BY
|
ORDER BY
|
||||||
m_initial ASC ");
|
m_initial ASC ");
|
||||||
while($rstDriver = fetch_array($sqDriver)){
|
while($rstDriver = fetch_array($sqDriver)){
|
||||||
|
|
@ -56,12 +56,10 @@ while($rstDriver = fetch_array($sqDriver)){
|
||||||
|
|
||||||
<label>Created By</label>
|
<label>Created By</label>
|
||||||
<select name="i_createdby" id="driver" class="custom-select-map-orderby" required>
|
<select name="i_createdby" id="driver" class="custom-select-map-orderby" required>
|
||||||
<option value="">Select</option>
|
<option value="<?=$_SESSION['ss_UID']?>">Select</option>
|
||||||
<?php
|
<?php
|
||||||
$defaultValue = 43; // E.X
|
|
||||||
foreach($drivers as $driver) {
|
foreach($drivers as $driver) {
|
||||||
$selected = ($driver['id'] == $defaultValue) ? 'selected' : '';
|
echo '<option value="'.$driver['id'].'">'.$driver['name'].'</option>';
|
||||||
echo '<option value="'.$driver['id'].'" '.$selected.'>'.$driver['name'].'</option>';
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</select>
|
</select>
|
||||||
|
|
@ -70,15 +68,17 @@ while($rstDriver = fetch_array($sqDriver)){
|
||||||
<label>Type</label>
|
<label>Type</label>
|
||||||
<select name="i_type" id="i_type" required>
|
<select name="i_type" id="i_type" required>
|
||||||
<option value="install">Install</option>
|
<option value="install">Install</option>
|
||||||
|
<option value="install_order">Install Request</option>
|
||||||
|
<option value="clean_before">Before Clean</option>
|
||||||
|
<option value="clean_after">After Clean</option>
|
||||||
<!-- <option value="container">Container</option> -->
|
<!-- <option value="container">Container</option> -->
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label>Image</label>
|
<label>Image</label>
|
||||||
<p style="font-size:12px; color:#666; margin-top:4px;">※ 기존 이미지가 있을 경우 삭제됩니다.</p>
|
<p style="font-size:12px; color:#666; margin-top:4px;">※ Will replace the same type images</p>
|
||||||
<p style="font-size:12px; color:#666; margin-top:-6px;">※ Install 이미지는 1개만 업로드 가능합니다.</p>
|
<input type="file" id="uploadFileInput" name="upload_file[]" accept="image/*" multiple required>
|
||||||
<input type="file" id="uploadFileInput" name="upload_file[]" accept="image/*" required>
|
|
||||||
|
|
||||||
<img id="previewImg" class="preview-img">
|
<div id="previewList" style="display:flex; gap:8px; flex-wrap:wrap; margin-top:12px;"></div>
|
||||||
|
|
||||||
<label>Note</label>
|
<label>Note</label>
|
||||||
<textarea name="i_note" rows="3"></textarea>
|
<textarea name="i_note" rows="3"></textarea>
|
||||||
|
|
@ -105,20 +105,29 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
|
||||||
// 이미지 preview
|
// 이미지 preview
|
||||||
const input = document.getElementById("uploadFileInput");
|
const input = document.getElementById("uploadFileInput");
|
||||||
const preview = document.getElementById("previewImg");
|
const previewList = document.getElementById("previewList");
|
||||||
|
|
||||||
if (input) {
|
if (input) {
|
||||||
input.addEventListener("change", function () {
|
input.addEventListener("change", function () {
|
||||||
const file = this.files[0];
|
previewList.innerHTML = "";
|
||||||
if (!file) return;
|
|
||||||
|
Array.from(this.files).forEach(file => {
|
||||||
|
if (!file.type.startsWith("image/")) return;
|
||||||
|
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = function () {
|
reader.onload = function () {
|
||||||
preview.src = reader.result;
|
const img = document.createElement("img");
|
||||||
preview.style.display = "block";
|
img.src = reader.result;
|
||||||
|
img.style.width = "90px";
|
||||||
|
img.style.height = "70px";
|
||||||
|
img.style.objectFit = "cover";
|
||||||
|
img.style.border = "1px solid #ccc";
|
||||||
|
img.style.borderRadius = "6px";
|
||||||
|
previewList.appendChild(img);
|
||||||
};
|
};
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -455,7 +455,7 @@ if ($actionStr == "DELETENOTE" && $mode == "delete") {
|
||||||
// ADD IMAGE (Customer Detail - Image Upload)
|
// ADD IMAGE (Customer Detail - Image Upload)
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
if ($actionStr == "ADDIMAGE") {
|
if ($actionStr == "ADDIMAGE") {
|
||||||
$singleTypes = ['install', 'container', 'install_order'];
|
$singleTypes = ['install', 'install_order', 'clean_before', 'clean_after'];
|
||||||
|
|
||||||
$i_note = isset($_POST['i_note']) ? trim($_POST['i_note']) : "";
|
$i_note = isset($_POST['i_note']) ? trim($_POST['i_note']) : "";
|
||||||
$i_createddate = date("YmdHis");
|
$i_createddate = date("YmdHis");
|
||||||
|
|
@ -478,37 +478,6 @@ if ($actionStr == "ADDIMAGE") {
|
||||||
$jdb->nQuery($qry_update, "update error");
|
$jdb->nQuery($qry_update, "update error");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 이미지 최대 6개 제한 체크
|
|
||||||
if ($i_type == "container") {
|
|
||||||
// 기존 이미지 수 조회
|
|
||||||
$qry_cnt = "
|
|
||||||
SELECT i_filename
|
|
||||||
FROM tbl_customer_image
|
|
||||||
WHERE i_customeruid = '$i_customeruid'
|
|
||||||
AND i_type = 'container'
|
|
||||||
AND i_status = 'A'
|
|
||||||
ORDER BY i_uid DESC LIMIT 1
|
|
||||||
";
|
|
||||||
$rt_cnt = $jdb->fQuery($qry_cnt, "error");
|
|
||||||
|
|
||||||
$existingCount = 0;
|
|
||||||
if (!empty($rt_cnt['i_filename'])) {
|
|
||||||
$existingFiles = explode(",", $rt_cnt['i_filename']);
|
|
||||||
$existingCount = count($existingFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 이번에 업로드할 파일 개수
|
|
||||||
$newCount = is_array($_FILES['upload_file']['name'])
|
|
||||||
? count($_FILES['upload_file']['name'])
|
|
||||||
: 1;
|
|
||||||
|
|
||||||
if ($existingCount + $newCount > 6) {
|
|
||||||
$msg = "Container 이미지는 최대 6개까지 업로드할 수 있습니다.";
|
|
||||||
$func->modalMsg($msg, "/index_intranet.php?view=customer_detail&mode=update&c_uid=$i_customeruid&$goStr");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 업로드 파일 체크
|
// 업로드 파일 체크
|
||||||
if (!isset($_FILES['upload_file'])) {
|
if (!isset($_FILES['upload_file'])) {
|
||||||
$msg = "Upload failed. Please try again.";
|
$msg = "Upload failed. Please try again.";
|
||||||
|
|
@ -592,7 +561,7 @@ if ($actionStr == "ADDIMAGE") {
|
||||||
$values = array(
|
$values = array(
|
||||||
$i_customeruid,
|
$i_customeruid,
|
||||||
$i_memberuid,
|
$i_memberuid,
|
||||||
$i_memberuid,
|
$i_createdby,
|
||||||
$i_createddate,
|
$i_createddate,
|
||||||
$i_type,
|
$i_type,
|
||||||
$fileNameString,
|
$fileNameString,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue