초기 커밋: 5130 레거시 시스템

- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경
- DB 연결 하드코딩 → .env 기반으로 변경
- MySQL strict mode DATE 오류 수정
This commit is contained in:
2025-12-10 20:14:31 +09:00
commit aca1767eb9
6728 changed files with 1863265 additions and 0 deletions

143
modelsTree/copyCategory.php Normal file
View File

@@ -0,0 +1,143 @@
<?php
header('Content-Type: application/json; charset=utf-8');
require_once($_SERVER['DOCUMENT_ROOT'].'/session.php');
require_once($_SERVER['DOCUMENT_ROOT'].'/lib/mydb.php');
$pdo = db_connect();
// GET 파라미터 level, id
$level = isset($_GET['level']) ? intval($_GET['level']) : 0;
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
// 여기선 level=1 만 처리한다고 가정
if($level !== 1) {
echo json_encode(["result"=>"error","msg"=>"Only level=1 copy is implemented"]);
exit;
}
// 트랜잭션 시작 (복사 도중 에러나면 rollback)
$pdo->beginTransaction();
try {
// 1) 원본 L1 가져오기
$sql = "SELECT * FROM {$DB}.category_l1 WHERE id = :id";
$st = $pdo->prepare($sql);
$st->bindValue(':id', $id, PDO::PARAM_INT);
$st->execute();
$row_l1 = $st->fetch(PDO::FETCH_ASSOC);
if(!$row_l1) {
throw new Exception("원본 L1이 존재하지 않습니다.");
}
// 2) 새 L1 생성
// 예: 이름에 (복사) 접미사 추가
$newName = $row_l1['name'] . " (복사)";
$sql = "INSERT INTO {$DB}.category_l1 (name, sortOrder)
VALUES (:name, :sortOrder)";
$st = $pdo->prepare($sql);
$st->bindValue(':name', $newName);
$st->bindValue(':sortOrder', $row_l1['sortOrder'] ?? 0);
$st->execute();
$new_l1_id = $pdo->lastInsertId(); // 새 L1의 ID
// 3) 원본 L2 목록 가져오기
$sql = "SELECT * FROM {$DB}.category_l2 WHERE parent_id = :pid";
$st = $pdo->prepare($sql);
$st->bindValue(':pid', $id, PDO::PARAM_INT);
$st->execute();
$rows_l2 = $st->fetchAll(PDO::FETCH_ASSOC);
// "구(old)->신(new)" ID 매핑 테이블
$l2_map_id = [];
// 4) L2들 복사
foreach($rows_l2 as $l2){
// 새 L2 Insert
$sql = "INSERT INTO {$DB}.category_l2 (name, parent_id, sortOrder)
VALUES (:name, :p, :so)";
$st2 = $pdo->prepare($sql);
// 이름에 (복사) 붙일지 여부 => 선택
$copyName = $l2['name'] ;
$st2->bindValue(':name', $copyName);
$st2->bindValue(':p', $new_l1_id, PDO::PARAM_INT);
$st2->bindValue(':so', $l2['sortOrder'] ?? 0, PDO::PARAM_INT);
$st2->execute();
$new_l2_id = $pdo->lastInsertId();
// 구 -> 신 매핑
$old_l2_id = $l2['id'];
$l2_map_id[$old_l2_id] = $new_l2_id;
}
// 5) 원본 L3 전부 가져오기 (조건: parent_id in (원본 l2 ids))
// 혹은 l2를 돌면서 l3를 가져와도 됨
if(!empty($l2_map_id)){
$old_l2_ids_str = implode(',', array_map('intval', array_keys($l2_map_id)));
$sql = "SELECT * FROM {$DB}.category_l3
WHERE parent_id IN ($old_l2_ids_str)";
$st = $pdo->prepare($sql);
$st->execute();
$rows_l3 = $st->fetchAll(PDO::FETCH_ASSOC);
} else {
$rows_l3 = [];
}
$l3_map_id = [];
// 6) L3 복사
foreach($rows_l3 as $l3){
$old_parent = $l3['parent_id']; // 원본 l2 id
if(!isset($l2_map_id[$old_parent])) continue; // 무효
$new_parent = $l2_map_id[$old_parent]; // 새로 생성된 l2 id
$copyName = $l3['name'] ;
$sql = "INSERT INTO {$DB}.category_l3 (name, parent_id, sortOrder)
VALUES (:name, :p, :so)";
$st3 = $pdo->prepare($sql);
$st3->bindValue(':name', $copyName);
$st3->bindValue(':p', $new_parent, PDO::PARAM_INT);
$st3->bindValue(':so', $l3['sortOrder'] ?? 0, PDO::PARAM_INT);
$st3->execute();
$new_l3_id = $pdo->lastInsertId();
$old_l3_id = $l3['id'];
$l3_map_id[$old_l3_id] = $new_l3_id;
}
// 7) 원본 L4
$l4_map_id = [];
if(!empty($l3_map_id)){
$old_l3_ids_str = implode(',', array_map('intval', array_keys($l3_map_id)));
$sql = "SELECT * FROM {$DB}.category_l4
WHERE parent_id IN ($old_l3_ids_str)";
$st = $pdo->prepare($sql);
$st->execute();
$rows_l4 = $st->fetchAll(PDO::FETCH_ASSOC);
} else {
$rows_l4 = [];
}
// 8) L4 복사
foreach($rows_l4 as $l4){
$old_parent = $l4['parent_id'];
if(!isset($l3_map_id[$old_parent])) continue;
$new_parent = $l3_map_id[$old_parent];
$copyName = $l4['name'] ;
$sql = "INSERT INTO {$DB}.category_l4 (name, parent_id, sortOrder)
VALUES (:name, :p, :so)";
$st4 = $pdo->prepare($sql);
$st4->bindValue(':name', $copyName);
$st4->bindValue(':p', $new_parent, PDO::PARAM_INT);
$st4->bindValue(':so', $l4['sortOrder'] ?? 0, PDO::PARAM_INT);
$st4->execute();
$new_l4_id = $pdo->lastInsertId();
$old_l4_id = $l4['id'];
$l4_map_id[$old_l4_id] = $new_l4_id;
}
$pdo->commit(); // 전체 복사 성공
echo json_encode(["result"=>"ok"]);
} catch(Exception $e){
$pdo->rollBack();
echo json_encode(["result"=>"error","msg"=>$e->getMessage()]);
}

