중간저장

master
강석 최 2023-06-15 18:13:38 +09:00
parent be93b50e5e
commit f4ae40d781
6 changed files with 219 additions and 103 deletions

View File

@ -1,6 +1,8 @@
package com.dbnt.faisp.main.searchEngine; package com.dbnt.faisp.main.searchEngine;
import com.dbnt.faisp.main.codeMgt.service.CodeMgtService; import com.dbnt.faisp.main.codeMgt.service.CodeMgtService;
import com.dbnt.faisp.main.menuMgt.model.MenuMgt;
import com.dbnt.faisp.main.menuMgt.service.MenuMgtService;
import com.dbnt.faisp.main.publicBoard.model.PublicBoard; import com.dbnt.faisp.main.publicBoard.model.PublicBoard;
import com.dbnt.faisp.main.publicBoard.model.PublicComment; import com.dbnt.faisp.main.publicBoard.model.PublicComment;
import com.dbnt.faisp.main.publicBoard.service.PublicBoardService; import com.dbnt.faisp.main.publicBoard.service.PublicBoardService;
@ -24,20 +26,21 @@ import java.util.List;
public class SearchEngineController { public class SearchEngineController {
private final SearchEngineService searchEngineService; private final SearchEngineService searchEngineService;
private final MenuMgtService menuMgtService;
@GetMapping("/searchPage") @GetMapping("/searchPage")
public ModelAndView organMgtPage(@AuthenticationPrincipal UserInfo loginUser, SearchParams params) { public ModelAndView organMgtPage(@AuthenticationPrincipal UserInfo loginUser, SearchParams params) {
ModelAndView mav = new ModelAndView("searchEngine/search"); ModelAndView mav = new ModelAndView("searchEngine/search");
if (Utils.isEmpty(params.getActiveTab())){ if (Utils.isEmpty(params.getActiveTab())){
params.setActiveTab("all"); params.setActiveTab("all");
params.setPageIndex(1);
} }
mav.addObject("searchParams", params);
int totalCnt = 0; int totalCnt = 0;
SearchResult result = null; SearchResult result = null;
MenuMgt menuParam = new MenuMgt();
switch (params.getActiveTab()){ switch (params.getActiveTab()){
case "all": case "all":
// params.setOffset("0"); params.setQueryInfo();
// params.setLimit("10");
params.setForm("search_menu_view.search_menu_view"); params.setForm("search_menu_view.search_menu_view");
result = searchEngineService.getData(params, SearchMenuView.class); result = searchEngineService.getData(params, SearchMenuView.class);
totalCnt += result.getTotalCount(); totalCnt += result.getTotalCount();
@ -50,26 +53,46 @@ public class SearchEngineController {
result = searchEngineService.getData(params, SearchFileView.class); result = searchEngineService.getData(params, SearchFileView.class);
totalCnt += result.getTotalCount(); totalCnt += result.getTotalCount();
mav.addObject("fileResult", result); mav.addObject("fileResult", result);
menuParam.setUserSeq(loginUser.getUserSeq());
menuParam.setFirstIndex(0);
menuParam.setRowCnt(Integer.MAX_VALUE);
mav.addObject("menuList", menuMgtService.selectMenuMgtList(null));
break; break;
case "menu": case "menu":
params.setQueryInfo();
params.setForm("search_menu_view.search_menu_view"); params.setForm("search_menu_view.search_menu_view");
result = searchEngineService.getData(params, SearchMenuView.class); result = searchEngineService.getData(params, SearchMenuView.class);
totalCnt += result.getTotalCount(); totalCnt += result.getTotalCount();
params.setContentCnt(totalCnt);
mav.addObject("menuResult", result); mav.addObject("menuResult", result);
params.setPaginationInfo();
break; break;
case "board": case "board":
params.setQueryInfo();
params.setForm("search_board_view.search_board_view"); params.setForm("search_board_view.search_board_view");
result = searchEngineService.getData(params, SearchBoardView.class); result = searchEngineService.getData(params, SearchBoardView.class);
totalCnt += result.getTotalCount(); totalCnt += result.getTotalCount();
params.setContentCnt(totalCnt);
mav.addObject("boardResult", result); mav.addObject("boardResult", result);
params.setPaginationInfo();
menuParam.setUserSeq(loginUser.getUserSeq());
menuParam.setFirstIndex(0);
menuParam.setRowCnt(Integer.MAX_VALUE);
mav.addObject("menuList", menuMgtService.selectMenuMgtList(null));
break; break;
case "file": case "file":
params.setQueryInfo();
params.setForm("search_file_view.search_file_view"); params.setForm("search_file_view.search_file_view");
result = searchEngineService.getData(params, SearchFileView.class); result = searchEngineService.getData(params, SearchFileView.class);
totalCnt += result.getTotalCount(); totalCnt += result.getTotalCount();
params.setContentCnt(totalCnt);
mav.addObject("fileResult", result); mav.addObject("fileResult", result);
params.setPaginationInfo();
break; break;
} }
mav.addObject("searchParams", params);
mav.addObject("totalCnt", totalCnt); mav.addObject("totalCnt", totalCnt);
return mav; return mav;
} }

View File

@ -3,12 +3,48 @@ package com.dbnt.faisp.main.searchEngine.model;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.persistence.Transient;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
public class SearchParams { public class SearchParams {
private String form; private String form;
private String keyword; private String keyword;
private String offset; private Integer offset;
private String limit; private Integer limit;
private String activeTab; private String activeTab;
private Integer pageIndex;
private Integer contentCnt;
private Integer startNum=1; // pagination 시작값
private Integer endNum=5; // pagination 마지막값
private Integer maxNum; // pagination 최대값
public void setQueryInfo(){
setLimit(10);
setOffset((getPageIndex()-1)*10);
}
public void setPaginationInfo(){
int contentCnt = getContentCnt();
int rowCnt = 10;
int maxNum = (int)Math.ceil(((double)contentCnt)/rowCnt);
if (maxNum==0){
maxNum = 1;
}
setMaxNum(maxNum);
int pageIndex = getPageIndex();
int startNum = pageIndex - 2;
if(startNum <= 0){
startNum = 1;
}
setStartNum(startNum);
int endNum = startNum + 4;
if(endNum>maxNum){
endNum = maxNum;
}
setEndNum(endNum);
}
} }

View File

@ -41,8 +41,9 @@ public class SearchEngineService {
.queryParam("select", "*") .queryParam("select", "*")
.queryParam("from", params.getForm()) .queryParam("from", params.getForm())
.queryParam("where", "text_idx = '"+params.getKeyword()+"' allword synonym order by $relevance desc") .queryParam("where", "text_idx = '"+params.getKeyword()+"' allword synonym order by $relevance desc")
// .queryParam("offset", params.getOffset()) .queryParam("offset", params.getOffset().toString())
// .queryParam("limit", params.getLimit()) //.queryParam("limit", params.getLimit().toString())
// total_count 갯수수가 limit로 제한걸려 조건에서 제외. 검색 결과는 정상적으로 나옴.
.queryParam("charset", "UTF-8") .queryParam("charset", "UTF-8")
.queryParam("hilite-keywords", params.getKeyword()) .queryParam("hilite-keywords", params.getKeyword())
.encode() .encode()

View File

@ -59,10 +59,12 @@ $(document).on('click', '.allChk', function (){
$(this).parents('table').find('[type="checkbox"]').prop("checked", this.checked); $(this).parents('table').find('[type="checkbox"]').prop("checked", this.checked);
}) })
$(document).on('click', '.page-item', function (){ $(document).on('click', '.page-item', function (){
if(!this.className.includes("modalPage")){ if(this.className.includes("modalPage")){
searchFormSubmit($(this).attr("data-pageindex"))
}else{
searchModalSubmit($(this).attr("data-pageindex")) searchModalSubmit($(this).attr("data-pageindex"))
}else if(this.className.includes("searchPage")){
searchPageFormSubmit($(this).attr("data-pageindex"))
}else{
searchFormSubmit($(this).attr("data-pageindex"))
} }
}) })
$(document).on('click', '#searchModalBtn', function (){ $(document).on('click', '#searchModalBtn', function (){
@ -84,6 +86,10 @@ function searchFormSubmit(pageIndex){
$("#pageIndex").val(pageIndex); $("#pageIndex").val(pageIndex);
$("#searchBtn").click(); $("#searchBtn").click();
} }
function searchPageFormSubmit(pageIndex){
$("#pageIndexInput").val(pageIndex);
$("#searchForm").submit();
}
function searchModalSubmit(pageIndex){ function searchModalSubmit(pageIndex){
$("#modalPageIndex").val(pageIndex); $("#modalPageIndex").val(pageIndex);
$.ajax({ $.ajax({

View File

@ -18,3 +18,12 @@ $(function () {
} }
}); });
}); });
$(document).on('click', '#searchBtn', function (){
searchPageFormSubmit(1);
})
$(document).on('click', '.searchTabLink', function (){
$("#activeTabInput").val($(this).attr('data-activetab'))
searchPageFormSubmit(1);
})

View File

@ -8,16 +8,17 @@
</th:block> </th:block>
<th:block layout:fragment="script"> <th:block layout:fragment="script">
<script type="text/javascript" th:src="@{/js/searchEngine/prefixfree.min.js}"></script> <script type="text/javascript" th:src="@{/js/searchEngine/prefixfree.min.js}"></script>
<script type="text/javascript" th:src="@{/js/searchEngine/layout.js}"></script> <script type="text/javascript" th:src="@{/js/searchEngine/searchPage.js}"></script>
</th:block> </th:block>
<div layout:fragment="content"> <div layout:fragment="content">
<main> <main>
<div class="headerArea"> <div class="headerArea">
<header id="searchHeader"> <header id="searchHeader">
<div class="searchPagetop guideBox"> <div class="searchPagetop guideBox">
<form method="get" action="/search/searchPage"> <form method="get" action="/search/searchPage" id="searchForm">
<div class="searchBox"> <div class="searchBox">
<input type="hidden" name="activeTab" th:value="${searchParams.activeTab}"> <input type="hidden" name="pageIndex" id="pageIndexInput" th:value="${searchParams.pageIndex}">
<input type="hidden" name="activeTab" id="activeTabInput" th:value="${searchParams.activeTab}">
<input type="text" title="입력" name="keyword" placeholder="검색어를 입력해주세요." th:value="${searchParams.keyword}"/> <input type="text" title="입력" name="keyword" placeholder="검색어를 입력해주세요." th:value="${searchParams.keyword}"/>
<a href="#" id="searchBtn">검색</a> <a href="#" id="searchBtn">검색</a>
@ -104,117 +105,157 @@
<li th:class="${searchParams.activeTab eq 'board'?'active':''}"><a class="searchTabLink" href="#" data-activetab="board">게시판</a></li> <li th:class="${searchParams.activeTab eq 'board'?'active':''}"><a class="searchTabLink" href="#" data-activetab="board">게시판</a></li>
<li th:class="${searchParams.activeTab eq 'file'?'active':''}"><a class="searchTabLink" href="#" data-activetab="file">첨부파일</a></li> <li th:class="${searchParams.activeTab eq 'file'?'active':''}"><a class="searchTabLink" href="#" data-activetab="file">첨부파일</a></li>
</ul> </ul>
<section class="searchDataListBox"> <section class="searchDataListBox" th:if="${searchParams.activeTab eq 'all' or searchParams.activeTab eq 'menu'}">
<h3>메뉴검색<span th:text="|${menuResult.totalCount}건|"></span></h3> <h3>메뉴검색<span th:text="|${menuResult.totalCount}건|"></span></h3>
<ul class="menuList"> <ul class="menuList">
<th:block th:each="menu:${menuResult.rowList}"> <li th:each="menu:${menuResult.rowList}">
<li>
<ol> <ol>
<li th:text="${menu.menu_nm}"></li> <li><a th:href="${menu.menu_url}" th:text="${menu.menu_nm}"></a></li>
</ol> </ol>
</li> </li>
</ul>
<div class="optionView" th:if="${searchParams.activeTab eq 'all'}">
<a href="#" class="plusView searchTabLink" data-activetab="menu">더보기 +</a>
</div>
<div class="row justify-content-center" th:if="${searchParams.activeTab eq 'menu'}">
<div class="col-auto">
<nav aria-label="Page navigation">
<ul class="pagination mb-0">
<th:block th:if="${searchParams.pageIndex>3}">
<li class="page-item searchPage" 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 searchPage" th:data-pageindex="${num}" th:classappend="${searchParams.pageIndex eq 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 searchPage" th:data-pageindex="${(searchParams.pageIndex)+3}">
<a class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</th:block> </th:block>
</ul> </ul>
<div class="optionView"> </nav>
<!--<a href="#" class="plusView">더보기 +</a>--> </div>
</div> </div>
</section> </section>
<section class="searchDataListBox"> <section class="searchDataListBox" th:if="${searchParams.activeTab eq 'all' or searchParams.activeTab eq 'board'}">
<h3>게시판<span th:text="|${boardResult.totalCount}건|"></span></h3> <h3>게시판<span th:text="|${boardResult.totalCount}건|"></span></h3>
<ul class="boardList"> <ul class="boardList">
<li> <li th:each="board:${boardResult.rowList}">
<dl> <dl>
<dt><a href="#">2023년 2월 부안<span class="red bold">해양</span>경찰서 위도파출소장 업무추진비 집행내역 공개</a><span class="titleDate">2023.03.08</span></dt> <dt>
<dd>2023년 2월 부안<span class="red bold">해양</span>경찰서 위도파출소장 업무추진비 집행내역입니다.</dd> <th:block th:if="${board.menu_key ne 0}">
<dd>해양경찰청 > 재정정보 > 업무추진비공개</dd> [<th:block th:each="menu:${menuList}">
<dd> <th:block th:if="${menu.menuKey eq board.menu_key}">
<b class="searchFileBtn openBul">· 첨부파일(2)</b> <th:block th:if="${!#strings.isEmpty(menu.cat3Cd)}">
<div class="searchFileList"> <th:block th:each="code:${session.commonCode.get('CAT3')}">
<a href="#">첨부파일 제목.hwp</a> <th:block th:if="${menu.cat3Cd eq code.itemCd}" th:text="${code.itemValue}"></th:block>
<a href="#">첨부파일 제목.hwp</a> </th:block>
</div> </th:block>
</dd> <th:block th:if="${!#strings.isEmpty(menu.cat2Cd) and #strings.isEmpty(menu.cat3Cd)}">
</dl> <th:block th:each="code:${session.commonCode.get('CAT2')}">
</li> <th:block th:if="${menu.cat2Cd eq code.itemCd}" th:text="${code.itemValue}"></th:block>
</th:block>
<li> </th:block>
<dl> <th:block th:if="${!#strings.isEmpty(menu.cat1Cd) and #strings.isEmpty(menu.cat2Cd) and #strings.isEmpty(menu.cat3Cd)}">
<dt><a href="#">2023년 2월 부안<span class="red bold">해양</span>경찰서 위도파출소장 업무추진비 집행내역 공개</a><span class="titleDate">2023.03.08</span></dt> <th:block th:each="code:${session.commonCode.get('CAT1')}">
<dd>2023년 2월 부안<span class="red bold">해양</span>경찰서 위도파출소장 업무추진비 집행내역입니다.2023년 2월 부안<span class="red bold">해양</span>경찰서 위도파출소장 업무추진비 집행내역입니다.2023년 2월 부안<span class="red bold">해양</span>경찰서 위도파출소장 업무추진비 집행내역입니다.</dd> <th:block th:if="${menu.cat1Cd eq code.itemCd}" th:text="${code.itemValue}"></th:block>
<dd>해양경찰청 > 재정정보 > 업무추진비공개</dd> </th:block>
</dl> </th:block>
</li> </th:block>
<li> </th:block>]
<dl> </th:block>
<dt><a href="#">2023년 2월 부안<span class="red bold">해양</span>경찰서 위도파출소장 업무추진비 집행내역 공개</a><span class="titleDate">2023.03.08</span></dt> <a href="#" th:text="${board.title1}"></a>
<dd>2023년 2월 부안<span class="red bold">해양</span>경찰서 위도파출소장 업무추진비 집행내역입니다.</dd> <span class="titleDate" th:text="${#temporals.format(board.wrt_dt, 'yyyy-MM-dd HH:mm')}"></span>
<dd>해양경찰청 > 재정정보 > 업무추진비공개</dd> </dt>
<dd> <dt th:if="${!#strings.isEmpty(board.title2)}"><a href="#" th:text="${board.title2}"></a></dt>
<b class="searchFileBtn openBul">· 첨부파일(1)</b> <dd th:if="${!#strings.isEmpty(board.content1)}" th:utext="${board.content1}"></dd>
<div class="searchFileList"> <dd th:if="${!#strings.isEmpty(board.content2)}" th:utext="${board.content2}"></dd>
<a href="#">첨부파일 제목.hwp</a> <dd th:if="${!#strings.isEmpty(board.content3)}" th:utext="${board.content3}"></dd>
</div> <dd th:if="${!#strings.isEmpty(board.content4)}" th:utext="${board.content4}"></dd>
</dd> <dd th:if="${!#strings.isEmpty(board.content5)}" th:utext="${board.content5}"></dd>
</dl>
</li>
<li>
<dl>
<dt><a href="#">2023년 2월 부안<span class="red bold">해양</span>경찰서 위도파출소장 업무추진비 집행내역 공개</a><span class="titleDate">2023.03.08</span></dt>
<dd>2023년 2월 부안<span class="red bold">해양</span>경찰서 위도파출소장 업무추진비 집행내역입니다.</dd>
<dd>해양경찰청 > 재정정보 > 업무추진비공개</dd>
<dd>
<b class="searchFileBtn openBul">· 첨부파일(1)</b>
<div class="searchFileList">
<a href="#">첨부파일 제목.hwp</a>
</div>
</dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<div class="optionView"> <div class="optionView" th:if="${searchParams.activeTab eq 'all'}">
<a href="#" class="plusView">더보기 +</a> <a href="#" class="plusView searchTabLink" data-activetab="board">더보기 +</a>
</div>
<div class="row justify-content-center" th:if="${searchParams.activeTab eq 'board'}">
<div class="col-auto">
<nav aria-label="Page navigation">
<ul class="pagination mb-0">
<th:block th:if="${searchParams.pageIndex>3}">
<li class="page-item searchPage" 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 searchPage" th:data-pageindex="${num}" th:classappend="${searchParams.pageIndex eq 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 searchPage" 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>
</section> </section>
<section class="searchDataListBox"> <section class="searchDataListBox" th:if="${searchParams.activeTab eq 'all' or searchParams.activeTab eq 'file'}">
<h3>첨부파일<span th:text="|${fileResult.totalCount}건|"></span></h3> <h3>첨부파일<span th:text="|${fileResult.totalCount}건|"></span></h3>
<ul class="boardList boardFileList"> <ul class="boardList boardFileList">
<li> <li th:each="file:${fileResult.rowList}">
<dl> <dl>
<dt><a href="#">180731 <span class="red bold">해양</span>경찰 “지자체 해안방제 대응 역량 높인다”.hwp</a><span class="titleDate">2018.07.31</span><a href="#" class="downBtn">내려받기</a></dt> <dt><a href="#" th:text="${#strings.concat(file.orig_nm, '.', file.file_extn)}"></a><a href="#" class="downBtn">내려받기</a></dt>
<dd>(화) 09:00 담당부서 기동방제과 담당과장 서기관 서정목 (044-205-2094/010-3942-1000) 담 당 자 사무관 김백제 (044-205-2296/010-9755-1327) <span class="red bold">해양</span>경찰 “지자체 해안방제 대응 역량 높인다” - 8월14일까지 지자체 대상 해안방제정책설명회 개최 - 해양경찰이 대규모 해양오염 사고 시.</dd> <dd th:text="${file.file_content}"></dd>
<dd>해양경찰청 > 새소식/알림 > 보도자료</dd>
</dl>
</li>
<li>
<dl>
<dt><a href="#">(0730)주문진 영진해변 파도에 외해로 떠밀리던 물놀이객 구조.hwp</a><span class="titleDate">2018.07.31</span><a href="#" class="downBtn">내려받기</a></dt>
<dd>보 도 자 료 보도일시 배포 즉시 보도해 주시기 바랍니다. 총 1쪽(붙임 없음) 배포일시 2018.7.30.(월) 담당부서 속초<span class="red bold">해양</span>경찰서 기획운영과 담당과장 기획운영과장 경정 곽윤희(033-634-2212) 담 당 자 기획운영과 경사 홍상의(033-634-2212) 속초해경, 강릉 영진해변 물놀이객 구조해 -.</dd>
<dd>속초해양경찰서 > 알림사항 > 보도자료</dd>
</dl>
</li>
<li>
<dl>
<dt><a href="#">선박교통관제 시설관리규정(시행 18.4.2).hwp</a><span class="titleDate">2018.07.31</span><a href="#" class="downBtn">내려받기</a></dt>
<dd>선박교통관제 시설관리규정 선박교통관제 시설관리규정 법제처 - / - 국가법령정보센터 [시행 2018. 4. 2.] [<span class="red bold">해양</span>경찰청훈령 제61호, 2018. 4. 2., 일부개정.] 해양경찰청(해상교통관제과) 044-205-2485 {전문} 제1조(목적) 이 규정은「선박의 입항 및 출항 등에 관한....</dd>
<dd>해양경찰청 > VTS > 알림마당</dd>
</dl>
</li>
<li>
<dl>
<dt><a href="#">선박교통관제 시설관리규정(시행 18.4.2).hwp</a><span class="titleDate">2018.07.31</span><a href="#" class="downBtn">내려받기</a></dt>
<dd>선박교통관제 시설관리규정 선박교통관제 시설관리규정 법제처 - / - 국가법령정보센터 [시행 2018. 4. 2.] [<span class="red bold">해양</span>경찰청훈령 제61호, 2018. 4. 2., 일부개정.] 해양경찰청(해상교통관제과) 044-205-2485 {전문} 제1조(목적) 이 규정은「선박의 입항 및 출항 등에 관한....</dd>
<dd>해양경찰청 > VTS > 알림마당</dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<div class="optionView"> <div class="optionView" th:if="${searchParams.activeTab eq 'all'}">
<!--<a href="#" class="plusView">더보기 +</a>--> <a href="#" class="plusView searchTabLink" data-activetab="file">더보기 +</a>
</div>
<div class="row justify-content-center" th:if="${searchParams.activeTab eq 'file'}">
<div class="col-auto">
<nav aria-label="Page navigation">
<ul class="pagination mb-0">
<th:block th:if="${searchParams.pageIndex>3}">
<li class="page-item searchPage" 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 searchPage" th:data-pageindex="${num}" th:classappend="${searchParams.pageIndex eq 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 searchPage" 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>
</section> </section>
</div> </div>
<div class="popularSearchWord"> <div class="popularSearchWord">
<section> <section>