diff --git a/src/main/java/com/dbnt/kcgfilemanager/BaseController.java b/src/main/java/com/dbnt/kcgfilemanager/BaseController.java index 6f8bb9c..017272d 100644 --- a/src/main/java/com/dbnt/kcgfilemanager/BaseController.java +++ b/src/main/java/com/dbnt/kcgfilemanager/BaseController.java @@ -1,6 +1,7 @@ package com.dbnt.kcgfilemanager; import com.dbnt.kcgfilemanager.model.UserInfo; +import com.dbnt.kcgfilemanager.service.BoardCategoryService; import com.dbnt.kcgfilemanager.service.CommonCodeService; import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -17,6 +18,7 @@ import java.security.Principal; public class BaseController { private final CommonCodeService commonCodeService; + private final BoardCategoryService boardCategoryService; @GetMapping("/") public ModelAndView loginCheck(Principal principal, HttpSession session) { @@ -26,6 +28,7 @@ public class BaseController { }else{ session.setAttribute("positionList", commonCodeService.selectCommonCodeValue("POSITION")); session.setAttribute("departmentList", commonCodeService.selectCommonCodeValue("DEPARTMENT")); + session.setAttribute("categoryList", boardCategoryService.selectBoardCategoryAll(null, 1)); if(((UserInfo)((UsernamePasswordAuthenticationToken) principal).getPrincipal()).getUserRole().indexOf("ADMIN")>0){ mav = new ModelAndView("redirect:/admin/main"); }else{ diff --git a/src/main/java/com/dbnt/kcgfilemanager/controller/adminController.java b/src/main/java/com/dbnt/kcgfilemanager/controller/adminController.java index 126c8cd..ad1d038 100644 --- a/src/main/java/com/dbnt/kcgfilemanager/controller/adminController.java +++ b/src/main/java/com/dbnt/kcgfilemanager/controller/adminController.java @@ -1,13 +1,18 @@ package com.dbnt.kcgfilemanager.controller; +import com.dbnt.kcgfilemanager.model.BoardCategory; import com.dbnt.kcgfilemanager.model.CommonCode; import com.dbnt.kcgfilemanager.model.UserInfo; +import com.dbnt.kcgfilemanager.service.BoardCategoryService; import com.dbnt.kcgfilemanager.service.CommonCodeService; import com.dbnt.kcgfilemanager.service.UserInfoService; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.util.List; @RestController @@ -16,6 +21,7 @@ import java.util.List; public class adminController { private final CommonCodeService commonCodeService; + private final BoardCategoryService boardCategoryService; private final UserInfoService userInfoService; @GetMapping("/main") @@ -26,9 +32,30 @@ public class adminController { @GetMapping("/categoryMgt") public ModelAndView categoryMgt(){ ModelAndView mav = new ModelAndView("admin/categoryMgt"); - + mav.addObject("categoryList", boardCategoryService.selectBoardCategory(null,1)); return mav; } + + @GetMapping("/getChildCategoryTable") + public ModelAndView getChildCategoryTable(Integer parentCategory, Integer depth){ + ModelAndView mav = new ModelAndView("admin/boardCategoryTable"); + mav.addObject("categoryList", boardCategoryService.selectBoardCategory(parentCategory, depth)); + mav.addObject("depth", depth); + return mav; + } + + @PostMapping("/insertCategory") + @ResponseBody + public int insertBoardCategory(@RequestBody List categoryList) { + boardCategoryService.insertBoardCategory(categoryList); + return categoryList.get(0).getDepth(); + } + @DeleteMapping("/deleteCategory") + @ResponseBody + public int deleteBoardCategory(Integer categorySeq, Integer depth) { + boardCategoryService.deleteBoardCategory(categorySeq, depth); + return categorySeq; + } @GetMapping("/userMgt") public ModelAndView userMgt(UserInfo userInfo) { userInfo.setQueryInfo(); diff --git a/src/main/java/com/dbnt/kcgfilemanager/mapper/BoardCategoryMapper.java b/src/main/java/com/dbnt/kcgfilemanager/mapper/BoardCategoryMapper.java new file mode 100644 index 0000000..50af817 --- /dev/null +++ b/src/main/java/com/dbnt/kcgfilemanager/mapper/BoardCategoryMapper.java @@ -0,0 +1,8 @@ +package com.dbnt.kcgfilemanager.mapper; + +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface BoardCategoryMapper { + +} diff --git a/src/main/java/com/dbnt/kcgfilemanager/model/BoardCategory.java b/src/main/java/com/dbnt/kcgfilemanager/model/BoardCategory.java index 5777448..90071fd 100644 --- a/src/main/java/com/dbnt/kcgfilemanager/model/BoardCategory.java +++ b/src/main/java/com/dbnt/kcgfilemanager/model/BoardCategory.java @@ -5,6 +5,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; +import org.springframework.web.bind.annotation.RequestBody; import javax.persistence.*; import java.util.List; diff --git a/src/main/java/com/dbnt/kcgfilemanager/repository/BoardCategoryRepository.java b/src/main/java/com/dbnt/kcgfilemanager/repository/BoardCategoryRepository.java new file mode 100644 index 0000000..0f3f4f7 --- /dev/null +++ b/src/main/java/com/dbnt/kcgfilemanager/repository/BoardCategoryRepository.java @@ -0,0 +1,12 @@ +package com.dbnt.kcgfilemanager.repository; + +import com.dbnt.kcgfilemanager.model.BoardCategory; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + + +public interface BoardCategoryRepository extends JpaRepository { + List findByParentCategoryAndDepth(Integer parentCategory, Integer depth); + List findByParentCategory(Integer parentCategory); +} diff --git a/src/main/java/com/dbnt/kcgfilemanager/service/BoardCategoryService.java b/src/main/java/com/dbnt/kcgfilemanager/service/BoardCategoryService.java new file mode 100644 index 0000000..2aad0e0 --- /dev/null +++ b/src/main/java/com/dbnt/kcgfilemanager/service/BoardCategoryService.java @@ -0,0 +1,46 @@ +package com.dbnt.kcgfilemanager.service; + +import com.dbnt.kcgfilemanager.mapper.BoardCategoryMapper; +import com.dbnt.kcgfilemanager.model.BoardCategory; +import com.dbnt.kcgfilemanager.repository.BoardCategoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class BoardCategoryService { + private final BoardCategoryMapper boardCategoryMapper; + private final BoardCategoryRepository boardCategoryRepository; + + + public List selectBoardCategory(Integer parentCategory, Integer depth) { + return boardCategoryRepository.findByParentCategoryAndDepth(parentCategory, depth); + } + public List selectBoardCategoryAll(Integer parentCategory, Integer depth){ + List categoryList = boardCategoryRepository.findByParentCategoryAndDepth(parentCategory, depth); + for(BoardCategory category: categoryList){ + category.setChildCategoryList(selectBoardCategoryAll(category.getCategorySeq(), depth+1)); + } + return categoryList; + } + + public void insertBoardCategory(List categoryList){ + boardCategoryRepository.saveAll(categoryList); + } + + public void deleteBoardCategory(Integer categorySeq, Integer depth) { + deleteChildCategory(selectBoardCategoryAll(categorySeq, depth+1)); + BoardCategory boardCategory = new BoardCategory(); + boardCategory.setCategorySeq(categorySeq); + boardCategoryRepository.delete(boardCategory); + } + + private void deleteChildCategory(List childList){ + for(BoardCategory category: childList){ + deleteChildCategory(category.getChildCategoryList()); + } + boardCategoryRepository.deleteAll(childList); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1d50bff..95fdb96 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -9,13 +9,14 @@ spring.thymeleaf.cache=false #mariaDB spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy -spring.datasource.url=jdbc:log4jdbc:mariadb://106.247.244.146:57306/kcg_fm?characterEncoding=UTF-8&serverTimezone=UTC +spring.datasource.url=jdbc:log4jdbc:mariadb://cks0504.iptime.org:3306/kcg_fm?characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.username=root -spring.datasource.password=dbnt0928 +spring.datasource.password=mariadb#0524 #jpa spring.jpa.show-sql=true spring.jpa.generate-ddl=false +spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl # MyBatis mybatis.mapper-locations: mybatisMapper/**/*.xml diff --git a/src/main/resources/static/css/common.css b/src/main/resources/static/css/common.css index e720f02..434da4c 100644 --- a/src/main/resources/static/css/common.css +++ b/src/main/resources/static/css/common.css @@ -1,9 +1,12 @@ -#loginPage{ - background-image: url("/img/img01.jpg"); -} + .form-signin{ width: 100%; max-width: 330px; padding: 15px; margin: auto; + position: absolute; + z-index: 200; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); } \ No newline at end of file diff --git a/src/main/resources/static/js/admin/categoryMgt.js b/src/main/resources/static/js/admin/categoryMgt.js index 102ae59..e5089df 100644 --- a/src/main/resources/static/js/admin/categoryMgt.js +++ b/src/main/resources/static/js/admin/categoryMgt.js @@ -1,4 +1,140 @@ +$(function(){ + +}) + +$(document).on('click', '.categoryTr', function (){ + const target = $(this).find(".trCheckBox"); + const depth = Number(target.val()); + const parentCategory = checkBoxAction(target); + getCategoryTable(parentCategory, depth+1); +}) +$(document).on('click', '.insertTr', function (){ + const target = $(this).find(".trCheckBox"); + checkBoxAction(target); +}) $(document).on('click', '.addCategoryBtn', function (){ - const depth = $(this).attr("data-depth") - $("#depth"+depth+"Category").append($("#appendTr").children().clone()) -}) \ No newline at end of file + const depth = Number($(this).attr("data-depth")); + const appendTr = $("#appendTr").children().clone(); + if(Number(depth)>1){ + const parentSeq = $(".trCheckBox:checked[value='"+(depth-1)+"']").parent().find(".categorySeq").val() + if(parentSeq === undefined){ + alert("선택된 상위 메뉴가 없습니다.") + return false; + } + appendTr.find(".parentCategory").val(parentSeq); + } + appendTr[0].className = "insertTr"; + appendTr.find(".trCheckBox").val(depth); + appendTr.find(".depth").val(depth); + $("#depth"+depth+"Category").append(appendTr); +}) + +$(document).on('click', '.deleteCategoryBtn', function (){ + let depth = Number($(this).attr("data-depth")); + const target = $(".trCheckBox:checked[value='"+depth+"']"); + if(target.length>0){ + const category = depth===1?"대분류":(depth===2?"연도":(depth===3?"중분류":(depth===4?"소분류":''))); + const categorySeq = target.parent().find(".categorySeq").val() + if(categorySeq===undefined || categorySeq===''){ + // DB에 등록되지 않은 분류 + deleteTr(target.parent().parent()); + }else{ + let msg = ""; + if(category!=="소분류"){ + msg = "\n하위 모든 분류가 삭제됩니다." + } + if(confirm(category+"의 선택된 분류를 삭제하시겠습니까?"+msg)){ + $.ajax({ + type : 'DELETE', + url : "/admin/deleteCategory", + data : {categorySeq: categorySeq, depth: depth}, + beforeSend: function (xhr){ + xhr.setRequestHeader($("[name='_csrf_header']").val(), $("[name='_csrf']").val()); + }, + success : function(data) { + alert("저장되었습니다."); + const target = $(".categorySeq[value='"+data+"']") + deleteTr(target.parent().parent()); + }, + error : function(xhr, status) { + + } + }) + } + + } + } +}) + +$(document).on('click', '#saveCategoryBtn', function (){ + const categoryList = []; + $(".insertTr").each(function (idx, el){ + categoryList.push({}); + const target = $(el); + categoryList[idx].depth = target.find(".depth").val(); + categoryList[idx].parentCategory = target.find(".parentCategory").val(); + categoryList[idx].categoryName = target.find(".categoryName").val(); + }) + + if(categoryList.length !== 0) { + if (confirm(categoryList.length + "건을 저장하시겠습니까?")) { + $.ajax({ + type : 'POST', + url : "/admin/insertCategory", + data : JSON.stringify(categoryList), + contentType: 'application/json', + beforeSend: function (xhr){ + xhr.setRequestHeader($("[name='_csrf_header']").val(), $("[name='_csrf']").val()); + }, + success : function(data) { + alert("저장되었습니다."); + const depth = data; + const parentCategory = $(".trCheckBox:checked[value='"+(depth-1)+"']").parent().find(".categorySeq").val() + getCategoryTable(parentCategory, depth); + }, + error : function(xhr, status) { + + } + }) + } + } +}) + +function checkBoxAction(target){ + const depth = Number(target.val()); + const parentCategory = Number($(target).parent().find(".categorySeq").val()); + $(".trCheckBox[value='"+depth+"']").prop("checked", false); + target[0].checked = true; + return parentCategory +} + +function getCategoryTable(parentCategory, depth){ + $.ajax({ + url: '/admin/getChildCategoryTable', + type: 'GET', + data : {parentCategory: parentCategory, depth: depth}, + dataType:"html", + success: function(html){ + let depth = Number($(html).find("thead").attr("data-depth")); + $("#depth"+depth+"Div").empty().append(html); + childTableReset(depth); + }, + error:function(){ + + } + }); +} + +function deleteTr(target){ + childTableReset(Number(target.find(".trCheckBox").val())) + target.remove(); +} + +function childTableReset(depth){ + let childTbody + do{ + depth++; + childTbody = $("#depth"+depth+"Category") + childTbody.empty(); + }while (childTbody.length>0) +} \ No newline at end of file diff --git a/src/main/resources/templates/admin/boardCategoryTable.html b/src/main/resources/templates/admin/boardCategoryTable.html new file mode 100644 index 0000000..e9136cc --- /dev/null +++ b/src/main/resources/templates/admin/boardCategoryTable.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + +
+ + + + + + +
+ \ No newline at end of file diff --git a/src/main/resources/templates/admin/categoryMgt.html b/src/main/resources/templates/admin/categoryMgt.html index 451eca0..46d18ab 100644 --- a/src/main/resources/templates/admin/categoryMgt.html +++ b/src/main/resources/templates/admin/categoryMgt.html @@ -9,80 +9,113 @@
+ +

게시판 분류 관리

- +
- - - - - - - - - -
대분류
+
+ + + + + + + + + + + + + +
대분류
+ + + + + + +
+
+
+ +
- - - - - - - - - -
연도
+
+ + + + + + + + + +
연도
+
-
-
-
- - - - - - - - - -
중분류
-
- +
- - - - - - - - - -
소분류
+
+ + + + + + + + + +
중분류
+
+
+
+ +
+
+ +
+
+
+
+
+ + + + + + + + + +
소분류
+
+
+ +
@@ -94,8 +127,14 @@ - + diff --git a/src/main/resources/templates/admin/codeValue.html b/src/main/resources/templates/admin/codeValue.html index 3fe164c..3a11d5e 100644 --- a/src/main/resources/templates/admin/codeValue.html +++ b/src/main/resources/templates/admin/codeValue.html @@ -24,5 +24,4 @@
- + + + + + + +
- \ No newline at end of file diff --git a/src/main/resources/templates/fragments/leftMenu.html b/src/main/resources/templates/fragments/leftMenu.html index dc37127..a0d0521 100644 --- a/src/main/resources/templates/fragments/leftMenu.html +++ b/src/main/resources/templates/fragments/leftMenu.html @@ -19,7 +19,51 @@
- 카테고리 메뉴 영역 +
+ +
+ + +
\ No newline at end of file diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index e7caa6c..26e9f63 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -4,7 +4,28 @@ xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/layout}"> -
+
+