View File

@@ -0,0 +1,46 @@
<?php
header('Content-Type: application/json; charset=utf-8');
require_once($_SERVER['DOCUMENT_ROOT'].'/session.php');
require_once($_SERVER['DOCUMENT_ROOT'].'/lib/mydb.php');
$pdo = db_connect();
// GET 파라미터
$level = isset($_GET['level']) ? intval($_GET['level']) : 0;
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
try {
// 유효성 검사
if ($level < 1 || $level > 4) {
throw new Exception("invalid level");
}
if ($id < 1) {
throw new Exception("invalid id");
}
// level에 따라 삭제할 테이블 결정
switch($level){
case 1:
// L1 삭제 → 외래키 CASCADE로 L2/L3/L4도 함께 삭제됨
$sql="DELETE FROM {$DB}.category_l1 WHERE id=:id";
break;
case 2:
$sql="DELETE FROM {$DB}.category_l2 WHERE id=:id";
break;
case 3:
$sql="DELETE FROM {$DB}.category_l3 WHERE id=:id";
break;
case 4:
$sql="DELETE FROM {$DB}.category_l4 WHERE id=:id";
break;
}
$st = $pdo->prepare($sql);
$st->bindValue(':id', $id, PDO::PARAM_INT);
$st->execute();
// 성공 응답
echo json_encode(["result" => "ok"]);
} catch(Exception $e) {
// 오류 응답
echo json_encode(["result" => "error", "msg" => $e->getMessage()]);
}

448
modelsTree/modelsTree.php Normal file
View File

