게시물 수정기능 작업중.
parent
bde144db79
commit
06df11d99d
|
|
@ -36,11 +36,16 @@ public class BoardController {
|
||||||
private final BoardService boardService;
|
private final BoardService boardService;
|
||||||
|
|
||||||
@GetMapping("/contentWrite")
|
@GetMapping("/contentWrite")
|
||||||
public ModelAndView contentWrite(Principal principal) {
|
public ModelAndView contentWrite(@AuthenticationPrincipal UserInfo loginUser, Board content) {
|
||||||
ModelAndView mav = new ModelAndView("board/contentWrite");
|
ModelAndView mav = new ModelAndView("board/contentWrite");
|
||||||
UserInfo loginUser = ((UserInfo)((UsernamePasswordAuthenticationToken) principal).getPrincipal());
|
if(content == null) {
|
||||||
|
mav.addObject("type", "new");
|
||||||
mav.addObject("userId", loginUser.getUserId());
|
mav.addObject("userId", loginUser.getUserId());
|
||||||
mav.addObject("userName", loginUser.getName());
|
mav.addObject("userName", loginUser.getName());
|
||||||
|
}else{
|
||||||
|
mav.addObject("type", "modify");
|
||||||
|
mav.addObject("content", boardService.selectContentModifyInfo(content.getContentSeq()));
|
||||||
|
}
|
||||||
return mav;
|
return mav;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,6 +55,13 @@ public class BoardController {
|
||||||
return boardService.saveContent(content);
|
return boardService.saveContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/updateContent")
|
||||||
|
public Integer updateContent(Board content, @RequestParam(value = "fileSeq") List<Integer> deleteFileSeq, MultipartHttpServletRequest request, @AuthenticationPrincipal UserInfo loginUser){
|
||||||
|
content.setFileList(request.getMultiFileMap().get("uploadFiles"));
|
||||||
|
return 0;
|
||||||
|
// return boardService.updateContent(content, loginUser);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/contentList")
|
@GetMapping("/contentList")
|
||||||
public ModelAndView contentList(Board board){
|
public ModelAndView contentList(Board board){
|
||||||
ModelAndView mav = new ModelAndView("board/contentList");
|
ModelAndView mav = new ModelAndView("board/contentList");
|
||||||
|
|
@ -66,7 +78,7 @@ public class BoardController {
|
||||||
public ModelAndView selectBoardContent(Board content, @AuthenticationPrincipal UserInfo loginUser){
|
public ModelAndView selectBoardContent(Board content, @AuthenticationPrincipal UserInfo loginUser){
|
||||||
ModelAndView mav = new ModelAndView("board/contentDetail");
|
ModelAndView mav = new ModelAndView("board/contentDetail");
|
||||||
Board target = boardService.selectContentByContentSeqAndViewCntUp(content.getContentSeq());
|
Board target = boardService.selectContentByContentSeqAndViewCntUp(content.getContentSeq());
|
||||||
mav.addObject("content", boardService.SelectContentForeignAttribute(target));
|
mav.addObject("content", boardService.selectContentForeignAttribute(target));
|
||||||
mav.addObject("loginUser", loginUser);
|
mav.addObject("loginUser", loginUser);
|
||||||
return mav;
|
return mav;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ public class BoardService {
|
||||||
private final FileInfoRepository fileInfoRepository;
|
private final FileInfoRepository fileInfoRepository;
|
||||||
private final BoardCategoryRepository boardCategoryRepository;
|
private final BoardCategoryRepository boardCategoryRepository;
|
||||||
private final BoardMapper boardMapper;
|
private final BoardMapper boardMapper;
|
||||||
|
private final UserInfoRepository userInfoRepository;
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public Integer saveContent(Board content){
|
public Integer saveContent(Board content){
|
||||||
|
|
@ -37,6 +38,17 @@ public class BoardService {
|
||||||
return contentSeq;
|
return contentSeq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Integer updateContent(Board updateContent, UserInfo userInfo) {
|
||||||
|
int contentSeq = updateContent.getContentSeq();
|
||||||
|
Board savedContent = boardRepository.findById(contentSeq).orElse(null);
|
||||||
|
savedContent.setCategorySeq(updateContent.getCategorySeq());
|
||||||
|
savedContent.setTitle(updateContent.getTitle());
|
||||||
|
savedContent.setDescription(updateContent.getDescription());
|
||||||
|
saveBoardLog(contentSeq, LogStatus.MODIFY, null, userInfo.getUserId());
|
||||||
|
return contentSeq;
|
||||||
|
}
|
||||||
|
|
||||||
private void saveBoardLog(Integer contentSeq, LogStatus status, String description, String createId){
|
private void saveBoardLog(Integer contentSeq, LogStatus status, String description, String createId){
|
||||||
BoardLog lastLog = boardLogRepository.findTopByContentSeqOrderByLogSeqDesc(contentSeq).orElse(null);
|
BoardLog lastLog = boardLogRepository.findTopByContentSeqOrderByLogSeqDesc(contentSeq).orElse(null);
|
||||||
BoardLog log = new BoardLog();
|
BoardLog log = new BoardLog();
|
||||||
|
|
@ -125,13 +137,30 @@ public class BoardService {
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public Board selectContentByContentSeqAndViewCntUp(Integer contentSeq) {
|
public Board selectContentByContentSeqAndViewCntUp(Integer contentSeq) {
|
||||||
Board target = boardRepository.findById(contentSeq).orElse(null);
|
Board target = selectContent(contentSeq);
|
||||||
if(target.getStatus()==null){
|
if(target.getStatus()==null){
|
||||||
target.setViewCnt(target.getViewCnt()+1);
|
target.setViewCnt(target.getViewCnt()+1);
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
public Board selectContent(int contentSeq){
|
||||||
|
Board content = boardRepository.findById(contentSeq).orElse(null);
|
||||||
|
content.setCreateName(userInfoRepository.findByUserId(content.getCreateId()).orElse(null).getUserId());
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
public Board selectContentModifyInfo(int contentSeq){
|
||||||
|
Board content = selectContent(contentSeq);
|
||||||
|
content = selectContentForeignAttribute(content);
|
||||||
|
StringBuilder hashTagStr = new StringBuilder();
|
||||||
|
for(HashTag tag : content.getHashTagList()){
|
||||||
|
hashTagStr.append("#").append(tag.getTagName()).append(", ");
|
||||||
|
}
|
||||||
|
if(!hashTagStr.toString().equals("")) {
|
||||||
|
hashTagStr = new StringBuilder(hashTagStr.substring(0, hashTagStr.length() - 2));
|
||||||
|
content.setHashTagStr(hashTagStr.toString());
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
public List<FileInfo> selectDownloadFileInfoList(Integer contentSeq, List<Integer> fileSeqList, String userId) {
|
public List<FileInfo> selectDownloadFileInfoList(Integer contentSeq, List<Integer> fileSeqList, String userId) {
|
||||||
List<FileInfo> fileList = fileInfoRepository.findByContentSeqOrderByFileSeqAsc(contentSeq);
|
List<FileInfo> fileList = fileInfoRepository.findByContentSeqOrderByFileSeqAsc(contentSeq);
|
||||||
List<FileInfo> targetList = new ArrayList<>();
|
List<FileInfo> targetList = new ArrayList<>();
|
||||||
|
|
@ -153,7 +182,7 @@ public class BoardService {
|
||||||
return boardMapper.selectBoardLogFromContentSeq(contentSeq);
|
return boardMapper.selectBoardLogFromContentSeq(contentSeq);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Board SelectContentForeignAttribute(Board target) {
|
public Board selectContentForeignAttribute(Board target) {
|
||||||
target.setHashTagList(boardMapper.selectHashTagListFromContentSeq(target.getContentSeq()));
|
target.setHashTagList(boardMapper.selectHashTagListFromContentSeq(target.getContentSeq()));
|
||||||
target.setChildFileList(fileInfoRepository.findByContentSeqOrderByFileSeqAsc(target.getContentSeq()));
|
target.setChildFileList(fileInfoRepository.findByContentSeqOrderByFileSeqAsc(target.getContentSeq()));
|
||||||
return target;
|
return target;
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ $(document).on('click', '#deleteBtn', function (){
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
$(document).on('click', '#modifyBtn', function (){
|
$(document).on('click', '#modifyBtn', function (){
|
||||||
|
location.href = "/board/contentWrite?contentSeq="+Number($(this).attr("data-contentseq"));
|
||||||
})
|
})
|
||||||
function getContentSeq(){
|
function getContentSeq(){
|
||||||
return $(".contentCheckBox:checked").val();
|
return $(".contentCheckBox:checked").val();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
const files = [];
|
const files = [];
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
|
if(pageType === "modify"){
|
||||||
|
$(".categorySelector").removeAttr("disabled");
|
||||||
|
setParentCategory(4, $("#categorySeq").find("[selected]").attr("data-parentseq"));
|
||||||
|
}
|
||||||
|
|
||||||
$("#uploadDiv").on("dragenter", function(e) {
|
$("#uploadDiv").on("dragenter", function(e) {
|
||||||
// $(this).addClass('drag-over');
|
// $(this).addClass('drag-over');
|
||||||
}).on("dragleave", function(e) {
|
}).on("dragleave", function(e) {
|
||||||
|
|
@ -15,7 +20,7 @@ $(function(){
|
||||||
setFileDiv(file, files.push(file));
|
setFileDiv(file, files.push(file));
|
||||||
}
|
}
|
||||||
}).on('click', function (e){
|
}).on('click', function (e){
|
||||||
if(e.target.className.indexOf("fileDelete")<0){
|
if(e.target.className.indexOf("ileDelete")<0){
|
||||||
$("#fileInputer").click();
|
$("#fileInputer").click();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -48,18 +53,33 @@ $(document).on('click', '.fileDelete', function (){
|
||||||
uploadDiv.append("<br>파일을 업로드 해주세요.");
|
uploadDiv.append("<br>파일을 업로드 해주세요.");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
$(document).on('click', '.uploadedFileDelete', function (){
|
||||||
|
const target = $(this).parent().find("span")[0];
|
||||||
|
if(target.className===""){
|
||||||
|
target.className = "text-decoration-line-through";
|
||||||
|
}else{
|
||||||
|
target.className = "";
|
||||||
|
}
|
||||||
|
})
|
||||||
$(document).on('click', '#saveBtn', function (){
|
$(document).on('click', '#saveBtn', function (){
|
||||||
if(contentCheck()){
|
if(contentCheck()){
|
||||||
if(confirm("저장하시겠습니까?")){
|
if(confirm("저장하시겠습니까?")){
|
||||||
|
let ajaxUrl = "/board/saveContent";
|
||||||
const formData = new FormData($("#contentForm")[0]);
|
const formData = new FormData($("#contentForm")[0]);
|
||||||
for(const file of files) {
|
for(const file of files) {
|
||||||
if(!file.isDelete)
|
if(!file.isDelete)
|
||||||
formData.append('uploadFiles', file, file.name);
|
formData.append('uploadFiles', file, file.name);
|
||||||
}
|
}
|
||||||
|
if(pageType==='modify'){
|
||||||
|
ajaxUrl = "/board/updateContent";
|
||||||
|
$(".text-decoration-line-through").each(function (idx, el){
|
||||||
|
formData.append('fileSeq', $(el).attr("data-fileseq"));
|
||||||
|
})
|
||||||
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type : 'POST',
|
type : 'POST',
|
||||||
data : formData,
|
data : formData,
|
||||||
url : "/board/saveContent",
|
url : ajaxUrl,
|
||||||
processData: false,
|
processData: false,
|
||||||
contentType: false,
|
contentType: false,
|
||||||
success : function(result) {
|
success : function(result) {
|
||||||
|
|
@ -112,6 +132,22 @@ function selectorDisabler(depth){
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setParentCategory(depth, parentSeq){
|
||||||
|
$("[data-depth='"+depth+"']").children().each(function (){
|
||||||
|
const option = $(this)
|
||||||
|
if(parentSeq === option.attr("data-parentseq")){
|
||||||
|
option.removeAttr("style");
|
||||||
|
}else{
|
||||||
|
option.css("display", "none");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const nextTarget = $("[value='"+parentSeq+"']");
|
||||||
|
nextTarget.attr("selected", "selected");
|
||||||
|
if(depth!==1){
|
||||||
|
setParentCategory(depth-1, nextTarget.attr("data-parentseq"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setFileDiv(file, idx){
|
function setFileDiv(file, idx){
|
||||||
const uploadDiv = $("#uploadDiv");
|
const uploadDiv = $("#uploadDiv");
|
||||||
if(files.length===1){
|
if(files.length===1){
|
||||||
|
|
@ -134,6 +170,7 @@ function contentCheck(){
|
||||||
alert("제목을 입력해주세요.")
|
alert("제목을 입력해주세요.")
|
||||||
flag = false;
|
flag = false;
|
||||||
}
|
}
|
||||||
|
if(pageType === "new"){
|
||||||
if($(".fileDelete ").length===0){
|
if($(".fileDelete ").length===0){
|
||||||
alert("업로드 할 파일이 없습니다.")
|
alert("업로드 할 파일이 없습니다.")
|
||||||
flag = false;
|
flag = false;
|
||||||
|
|
@ -150,6 +187,7 @@ function contentCheck(){
|
||||||
if(totalSize>104857600){
|
if(totalSize>104857600){
|
||||||
alert("첨부파일의 용량 합은 100MB를 넘길 수 없습니다.")
|
alert("첨부파일의 용량 합은 100MB를 넘길 수 없습니다.")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,14 @@
|
||||||
</style>
|
</style>
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block layout:fragment="script">
|
<th:block layout:fragment="script">
|
||||||
|
<script type="text/javascript">
|
||||||
|
const pageType = '[[${type}]]';
|
||||||
|
</script>
|
||||||
<script type="text/javascript" th:src="@{/js/board/contentWrite.js}"></script>
|
<script type="text/javascript" th:src="@{/js/board/contentWrite.js}"></script>
|
||||||
</th:block>
|
</th:block>
|
||||||
<div layout:fragment="content">
|
<div layout:fragment="content">
|
||||||
<main class="pt-3">
|
<main class="pt-3">
|
||||||
<h4>자료 등록</h4>
|
<h4 th:text="${type=='new'?'자료 등록':'자료 수정'}"></h4>
|
||||||
<div class="row mx-0">
|
<div class="row mx-0">
|
||||||
<div class="col-7 card">
|
<div class="col-7 card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
@ -26,6 +29,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="contentForm" th:action="@{/board/saveContent}" method="post">
|
<form id="contentForm" th:action="@{/board/saveContent}" method="post">
|
||||||
|
<th:block th:if="${type!='new'}">
|
||||||
|
<input type="hidden" name="contentSeq" th:value="${content.contentSeq}">
|
||||||
|
</th:block>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="title" class="col-sm-2 col-form-label">분류 선택</label>
|
<label for="title" class="col-sm-2 col-form-label">분류 선택</label>
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
|
|
@ -60,12 +66,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<select class="form-select categorySelector" data-depth="4" name="categorySeq" id="categorySeq" disabled>
|
<select class="form-select categorySelector" data-depth="4" name="categorySeq" id="categorySeq" disabled>
|
||||||
<option value="" selected>분류를 선택해주세요</option>
|
<option value="" th:selected="${type=='new'}">분류를 선택해주세요</option>
|
||||||
<th:block th:each="depth1:${session.categoryList}">
|
<th:block th:each="depth1:${session.categoryList}">
|
||||||
<th:block th:each="depth2:${depth1.childCategoryList}">
|
<th:block th:each="depth2:${depth1.childCategoryList}">
|
||||||
<th:block th:each="depth3:${depth2.childCategoryList}">
|
<th:block th:each="depth3:${depth2.childCategoryList}">
|
||||||
<th:block th:each="depth4:${depth3.childCategoryList}">
|
<th:block th:each="depth4:${depth3.childCategoryList}">
|
||||||
<option th:value="${depth4.categorySeq}" th:data-parentseq="${depth4.parentSeq}" th:text="${depth4.categoryName}"></option>
|
<option th:value="${depth4.categorySeq}" th:data-parentseq="${depth4.parentSeq}"
|
||||||
|
th:text="${depth4.categoryName}" th:selected="${type=='modify' && content.categorySeq == depth4.categorySeq}"></option>
|
||||||
</th:block>
|
</th:block>
|
||||||
</th:block>
|
</th:block>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
@ -76,25 +83,34 @@
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="title" class="col-sm-2 col-form-label">제목</label>
|
<label for="title" class="col-sm-2 col-form-label">제목</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="title" name="title" autocomplete="off">
|
<input type="text" class="form-control" id="title" name="title" autocomplete="off" th:value="${type!='new'?content.title:''}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="createName" class="col-sm-2 col-form-label">작성자</label>
|
<label for="createName" class="col-sm-2 col-form-label">작성자</label>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<input type="hidden" name="createId" th:value="${userId}">
|
<input type="hidden" name="createId" th:value="${type!='new'?content.createId:userId}">
|
||||||
<input type="text" class="form-control" id="createName" th:value="${userName}" readonly>
|
<input type="text" class="form-control" id="createName" th:value="${type!='new'?content.createName:userName}" readonly>
|
||||||
</div>
|
</div>
|
||||||
<label for="createDate" class="col-sm-2 col-form-label">작성일</label>
|
<label for="createDate" class="col-sm-2 col-form-label">작성일</label>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<input type="text" class="form-control" id="createDate" value="저장시 생성" readonly>
|
<input type="text" class="form-control" id="createDate"
|
||||||
|
th:value="${type!='new'?(#temporals.format(content.createDate, 'yyyy-MM-dd HH:mm:dd')):'저장시 생성'}" readonly>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="fileInputer" class="col-sm-2 col-form-label">업로드 자료</label>
|
<label for="fileInputer" class="col-sm-2 col-form-label">업로드 자료</label>
|
||||||
<div class="col-sm-10" style="min-height: 70px;">
|
<div class="col-sm-10" style="min-height: 70px;">
|
||||||
<div class="w-100 h-100 border border-info rounded text-center" id="uploadDiv">
|
<div class="w-100 h-100 border border-info rounded text-center" id="uploadDiv">
|
||||||
|
<th:block th:if="${type=='new'}">
|
||||||
<br>파일을 업로드 해주세요.
|
<br>파일을 업로드 해주세요.
|
||||||
|
</th:block>
|
||||||
|
<th:block th:if="${type=='modify'}">
|
||||||
|
<div class='row-col-6' th:each="fileInfo:${content.childFileList}">
|
||||||
|
<span th:data-fileseq="${fileInfo.fileSeq}" th:text="|${fileInfo.originalName}.${fileInfo.extention} ${fileInfo.fileSize}|"></span>
|
||||||
|
<a href='#' class='uploadedFileDelete text-danger text-decoration-none'>삭제</a>
|
||||||
|
</div>
|
||||||
|
</th:block>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="file" class="d-none" id="fileInputer" multiple>
|
<input type="file" class="d-none" id="fileInputer" multiple>
|
||||||
|
|
@ -102,13 +118,14 @@
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="description" class="col-sm-2 col-form-label">설명</label>
|
<label for="description" class="col-sm-2 col-form-label">설명</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<textarea id="description" name="description"></textarea>
|
<textarea id="description" name="description" th:text="${type!='new'?content.description:''}"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="hashTag" class="col-sm-2 col-form-label">해시태그</label>
|
<label for="hashTag" class="col-sm-2 col-form-label">해시태그</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="hashTag" name="hashTagStr" placeholder="태그는 앞에 #을 붙여 띄어쓰기 없이 작성해주세요. ex) #태그1, #태그2, ..." autocomplete="off">
|
<input type="text" class="form-control" id="hashTag" name="hashTagStr" th:value="${type!='new'?content.hashTagStr:''}"
|
||||||
|
placeholder="태그는 앞에 #을 붙여 띄어쓰기 없이 작성해주세요. ex) #태그1, #태그2, ..." autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,9 @@
|
||||||
</head>
|
</head>
|
||||||
<body class="d-flex flex-column h-100">
|
<body class="d-flex flex-column h-100">
|
||||||
<header th:replace="fragments/header :: headerFragment"></header>
|
<header th:replace="fragments/header :: headerFragment"></header>
|
||||||
<div sec:authorize="isAnonymous()" layout:fragment="content"></div>
|
<div class="h-100" sec:authorize="isAnonymous()" layout:fragment="content"></div>
|
||||||
<div sec:authorize="isAuthenticated()" class="row mx-0 ">
|
<div sec:authorize="isAuthenticated()" class="row mx-0 h-100">
|
||||||
<div class="col-2 centerDiv">
|
<div class="col-2 centerDiv border-end">
|
||||||
<div th:replace="fragments/leftMenu :: leftMenuFragment"></div>
|
<div th:replace="fragments/leftMenu :: leftMenuFragment"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-10 centerDiv">
|
<div class="col-10 centerDiv">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue