게시판 분류 관리 편의성 개선 작업 종료
parent
4fe795a343
commit
83aab6fb11
|
|
@ -28,6 +28,8 @@ public class BoardCategory {
|
|||
private Integer parentSeq;
|
||||
@Column(name = "CATEGORY_NAME", nullable = false)
|
||||
private String categoryName;
|
||||
@Column(name = "SORT_CNT")
|
||||
private Integer sortCnt;
|
||||
@Transient
|
||||
private List<BoardCategory> childCategoryList;
|
||||
@Transient
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ import java.util.List;
|
|||
|
||||
|
||||
public interface BoardCategoryRepository extends JpaRepository<BoardCategory, Integer> {
|
||||
List<BoardCategory> findByParentSeqAndDepth(Integer parentSeq, Integer depth);
|
||||
List<BoardCategory> findByParentSeqAndDepthOrderBySortCntDesc(Integer parentSeq, Integer depth);
|
||||
List<BoardCategory> findByParentSeq(Integer parentSeq);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package com.dbnt.kcgfilemanager.repository;
|
|||
import com.dbnt.kcgfilemanager.model.Board;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface BoardRepository extends JpaRepository<Board, Integer> {
|
||||
import java.util.List;
|
||||
|
||||
public interface BoardRepository extends JpaRepository<Board, Integer> {
|
||||
List<Board> findByCategorySeq(int categorySeq);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package com.dbnt.kcgfilemanager.service;
|
||||
|
||||
import com.dbnt.kcgfilemanager.model.Board;
|
||||
import com.dbnt.kcgfilemanager.model.BoardCategory;
|
||||
import com.dbnt.kcgfilemanager.model.CategoryRole;
|
||||
import com.dbnt.kcgfilemanager.model.ContentPosition;
|
||||
import com.dbnt.kcgfilemanager.repository.BoardCategoryRepository;
|
||||
import com.dbnt.kcgfilemanager.repository.BoardRepository;
|
||||
import com.dbnt.kcgfilemanager.repository.CategoryRoleRepository;
|
||||
import com.dbnt.kcgfilemanager.repository.ContentPositionRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
|
@ -18,17 +20,20 @@ import java.util.Objects;
|
|||
@RequiredArgsConstructor
|
||||
public class BoardCategoryService {
|
||||
|
||||
private final FileInfoService fileInfoService;
|
||||
|
||||
private final BoardRepository boardRepository;
|
||||
private final BoardCategoryRepository boardCategoryRepository;
|
||||
private final CategoryRoleRepository categoryRoleRepository;
|
||||
private final ContentPositionRepository contentPositionRepository;
|
||||
|
||||
|
||||
public List<BoardCategory> selectBoardCategory(Integer parentSeq, Integer depth) {
|
||||
return boardCategoryRepository.findByParentSeqAndDepth(parentSeq, depth);
|
||||
return boardCategoryRepository.findByParentSeqAndDepthOrderBySortCntDesc(parentSeq, depth);
|
||||
}
|
||||
|
||||
public List<BoardCategory> selectBoardCategoryAll(Integer parentSeq, Integer depth){
|
||||
List<BoardCategory> categoryList = boardCategoryRepository.findByParentSeqAndDepth(parentSeq, depth);
|
||||
List<BoardCategory> categoryList = boardCategoryRepository.findByParentSeqAndDepthOrderBySortCntDesc(parentSeq, depth);
|
||||
for(BoardCategory category: categoryList){
|
||||
category.setChildCategoryList(selectBoardCategoryAll(category.getCategorySeq(), depth+1));
|
||||
}
|
||||
|
|
@ -96,6 +101,8 @@ public class BoardCategoryService {
|
|||
for(BoardCategory category: categoryList){
|
||||
switch (category.getStatus()){
|
||||
case "deleted":
|
||||
/*게시물 삭제 로직 필요.*/
|
||||
deleteContentToCategorySeq(category.getCategorySeq());
|
||||
boardCategoryRepository.delete(category);
|
||||
break;
|
||||
case "modified":
|
||||
|
|
@ -104,9 +111,12 @@ public class BoardCategoryService {
|
|||
case "added":
|
||||
category.setTempSeq(category.getCategorySeq());
|
||||
category.setCategorySeq(null);
|
||||
for(BoardCategory temp : categoryList){
|
||||
if(Objects.equals(temp.getTempSeq(), category.getParentSeq())){
|
||||
category.setParentSeq(temp.getCategorySeq());
|
||||
if(category.getDepth()!=1){
|
||||
for(BoardCategory temp : categoryList){
|
||||
if(Objects.equals(temp.getTempSeq(), category.getParentSeq())){
|
||||
category.setParentSeq(temp.getCategorySeq());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
boardCategoryRepository.saveAndFlush(category);
|
||||
|
|
@ -114,4 +124,12 @@ public class BoardCategoryService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteContentToCategorySeq(Integer categorySeq) {
|
||||
List<Board> deleteContentList = boardRepository.findByCategorySeq(categorySeq);
|
||||
for(Board deleteContent: deleteContentList){
|
||||
fileInfoService.deleteFileInfoAll(deleteContent.getContentSeq());
|
||||
boardRepository.delete(deleteContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,13 @@ import java.util.*;
|
|||
@RequiredArgsConstructor
|
||||
public class BoardService {
|
||||
|
||||
private final BoardMapper boardMapper;
|
||||
private final BoardRepository boardRepository;
|
||||
|
||||
private final BoardCategoryRepository boardCategoryRepository;
|
||||
private final FileInfoService fileInfoService;
|
||||
private final BoardCategoryService boardCategoryService;
|
||||
|
||||
private final BoardMapper boardMapper;
|
||||
|
||||
private final BoardRepository boardRepository;
|
||||
private final BoardCategoryRepository boardCategoryRepository;
|
||||
private final BoardLogRepository boardLogRepository;
|
||||
private final FileInfoRepository fileInfoRepository;
|
||||
private final HashTagRepository hashTagRepository;
|
||||
|
|
@ -221,7 +222,7 @@ public class BoardService {
|
|||
content.setStatus("D");
|
||||
saveBoardLog(contentSeq, LogStatus.DELETE, null, user.getUserId());
|
||||
deleteHashTagLink(contentSeq);
|
||||
deleteFileInfoAll(contentSeq);
|
||||
fileInfoService.deleteFileInfoAll(contentSeq);
|
||||
return contentSeq;
|
||||
}
|
||||
|
||||
|
|
@ -254,29 +255,18 @@ public class BoardService {
|
|||
List<HashTagLink> tagLinkList = hashTagLinkRepository.findByContentSeq(contentSeq);
|
||||
hashTagLinkRepository.deleteAll(tagLinkList);
|
||||
}
|
||||
private void deleteFileInfoAll(int contentSeq){
|
||||
List<FileInfo> fileInfoList = fileInfoRepository.findByContentSeqOrderByFileSeqAsc(contentSeq);
|
||||
for(FileInfo fileInfo: fileInfoList){
|
||||
deleteStoredFile(fileInfo.getSavePath(), fileInfo.getConversionName());
|
||||
}
|
||||
fileInfoRepository.deleteAll(fileInfoList);
|
||||
}
|
||||
|
||||
private void deleteFileInfo(Integer contentSeq, List<Integer> fileSeqList, String userId){
|
||||
List<FileInfo> fileInfoList = fileInfoRepository.findByContentSeqOrderByFileSeqAsc(contentSeq);
|
||||
for(FileInfo fileInfo: fileInfoList){
|
||||
if(fileSeqList.contains(fileInfo.getFileSeq())){
|
||||
deleteStoredFile(fileInfo.getSavePath(), fileInfo.getConversionName());
|
||||
fileInfoService.deleteStoredFile(fileInfo.getSavePath(), fileInfo.getConversionName());
|
||||
saveBoardLog(contentSeq, LogStatus.FILE_REMOVE, fileInfo.getFullName(), userId);
|
||||
fileInfoRepository.delete(fileInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteStoredFile(String savePath, String conversionName){
|
||||
File deleteFile = new File(savePath, conversionName);
|
||||
deleteFile.delete();
|
||||
}
|
||||
private String calculationSize(double fileSize){
|
||||
String[] units = {"bytes", "KB", "MB", "GB", "TB", "PB"};
|
||||
double unitSelector = Math.floor(Math.log(fileSize)/Math.log(1024));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package com.dbnt.kcgfilemanager.service;
|
||||
|
||||
import com.dbnt.kcgfilemanager.config.LogStatus;
|
||||
import com.dbnt.kcgfilemanager.model.FileInfo;
|
||||
import com.dbnt.kcgfilemanager.repository.FileInfoRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class FileInfoService {
|
||||
private final FileInfoRepository fileInfoRepository;
|
||||
|
||||
public void deleteFileInfoAll(int contentSeq){
|
||||
List<FileInfo> fileInfoList = fileInfoRepository.findByContentSeqOrderByFileSeqAsc(contentSeq);
|
||||
for(FileInfo fileInfo: fileInfoList){
|
||||
deleteStoredFile(fileInfo.getSavePath(), fileInfo.getConversionName());
|
||||
}
|
||||
fileInfoRepository.deleteAll(fileInfoList);
|
||||
}
|
||||
|
||||
public void deleteStoredFile(String savePath, String conversionName){
|
||||
File deleteFile = new File(savePath, conversionName);
|
||||
deleteFile.delete();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
let categoryList = []
|
||||
let maxSeq = 0;
|
||||
let maxSeq = 1;
|
||||
$(function (){
|
||||
getCategoryList();
|
||||
})
|
||||
|
|
@ -9,16 +9,20 @@ $(document).on('click', '.categoryTr', function (){
|
|||
chooseTr.find(".trCheckBox").prop("checked", true);
|
||||
setCategoryTable(Number(chooseTr.attr("data-depth"))+1, Number(chooseTr.attr("data-categoryseq")));
|
||||
})
|
||||
$(document).on('change', '.categoryName', function (){
|
||||
$(document).on('change', '.categoryName, .sortCnt', function (){
|
||||
const categoryInfo = $(this).parents("tr");
|
||||
const changedName = this.value;
|
||||
if(changedName !== categoryInfo.attr("data-categoryname")){
|
||||
const changedValue = this.value;
|
||||
let sortCntFlag = this.className.includes("sortCnt")&&(changedValue !== categoryInfo.attr("data-sortcnt"));
|
||||
let categoryNameFlag = this.className.includes("categoryName")&&(changedValue !== categoryInfo.attr("data-categoryname"));
|
||||
if(sortCntFlag || categoryNameFlag){
|
||||
categoryList.forEach(function (category){
|
||||
if(category.categorySeq === Number(categoryInfo.attr("data-categoryseq"))){
|
||||
category.categoryName = changedName;
|
||||
if(category.status !== "added"){
|
||||
if(categoryNameFlag)
|
||||
category.categoryName = changedValue;
|
||||
if(sortCntFlag)
|
||||
category.sortCnt = changedValue;
|
||||
if(category.status !== "added")
|
||||
category.status = "modified";
|
||||
}
|
||||
}
|
||||
})
|
||||
categoryInfo[0].className += "bg-warning bg-opacity-25";
|
||||
|
|
@ -27,7 +31,9 @@ $(document).on('change', '.categoryName', function (){
|
|||
$(document).on('click', '.addCategoryBtn', function (){
|
||||
const depth = Number($(this).attr("data-depth"));
|
||||
const parentCategory = $("#depth"+(depth-1)+"Tbody").find(".trCheckBox:checked").parents("tr");
|
||||
if(parentCategory.attr("data-status")==="deleted"){
|
||||
if(depth!==1 && parentCategory.length===0){
|
||||
alert("상위 분류를 선택해 주세요.");
|
||||
}else if(parentCategory.attr("data-status")==="deleted"){
|
||||
alert("삭제될 상위 분류에는 추가할 수 없습니다.");
|
||||
}else{
|
||||
const parentSeq = parentCategory.attr("data-categoryseq");
|
||||
|
|
@ -35,6 +41,7 @@ $(document).on('click', '.addCategoryBtn', function (){
|
|||
categorySeq: maxSeq++,
|
||||
parentSeq: depth===1?null:Number(parentSeq),
|
||||
categoryName: "신규",
|
||||
sortCnt: 0,
|
||||
depth: depth,
|
||||
status: "added"
|
||||
})
|
||||
|
|
@ -52,6 +59,7 @@ $(document).on('click', '.copyCategory', function (){
|
|||
parentSeq: depth===1?null:Number(parentSeq),
|
||||
categoryName: "복사된 분류",
|
||||
depth: depth,
|
||||
sortCnt: 0,
|
||||
status: "added"
|
||||
}];
|
||||
copyList = copyList.concat(getCopyData(depth+1, Number(copyInfo.attr("data-categoryseq")), lastSeq));
|
||||
|
|
@ -64,7 +72,7 @@ $(document).on('click', '.deleteCategory', function (){
|
|||
const categoryInfo = $(this).parents("tr");
|
||||
const categorySeq = categoryInfo.attr("data-categoryseq");
|
||||
if(categoryInfo.attr("data-status") !== "deleted"){
|
||||
if(confirm("선택된 분류와 하위 분류를 삭제하시겠습니까?")){
|
||||
if(confirm("선택된 분류와 하위 분류를 삭제하시겠습니까?\n등록된 자료가 모두 삭제됩니다.")){
|
||||
statusChange("deleted", Number(categorySeq));
|
||||
}
|
||||
}else{
|
||||
|
|
@ -122,6 +130,7 @@ function getCategoryList(){
|
|||
categoryName: category.categoryName,
|
||||
originalName: category.categoryName,
|
||||
depth: category.depth,
|
||||
sortCnt: category.sortCnt,
|
||||
status: "saved",
|
||||
})
|
||||
if(maxSeq<=category.categorySeq){
|
||||
|
|
@ -147,10 +156,11 @@ function setCategoryTable(depth, parentSeq){
|
|||
case "deleted": statusColor = "bg-danger bg-opacity-25"; break;
|
||||
}
|
||||
tbody += "<tr class='categoryTr "+statusColor+"' data-categoryseq='"+data.categorySeq+"'" +
|
||||
" data-parentseq='"+data.parentSeq+"' data-depth='"+data.depth+"'" +
|
||||
" data-categoryname='"+data.categoryName+"' data-status='"+data.status+"'>";
|
||||
" data-parentseq='"+data.parentSeq+"' data-categoryname='"+data.categoryName+"'" +
|
||||
" data-depth='"+data.depth+"' data-sortcnt='"+data.sortCnt+"' data-status='"+data.status+"'>";
|
||||
tbody += "<td><input type='checkbox' class='trCheckBox'></td>"
|
||||
tbody += "<td><input type='text' class='form-control form-control-sm categoryName' value='"+data.categoryName+"' "+(data.status==="deleted"?"readonly":"")+"></td>"
|
||||
tbody += "<td><input type='number' class='form-control form-control-sm sortCnt' value='"+data.sortCnt+"' "+(data.status==="deleted"?"readonly":"")+"></td>"
|
||||
tbody += "<td><a href='#' class='copyCategory'><i class='bi bi-journals text-success'></i></a></td>";
|
||||
tbody += "<td><a href='#' class='deleteCategory'><i class='bi bi-x-square text-danger'></i></a></td>";
|
||||
tbody += "</tr>";
|
||||
|
|
@ -163,15 +173,11 @@ function getCopyData(depth, parentSeq, lastSeq){
|
|||
let copyList = getTableData(categoryList, depth, parentSeq);
|
||||
let childList = [];
|
||||
copyList.forEach(function (category){
|
||||
const tempList = getCopyData(category.depth+1, category.categorySeq)
|
||||
category.categorySeq = maxSeq++;
|
||||
const tempSeq = maxSeq++;
|
||||
const tempList = getCopyData(category.depth+1, category.categorySeq, tempSeq)
|
||||
category.categorySeq = tempSeq;
|
||||
category.parentSeq = lastSeq;
|
||||
category.status = "added";
|
||||
tempList.forEach(function (child){
|
||||
child.parentSeq = category.categorySeq;
|
||||
child.categorySeq = maxSeq++;
|
||||
child.status = "added";
|
||||
})
|
||||
childList = childList.concat(tempList);
|
||||
})
|
||||
copyList = copyList.concat(childList);
|
||||
|
|
@ -184,9 +190,10 @@ function getTableData(categoryList, depth, parentSeq){
|
|||
if(category.depth===depth && category.parentSeq===parentSeq){
|
||||
targetList.push({
|
||||
categorySeq: category.categorySeq,
|
||||
categoryName: category.categoryName,
|
||||
parentSeq: category.parentSeq,
|
||||
categoryName: category.categoryName,
|
||||
depth: category.depth,
|
||||
sortCnt: category.sortCnt,
|
||||
status: category.status
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,16 @@
|
|||
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{layout/layout}">
|
||||
<th:block layout:fragment="css">
|
||||
<style>
|
||||
.categoryName{
|
||||
width: 130px;
|
||||
}
|
||||
.sortCnt{
|
||||
width: 60px;
|
||||
}
|
||||
</style>
|
||||
</th:block>
|
||||
<th:block layout:fragment="script">
|
||||
<script type="text/javascript" th:src="@{/js/admin/categoryMgt2.js}"></script>
|
||||
</th:block>
|
||||
|
|
@ -23,7 +33,8 @@
|
|||
<thead data-depth="1">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>대분류</th>
|
||||
<th class="categoryName">대분류</th>
|
||||
<th class="sortCnt">순서</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
|
@ -44,7 +55,8 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>연도</th>
|
||||
<th class="categoryName">연도</th>
|
||||
<th class="sortCnt">순서</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
|
@ -65,7 +77,8 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>중분류</th>
|
||||
<th class="categoryName">중분류</th>
|
||||
<th class="sortCnt">순서</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
|
@ -86,7 +99,8 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>소분류</th>
|
||||
<th class="categoryName">소분류</th>
|
||||
<th class="sortCnt">순서</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
|
|
|||
Loading…
Reference in New Issue