menuModel = new MenuModel(); } public function lists(): string { return view("pages/manage/menu/lists"); } // 메뉴목록조회 public function getMenuList() { $params = []; $total = $this->menuModel->getTotalCount(); $datas = $this->menuModel->getMenuList($params); $lft = 1; if (!empty($datas)) { foreach ($datas as $k => $v) { $menuTp = $v['mnu_tp']; $menuCd = $v['mnu_id']; $menuPid = $v['mnu_pid']; // lft $datas[$k]['lft'] = $lft; // ROOT vs 나머지 level 계산 (지금처럼 코드 길이 쓰고 싶으면 기존 로직 유지 가능) if ($menuPid === 'ROOT') { $datas[$k]['level'] = "0"; $datas[$k]['parentLv'] = ""; $datas[$k]['expanded'] = true; } else { // 예: "M" 제거 후 길이 기반 $levelStr = str_replace('M', '', $menuCd); $len = strlen($levelStr); if ($len === 1 || $len === 2) $datas[$k]['level'] = "1"; else $datas[$k]['level'] = "2"; // 필요시 더 세분화 } // 아이콘 switch ($menuTp) { case "A": $datas[$k]['iconCls'] = "ui-icon-play"; break; case "P": $datas[$k]['iconCls'] = "ui-icon-document"; break; case "D": $datas[$k]['iconCls'] = "ui-icon-folder-open"; break; } if ($menuTp === 'A') { // 액션 $datas[$k]['isLeaf'] = true; $datas[$k]['rgt'] = $lft + 1; $lft++; } elseif ($menuTp === 'P') { // 화면: 내 자식은 mnu_pid == 내 mnu_id $subCnt = 0; foreach ($datas as $v2) { if ($v2['mnu_pid'] === $menuCd) { $subCnt++; } } $datas[$k]['rgt'] = $lft + ($subCnt * 2) + 1; if ($subCnt === 0) { $datas[$k]['isLeaf'] = true; $lft++; } else { $datas[$k]['isLeaf'] = false; } } elseif ($menuTp === 'D') { // 디렉토리: 코드 prefix 로 자식/후손 판단 (자바와 동일) $subCnt = 0; foreach ($datas as $v2) { $subMenuCd = $v2['mnu_id']; if (strpos($subMenuCd, $menuCd) === 0) { $subCnt++; } } $datas[$k]['rgt'] = $lft + ($subCnt * 2) + 1; if ($subCnt === 0) { $datas[$k]['isLeaf'] = true; $lft++; } else { $datas[$k]['isLeaf'] = false; } } elseif ($menuTp === 'R') { // 루트 $datas[$k]['isLeaf'] = false; $datas[$k]['rgt'] = 1 + ($total * 2) + 1; } $lft++; } } // $datas = $this->buildTree($datas); return $this->response->setJSON(body: [ 'total' => $total, 'rows' => $datas, ]); } // private function buildTree(array $items, $parentId = 'ROOT', int $level = 0): array // { // $branch = []; // $lft = 1; // foreach ($items as $k => $item) { // // 현재 parentId의 자식인지 확인 // if ($item['mnu_pid'] === $parentId) { // $item['lft'] = $lft; // if ($item['mnu_tp'] === 'R') { // $item['isLeaf'] = false; // $item['rgt'] = 1 + (63 * 2 + 1); // } else if ($item['mnu_tp'] === 'D') { // $item['level'] = 1; // $item['menu_tp'] = 'D'; // $item['menu_tp_nm'] = '디렉토리'; // $item['iconCls'] = 'ui-icon-folder-open'; // $subCnt = 0; // foreach ($items as $item2): // if (strpos($item2['mnu_id'], $item['mnu_id'] . '.') === 0) { // $subCnt++; // } // endforeach; // $item['rgt'] = $lft + ($subCnt * 2) + 1; // if ($subCnt === 0) { // $item['isLeaf'] = true; // } else { // $item['isLeaf'] = false; // } // } else if ($item['mnu_tp'] == 'P') { // $item['level'] = 2; // $item['menu_tp'] = 'R'; // $item['menu_tp_nm'] = '화면'; // $item['iconCls'] = 'ui-icon-document'; // } // // else { // // // 예: 루트 R 같은 경우 // // $item['menu_tp'] = $item['mnu_tp']; // // $item['menu_tp_nm'] = ($item['mnu_tp'] === 'R') ? '루트' : '메뉴'; // // $item['iconCls'] = 'ui-icon-home'; // // } // // 자식 찾기 (⚠️ 여기 반드시 $this->buildTree) // // $children = $this->buildTree($items, $item['mnu_id'], $level + 1); // // if (!empty($children)) { // // // 자식 정렬 (view_odr → mnu_id 순) // // usort($children, function ($a, $b) { // // $ao = $a['view_odr'] ?? 0; // // $bo = $b['view_odr'] ?? 0; // // if ($ao == $bo) { // // return strcmp($a['mnu_id'], $b['mnu_id']); // // } // // return $ao <=> $bo; // // }); // // $item['children'] = $children; // // } // $branch[] = $item; // } // $lft++; // } // // 현재 레벨도 정렬 (view_odr → mnu_id 순) // usort($branch, function ($a, $b) { // $ao = $a['view_odr'] ?? 0; // $bo = $b['view_odr'] ?? 0; // if ($ao == $bo) { // return strcmp($a['mnu_id'], $b['mnu_id']); // } // return $ao <=> $bo; // }); // return $branch; // } }