개발 & 데이터베이스/JAVA

Toast grid 트리 구조 만드는 방법

K.두부 2025. 3. 31. 14:21
반응형

 

Toast grid로 트리 구조 형태 그리드 생성하는 방법

편의상 Controller, Mapper, XML(Query) 는 생략한다.

 

해당 그리드에서는 트리 구조를 만들기 위해서 _children 필드와 _leaf 필드가 필요하다.

 

  • _children 필드: 하위 노드 정보 저장
  • _leaf 필드: 최하위 노드 여부
  • _inlcude 필드: 해당 노드를 최종 노드에 포함 여부

 

 

트리 구조 조건은 아래와 같다.

 

  1. 같은 회사 (org_co_cd) 내에서 정렬 
  2. 부모(supi_org_co_cd) - 자식 (itg_org_cd) 가 같은 것들끼리 정렬
  3. 해당 부서에 권한 인원 (auth_cnt)가 1 이상인 것들만 표시 (상위 노드 포함)
  4. 자식 노드가 없는 노드들은 뒤로 배치

 

public class TempSerivce extends {
private final TempMapper Mapper;
public ResponseEntity<?> selectTreeList(Map<String, Object> data) {
try {
List<Map<String, Object>> result = Mapper.selectTreeList(data);
List<Map<String, Object>> tree = convertToTreeData(result);
return responseEntityUtil
.getResponseEntity(CodeCoreResultList.RESULT_CODE_SUCCESS, getMessage(""), tree);
} catch (Exception e) {
return this.responseEntityUtil
.getResponseEntity(CodeCoreResultList.RESULT_CODE_FAILED, getMessage(""));
}
}
private List<Map<String, Object>> convertToTreeData(List<Map<String, Object>> result) {
List<Map<String, Object>> tree = new ArrayList<>();
Map<String, Map<String, Object>> nodeMap = new HashMap<>();
Set<String> includeNodes = new HashSet<>(); // 포함할 조직 저장
// 1️⃣ 모든 노드를 Map에 저장하고 초기값 설정
for (Map<String, Object> row : result) {
row.put("_children", new ArrayList<Map<String, Object>>());
row.put("_leaf", true);
row.put("_include", false); // 기본적으로 표시하지 않음
nodeMap.put((String) row.get("itg_org_cd"), row);
}
// 2️⃣ 부모-자식 관계 설정 (같은 회사 내에서만)
for (Map<String, Object> row : result) {
String parentCode = (String) row.get("supi_itg_org_cd");
String orgCoCd = (String) row.get("org_co_cd");
if (parentCode != null && nodeMap.containsKey(parentCode) && orgCoCd.equals(nodeMap.get(parentCode).get("org_co_cd"))) {
((List<Map<String, Object>>) nodeMap.get(parentCode).get("_children")).add(row);
nodeMap.get(parentCode).put("_leaf", false); // 부모는 leaf가 아님
}
}
// 3️⃣ auth_cnt가 1 이상인 노드와 부모를 포함 (같은 회사 내에서만)
for (Map<String, Object> row : result) {
String orgCode = (String) row.get("itg_org_cd");
String parentCode = (String) row.get("supi_itg_org_cd");
Integer authCnt = getAuthCount(row.get("auth_cnt"));
if (authCnt >= 1) {
row.put("_include", true);
includeNodes.add(orgCode);
// 최상위 노드도 auth_cnt >= 1이면 포함
if (parentCode == null || !nodeMap.containsKey(parentCode)) {
tree.add(row); // 바로 트리에 추가
continue; // 부모 탐색 생략
}
// 부모 노드들도 `_include = true` 설정
while (parentCode != null && nodeMap.containsKey(parentCode)) {
Map<String, Object> parentNode = nodeMap.get(parentCode);
if (includeNodes.contains(parentCode)) break; // 이미 추가된 경우 중단
parentNode.put("_include", true);
includeNodes.add(parentCode);
parentCode = (String) parentNode.get("supi_itg_org_cd"); // 상위 부모로 이동
}
}
}
// 4️⃣ `_include = true`인 노드만 트리에 추가
for (String key : includeNodes) {
Map<String, Object> node = nodeMap.get(key);
if (node != null && Boolean.TRUE.equals(node.get("_include"))) {
String parentCode = (String) node.get("supi_itg_org_cd");
if (parentCode == null || !includeNodes.contains(parentCode)) {
tree.add(node);
}
}
}
// 5️⃣ `_children` 리스트에서도 `_include = false`인 노드 제거
removeExcludedChildren(tree);
// 6️⃣ 트리 데이터 정렬 (예: `itg_org_cd` 기준 정렬)
Collections.sort(tree, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> node1, Map<String, Object> node2) {
// 자식이 없는 경우, 마지막에 배치
boolean hasChildren1 = !((List<?>) node1.get("_children")).isEmpty();
boolean hasChildren2 = !((List<?>) node2.get("_children")).isEmpty();
// 자식이 없는 노드들이 마지막에 오도록 정렬
if (!hasChildren1 && hasChildren2) {
return 1; // node1이 자식이 없으면 뒤로 보내기
} else if (hasChildren1 && !hasChildren2) {
return -1; // node2가 자식이 없으면 뒤로 보내기
}
// 자식이 모두 있는 경우, org_cd로 알파벳 순서로 정렬
String orgCd1 = (String) node1.get("itg_org_cd");
String orgCd2 = (String) node2.get("itg_org_cd");
return orgCd1.compareTo(orgCd2);
}
});
return tree;
}
}

 

 

toast gird option.

let config = {
treeColumnOptions: {
name: 'itg_org_nm',
useIcon: true
},
header: {
align: 'center',
columns: [
{
name: 'itg_org_nm',
renderer: treeHeaderRenderer
}
]
}
}

 

반응형