자료등록 페이지 작업중.
parent
e71e57910a
commit
5134bcbe13
|
|
@ -1,16 +1,18 @@
|
|||
package com.dbnt.kcgfilemanager.controller;
|
||||
|
||||
import com.dbnt.kcgfilemanager.model.Board;
|
||||
import com.dbnt.kcgfilemanager.model.UserInfo;
|
||||
import com.dbnt.kcgfilemanager.service.UserInfoService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
|
|
@ -32,8 +34,16 @@ public class BoardController {
|
|||
UserInfo loginUser = ((UserInfo)((UsernamePasswordAuthenticationToken) principal).getPrincipal());
|
||||
mav.addObject("userId", loginUser.getUserId());
|
||||
mav.addObject("userName", loginUser.getName());
|
||||
mav.addObject("nowDate", LocalDateTime.now());
|
||||
return mav;
|
||||
}
|
||||
|
||||
@PostMapping("/saveContent")
|
||||
public Integer saveContent(Board board){
|
||||
System.out.println("controller coming");
|
||||
return board.getContentSeq();
|
||||
}
|
||||
@PostMapping("/uploadFiles")
|
||||
public void uploadFiles(Integer contentSeq, MultipartHttpServletRequest request){
|
||||
System.out.println("controller coming");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ import lombok.NoArgsConstructor;
|
|||
import lombok.Setter;
|
||||
import org.hibernate.annotations.DynamicInsert;
|
||||
import org.hibernate.annotations.DynamicUpdate;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
|
@ -33,4 +35,11 @@ public class Board extends BaseModel{
|
|||
private String createId;
|
||||
@Column(name = "CREATE_DATE")
|
||||
private LocalDateTime createDate;
|
||||
|
||||
@Transient
|
||||
private List<FileInfo> childFiles;
|
||||
@Transient
|
||||
private List<HashTagLink> hashTags;
|
||||
@Transient
|
||||
private String hashTagStr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,29 @@
|
|||
const files = [];
|
||||
|
||||
$(function(){
|
||||
$("#uploadDiv").on("dragenter", function(e) {
|
||||
// $(this).addClass('drag-over');
|
||||
}).on("dragleave", function(e) {
|
||||
// $(this).removeClass('drag-over');
|
||||
}).on("dragover", function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}).on('drop', function(e) {
|
||||
e.preventDefault();
|
||||
// $(this).removeClass('drag-over');
|
||||
for(const file of e.originalEvent.dataTransfer.files){
|
||||
setFileDiv(file, files.push(file));
|
||||
}
|
||||
}).on('click', function (e){
|
||||
if(e.target.className.indexOf("fileDelete")<0){
|
||||
$("#fileInputer").click();
|
||||
}
|
||||
});
|
||||
|
||||
$("#description").summernote({
|
||||
lang:'ko-KR',
|
||||
height: 120,
|
||||
disableDragAndDrop: true,
|
||||
toolbar: [
|
||||
['style', ['style']],
|
||||
['font', ['bold', 'underline', 'clear']],
|
||||
|
|
@ -11,6 +33,38 @@ $(function(){
|
|||
]
|
||||
})
|
||||
})
|
||||
$(document).on('change', '#fileInputer', function (){
|
||||
for(const file of this.files){
|
||||
setFileDiv(file, files.push(file));
|
||||
}
|
||||
this.value = null;
|
||||
})
|
||||
$(document).on('click', '.fileDelete', function (){
|
||||
const target = $(this);
|
||||
files[Number(target.attr("data-fileidx"))].isDelete = true;
|
||||
target.parent().remove();
|
||||
const uploadDiv = $("#uploadDiv");
|
||||
if(uploadDiv.children().length === 0){
|
||||
uploadDiv.append("<br>파일을 업로드 해주세요.");
|
||||
}
|
||||
})
|
||||
$(document).on('click', '#saveBtn', function (){
|
||||
const formData = new FormData($("#contentForm")[0]);
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
data : formData,
|
||||
url : "/board/saveContent",
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success : function(data) {
|
||||
$("#contentSeq").val(data);
|
||||
uploadFiles();
|
||||
},
|
||||
error : function(xhr, status) {
|
||||
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
$(document).on('change', '.categorySelector', function (){
|
||||
const categorySeq = Number(this.value);
|
||||
|
|
@ -46,4 +100,45 @@ function selectorDisabler(depth){
|
|||
this[0].selected = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function uploadFiles(){
|
||||
const formData = new FormData($("#fileForm")[0]);
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
data : formData,
|
||||
url : "/board/uploadFiles",
|
||||
enctype: "multipart/form-data",
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success : function(data) {
|
||||
alert("저장되었습니다.")
|
||||
},
|
||||
error : function(xhr, status) {
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function setFileDiv(file, idx){
|
||||
const uploadDiv = $("#uploadDiv");
|
||||
if(files.length===1){
|
||||
uploadDiv.empty();
|
||||
}
|
||||
let fileInfo = "<div class='row-col-6'>";
|
||||
fileInfo += file.name+" "+byteCalculation(file.size)+" ";
|
||||
fileInfo += "<a href='#' class='fileDelete text-danger text-decoration-none' data-fileidx='"+(idx-1)+"'>삭제</a>";
|
||||
fileInfo += "</div>";
|
||||
uploadDiv.append(fileInfo);
|
||||
}
|
||||
|
||||
function byteCalculation(size) {
|
||||
const bytes = parseInt(size);
|
||||
const s = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
||||
const e = Math.floor(Math.log(bytes)/Math.log(1024));
|
||||
|
||||
if(e === "-Infinity") return "0 "+s[0];
|
||||
else
|
||||
return (bytes/Math.pow(1024, Math.floor(e))).toFixed(2)+" "+s[e];
|
||||
|
||||
}
|
||||
|
|
@ -20,90 +20,101 @@
|
|||
<div class="row mx-0">
|
||||
<div class="col-7 card">
|
||||
<div class="card-body">
|
||||
<div class="row mb-3">
|
||||
<label for="title" class="col-sm-2 col-form-label">분류 선택</label>
|
||||
<div class="col-sm">
|
||||
<select class="form-select categorySelector" data-depth="1">
|
||||
<option selected>분류를 선택해주세요</option>
|
||||
<th:block th:each="depth1:${session.categoryList}">
|
||||
<option th:value="${depth1.categorySeq}" th:text="${depth1.categoryName}"></option>
|
||||
</th:block>
|
||||
</select>
|
||||
<div class="row mb-3 justify-content-end">
|
||||
<div class="col-auto">
|
||||
<button class="bi bi-save btn btn-primary" id="saveBtn"> 저장</button>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<select class="form-select categorySelector" data-depth="2" disabled>
|
||||
<option selected>분류를 선택해주세요</option>
|
||||
<th:block th:each="depth1:${session.categoryList}">
|
||||
<th:block th:each="depth2:${depth1.childCategoryList}">
|
||||
<option th:value="${depth2.categorySeq}" th:data-parentseq="${depth2.parentSeq}" th:text="${depth2.categoryName}"></option>
|
||||
</div>
|
||||
<form id="contentForm" th:action="@{/board/saveContent}" method="post">
|
||||
<div class="row mb-3">
|
||||
<label for="title" class="col-sm-2 col-form-label">분류 선택</label>
|
||||
<div class="col-sm">
|
||||
<select class="form-select categorySelector" data-depth="1">
|
||||
<option selected>분류를 선택해주세요</option>
|
||||
<th:block th:each="depth1:${session.categoryList}">
|
||||
<option th:value="${depth1.categorySeq}" th:text="${depth1.categoryName}"></option>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<select class="form-select categorySelector" data-depth="3" disabled>
|
||||
<option selected>분류를 선택해주세요</option>
|
||||
<th:block th:each="depth1:${session.categoryList}">
|
||||
<th:block th:each="depth2:${depth1.childCategoryList}">
|
||||
<th:block th:each="depth3:${depth2.childCategoryList}">
|
||||
<option th:value="${depth3.categorySeq}" th:data-parentseq="${depth3.parentSeq}" th:text="${depth3.categoryName}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<select class="form-select categorySelector" data-depth="2" disabled>
|
||||
<option selected>분류를 선택해주세요</option>
|
||||
<th:block th:each="depth1:${session.categoryList}">
|
||||
<th:block th:each="depth2:${depth1.childCategoryList}">
|
||||
<option th:value="${depth2.categorySeq}" th:data-parentseq="${depth2.parentSeq}" th:text="${depth2.categoryName}"></option>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<select class="form-select categorySelector" data-depth="4" disabled>
|
||||
<option selected>분류를 선택해주세요</option>
|
||||
<th:block th:each="depth1:${session.categoryList}">
|
||||
<th:block th:each="depth2:${depth1.childCategoryList}">
|
||||
<th:block th:each="depth3:${depth2.childCategoryList}">
|
||||
<th:block th:each="depth4:${depth3.childCategoryList}">
|
||||
<option th:value="${depth4.categorySeq}" th:data-parentseq="${depth4.parentSeq}" th:text="${depth4.categoryName}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<select class="form-select categorySelector" data-depth="3" disabled>
|
||||
<option selected>분류를 선택해주세요</option>
|
||||
<th:block th:each="depth1:${session.categoryList}">
|
||||
<th:block th:each="depth2:${depth1.childCategoryList}">
|
||||
<th:block th:each="depth3:${depth2.childCategoryList}">
|
||||
<option th:value="${depth3.categorySeq}" th:data-parentseq="${depth3.parentSeq}" th:text="${depth3.categoryName}"></option>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="title" class="col-sm-2 col-form-label">제목</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="title" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="createName" class="col-sm-2 col-form-label">작성자</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="hidden" name="createId" th:value="${userId}">
|
||||
<input type="text" class="form-control" id="createName" th:value="${userName}" readonly>
|
||||
</div>
|
||||
<label for="createDate" class="col-sm-2 col-form-label">작성일</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" class="form-control" id="createDate" th:value="${#temporals.format(nowDate, 'yyyy-MM-dd')}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="uploadFile" class="col-sm-2 col-form-label">업로드 자료</label>
|
||||
<div class="col-sm-10" style="height: 70px;">
|
||||
<div class="w-100 h-100 border border-info rounded text-center" id="uploadFile">
|
||||
<br>파일을 업로드 해주세요.
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<select class="form-select categorySelector" data-depth="4" name="categorySeq" disabled>
|
||||
<option selected>분류를 선택해주세요</option>
|
||||
<th:block th:each="depth1:${session.categoryList}">
|
||||
<th:block th:each="depth2:${depth1.childCategoryList}">
|
||||
<th:block th:each="depth3:${depth2.childCategoryList}">
|
||||
<th:block th:each="depth4:${depth3.childCategoryList}">
|
||||
<option th:value="${depth4.categorySeq}" th:data-parentseq="${depth4.parentSeq}" th:text="${depth4.categoryName}"></option>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="description" class="col-sm-2 col-form-label">설명</label>
|
||||
<div class="col-sm-10">
|
||||
<div id="description"></div>
|
||||
<div class="row mb-3">
|
||||
<label for="title" class="col-sm-2 col-form-label">제목</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="title" name="title" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="hashTag" class="col-sm-2 col-form-label">해시태그</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="hashTag" placeholder="태그는 앞에 #을 붙여 띄어쓰기 없이 작성해주세요. ex) #태그1, #태그2, ..." autocomplete="off">
|
||||
<div class="row mb-3">
|
||||
<label for="createName" class="col-sm-2 col-form-label">작성자</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="hidden" name="createId" th:value="${userId}">
|
||||
<input type="text" class="form-control" id="createName" th:value="${userName}" readonly>
|
||||
</div>
|
||||
<label for="createDate" class="col-sm-2 col-form-label">작성일</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" class="form-control" id="createDate" value="저장시 생성" readonly>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="files" class="col-sm-2 col-form-label">업로드 자료</label>
|
||||
<div class="col-sm-10" style="min-height: 70px;">
|
||||
<div class="w-100 h-100 border border-info rounded text-center" id="uploadDiv">
|
||||
<br>파일을 업로드 해주세요.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="description" class="col-sm-2 col-form-label">설명</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea id="description" name="description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="hashTag" class="col-sm-2 col-form-label">해시태그</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="hashTag" name="hashTagStr" placeholder="태그는 앞에 #을 붙여 띄어쓰기 없이 작성해주세요. ex) #태그1, #태그2, ..." autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form id="fileForm" class="d-none" th:action="@{/board/uploadFiles}" method="post" enctype="multipart/form-data">
|
||||
<input type="text" id="contentSeq" name="contentSeq">
|
||||
<input type="file" id="fileInputer" name="fileInputer" multiple>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="d-grid gap-2">
|
||||
<button class="bi bi-search btn btn-outline-primary"> 통합 검색</button>
|
||||
<button class="bi bi-search btn btn-info"> 통합 검색</button>
|
||||
</div>
|
||||
<div class="d-grid gap-2 pt-1">
|
||||
<a class="btn btn-outline-success" href="/board/contentWrite"><i class="bi bi-file-earmark-plus "></i> 자료 등록</a>
|
||||
<a class="btn btn-success" href="/board/contentWrite"><i class="bi bi-file-earmark-plus "></i> 자료 등록</a>
|
||||
</div>
|
||||
<div sec:authorize="isAuthenticated()">
|
||||
<div class="flex-shrink-0 pe-3 py-3 bg-transparent">
|
||||
|
|
|
|||
Loading…
Reference in New Issue