@@ -0,0 +1,448 @@
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/session.php');
require_once($_SERVER['DOCUMENT_ROOT'].'/lib/mydb.php');
$pdo = db_connect();
$title_message = '경동기업 4단계 BOM 구성';
// 1) DB에서 1~4레벨 카테고리 전부 SELECT
$l1_data = $pdo->query("SELECT * FROM {$DB}.category_l1 ORDER BY sortOrder, id")->fetchAll(PDO::FETCH_ASSOC);
$l2_data = $pdo->query("SELECT * FROM {$DB}.category_l2 ORDER BY sortOrder, id")->fetchAll(PDO::FETCH_ASSOC);
$l3_data = $pdo->query("SELECT * FROM {$DB}.category_l3 ORDER BY sortOrder, id")->fetchAll(PDO::FETCH_ASSOC);
$l4_data = $pdo->query("SELECT * FROM {$DB}.category_l4 ORDER BY sortOrder, id")->fetchAll(PDO::FETCH_ASSOC);
// 2) PHP에서 parent_id별로 배열화
$l2_map = [];
foreach($l2_data as $row2){
$l2_map[$row2['parent_id']][] = $row2;
}
$l3_map = [];
foreach($l3_data as $row3){
$l3_map[$row3['parent_id']][] = $row3;
}
$l4_map = [];
foreach($l4_data as $row4){
$l4_map[$row4['parent_id']][] = $row4;
}
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php'; // common.php 포함되어 있음
?>
<title><?=$title_message?></title>
<style>
.tree-node {
margin-left: 1.25rem; /* Bootstrap의 1rem = 16px -> 약 20px */
}
.toggle-btn {
cursor: pointer;
color: #0d6efd; /* 부트스트랩 primary 색상 */
margin-right: 0.25rem;
}
.d-none {
display: none !important;
}
</style>
</head>
<body>
<div class="container mt-4">
<div class="card justify-content-center text-center mt-3 mb-2">
<div class="card-body">
<div class="d-flex justify-content-center align-items-center mb-2">
<h4 class="mx-1"><?=$title_message?></h4>
<button type="button" class="btn btn-dark btn-sm mx-3" onclick='location.reload();' > <i class="bi bi-arrow-clockwise"></i> </button>
<button type="button" class="btn btn-success btn-sm mx-1" onclick="addCategory(1,0)"> <i class="bi bi-plus-square"></i> 최상위 추가 </button>
<button type="button" class="btn btn-primary btn-sm mx-1" onclick="expandAllTree();"> <i class="bi bi-plus-square"></i> 전체 펼치기 </button>
<button type="button" class="btn btn-secondary btn-sm mx-1" onclick="foldAllTree();"> <i class="bi bi-plus-square"></i> 전체 접기 </button>
<button type="button" class="btn btn-dark btn-sm mx-5" onclick="self.close();"> &times; 닫기 </button>
</div>
</div>
</div>
<!-- 레벨1 목록 -->
<?php foreach($l1_data as $l1): ?>
<div class="tree-node mb-2">
<!-- 펼치기/접기 아이콘 -->
<span class="toggle-btn" data-target="l1-<?= $l1['id'] ?>" >
<i class="bi bi-caret-right-fill"></i>
</span>
<strong><?= htmlspecialchars($l1['name']) ?></strong>
<!-- 수정/삭제/하위추가 버튼들 -->
<!-- 1단계 항목의 복사 버튼 (아이콘: bi-files) -->
<button class="btn btn-sm btn-outline-secondary ms-1 mb-1" style="padding:2"
onclick="copyCategory(1, <?= $l1['id'] ?>)">
<i class="bi bi-files"></i>
</button>
<button class="btn btn-sm btn-outline-info ms-2 mb-1" style="padding : 2"
onclick="editCategory(1, <?= $l1['id'] ?> , '<?= $l1['name'] ?>')">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-sm btn-outline-danger ms-1 mb-1" style="padding : 2"
onclick="deleteCategory(1, <?= $l1['id'] ?>)">
<i class="bi bi-trash3"></i>
</button>
<button class="btn btn-sm btn-outline-primary ms-1 mb-1" style="padding : 2"
onclick="addCategory(2, <?= $l1['id'] ?>)">
<i class="bi bi-plus-square"></i>
</button>
<!-- L2 목록 -->
<div id="l1-<?= $l1['id'] ?>" class="d-none">
<?php if(isset($l2_map[$l1['id']])):
foreach($l2_map[$l1['id']] as $l2):
$l2_id = $l2['id'];
?>
<div class="tree-node mb-2">
&nbsp;&nbsp;&nbsp;
<span class="toggle-btn" data-target="l2-<?= $l2_id ?>">
<i class="bi bi-caret-right-fill"></i>
</span>
<?= htmlspecialchars($l2['name']) ?>
<button class="btn btn-sm btn-outline-info ms-2 mb-1" style="padding : 2"
onclick="editCategory(2, <?= $l2_id ?>, '<?= $l2['name'] ?>')">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-sm btn-outline-danger ms-1 mb-1" style="padding : 2"
onclick="deleteCategory(2, <?= $l2_id ?>)">
<i class="bi bi-trash3"></i>
</button>
<button class="btn btn-sm btn-outline-primary ms-1 mb-1" style="padding : 2"
onclick="addCategory(3, <?= $l2_id ?>)">
<i class="bi bi-plus-square"></i>
</button>
<!-- L3 목록 -->
<div id="l2-<?= $l2_id ?>" class="d-none">
<?php if(isset($l3_map[$l2_id])):
foreach($l3_map[$l2_id] as $l3):
$l3_id = $l3['id'];
?>
<div class="tree-node mb-2">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span class="toggle-btn" data-target="l3-<?= $l3_id ?>">
<i class="bi bi-caret-right-fill"></i>
</span>
<?= htmlspecialchars($l3['name']) ?>
<button class="btn btn-sm btn-outline-info ms-2 mb-1" style="padding : 2"
onclick="editCategory(3, <?= $l3_id ?>, '<?= $l3['name'] ?>')">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-sm btn-outline-danger ms-1 mb-1" style="padding : 2"
onclick="deleteCategory(3, <?= $l3_id ?>)">
<i class="bi bi-trash3"></i>
</button>
<button class="btn btn-sm btn-outline-primary ms-1 mb-1" style="padding : 2"
onclick="addCategory(4, <?= $l3_id ?>)">
<i class="bi bi-plus-square"></i>
</button>
<!-- L4 목록 -->
<div id="l3-<?= $l3_id ?>" class="d-none">
<?php if(isset($l4_map[$l3_id])):
foreach($l4_map[$l3_id] as $l4):
$l4_id = $l4['id'];
?>
<div class="tree-node mb-2">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<?= htmlspecialchars($l4['name']) ?>
<button class="btn btn-sm btn-outline-info ms-2 mb-1" style="padding : 2"
onclick="editCategory(4, <?= $l4_id ?>, '<?= $l4['name'] ?>')">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-sm btn-outline-danger ms-1 mb-1" style="padding : 2"
onclick="deleteCategory(4, <?= $l4_id ?>)">
<i class="bi bi-trash3"></i>
</button>
</div>
<?php endforeach; endif; ?>
</div>
<!-- end L4 -->
</div>
<?php endforeach; endif; ?>
</div>
<!-- end L3 -->
</div>
<?php endforeach; endif; ?>
</div>
<!-- end L2 -->
</div>
<?php endforeach; ?>
</div>
<!-- Bootstrap Modal -->
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="editModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editModalLabel">카테고리 수정/추가</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="닫기"></button>
</div>
<div class="modal-body">
<input type="hidden" id="catLevel" value="">
<input type="hidden" id="catId" value="">
<input type="hidden" id="catParent" name="catParent" value="">
<div class="mb-3">
<label for="catName" class="form-label">이름</label>
<input type="text" class="form-control" id="catName" name="catName" placeholder="카테고리명" autocomplete="off">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary mx-1" onclick="saveCategory()">저장</button>
<button type="button" class="btn btn-secondary mx-1" data-bs-dismiss="modal">취소</button>
</div>
</div>
</div>
</div>
<!-- 로딩 오버레이 숨김 + 트리 토글 + SweetAlert2 알림 -->
<script>
$(document).ready(function(){
// 로딩 hide
var loader = document.getElementById('loadingOverlay');
if(loader) loader.style.display = 'none';
// // 트리 토글 (부트스트랩 아이콘 caret 교체)
// document.querySelectorAll('.toggle-btn').forEach(btn => {
// btn.addEventListener('click', () => {
// const targetId = btn.getAttribute('data-target');
// const sub = document.getElementById(targetId);
// if(sub) {
// if(sub.classList.contains('d-none')){
// sub.classList.remove('d-none');
// btn.innerHTML = '<i class="bi bi-caret-down-fill"></i>';
// } else {
// sub.classList.add('d-none');
// btn.innerHTML = '<i class="bi bi-caret-right-fill"></i>';
// }
// }
// });
// });
// // [추가 요구사항] 초기에 전체 트리를 펼치기
// expandAllTree();
});
// 트리를 전부 접는 함수
function foldAllTree(){
// 모든 .d-none 제거하고, 아이콘을 caret-down-fill 로 변경
document.querySelectorAll('[id^="l1-"], [id^="l2-"], [id^="l3-"]').forEach(subDiv => {
subDiv.classList.add('d-none');
});
// toggle-btn 아이콘도 다 down으로
document.querySelectorAll('.toggle-btn').forEach(btn => {
btn.innerHTML = '<i class="bi bi-caret-right-fill"></i>';
});
}
// 트리를 전부 펼치는 함수
function expandAllTree(){
// 모든 .d-none 제거하고, 아이콘을 caret-down-fill 로 변경
document.querySelectorAll('[id^="l1-"], [id^="l2-"], [id^="l3-"]').forEach(subDiv => {
subDiv.classList.remove('d-none');
});
// toggle-btn 아이콘도 다 down으로
document.querySelectorAll('.toggle-btn').forEach(btn => {
btn.innerHTML = '<i class="bi bi-caret-down-fill"></i>';
});
}
// 추가
function addCategory(level, parentId){
document.getElementById('catLevel').value = level;
document.getElementById('catId').value = 0; // insert
document.getElementById('catParent').value = parentId;
document.getElementById('catName').value = '';
const myModal = new bootstrap.Modal(document.getElementById('editModal'));
myModal.show();
}
// 수정
function editCategory(level, id, name){
document.getElementById('catLevel').value = level;
document.getElementById('catId').value = id;
document.getElementById('catName').value = name ;
const myModal = new bootstrap.Modal(document.getElementById('editModal'));
myModal.show();
}
// 삭제
function deleteCategory(level, id){
Swal.fire({
title: '삭제 확인',
text: '정말 삭제하시겠습니까?',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: '삭제',
cancelButtonText: '취소'
}).then((result) => {
if (result.isConfirmed) {
fetch(`deleteCategory.php?level=${level}&id=${id}`)
.then(res=>res.json())
.then(data=>{
if(data.result==='ok'){
Swal.fire({
icon: 'success',
title: '삭제완료',
text: '카테고리가 삭제되었습니다.'
}).then(()=> location.reload());
} else {
Swal.fire({
icon: 'error',
title: '삭제실패',
text: data.msg
});
}
});
}
});
}
// 저장
function saveCategory(){
const level = document.getElementById('catLevel').value;
const id = document.getElementById('catId').value;
const parentId = document.getElementById('catParent').value;
const name = document.getElementById('catName').value.trim();
if(name === ''){
Swal.fire({
icon: 'warning',
title: '입력확인',
text: '이름을 입력하세요.'
});
return;
}
fetch('saveCategory.php',{
method:'POST',
headers:{ 'Content-Type':'application/json' },
body: JSON.stringify({ level, id, parentId, name })
})
.then(r=>r.json())
.then(d=>{
if(d.result==='ok'){
Swal.fire({
icon: 'success',
title: '저장완료',
text: '카테고리 등록/수정되었습니다.'
}).then(()=> location.reload());
} else {
Swal.fire({
icon: 'error',
title: '오류',
text: d.msg
});
}
});
}
// 복사 카테고리
function copyCategory(level, id) {
Swal.fire({
title: '복사 확인',
text: '해당 1단계와 그 하위 항목 전체를 복사하시겠습니까?',
icon: 'question',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: '복사',
cancelButtonText: '취소'
}).then((result) => {
if (result.isConfirmed) {
fetch(`copyCategory.php?level=${level}&id=${id}`)
.then(res => res.json())
.then(data => {
if(data.result==='ok'){
Swal.fire({
icon: 'success',
title: '복사완료',
text: '하위 단계까지 복사되었습니다.'
}).then(()=> location.reload());
} else {
Swal.fire({
icon: 'error',
title: '복사실패',
text: data.msg
});
}
});
}
});
}
</script>
<script>
// [기존] 트리 토글 (부트스트랩 아이콘 caret 교체) + 쿠키 업데이트 기능 추가
function updateTreeStateCookie(){
let expandedNodes = [];
// 모든 토글 버튼을 순회하면서 대상 요소가 보이면 배열에 추가
document.querySelectorAll('.toggle-btn').forEach(btn => {
const targetId = btn.getAttribute('data-target');
const sub = document.getElementById(targetId);
if(sub && !sub.classList.contains('d-none')){
expandedNodes.push(targetId);
}
});
// 쿠키에 저장 (유효시간 10분)
setCookie("treeState", JSON.stringify(expandedNodes), 10);
}
document.querySelectorAll('.toggle-btn').forEach(btn => {
btn.addEventListener('click', () => {
const targetId = btn.getAttribute('data-target');
const sub = document.getElementById(targetId);
if(sub) {
if(sub.classList.contains('d-none')){
sub.classList.remove('d-none');
btn.innerHTML = '<i class="bi bi-caret-down-fill"></i>';
} else {
sub.classList.add('d-none');
btn.innerHTML = '<i class="bi bi-caret-right-fill"></i>';
}
// 토글 동작 후 현재 트리 상태를 쿠키에 저장
updateTreeStateCookie();
}
});
});
// 쿠키에서 트리 상태 복원 함수
function restoreTreeStateFromCookie(){
let cookieVal = getCookie("treeState");
if(cookieVal){
try{
let expandedNodes = JSON.parse(cookieVal);
expandedNodes.forEach(targetId => {
let sub = document.getElementById(targetId);
if(sub && sub.classList.contains('d-none')){
sub.classList.remove('d-none');
// 해당 토글 버튼의 아이콘도 down으로 변경
document.querySelectorAll(`.toggle-btn[data-target="${targetId}"]`).forEach(btn => {
btn.innerHTML = '<i class="bi bi-caret-down-fill"></i>';
});
}
});
} catch(e){
console.error("Error parsing treeState cookie", e);
}
}
}
// 페이지 로드시 트리 상태 복원
document.addEventListener("DOMContentLoaded", function(){
restoreTreeStateFromCookie();
});
</script>
</body>
</html>

