알람기능 작업 완료.
parent
698616fb80
commit
16b7570b56
|
|
@ -24,7 +24,6 @@ public class BaseController {
|
|||
private final CodeMgtService codeMgtService;
|
||||
private final OrganConfigService organConfigService;
|
||||
private final MenuMgtService menuMgtService;
|
||||
private final UserInfoService userInfoService;
|
||||
|
||||
@GetMapping("/")
|
||||
public ModelAndView loginCheck(@AuthenticationPrincipal UserInfo loginUser) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ public class BaseModel {
|
|||
private String endDate;
|
||||
@Transient
|
||||
private Boolean dashboardFlag = false;
|
||||
@Transient
|
||||
private Integer refDocKey;
|
||||
|
||||
public void setQueryInfo(){
|
||||
setFirstIndex((getPageIndex()-1)*getRowCnt());
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ public class FaispInterceptor implements HandlerInterceptor {
|
|||
param.setViewYn("N");
|
||||
param.setQueryInfo();
|
||||
mav.addObject("alarmList", userAlarmService.selectAlarmList(param));
|
||||
mav.addObject("alarmListCnt", userAlarmService.selectAlarmListCnt(param));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,4 +167,9 @@ public class MenuMgtService {
|
|||
});
|
||||
return firstMenuList;
|
||||
}
|
||||
|
||||
public String selectMenuUrl(Integer menuKey) {
|
||||
MenuMgt menuMgt = menuMgtRepository.findById(menuKey).orElse(new MenuMgt());
|
||||
return menuMgt.getMenuUrl();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@ package com.dbnt.faisp.main.userInfo;
|
|||
|
||||
import com.dbnt.faisp.kwms.service.KwmsService;
|
||||
import com.dbnt.faisp.main.codeMgt.service.CodeMgtService;
|
||||
import com.dbnt.faisp.main.menuMgt.service.MenuMgtService;
|
||||
import com.dbnt.faisp.main.userInfo.model.DashboardConfig;
|
||||
import com.dbnt.faisp.main.userInfo.model.UserAlarm;
|
||||
import com.dbnt.faisp.main.userInfo.model.UserInfo;
|
||||
import com.dbnt.faisp.main.userInfo.service.UserAlarmService;
|
||||
import com.dbnt.faisp.main.userInfo.service.UserInfoService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
|
|
@ -19,6 +22,8 @@ public class MyInfoController {
|
|||
|
||||
private final UserInfoService userInfoService;
|
||||
private final CodeMgtService codeMgtService;
|
||||
private final UserAlarmService userAlarmService;
|
||||
private final MenuMgtService menuMgtService;
|
||||
private final KwmsService kwmsService;
|
||||
|
||||
@GetMapping("/myInfoPage")
|
||||
|
|
@ -70,4 +75,27 @@ public class MyInfoController {
|
|||
userInfoService.updateUserInfo(loginUser,kwmsInfo);
|
||||
}
|
||||
}
|
||||
@GetMapping("/moveAlarmBoard")
|
||||
public ModelAndView moveAlarmBoard(UserAlarm alarm){
|
||||
alarm = userAlarmService.selectAlarm(alarm);
|
||||
String url = menuMgtService.selectMenuUrl(alarm.getMenuKey());
|
||||
if(url.contains("?")){
|
||||
url+="&refDocKey="+alarm.getRefDocKey();
|
||||
}else{
|
||||
url+="?refDocKey="+alarm.getRefDocKey();
|
||||
}
|
||||
return new ModelAndView("redirect:"+url);
|
||||
}
|
||||
|
||||
@GetMapping("/myAlarm")
|
||||
public ModelAndView myAlarm(@AuthenticationPrincipal UserInfo loginUser, UserAlarm alarm){
|
||||
ModelAndView mav = new ModelAndView("user/myAlarm");
|
||||
alarm.setQueryInfo();
|
||||
alarm.setUserSeq(loginUser.getUserSeq());
|
||||
mav.addObject("pageAlarmList", userAlarmService.selectAlarmList(alarm));
|
||||
alarm.setContentCnt(userAlarmService.selectAlarmListCnt(alarm));
|
||||
alarm.setPaginationInfo();
|
||||
mav.addObject("searchParams", alarm);
|
||||
return mav;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,13 @@ public class UserAlarm extends BaseModel {
|
|||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime wrtDt;
|
||||
|
||||
@Transient
|
||||
private String cat1Cd;
|
||||
@Transient
|
||||
private String cat2Cd;
|
||||
@Transient
|
||||
private String cat3Cd;
|
||||
|
||||
@Embeddable
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
|
|
|
|||
|
|
@ -63,4 +63,16 @@ public class UserAlarmService {
|
|||
alarmList.add(alarm);
|
||||
saveAlarmList(alarmList);
|
||||
}
|
||||
|
||||
public UserAlarm selectAlarm(UserAlarm alarm) {
|
||||
alarm = userAlarmRepository.findById(new UserAlarm.UserAlarmId(alarm.getAlarmKey(), alarm.getUserSeq())).orElse(null);
|
||||
alarm.setViewYn("Y");
|
||||
updateAlarm(alarm);
|
||||
return alarm;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateAlarm(UserAlarm alarm) {
|
||||
userAlarmRepository.save(alarm);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,19 +393,24 @@
|
|||
<if test='userSeq != null and userSeq != 0'>
|
||||
and a.user_seq = #{userSeq}
|
||||
</if>
|
||||
<if test='viewYn != null and viewYn != ""'>
|
||||
and a.view_yn = #{viewYn}
|
||||
</if>
|
||||
</where>
|
||||
</sql>
|
||||
<select id="selectAlarmList" resultType="UserAlarm" parameterType="UserAlarm">
|
||||
select a.alarm_key ,
|
||||
a.user_seq ,
|
||||
a.menu_key ,
|
||||
b.menu_url ,
|
||||
a.ref_doc_key ,
|
||||
b.cat1_cd,
|
||||
b.cat2_cd,
|
||||
b.cat3_cd,
|
||||
a.alarm_msg ,
|
||||
a.view_yn ,
|
||||
a.wrt_dt
|
||||
from user_alarm a
|
||||
inner join menu_mgt b on a.menu_key = b.menu_key
|
||||
inner join menu_mgt b on a.menu_key = b.menu_key
|
||||
<include refid="selectAlarmListWhere"></include>
|
||||
order by wrt_dt desc
|
||||
limit #{rowCnt} offset #{firstIndex}
|
||||
|
|
@ -413,7 +418,7 @@
|
|||
<select id="selectAlarmListCnt" resultType="int" parameterType="UserAlarm">
|
||||
select count(*)
|
||||
from user_alarm a
|
||||
inner join menu_mgt b on a.menu_key = b.menu_key
|
||||
inner join menu_mgt b on a.menu_key = b.menu_key
|
||||
<include refid="selectAlarmListWhere"></include>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
#fadeDiv{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
@ -34,6 +35,19 @@
|
|||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#alarmCntDiv{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
left: 12px;
|
||||
top: -4px;
|
||||
}
|
||||
#alarmListDiv{
|
||||
width: 500px;
|
||||
left: -300px;
|
||||
top: 30px;
|
||||
z-index: 5000;
|
||||
}
|
||||
|
||||
.activeTr{
|
||||
--bs-bg-opacity: 0.25;
|
||||
background-color: rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,20 @@ function searchFade(action){
|
|||
}
|
||||
}
|
||||
|
||||
$(document).on('click', '#bellIcon', function (){
|
||||
const alarmListDiv = $("#alarmListDiv")[0];
|
||||
if(alarmListDiv.className.includes('d-none')){
|
||||
alarmListDiv.className = "position-absolute bg-white card";
|
||||
}else{
|
||||
alarmListDiv.className = "position-absolute bg-white card d-none";
|
||||
}
|
||||
})
|
||||
$(document).on('click', '.alarmTr', function (){
|
||||
location.href = "/myInfo/moveAlarmBoard?" +
|
||||
"alarmKey="+$(this).find(".alarmKey").val()+
|
||||
"&userSeq="+$(this).find(".userSeq").val();
|
||||
})
|
||||
|
||||
$(document).on('click', '.allChk', function (){
|
||||
$(this).parents('table').find('[type="checkbox"]').prop("checked", this.checked);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
let selectedList = [];
|
||||
$(function(){
|
||||
if(location.search.includes("refDocKey")){
|
||||
const params = location.search.split('&');
|
||||
$.each(params, function (idx, param){
|
||||
if(param.includes("refDocKey")){
|
||||
const faRptKey = param.slice(param.indexOf("=")+1, param.length);
|
||||
getFaRptViewModal(faRptKey);
|
||||
}
|
||||
})
|
||||
}
|
||||
$("#dateSelectorDiv").datepicker({
|
||||
format: "yyyy-mm-dd",
|
||||
language: "ko",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
|
||||
$(function(){
|
||||
if(location.search.includes("refDocKey")){
|
||||
const params = location.search.split('&');
|
||||
$.each(params, function (idx, param){
|
||||
if(param.includes("refDocKey")){
|
||||
const key = param.slice(param.indexOf("=")+1, param.length);
|
||||
getAffairViewModal(key);
|
||||
}
|
||||
})
|
||||
}
|
||||
$("#dateSelectorDiv").datepicker({
|
||||
format: "yyyy-mm-dd",
|
||||
language: "ko",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
|
||||
$(function(){
|
||||
if(location.search.includes("refDocKey")){
|
||||
const params = location.search.split('&');
|
||||
$.each(params, function (idx, param){
|
||||
if(param.includes("refDocKey")){
|
||||
const key = param.slice(param.indexOf("=")+1, param.length);
|
||||
getPlanViewModal(key);
|
||||
}
|
||||
})
|
||||
}
|
||||
$("#dateSelectorDiv").datepicker({
|
||||
format: "yyyy-mm-dd",
|
||||
language: "ko",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
|
||||
$(function(){
|
||||
if(location.search.includes("refDocKey")){
|
||||
const params = location.search.split('&');
|
||||
$.each(params, function (idx, param){
|
||||
if(param.includes("refDocKey")){
|
||||
const key = param.slice(param.indexOf("=")+1, param.length);
|
||||
getResultViewModal(key);
|
||||
}
|
||||
})
|
||||
}
|
||||
$("#dateSelectorDiv").datepicker({
|
||||
format: "yyyy-mm-dd",
|
||||
language: "ko",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,17 @@
|
|||
let selectedList = [];
|
||||
|
||||
$(function() {
|
||||
if (location.search.includes("refDocKey")) {
|
||||
const params = location.search.split('&');
|
||||
$.each(params, function (idx, param) {
|
||||
if (param.includes("refDocKey")) {
|
||||
const key = param.slice(param.indexOf("=") + 1, param.length);
|
||||
getSriViewModal(key);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
$(document).on('click', '#addSriBtn', function (){
|
||||
getSriEditModal({faSriKey: null})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -50,7 +50,43 @@
|
|||
</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:classappend="${#lists.isEmpty(alarmList)?'link-dark':'link-danger'}"><i class="bi bi-bell-fill"></i></a></li>
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link" 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-white fs-11" th:text="${alarmListCnt}"></div>
|
||||
<div id="alarmListDiv" class="position-absolute bg-white card d-none">
|
||||
<div class="card-body">
|
||||
<table class="table 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">더보기</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</th:block>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bell-fill" viewBox="0 0 16 16" th:id="${#lists.isEmpty(alarmList)?'':'bellIcon'}">
|
||||
<path d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2zm.995-14.901a1 1 0 1 0-1.99 0A5.002 5.002 0 0 0 3 6c0 1.098-.5 6-2 7h14c-1.5-1-2-5.902-2-7 0-2.42-1.72-4.44-4.005-4.901z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle text-black" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<th:block th:each="commonCode:${session.commonCode.get('JT')}">
|
||||
|
|
@ -62,6 +98,7 @@
|
|||
</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>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,116 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{layout/layout}">
|
||||
<div layout:fragment="content">
|
||||
<main class="pt-3">
|
||||
<h4>수신 알람 목록</h4>
|
||||
<div class="row mx-0">
|
||||
<div class="col-12 card">
|
||||
<div class="card-body">
|
||||
<form method="get" th:action="@{/myInfo/noticePage}">
|
||||
<input type="hidden" name="pageIndex" id="pageIndex" th:value="${searchParams.pageIndex}">
|
||||
<div class="row justify-content-between pe-3 py-1">
|
||||
<div class="col-auto">
|
||||
<select class="form-select form-select-sm" name="rowCnt" id="rowCnt">
|
||||
<th:block th:each="num : ${#numbers.sequence(1,5)}">
|
||||
<option th:value="${num*10}" th:text="${num*10}" th:selected="${searchParams.rowCnt eq num*10}"></option>
|
||||
</th:block>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="row justify-content-end">
|
||||
<div class="col-4">
|
||||
<div class="input-group w-auto input-daterange" id="dateSelectorDiv">
|
||||
<input type="text" class="form-control form-control-sm" id="startDate" name="startDate" placeholder="시작일" autocomplete="off" readonly th:value="${searchParams.startDate}">
|
||||
<input type="text" class="form-control form-control-sm" id="endDate" name="endDate" placeholder="종료일" autocomplete="off" readonly th:value="${searchParams.endDate}">
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-sm btn-primary col-auto" id="searchBtn" value="검색">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="row justify-content-start">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<table class="table table-hover table-bordered">
|
||||
<thead>
|
||||
<tr class="table-secondary">
|
||||
<th>대분류</th>
|
||||
<th>중분류</th>
|
||||
<th>소분류</th>
|
||||
<th>메시지</th>
|
||||
<th>열람여부</th>
|
||||
<th>등록일시</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="table-group-divider">
|
||||
<tr class="alarmTr" th:each="alarm:${pageAlarmList}">
|
||||
<input type="hidden" class="alarmKey" th:value="${alarm.alarmKey}">
|
||||
<input type="hidden" class="userSeq" th:value="${alarm.userSeq}">
|
||||
<td>
|
||||
<th:block th:each="code:${session.commonCode.get('CAT1')}">
|
||||
<th:block th:if="${code.itemCd eq alarm.cat1Cd}" th:text="${code.itemValue}"></th:block>
|
||||
</th:block>
|
||||
</td>
|
||||
<td>
|
||||
<th:block th:each="code:${session.commonCode.get('CAT2')}">
|
||||
<th:block th:if="${code.itemCd eq alarm.cat2Cd}" th:text="${code.itemValue}"></th:block>
|
||||
</th:block>
|
||||
</td>
|
||||
<td>
|
||||
<th:block th:each="code:${session.commonCode.get('CAT3')}">
|
||||
<th:block th:if="${code.itemCd eq alarm.cat3Cd}" th:text="${code.itemValue}"></th:block>
|
||||
</th:block>
|
||||
</td>
|
||||
<td th:text="${alarm.alarmMsg}"></td>
|
||||
<td th:text="${alarm.viewYn eq 'Y'?'O':'X'}"></td>
|
||||
<td th:text="${#temporals.format(alarm.wrtDt, 'yyyy-MM-dd HH:mm:ss')}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row justify-content-between">
|
||||
<div class="col-auto"></div>
|
||||
<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">«</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 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" th:data-pageindex="${(searchParams.pageIndex)+3}">
|
||||
<a class="page-link" href="#" aria-label="Next">
|
||||
<span aria-hidden="true">»</span>
|
||||
</a>
|
||||
</li>
|
||||
</th:block>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<input type="button" class="btn btn-success" value="등록" id="addNoticeBtn" sec:authorize="hasRole('ROLE_SUB_ADMIN')">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</html>
|
||||
Loading…
Reference in New Issue