중간저장.

master
강석 최 2023-06-14 18:15:12 +09:00
parent dd3453887d
commit be93b50e5e
10 changed files with 210 additions and 160 deletions

View File

@ -41,7 +41,6 @@ dependencies {
implementation 'com.oracle.database.jdbc:ojdbc8:21.7.0.0'
implementation files('libs/tibero6-jdbc.jar')
// json
implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'

View File

@ -4,7 +4,7 @@ import com.dbnt.faisp.main.codeMgt.service.CodeMgtService;
import com.dbnt.faisp.main.publicBoard.model.PublicBoard;
import com.dbnt.faisp.main.publicBoard.model.PublicComment;
import com.dbnt.faisp.main.publicBoard.service.PublicBoardService;
import com.dbnt.faisp.main.searchEngine.model.SearchParams;
import com.dbnt.faisp.main.searchEngine.model.*;
import com.dbnt.faisp.main.searchEngine.service.SearchEngineService;
import com.dbnt.faisp.main.userInfo.model.UserInfo;
import com.dbnt.faisp.util.Utils;
@ -31,20 +31,46 @@ public class SearchEngineController {
if (Utils.isEmpty(params.getActiveTab())){
params.setActiveTab("all");
}
mav.addObject("searchParams", params);
int totalCnt = 0;
SearchResult result = null;
switch (params.getActiveTab()){
case "all":
params.setOffset("0");
params.setLimit("5");
// params.setOffset("0");
// params.setLimit("10");
params.setForm("search_menu_view.search_menu_view");
result = searchEngineService.getData(params, SearchMenuView.class);
totalCnt += result.getTotalCount();
mav.addObject("menuResult", result);
params.setForm("search_board_view.search_board_view");
result = searchEngineService.getData(params, SearchBoardView.class);
totalCnt += result.getTotalCount();
mav.addObject("boardResult", result);
params.setForm("search_file_view.search_file_view");
result = searchEngineService.getData(params, SearchFileView.class);
totalCnt += result.getTotalCount();
mav.addObject("fileResult", result);
break;
case "menu":
params.setForm("search_menu_view.search_menu_view");
result = searchEngineService.getData(params, SearchMenuView.class);
totalCnt += result.getTotalCount();
mav.addObject("menuResult", result);
break;
case "board":
params.setForm("search_board_view.search_board_view");
result = searchEngineService.getData(params, SearchBoardView.class);
totalCnt += result.getTotalCount();
mav.addObject("boardResult", result);
break;
case "file":
params.setForm("search_file_view.search_file_view");
result = searchEngineService.getData(params, SearchFileView.class);
totalCnt += result.getTotalCount();
mav.addObject("fileResult", result);
break;
}
mav.addObject("totalCnt", totalCnt);
return mav;
}

View File

@ -1,37 +1,42 @@
package com.dbnt.faisp.main.searchEngine.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
public class SearchBoardView {
private Integer menuKey;
private Integer mainKey;
private Integer menu_key;
private Integer main_key;
private String category;
private String title1Nm;
private String title1_nm;
private String title1;
private String title2Nm;
private String title2_nm;
private String title2;
private String content1Nm;
private String content1_nm;
private String content1;
private String content2Nm;
private String content2_nm;
private String content2;
private String content3Nm;
private String content3_nm;
private String content3;
private String content4Nm;
private String content4_nm;
private String content4;
private String content5Nm;
private String content5_nm;
private String content5;
private String description;
private String hashTag;
private String wrtOrgan;
private String wrtPart;
private Integer wrtUserSeq;
private String wrtUserGrd;
private String wrtUserNm;
private LocalDateTime wrtDt;
private String readAbleUser;
private String hash_tag;
private String wrt_organ;
private String wrt_part;
private Integer wrt_user_seq;
private String wrt_user_grd;
private String wrt_user_nm;
@JsonFormat(pattern = "yyyyMMddHHmmss")
private LocalDateTime wrt_dt;
private String readableuser;
}

View File

@ -6,13 +6,14 @@ import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class SearchFileView {
private Integer menuKey;
private Integer mainKey;
private Integer fileSeq;
private String origNm;
private String convNm;
private String fileExtn;
private String fileSize;
private String savePath;
private String fullPath;
private Integer menu_key;
private Integer main_key;
private Integer file_seq;
private String orig_nm;
private String conv_nm;
private String file_extn;
private String file_size;
private String save_path;
private String full_path;
private String file_content;
}

View File

@ -6,7 +6,7 @@ import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class SearchMenuView {
private Integer menuKey;
private String menuUrl;
private String menuNm;
private Integer menu_key;
private String menu_url;
private String menu_nm;
}

View File

@ -10,6 +10,5 @@ import java.util.List;
@NoArgsConstructor
public class SearchResult {
private Long totalCount;
private JSONArray rows;
private List<?> rowList;
}

View File

@ -1,9 +1,13 @@
package com.dbnt.faisp.main.searchEngine.service;
import com.dbnt.faisp.main.searchEngine.model.SearchMenuView;
import com.dbnt.faisp.main.searchEngine.model.SearchParams;
import com.dbnt.faisp.main.searchEngine.model.SearchResult;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
@ -16,6 +20,8 @@ import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
@ -24,14 +30,19 @@ public class SearchEngineService {
@Value("${search.engine.url}")
private String engineUrl;
public SearchResult requestToSearchEngine(SearchParams params){
public SearchResult getData(SearchParams params, Class<?> rowClass){
JSONObject jsonObj = requestToSearchEngine(params);
return convertJSONObjectToSearchResult(jsonObj, rowClass);
}
private JSONObject requestToSearchEngine(SearchParams params){
URI uri = UriComponentsBuilder.fromHttpUrl(engineUrl)
.path("/search5")
.queryParam("select", "*")
.queryParam("from", params.getForm())
.queryParam("where", "text_idx = '"+params.getKeyword()+"' allword synonym order by $relevance desc")
.queryParam("offset", params.getOffset())
.queryParam("limit", params.getLimit())
// .queryParam("offset", params.getOffset())
// .queryParam("limit", params.getLimit())
.queryParam("charset", "UTF-8")
.queryParam("hilite-keywords", params.getKeyword())
.encode()
@ -60,14 +71,30 @@ public class SearchEngineService {
} catch (ParseException e) {
e.printStackTrace();
}
/*이 근처에서 한번 분리할까...?*/
return jsonObj;
}
private SearchResult convertJSONObjectToSearchResult(JSONObject jsonObj, Class<?> rowClass){
JSONObject resultJSON = (JSONObject) jsonObj.get("result");
SearchResult result = new SearchResult();
result.setTotalCount((Long) resultJSON.get("total_count"));
result.setRows((JSONArray) resultJSON.get("rows"));
List<JSONObject> rowList = (List<JSONObject>)resultJSON.get("rows");
List<Object> convertList = new ArrayList<>();
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.registerModule(new JavaTimeModule());
try {
for(JSONObject row : rowList){
JSONObject fields = (JSONObject)row.get("fields");
Object rowObj = mapper.readValue(fields.toJSONString(), rowClass);
convertList.add(rowObj);
}
}catch (JsonProcessingException e) {
e.printStackTrace();
}
result.setRowList(convertList);
return result;
}
}

View File

@ -56,7 +56,7 @@ input::-moz-placeholder { color: #aaa; }
.searchWideBox > li p{position:absolute; top:13px; left:15px; font-size:16px; line-height:30px; font-weight:bold;}
.searchWideBox > li label{margin-right:14px; font-size:15px; line-height:32px; vertical-align:middle; color:#666;}
.searchWideBox > li ul:after{content:''; display:block; visibility:hidden; clear:both;}
.searchWideBox > li ul{width:331px; border:1px solid #ddd; border-left:none; box-sizing:border-box; float:left;}
.searchWideBox > li ul{padding-left:0; width:331px; border:1px solid #ddd; border-left:none; box-sizing:border-box; float:left;}
.searchWideBox > li > span{float:left; margin-left:8px;}
.searchWideBox > li ul li{float:left; width:55px; border-left:1px solid #ddd; box-sizing:border-box;}
.searchWideBox > li ul li a{display:block; text-align:center; font-size:14px; line-height:30px; background-color:#fff;}

View File

@ -47,61 +47,73 @@
</ul>
</div>
</div>
<div class="col-auto my-auto">
<ul class="nav nav-pills" sec:authorize="isAuthenticated()">
<li class="nav-item">
<a href="#" class="nav-link" th:id="${#lists.isEmpty(alarmList)?'':'bellIcon'}" th:classappend="${#lists.isEmpty(alarmList)?'link-dark':'link-danger'}">
<th:block th:if="${!#lists.isEmpty(alarmList)}">
<div class="position-relative">
<div id="alarmCntDiv" class="position-absolute text-center rounded-circle bg-danger text-light fs-11" th:text="${alarmListCnt>10?'9+':alarmListCnt}"></div>
<div id="alarmListDiv" class="position-absolute bg-white card d-none">
<div class="card-body">
<table class="table table-sm table-bordered table-hover">
<thead>
<tr class="table-secondary">
<th>메시지</th>
<th>발생일</th>
</tr>
</thead>
<tbody class="table-group-divider">
<tr class="alarmTr" th:each="alarm:${alarmList}">
<input type="hidden" class="alarmKey" th:value="${alarm.alarmKey}">
<input type="hidden" class="userSeq" th:value="${alarm.userSeq}">
<td th:text="${alarm.alarmMsg}"></td>
<td th:text="${#temporals.format(alarm.wrtDt, 'yyyy-MM-dd HH:mm:ss')}"></td>
</tr>
</tbody>
<tfoot th:if="${alarmListCnt>10}">
<tr>
<td colspan="2">
<a class="link-dark" href="/myInfo/myAlarm">더보기</a>
</td>
</tr>
</tfoot>
</table>
<div class="col-auto row justify-content-end my-auto">
<th:block sec:authorize="isAuthenticated()">
<div class="col-auto my-1">
<form action="/search/searchPage" method="get">
<div class="input-group">
<input type="text" class="form-control" name="keyword">
<input type="submit" class="btn btn-primary" value="검색">
</div>
</form>
</div>
<div class="col-auto">
<ul class="nav nav-pills">
<li class="nav-item">
<a href="#" class="nav-link" th:id="${#lists.isEmpty(alarmList)?'':'bellIcon'}" th:classappend="${#lists.isEmpty(alarmList)?'link-dark':'link-danger'}">
<th:block th:if="${!#lists.isEmpty(alarmList)}">
<div class="position-relative">
<div id="alarmCntDiv" class="position-absolute text-center rounded-circle bg-danger text-light fs-11" th:text="${alarmListCnt>10?'9+':alarmListCnt}"></div>
<div id="alarmListDiv" class="position-absolute bg-white card d-none">
<div class="card-body">
<table class="table table-sm table-bordered table-hover">
<thead>
<tr class="table-secondary">
<th>메시지</th>
<th>발생일</th>
</tr>
</thead>
<tbody class="table-group-divider">
<tr class="alarmTr" th:each="alarm:${alarmList}">
<input type="hidden" class="alarmKey" th:value="${alarm.alarmKey}">
<input type="hidden" class="userSeq" th:value="${alarm.userSeq}">
<td th:text="${alarm.alarmMsg}"></td>
<td th:text="${#temporals.format(alarm.wrtDt, 'yyyy-MM-dd HH:mm:ss')}"></td>
</tr>
</tbody>
<tfoot th:if="${alarmListCnt>10}">
<tr>
<td colspan="2">
<a class="link-dark" href="/myInfo/myAlarm">더보기</a>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</div>
</th:block>
<i class="bi bi-bell-fill"></i>
</a>
</li>
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle text-dark" data-bs-toggle="dropdown" aria-expanded="false">
<th:block th:each="commonCode:${session.commonCode.get('JT')}">
<th:block th:if="${commonCode.itemCd eq #authentication.principal.titleCd}">
<span class="d-lg-inline d-md-none" th:text="|${commonCode.itemValue} ${#authentication.principal.userNm}|">관리기능</span>
</th:block>
</th:block>
<b class="caret ms-1"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/myInfo/myInfoPage" class="dropdown-item">마이페이지</a></li>
<li><a href="/myInfo/myAlarm" class="dropdown-item">수신알람</a></li>
<li><a href="/logout" class="dropdown-item">로그아웃</a></li>
</th:block>
<i class="bi bi-bell-fill"></i>
</a>
</li>
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle text-dark" data-bs-toggle="dropdown" aria-expanded="false">
<th:block th:each="commonCode:${session.commonCode.get('JT')}">
<th:block th:if="${commonCode.itemCd eq #authentication.principal.titleCd}">
<span class="d-lg-inline d-md-none" th:text="|${commonCode.itemValue} ${#authentication.principal.userNm}|">관리기능</span>
</th:block>
</th:block>
<b class="caret ms-1"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/myInfo/myInfoPage" class="dropdown-item">마이페이지</a></li>
<li><a href="/myInfo/myAlarm" class="dropdown-item">수신알람</a></li>
<li><a href="/logout" class="dropdown-item">로그아웃</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</th:block>
</div>
</header>
</html>

View File

@ -15,13 +15,14 @@
<div class="headerArea">
<header id="searchHeader">
<div class="searchPagetop guideBox">
<form>
<form method="get" action="/search/searchPage">
<div class="searchBox">
<label class="hide" for="T_search">통합검색</label>
<input type="text" title="입력" id="T_search" placeholder="검색어를 입력해주세요." />
<a href="#">검색</a>
<div class="autoSearchList">
<!--<p>자동완성 기능입니다.(데이터 없을 경우 문구)</p>-->
<input type="hidden" name="activeTab" th:value="${searchParams.activeTab}">
<input type="text" title="입력" name="keyword" placeholder="검색어를 입력해주세요." th:value="${searchParams.keyword}"/>
<a href="#" id="searchBtn">검색</a>
<!--<div class="autoSearchList">
&lt;!&ndash;<p>자동완성 기능입니다.(데이터 없을 경우 문구)</p>&ndash;&gt;
<ul>
<li><a href="#">연관검색어 1</a></li>
<li><a href="#">연관검색어 2</a></li>
@ -31,13 +32,13 @@
<li><a href="#">연관검색어 6</a></li>
<li><a href="#">연관검색어 7</a></li>
</ul>
</div>
</div>-->
<a href="#" class="searchPageBoxBtn">검색옵션</a>
<div class="sRightBox">
<span>
<input id="reSearch" type="checkbox" value="#" />
<label for="reSearch">결과 내 재검색</label>
</span>
<span>
<input id="reSearch" type="checkbox" value="#" />
<label for="reSearch">결과 내 재검색</label>
</span>
</div>
</div>
</form>
@ -49,13 +50,13 @@
<fieldset>
<legend class="hide">상세검색</legend>
<ul class="searchWideBox">
<li>
<!--<li>
<p>정렬</p>
<input id="btn_chk1" type="radio" checked="checked" name="radio1" value="정확도순" />
<label for="btn_chk1">정확도순</label>
<input id="btn_chk2" type="radio" name="radio1" value="최신순" />
<label for="btn_chk2">최신순</label>
</li>
</li>-->
<li>
<p>기간</p>
<ul>
@ -67,19 +68,18 @@
<li><a href="#">1년</a></li>
</ul>
<span>
<span class="tie">
<label class="hide" for="beginDay">시작일</label>
<input id="beginDay" name="beginDay" type="date" value="" maxlength="250" class="shortText" />
</span>
<b>~</b>
<span class="tie">
<label class="hide" for="endDay">종료일</label>
<input id="endDay" name="endDay" type="date" value="" maxlength="250" class="shortText" />
</span>
<a href="#" class="dateAppBtn">적용하기</a>
</span>
<span class="tie">
<label class="hide" for="beginDay">시작일</label>
<input id="beginDay" name="beginDay" type="date" value="" maxlength="250" class="shortText" />
</span>
<b>~</b>
<span class="tie">
<label class="hide" for="endDay">종료일</label>
<input id="endDay" name="endDay" type="date" value="" maxlength="250" class="shortText" />
</span>
</span>
</li>
<li>
<!--<li>
<p>영역</p>
<input id="btn_chk3" type="checkbox" checked="checked" value="제목" />
<label for="btn_chk3">제목</label>
@ -87,7 +87,7 @@
<label for="btn_chk4">내용</label>
<input id="btn_chk5" type="checkbox" value="첨부파일" />
<label for="btn_chk5">첨부파일</label>
</li>
</li>-->
</ul>
</fieldset>
</form>
@ -95,51 +95,32 @@
<div class="searchContents">
<div class="guideBox searchDataBox" id="start_contents">
<div class="searchDataList">
<p class="searchDataInfo">검색어 <span class="red bold">"해양"</span>에 대한 총<span class="blue bold">7,623건</span>의 검색결과를 찾았습니다.</p>
<p class="searchDataInfo" th:if="${searchParams.activeTab eq 'all'}">
검색어 <span class="red bold" th:text="${searchParams.keyword}"></span>에 대한 총<span class="blue bold" th:text="${totalCnt}"></span>의 검색결과를 찾았습니다.
</p>
<ul class="searchDataNav">
<li class="active"><a href="search.html">통합검색</a></li>
<li><a href="search_menu.html">메뉴검색</a></li>
<li><a href="search_board.html">게시판</a></li>
<li><a href="search_file.html">첨부파일</a></li>
<li th:class="${searchParams.activeTab eq 'all'?'active':''}"><a class="searchTabLink" href="#" data-activetab="all">통합검색</a></li>
<li th:class="${searchParams.activeTab eq 'menu'?'active':''}"><a class="searchTabLink" href="#" data-activetab="menu">메뉴검색</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>
</ul>
<section class="searchDataListBox">
<h3>메뉴검색<span>8건</span></h3>
<h3>메뉴검색<span th:text="|${menuResult.totalCount}건|"></span></h3>
<ul class="menuList">
<li>
<ol>
<li><a href="#"><span class="red bold">해양</span>경찰청</a></li>
<li><a href="#">정책자료</a></li>
<li><a href="#"><span class="red bold">해양</span>경찰 나라지표</a></li>
</ol>
</li>
<li>
<ol>
<li><a href="#"><span class="red bold">해양</span>경찰청</a></li>
<li><a href="#">기관소개</a></li>
<li><a href="#"><span class="red bold">해양</span>경찰 추모관</a></li>
</ol>
</li>
<li>
<ol>
<li><a href="#"><span class="red bold">해양</span>경찰청</a></li>
<li><a href="#">새소식/알림</a></li>
<li><a href="#">공지사항</a></li>
</ol>
</li>
<li>
<ol>
<li><a href="#"><span class="red bold">해양</span>경찰청</a></li>
<li><a href="#">새소식/알림</a></li>
<li><a href="#">채용정보</a></li>
</ol>
</li>
<th:block th:each="menu:${menuResult.rowList}">
<li>
<ol>
<li th:text="${menu.menu_nm}"></li>
</ol>
</li>
</th:block>
</ul>
<div class="optionView">
<a href="#" class="plusView">더보기 +</a>
<!--<a href="#" class="plusView">더보기 +</a>-->
</div>
</section>
<section class="searchDataListBox">
<h3>게시판<span>998건</span></h3>
<h3>게시판<span th:text="|${boardResult.totalCount}건|"></span></h3>
<ul class="boardList">
<li>
<dl>
@ -195,7 +176,7 @@
</div>
</section>
<section class="searchDataListBox">
<h3>첨부파일<span>201건</span></h3>
<h3>첨부파일<span th:text="|${fileResult.totalCount}건|"></span></h3>
<ul class="boardList boardFileList">
<li>
<dl>
@ -228,7 +209,7 @@
</li>
</ul>
<div class="optionView">
<a href="#" class="plusView">더보기 +</a>
<!--<a href="#" class="plusView">더보기 +</a>-->
</div>
</section>