103
modelsTree/saveCategory.php Normal file
View File

@@ -0,0 +1,103 @@
<?php
header('Content-Type: application/json; charset=utf-8');
require_once($_SERVER['DOCUMENT_ROOT'].'/session.php');
require_once($_SERVER['DOCUMENT_ROOT'].'/lib/mydb.php');
$pdo = db_connect();
// JS에서 POST된 JSON 파싱
$data = json_decode(file_get_contents('php://input'), true);
$level = intval($data['level'] ?? 0);
$id = intval($data['id'] ?? 0); // 0이면 Insert, >0이면 Update
$parentId = intval($data['parentId'] ?? 0); // 상위 id (Insert 시 사용)
$name = trim($data['name'] ?? '');
// 예외 처리
if ($level < 1 || $level > 4) {
echo json_encode(["result"=>"error","msg"=>"invalid level"]);
exit;
}
if ($name === '') {
echo json_encode(["result"=>"error","msg"=>"name is empty"]);
exit;
}
try {
switch($level) {
case 1: // category_l1
if($id === 0) {
// INSERT
$sql = "INSERT INTO {$DB}.category_l1 (name) VALUES (:name)";
$st = $pdo->prepare($sql);
$st->bindValue(':name', $name);
$st->execute();
} else {
// UPDATE
$sql = "UPDATE {$DB}.category_l1 SET name=:name WHERE id=:id";
$st = $pdo->prepare($sql);
$st->bindValue(':name', $name);
$st->bindValue(':id', $id, PDO::PARAM_INT);
$st->execute();
}
break;
case 2: // category_l2
if($id === 0) {
// 새로 추가 → parentId가 category_l1의 id
$sql = "INSERT INTO {$DB}.category_l2 (name, parent_id) VALUES (:name, :p)";
$st = $pdo->prepare($sql);
$st->bindValue(':name', $name);
$st->bindValue(':p', $parentId, PDO::PARAM_INT);
$st->execute();
} else {
// 수정
$sql = "UPDATE {$DB}.category_l2 SET name=:name WHERE id=:id";
$st = $pdo->prepare($sql);
$st->bindValue(':name', $name);
$st->bindValue(':id', $id, PDO::PARAM_INT);
$st->execute();
}
break;
case 3: // category_l3
if($id === 0) {
// parentId는 category_l2의 id
$sql = "INSERT INTO {$DB}.category_l3 (name, parent_id) VALUES (:name, :p)";
$st = $pdo->prepare($sql);
$st->bindValue(':name', $name);
$st->bindValue(':p', $parentId, PDO::PARAM_INT);
$st->execute();
} else {
$sql = "UPDATE {$DB}.category_l3 SET name=:name WHERE id=:id";
$st = $pdo->prepare($sql);
$st->bindValue(':name', $name);
$st->bindValue(':id', $id, PDO::PARAM_INT);
$st->execute();
}
break;
case 4: // category_l4
if($id === 0) {
// parentId는 category_l3의 id
$sql = "INSERT INTO {$DB}.category_l4 (name, parent_id) VALUES (:name, :p)";
$st = $pdo->prepare($sql);
$st->bindValue(':name', $name);
$st->bindValue(':p', $parentId, PDO::PARAM_INT);
$st->execute();
} else {
$sql = "UPDATE {$DB}.category_l4 SET name=:name WHERE id=:id";
$st = $pdo->prepare($sql);
$st->bindValue(':name', $name);
$st->bindValue(':id', $id, PDO::PARAM_INT);
$st->execute();
}
break;
}
echo json_encode(["result" => "ok"]);
} catch (Exception $e) {
echo json_encode([
"result" => "error",
"msg" => $e->getMessage()
]);
}