메인페이지 추가.

master
강석 최 2021-12-22 18:09:17 +09:00
parent ec6468d64b
commit 0bd96565ed
25 changed files with 251 additions and 68 deletions

View File

@ -34,9 +34,14 @@ public class BoardController {
@GetMapping("/main") @GetMapping("/main")
public ModelAndView main() { public ModelAndView main(Board param) {
ModelAndView mav = new ModelAndView("main"); ModelAndView mav = new ModelAndView("board/main");
param.setStatus("M");
mav.addObject("contentList", boardService.selectContentList(param));
param.setQueryInfo();
param.setContentCnt(boardService.selectContentListCnt(param));
param.setPaginationInfo();
mav.addObject("searchParams", param);
return mav; return mav;
} }
@ -72,7 +77,7 @@ public class BoardController {
@RequestParam(value = "tagName", required = false) List<String> tagNameList @RequestParam(value = "tagName", required = false) List<String> tagNameList
){ ){
ModelAndView mav = new ModelAndView("board/contentList"); ModelAndView mav = new ModelAndView("board/contentList");
mav.addObject("pageTitle", boardCategoryService.getPageTitle(board.getCategorySeq())); mav.addObject("pageTitle", boardCategoryService.getDepth4PageTitle(board.getCategorySeq()));
board.setQueryInfo(); board.setQueryInfo();
if(tagNameList != null && tagNameList.size() != 0){ if(tagNameList != null && tagNameList.size() != 0){
board = boardService.setHashTagSearch(board, tagNameList); board = boardService.setHashTagSearch(board, tagNameList);

View File

@ -40,7 +40,7 @@ public class Board extends BaseModel{
private LocalDateTime createDate; private LocalDateTime createDate;
@Transient @Transient
private String originalName; private String categoryName;
@Transient @Transient
private String createName; private String createName;
@ -58,4 +58,7 @@ public class Board extends BaseModel{
private String hashTagStr; private String hashTagStr;
@Transient @Transient
private List<MultipartFile> fileList; private List<MultipartFile> fileList;
@Transient
private String originalName;
} }

View File

@ -0,0 +1,20 @@
package com.dbnt.kcgfilemanager.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Getter
@Setter
@Entity
@NoArgsConstructor
@Table(name = "CONTENT_POSITION")
public class ContentPosition {
@Id
@Column(name = "CATEGORY_SEQ")
private Integer categorySeq;
@Column(name = "CATEGORY_NAME", nullable = false)
private String categoryName;
}

View File

@ -0,0 +1,8 @@
package com.dbnt.kcgfilemanager.repository;
import com.dbnt.kcgfilemanager.model.ContentPosition;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ContentPositionRepository extends JpaRepository<ContentPosition, Integer> {
}

View File

@ -2,8 +2,10 @@ package com.dbnt.kcgfilemanager.service;
import com.dbnt.kcgfilemanager.model.BoardCategory; import com.dbnt.kcgfilemanager.model.BoardCategory;
import com.dbnt.kcgfilemanager.model.CategoryRole; import com.dbnt.kcgfilemanager.model.CategoryRole;
import com.dbnt.kcgfilemanager.model.ContentPosition;
import com.dbnt.kcgfilemanager.repository.BoardCategoryRepository; import com.dbnt.kcgfilemanager.repository.BoardCategoryRepository;
import com.dbnt.kcgfilemanager.repository.CategoryRoleRepository; import com.dbnt.kcgfilemanager.repository.CategoryRoleRepository;
import com.dbnt.kcgfilemanager.repository.ContentPositionRepository;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -17,6 +19,7 @@ public class BoardCategoryService {
private final BoardCategoryRepository boardCategoryRepository; private final BoardCategoryRepository boardCategoryRepository;
private final CategoryRoleRepository categoryRoleRepository; private final CategoryRoleRepository categoryRoleRepository;
private final ContentPositionRepository contentPositionRepository;
public List<BoardCategory> selectBoardCategory(Integer parentSeq, Integer depth) { public List<BoardCategory> selectBoardCategory(Integer parentSeq, Integer depth) {
@ -69,6 +72,10 @@ public class BoardCategoryService {
return getPageTitle(category.getParentSeq())+" > "+category.getCategoryName(); return getPageTitle(category.getParentSeq())+" > "+category.getCategoryName();
} }
public String getDepth4PageTitle(Integer categorySeq) {
ContentPosition contentPosition = contentPositionRepository.findById(categorySeq).orElse(null);
return contentPosition.getCategoryName();
}
public String makeFilePath(Integer categorySeq){ public String makeFilePath(Integer categorySeq){
BoardCategory category = boardCategoryRepository.findById(categorySeq).orElse(null); BoardCategory category = boardCategoryRepository.findById(categorySeq).orElse(null);
if(category.getParentSeq()==null){ if(category.getParentSeq()==null){

View File

@ -49,7 +49,7 @@ public class BoardService {
board.getCategoryList().add(category); board.getCategoryList().add(category);
} }
searchResult.setContentList(boardMapper.selectContentList(board)); searchResult.setContentList(selectContentList(board));
results.add(searchResult); results.add(searchResult);
} }
return results; return results;

View File

@ -5,12 +5,17 @@
<mapper namespace="com.dbnt.kcgfilemanager.mapper.BoardMapper"> <mapper namespace="com.dbnt.kcgfilemanager.mapper.BoardMapper">
<select id="selectContentList" resultType="Board" parameterType="Board"> <select id="selectContentList" resultType="Board" parameterType="Board">
SELECT A.CONTENT_SEQ AS contentSeq, SELECT
A.TITLE AS title, <if test='status == "M"'>
C.FILE_CNT AS fileCnt, D.CATEGORY_NAME AS categoryName,
B.NAME AS createName, </if>
A.CREATE_DATE AS createDate, A.CONTENT_SEQ AS contentSeq,
A.VIEW_CNT AS viewCnt A.CATEGORY_SEQ AS categorySeq,
A.TITLE AS title,
C.FILE_CNT AS fileCnt,
B.NAME AS createName,
A.CREATE_DATE AS createDate,
A.VIEW_CNT AS viewCnt
FROM BOARD A FROM BOARD A
INNER JOIN USER_INFO B INNER JOIN USER_INFO B
ON A.CREATE_ID = B.USER_ID ON A.CREATE_ID = B.USER_ID
@ -18,7 +23,14 @@
FROM FILE_INFO FROM FILE_INFO
GROUP BY CONTENT_SEQ ) C GROUP BY CONTENT_SEQ ) C
ON A.CONTENT_SEQ = C.CONTENT_SEQ ON A.CONTENT_SEQ = C.CONTENT_SEQ
<if test='status == "M"'>
INNER JOIN CONTENT_POSITION D
ON A.CATEGORY_SEQ = D.CATEGORY_SEQ
</if>
<where> <where>
<if test="status != null and status != ''">
AND A.STATUS = #{status}
</if>
<if test="categorySeq != null and categorySeq != ''"> <if test="categorySeq != null and categorySeq != ''">
AND A.CATEGORY_SEQ = #{categorySeq} AND A.CATEGORY_SEQ = #{categorySeq}
</if> </if>
@ -60,7 +72,12 @@
) )
</if> </if>
</where> </where>
ORDER BY A.CREATE_DATE DESC <if test='status == "M"'>
ORDER BY A.VIEW_CNT DESC
</if>
<if test="status == null or status == ''">
ORDER BY A.CREATE_DATE DESC
</if>
LIMIT #{rowCnt} OFFSET #{firstIndex} LIMIT #{rowCnt} OFFSET #{firstIndex}
</select> </select>
<!--<if test="endDate != null and endDate != ''"> <!--<if test="endDate != null and endDate != ''">
@ -75,7 +92,55 @@
FROM FILE_INFO FROM FILE_INFO
GROUP BY CONTENT_SEQ ) C GROUP BY CONTENT_SEQ ) C
ON A.CONTENT_SEQ = C.CONTENT_SEQ ON A.CONTENT_SEQ = C.CONTENT_SEQ
WHERE A.CATEGORY_SEQ = ${categorySeq} <if test='status == "M"'>
INNER JOIN CONTENT_POSITION D
ON A.CATEGORY_SEQ = D.CATEGORY_SEQ
</if>
<where>
<if test="status != null and status != ''">
AND A.STATUS = #{status}
</if>
<if test="categorySeq != null and categorySeq != ''">
AND A.CATEGORY_SEQ = #{categorySeq}
</if>
<if test="title != null and title != ''">
AND A.TITLE LIKE CONCAT('%', #{title}, '%')
</if>
<if test="createName != null and createName != ''">
AND B.NAME LIKE CONCAT('%', #{createName}, '%')
</if>
<if test="startDate != null and startDate != ''">
AND A.CREATE_DATE >= CONCAT(#{startDate}, ' 00:00:00')
</if>
<if test="endDate != null and endDate != ''">
AND A.CREATE_DATE &lt;= CONCAT(#{endDate}, ' 23:59:59')
</if>
<if test="hashTagList != null and hashTagList.size != 0">
AND A.CONTENT_SEQ IN (
SELECT B.CONTENT_SEQ
FROM HASH_TAG A
INNER JOIN HASH_TAG_LINK B ON A.TAG_SEQ = B.TAG_SEQ
<where>
<foreach collection="hashTagList" item="hashTag">
OR A.TAG_NAME LIKE CONCAT('%',#{hashTag.tagName},'%')
</foreach>
</where>
)
</if>
<if test="categoryList != null and categoryList.size != 0">
AND A.CATEGORY_SEQ IN
<foreach collection="categoryList" item="category" open="(" separator="," close=")">
#{category.categorySeq}
</foreach>
</if>
<if test="originalName != null and originalName != ''">
AND A.CONTENT_SEQ IN (
SELECT DISTINCT CONTENT_SEQ
FROM FILE_INFO
WHERE ORIGINAL_NAME LIKE CONCAT('%', #{originalName}, '%')
)
</if>
</where>
</select> </select>
<select id="selectHashTagListFromContentSeq" resultType="HashTag" parameterType="int"> <select id="selectHashTagListFromContentSeq" resultType="HashTag" parameterType="int">

View File

@ -4,7 +4,11 @@ $(function (){
language: "ko" language: "ko"
}); });
}) })
$(document).on('click', '.categoryTr', function (){
if(confirm(this.innerText+" 페이지로 이동하시겠습니까?")){
location.href = "/board/contentList?categorySeq="+$(this).attr("data-categoryseq")
}
})
$(document).on('click', '.contentTr', function (){ $(document).on('click', '.contentTr', function (){
$(".contentCheckBox").prop('checked', false); $(".contentCheckBox").prop('checked', false);
const target = $(this).find(".contentCheckBox")[0]; const target = $(this).find(".contentCheckBox")[0];

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<th:block layout:fragment="script"> <th:block layout:fragment="script">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<th:block layout:fragment="script"> <th:block layout:fragment="script">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<div layout:fragment="content" class="pt-3"> <div layout:fragment="content" class="pt-3">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<div layout:fragment="content"> <div layout:fragment="content">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<th:block layout:fragment="css"> <th:block layout:fragment="css">

View File

@ -7,7 +7,7 @@
<div class="col-auto"> <div class="col-auto">
<h5 class="fw-bold"> <h5 class="fw-bold">
<th:block th:if="${content.status =='M'}"> <th:block th:if="${content.status =='M'}">
<i class="bi bi-star-fill"></i> (메인)
</th:block> </th:block>
<span th:text="${content.title}"></span> <span th:text="${content.title}"></span>
</h5> </h5>

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<th:block layout:fragment="script"> <th:block layout:fragment="script">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<th:block layout:fragment="script"> <th:block layout:fragment="script">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<th:block layout:fragment="css"> <th:block layout:fragment="css">

View File

@ -0,0 +1,109 @@
<!DOCTYPE html>
<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="script">
<script type="text/javascript" th:src="@{/js/board/contentList.js}"></script>
</th:block>
<div layout:fragment="content" class="pt-3">
<main class="pt-3">
<h4>사용자 메인 페이지</h4>
<div class="row mx-0">
<div class="col-12 card">
<div class="card-body">
<div class="row justify-content-start">
<div class="col-7">
<div class="row-cols-6">
<table class="table table-striped table-hover">
<thead>
<tr>
<th></th>
<th>제목</th>
<th>파일 수</th>
<th>작성자</th>
<th>작성일</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
<th:block th:each="content:${contentList}">
<tr class="categoryTr" th:data-categoryseq="${content.categorySeq}">
<td class="p-0 fs-6" colspan="7" th:text="${content.categoryName}"></td>
</tr>
<tr class="contentTr">
<td>
<input type="checkbox" class="contentCheckBox" th:value="${content.contentSeq}">
</td>
<td th:text="${content.title}"></td>
<td th:text="${content.fileCnt}"></td>
<td th:text="${content.createName}"></td>
<th:block th:if="${#dates.format(#dates.createNow(), 'yyyy-MM-dd')} == ${#temporals.format(content.createDate, 'yyyy-MM-dd')}">
<td th:text="${#temporals.format(content.createDate, 'HH:mm:ss')}"></td>
</th:block>
<th:block th:if="${#dates.format(#dates.createNow(), 'yyyy-MM-dd')} != ${#temporals.format(content.createDate, 'yyyy-MM-dd')}">
<td th:text="${#temporals.format(content.createDate, 'yyyy-MM-dd')}"></td>
</th:block>
<td class="viewCntTd" th:text="${content.viewCnt}"></td>
</tr>
</th:block>
</tbody>
</table>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<nav aria-label="Page navigation">
<ul class="pagination">
<th:block th:if="${searchParams.pageIndex>3}">
<li class="page-item" th:data-pageindex="${(searchParams.pageIndex)-3}">
<a class="page-link" href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
</th:block>
<th:block th:each="num : ${#numbers.sequence(searchParams.startNum, searchParams.endNum)}">
<li class="page-item" th:data-pageindex="${num}" th:classappend="${searchParams.pageIndex==num?'active':''}">
<a class="page-link" href="#" th:text="${num}"></a>
</li>
</th:block>
<th:block th:if="${searchParams.maxNum>searchParams.endNum+2}">
<li class="page-item" th:data-pageindex="${(searchParams.pageIndex)+3}">
<a class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</th:block>
</ul>
</nav>
</div>
</div>
</div>
<div class="col-5">
<ul class="nav nav-tabs" id="boardTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="contentTab" data-bs-toggle="tab" data-bs-target="#contentDiv" type="button" role="tab">내용</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="logTab" data-bs-toggle="tab" data-bs-target="#logDiv" type="button" role="tab">이력</button>
</li>
</ul>
<div class="tab-content border border-top-0" id="boardDiv">
<div class="tab-pane fade show active" id="contentDiv" role="tabpanel" aria-labelledby="contentTab">
<div class="py-5 text-center">
<h3>왼쪽 목록에서 선택해주세요.</h3>
</div>
</div>
<div class="tab-pane fade" id="logDiv" role="tabpanel" aria-labelledby="logTab">
<div class="py-5 text-center">
<h3>왼쪽 목록에서 선택해주세요.</h3>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</html>

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org">
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<footer th:fragment="footerFragment" class="d-flex flex-wrap py-2 mt-auto border-top bg-dark"> <footer th:fragment="footerFragment" class="d-flex flex-wrap py-2 mt-auto border-top bg-dark">
<div class="row mx-3"> <div class="row mx-3">
<div class="col-auto"> <div class="col-auto">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<th:block layout:fragment="script"> <th:block layout:fragment="script">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<div layout:fragment="content" class="h-100"> <div layout:fragment="content" class="h-100">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<div layout:fragment="content" class="p-5"> <div layout:fragment="content" class="p-5">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<div layout:fragment="content"> <div layout:fragment="content">

View File

@ -1,7 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko" <html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}"> layout:decorate="~{layout/layout}">
<div layout:fragment="content"> <div layout:fragment="content">

View File

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}">
<div layout:fragment="content" class="pt-3">
<h4>사용자 메인 페이지</h4>
</div>
</html>